This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Ethernet Http Get Cyclic Error 101

Other Parts Discussed in Thread: SYSBIOS

Hello,

I am having a weird problem with the NDK stack, when I try to make a http get request, I get from time to time an error 101 (on httpcli_connect), and in between the value are well received.

Before, I was having this kind of error after disconnecting and reconnecting the ethernet physical link but now it's happening even without disconnection of physical socket...


Here the source code based on the HTTP Get example for TM4C1294XL board.

/*
 * Copyright (c) 2015, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 *  ======== httpget.c ========
 *  An HTTP Client example application that GETs weather info.
 */
#include <string.h>

/* XDCtools Header files */
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>

/* TI-RTOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/drivers/GPIO.h>
#include <ti/net/http/httpcli.h>

#include <sys/socket.h>

/* Example/Board Header file */
#include "Board.h"

#define IP   "54.175.219.8"
#define PORT  80

#define HOSTNAME "httpbin.org"
#define REQUEST_URI "/ip"
#define HTTPTASKSTACKSIZE 2048 /* * ======== printError ======== */ void printError(char *errString, int code) { System_printf("Error! code = %d, desc = %s\n", code, errString); System_flush(); BIOS_exit(code); } /* * ======== httpTask ======== * Makes an HTTP GET request */ Void httpTask(UArg arg0, UArg arg1) { bool moreFlag = false; char db_write_ok[20]={0x00,0x00,0x00,0x00,'\0'}; int ret; char header[100]={}; struct sockaddr_in addr; HTTPCli_Struct cli; HTTPCli_Field fields[2] = { { HTTPStd_FIELD_NAME_HOST, HOSTNAME }, { NULL, NULL } }; while(1) { // Set port and IP address of the database addr.sin_family = AF_INET; addr.sin_port = htons(PORT); inet_pton(AF_INET, IP, &addr.sin_addr); HTTPCli_construct(&cli); HTTPCli_setRequestFields(&cli, fields); ret = HTTPCli_connect(&cli, (struct sockaddr *)&addr, 0, NULL); if (ret < 0) { System_printf("httpTask: connect failed : %d\n", ret);System_flush(); HTTPCli_disconnect(&cli); HTTPCli_destruct(&cli); } ret = HTTPCli_sendRequest(&cli, HTTPStd_GET, REQUEST_URI, false); if (ret < 0) { System_printf("httpTask: send failed : %d\n", ret);System_flush(); HTTPCli_disconnect(&cli); HTTPCli_destruct(&cli); } ret = HTTPCli_getResponseStatus(&cli); if (ret != HTTPStd_OK) { System_printf("httpTask: cannot get status : %d\n", ret);System_flush(); HTTPCli_disconnect(&cli); HTTPCli_destruct(&cli); } ret = HTTPCli_getResponseField(&cli, header, sizeof(header), &moreFlag); if (ret != HTTPCli_FIELD_ID_END) { System_printf("httpTask: response field processing failed : %d\n", ret);System_flush(); HTTPCli_disconnect(&cli); HTTPCli_destruct(&cli); } ret = HTTPCli_readResponseBody(&cli, db_write_ok, sizeof(db_write_ok), &moreFlag); if (ret < 0) { System_printf("httpTask: response body processing failed : %d\n", ret);System_flush(); HTTPCli_disconnect(&cli); HTTPCli_destruct(&cli); } System_printf("Rcv : %s\n",db_write_ok);System_flush(); HTTPCli_disconnect(&cli); HTTPCli_destruct(&cli); Task_sleep(3000); } } /* * ======== netIPAddrHook ======== * This function is called when IP Addr is added/deleted */ void netIPAddrHook(unsigned int IPAddr, unsigned int IfIdx, unsigned int fAdd) { static Task_Handle taskHandle; Task_Params taskParams; Error_Block eb; /* Create a HTTP task when the IP address is added */ if (fAdd && !taskHandle) { Error_init(&eb); Task_Params_init(&taskParams); taskParams.stackSize = HTTPTASKSTACKSIZE; taskParams.priority = 1; taskHandle = Task_create((Task_FuncPtr)httpTask, &taskParams, &eb); if (taskHandle == NULL) { printError("netIPAddrHook: Failed to create HTTP Task\n", -1); } } } /* * ======== main ======== */ int main(void) { /* Call board init functions */ Board_initGeneral(); Board_initGPIO(); Board_initEMAC(); /* Turn on user LED */ GPIO_write(Board_LED0, Board_LED_ON); System_printf("Starting the HTTP GET example\nSystem provider is set to " "SysMin. Halt the target to view any SysMin contents in ROV.\n"); /* SysMin will only print to the console when you call flush or exit */ System_flush(); /* Start BIOS */ BIOS_start(); return (0); }

The TI-RTOS version is 2.14.00.10.

Thank you in advance for your help.

  • Yannick,

    Have you tried calling HTTPCli_getSocketError() when this occurs?  What does it report?

    Are you running the httpget example unmodified and seeing this error?  Or have you modified the example?

    And can you describe your network setup?  Have you tried different network cables and configurations? 

    I see you have a separate thread going regarding getting this error after physical disconnect/connect (e2e.ti.com/.../1737736 I wonder if maybe there is an intermittent physical connection in your setup?

    Regards,
    Scott

  • Thank you for your answer,

    ScottG said:

    Yannick,

    Have you tried calling HTTPCli_getSocketError() when this occurs?  What does it report?

    The HTTPCli_getSocketError() function returns -1 as error but the HTTPCli_connect() function return 101 which means switching protocol or socket connect failed. But after the socket can successfully get data... The error happen cyclically (like 1 every x http get)

    ScottG said:

    Are you running the httpget example unmodified and seeing this error?  Or have you modified the example?

    I modified the example because the original one was not working (the ip address for the http get is false, it is a local one...), so I just modified it to get my ip address in plain text from a website.

    ScottG said:


    And can you describe your network setup?  Have you tried different network cables and configurations? 

    The board is connected to a router to the internet, yes I tried other network cable an the same poblem occur.

    ScottG said:

    I see you have a separate thread going regarding getting this error after physical disconnect/connect (e2e.ti.com/.../1737736 I wonder if maybe there is an intermittent physical connection in your setup?

    The physical ethernet cable is well connected during the tests.


    Best Regards,

    Yannick

  • Yannick,

    I’ve been talking with the NDK team.  When the error happens… can you please print errno and tell us what it is?

    Thanks,
    Scott

  • Hello,


    I just tried on another network without another router and the error is still happening. What do you mean by "errno", which function do I need to use ?

    The problem is happening with

    ret = HTTPCli_connect(&cli, (struct sockaddr *)&addr, 0, NULL);
    if (ret < 0)
    {
               System_printf("httpTask: connect failed : %d\n", ret);System_flush();
    
               HTTPCli_disconnect(&cli);
               HTTPCli_destruct(&cli);
    }

    In my case the error happens every 12 request before showing a connect failed error (101). The http get request is launched every 2000 ticks (Task_sleep(2000). It appears that when I slow down the request rate to 5000 ticks, the cyclic connection failed doesn't happen anymore. But I want to send fast request response without waiting a long delay, why this error is happening ?

    I think that the problem is that the connection is reseted because the server is protecting himself against too many request.

    If I make 11 request, wait 60 seconds, then send another 11 request the system is working fine, but if I wait less than 60 seconds, the 12th request will lead to a connection failed (101) and then the rest of the 10 request will go fine. In other terms, if I make more than 11 request during a 1 minute time slot, then there will be a connection failed once and the rest of the request will go fine. Every 11 request, there will be a connection failed.

    And the error printed is 101.

    Regards,

    Yannick Riou

  • Yannick,

    Thanks for the additional details. I'll ask to see if there is an explanation for this behavior.

    In the meantime... errno is a global variable set by some system calls when an error occurs.  You can print this like any other global variable:

        System_printf("errno = %d”, errno);

    You may need to include the errno.h header in your file:

        #include <errno.h>

    Can you please report what it is when the connect fails?

    Thanks,
    Scott

  • Scott,


    When the http connect error occurs, I got the errno = 12.

    For information, if I make get request via a wifi device (tcp client), the same error DOESN'T occur, so I think the error comes from the NDK I think.

    Waiting for your reply.


    Regards,

  • Yannick,

    errno = 12 indicates “cannot allocate memory”.   I’m asking the NDK guys for advice on this.  In the meantime, have you checked memory usage by your app?  Might it makes sense the app can be running out of memory when requests are made too fast?

    And just FYI if you haven't seen it, here is a wiki page with info about NDK memory usage: processors.wiki.ti.com/.../TI-RTOS_Networking_Stack_Memory_Usage

    Regards,
    Scott

  • Hi,


    Thank you for the explanation, it is now clearer ! 

    I tried to increase the Page Size and the Number of Pages in the Memory manager buffers section (TI-RTOS > Products > NDK > Networking - Stack Buffer Sizes and Placement), with this modification, I can send more http get before the error occurs, but it doesn't solve the problem.


    In my opinion, it's like the stack isn't unallocating the socket related memory, so it can send a number of frame depending on the memory that is available and after this number is reached, the stack goes on error, unallocate all memory related and then restart to send the http get before running into another error, etc.


    But why the stack isn't unallocating ? I properly executed the HttpCli_disconnect and the HttpCli_destruct, as in the example.


    Another question is that why does this works if the send frequency is low (1 every minutes per example) ? Does the stack need time before unallocating things ?


    I tried custom memory settings for the stack, the task but it didn't resolve the problem, error is still occuring but at different tim depending on the memory available (more memory available = more frame before the error occur)

    Thank you for your help !


    Regards,

  • Yannick,

    OK, thanks. 

    One of the engineers here has been able to recreate the problem you are reporting.  It may indeed be a memory leak, or a delayed memory cleanup issue.  The team is investigating this, and we’ll get back to you when we know more.

    Thanks for your patience.

    Regards,
    Scott

  • Hi Scott,

    do you have any news so far from the NDK team about the problem ?

    Thank you for your help !

    Regards,

    Yannick
  • Yannick,

    I'm still looking at this issue. I'll respond back here as soon as I have an update. Thank you for your patience.

    Steve
  • Hi Steven,

    Coming to see if there is update about the memory problem ?

    Thank you for your help !

    Yannick
  • Yannick,

    Yes, a couple of things.  First, I'm wondering if you're running out of frame buffers by chance.  These are the buffers that are used to store Ethernet frames.

    You can quickly test this by increasing the number of PBM frame buffers in your XGCONF configuration for your app (under the NDK's "Global" module view).

    Next, a possible memory leak was discovered recently.  Can you try to see if this if the following code addition fixes your issue?

    Note that this will require an NDK rebuild.  So, to try it, you should use a duplicate/separate copy of the NDK to test it.  You can find details on rebuilding the NDK in the NDK's release notes:

    The fix is to flush the transmit buffer (shown in red), as well as the receive buffer, in "SockShutdown( HANDLE h, int how )" in sock.c:

    /* Perform read flush */
    if( ps->hSBRx )
         SBFlush( ps->hSBRx, 1 );

    /* Perform transmit flush (ADDED) */
    if( ps->hSBTx )
         SBFlush( ps->hSBTx, 1 );

    Steve

  • Steve,


    I tested the two method but none of them seems to fix my issue :

    - when I try to change the number of PBM frames from 16 to 32, I just run into this issue

    ti.sysbios.family.arm.m3.Hwi: line 1087: E_hardFault: FORCED
    ti.sysbios.family.arm.m3.Hwi: line 1132: E_memFault: IACCVIOL: Instruction Access Violation, address: e000ed34
    Exception occurred in ISR thread at PC = 0xfffffffe.
    Core 0: Exception occurred in ThreadType_Hwi.
    Hwi name: {unknown-instance-name}, handle: 0x2000ce68.


    I had the same issue when I tried this earlier.

    - I rebuilded the stack with given fix into the sock.c file but It doesn't solve the problem, there is still an http connect error 101 after 12 frames sent.

    Thanks for your help,


    Regards,

  • Hello,

    Do you have any news about the problem ?

    thank you,

    Regards,
  • I would also like an update on this issue (from either TI or anyone else who has solved it).

    I'm seeing the same issue using both HTTPGET and HTTPPOST.
    I get a socket error 12 (ENOMEM) every 12/13 requsts/posts on HTTPCli_connect.
    The timing between the gets/posts doesn't seem to matter from what I can tell.

    I'm using the TM4C1294 eval board like the OP and also using a modified version of the httpget example program.
    tirtos_tivac_2_14_04_31

    (Not trying to hijack the thread, I'm guessing that this is the same issue that I'm seeing though?)
  • Hi Steven,

    Do you have any news about the issue ?

    Thanks

  • Hi, does anyone from TI have news about this issue ?

    Thanks,

    Regards,

  • Not sure this helps since you already looked into adusting the frame bufs, but I resolved my issues by adjusting the memory sizes for the tasks/buffers in the config file. Also, I had to change my heapmem size.


    This is my NDK config for reference:

    /* ================ NDK configuration ================ */

    var Ndk = xdc.loadPackage('ti.ndk.config');
    var Global = xdc.useModule('ti.ndk.config.Global');
    var Tcp = xdc.useModule('ti.ndk.config.Tcp');
    Global.IPv6 = false;
    Global.stackLibType = Global.MIN;
    Global.networkIPAddrHook = "&NetIP_AddressUpdateHook";
    /* automatically call fdOpen/CloseSession for our sockets Task */
    Global.autoOpenCloseFD = true;
    Global.pktNumFrameBufs = 10;
    Global.memRawPageCount = 8;
    Global.ndkThreadStackSize = 2048;
    Global.lowTaskStackSize = 1536;
    Global.normTaskStackSize = 1536;
    Global.highTaskStackSize = 1536;
    Tcp.transmitBufSize = 1024;
    Tcp.receiveBufSize = 1024;

    Also, if you haven't tried, it might be worth updating RTOS version? Not very helpful, but still might be worth trying...

    Good luck.

  • Hi SD,

    my NDK config looks exactly the same as you and the problem still occurs, and I did try to adjust the buff size in many ways without resolving the problem but thanks for the help.

    Also my TI-RTOS for Tivac is the last version...

    Thanks again for your help.
  • Hi,

    is there any one who had solved this issue? I have the same issue as same as Yannick's issue.

    Thanks.
    BR
  • Hi Murat,
    We generally discourage posting a new question to an old closed thread because the person who answered before may no longer be available, and also it will allow whomever is currently assigned to monitor the forum to respond to you more quickly. For these reasons, I suggest you start a new thread with your question and reference this thread.

    Thank you