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.

TM4C1294NCPDT: Issue with HTTP POST within LAN

Part Number: TM4C1294NCPDT

To develop a Ethernet based Monitoring Device (read: HTTPClient) for a customer, we modified the qs_iot example from TivaWare_C_Series-2.1.4.178 to sent HTTP POST requests (with JSON body) to a Web Service developed by ourselves only. 

For the implementation, we used a Public IP to expose the Web API and all HTTP POST operation was happening OK. There was no issue. The Device was able to send HTTP Post requests to the Web Service similar to what a PC based HTTP client does (such as ARC Advanced Rest Client). The product was tested OK. 

Somedays back we had to move the Internet based Web Service to our LAN, which meant that the web service was now available in the LAN (over an IP 192.168.1.2). 

Surprisingly, the device failed to send Data to the web service within our LAN and upon debugging, I found out that the function exoHAL_SocketOpenTCP(server) in exosite.c was failing with the message: 

Err: Bad Socket (Issue with Internet or Server) 

However the Device is able to procure an IP address from DHCP but somehow socket connection fails within the LAN. 

Secondly, We again tried to send the HTTP POST request to a server based in the Internet (Public IP) and to my surprise, the same Firmware (only with change in API endpoint) works flawlessly from the same network. 

In short, exoHAL_SocketOpenTCP() fails when the destination is within the LAN but works OK when the destination is a URL / Publc IP over the internet. 

Some hints: 

  • I'm able to PING my Device (192.168.1.20) from the Server (192.168.1.2) within the LAN
  • HTTP POST requests using a desktop based HTTP Client are OK (200) within the LAN 
  • I assigned the IP taken by the Device to my PC and then sent the HTTP POST request using a HTTP Client and it succeeds. 
  • So in short, Something is Wrong with the exoHAL which is caused the socket error. 

Please help with the solution.

Thanks. 

  • Hi Anwej,

      I'm not familiar with the exoHAL_SocketOpenTCP. Reading the code, I'm not too sure if this is the right function to use to connect to the socket if you are within a LAN network. I see in the code that it is trying to call  exoHAL_ServerConnect(0) which is on the internet. 

      I will suggest you reference other ethernet examples we have such as enet_io or enet_lwip. These examples work within the LAN. First run them as is and make sure it works on your LAN network. Hopefully, with some modification you can adapt to your application. 

  • Hi Charles, 

    Thanks for the prompt response. 

    We have invested a lot of time developing this solution assuming that the behavior of the HTTP Client firmware would be the same within and outside the LAN. Somehow it fails to within the LAN. We are now at the stage of deployment but the issue has stalled it. I understand that using enet_io or enet_lwip solution could be an alternative but we need help to ease the current situation.

    There must be some way, Please suggest me the changes needed to be done in order to get this working. 

    Thanks, Regards 

    Anwej Alam

  • Hi Anwej,

      I'm not sure how much I'm able to help out here. I myself is not familiar with the exocite code at all. 

      Is it the connect_to_exosite() where you are stalled when you call exoHAL_SocketOpenTCP()? as shown below? If not, where do you call exoHAL_SocketOpenTCP() that fails? Can you provide more detail as to which line of code it is stuck? What is the return value when you call exoHAL_SocketOpenTCP()?

    long
    connect_to_exosite(void)
    {
    unsigned char connectRetries = 0;
    unsigned char server[META_SERVER_SIZE];
    long sock = -1;

    exosite_meta_read(server, META_SERVER_SIZE, META_SERVER);

    while (connectRetries++ <= EXOSITE_MAX_CONNECT_RETRY_COUNT) {

    sock = exoHAL_SocketOpenTCP(server);

    if (sock == -1)
    {
    continue;
    }

      Can you also use wireshark to see if you can troubleshoot where the problem is?

      

  • Hi Charles, 

    Thanks for the reply. Below is how I send data: 

    SyncWithExosite()  in main() calls Exosite_Write() which calls the below snippet

    long sock = connect_to_exosite();
    if (sock < 0) {
    status_code = EXO_STATUS_BAD_TCP;

    UARTprintf(" \n Err: Bad Socket (Issue with Internet or Server)\n");

    return 0;
    }

    in the function connect_to_exosite(), I overwrite the server IP 

    server[0]=192;
    server[1]=168;
    server[2]=1;
    server[3]=2;

    before calling 

    sock = exoHAL_SocketOpenTCP(server);

    It is here, the socket connection fails. 

    Interestingly, the socket connection, and the POST request succeeds with 200 Status when the server IP is 61.246.3.94 (a public IP used by us)

    server[0]=61;
    server[1]=246;
    server[2]=3;
    server[3]=94;

    I hope I have explained it properly. 

    br

    Anwej Alam

  • Sorry, I forgot to mention, wireshark doesnt show any activity related to the interaction between client and server when we fail to create TCP socket. But in case of public IP, all transaction is visible as it should be.

    br

    Anwej

  • Hi,

      If possible, would you also seek help from exocite as I really don't know what happened that is causing the failure. Hopefully they there is some experts to advice. I suppose when you call sock = exoHAL_SocketOpenTCP(server), the sock is -1.  Can you single step through exoHAL_SocketOpenTCP and find out which line/step caused the API to return -1?

      I also have a feeling that if the server is on your LAN network, does it make sense to use the exocite code which is meant to connect to a remote server on the internet? Normally, I see below LwIP code for the client to connect to a socket. Below is a snippet of code. Unfortunately we don't have any client example but if you do some Google search I hope you might find some LwIP client examples on the web.

    void echo_client_init(void)
    {
        /* create an ip */
        struct ip_addr server_addr;
    
        /* create the control block */
        testpcb = tcp_new();    
    
        if (testpcb != NULL)
        {
            IP4_ADDR(&server_addr, 10,219,15,38);    //IP of the PC computer
    
    		tcp_bind(testpcb, IP_ADDR_ANY, 7000);
    
    		/* now connect */
    		err = tcp_connect(testpcb, &server_addr, 8000, connectCallback);
    	    if (err) {
    	        UARTprintf("ERROR: Code: %d (tcp_connect)\n", err);
    	    }
    
    		UARTprintf("PCB CREATED\n");
    
        } else {
            memp_free(MEMP_TCP_PCB, testpcb);
    		UARTprintf("PCB NOT CREATED\n");
    
        }
    
    }

     

     

  • Dear Charles,

    It's just the exosite example we are using, apart from that exosite is nowhere in the picture, how can someone from exosite help me?

    It makes absolute sense to use the exosite example to send http post requests to a web api.

    Pls look into the qs_iot example and let me know where the corrections are to be done.

    Br

    Anwej

  • Hi Anwej,

      I wonder if it has something to do with the DNS. The exoHAL_SocketOpenTCP  may be expecting a portal name such as www.xyz.com  instead of an IP address as you directly supply in your code. Another question for the working case where you can successfully send the request to the server on the internet, do you use the DNS and a portal name? If you are using a portal name, can you change to an direct IP address? Will that make it fail now? This experiment is to test if it has something to do with the IP address vs. using portal name. Sorry, I can only offer limited advice here as I'm not an expert in the exocite stacks. 

  • Dear Charles, 

    Thanks for the reply. We have tested sending POST requests to both IP addresses and URLs and it works OK in both the cases. 

    Below snippet is from original code (exosite.c)

    #define STR_HTTP " HTTP/1.1\r\n"
    #define STR_HOST "Host: m2.exosite.com\r\n"
    #define STR_ACCEPT "Accept: application/x-www-form-urlencoded; charset=utf-8\r\n"
    #define STR_CONTENT "Content-Type: application/x-www-form-urlencoded; charset=utf-8\r\n"

    Below snippet-1 is also working (Host: URL of my web API)

    #define STR_HTTP " HTTP/1.1\r\n"
    #define STR_HOST "Host: gaurav325-001-site1.gtempurl.com\r\n"
    #define STR_ACCEPT "Accept: application/x-www-form-urlencoded; charset=utf-8\r\n"
    #define STR_CONTENT "Content-Type: application/json; charset=utf-8\r\n"

    Below snippet-2 is also working (Host: Public IP, of my web API)

    #define STR_HTTP " HTTP/1.1\r\n"
    #define STR_HOST "Host: 61.246.3.94\r\n"
    #define STR_ACCEPT "Accept: application/x-www-form-urlencoded; charset=utf-8\r\n"
    #define STR_CONTENT "Content-Type: application/json; charset=utf-8\r\n"

    :)

    You see, we have already attempted the above tests. Only issue is the when the Host is within the LAN, it fails. 

    Thanks, Regards

    Anwej

  • Hi Anwej,

      In the exoHal_SocketOpenTCP API which line did you fail? Can you please elaborate? 

      In line 749 of the original exosite_hal_lwip.c file it has the below line of code. What IP address was returned? 

    // Get the current IP address.
    //
    ui32IPAddr = EthClientAddrGet();

    In the exoHAL_SocketOpenTCP() it also checks if you have proxy and DNS. Since you are working on your LAN and therefore you should not need DNS.  However, is it possible that you fail DNS here as it thinks that it needs to resolve the DNS but you really don't need it. The DNS checks is shown as follows. 

    if (!HWREGBITW(&g_sExosite.ui32Flags, FLAG_DNS_INIT))
    {
    //
    // Resolve the host address.
    //
    i32Error = EthClientDNSResolve();

    //
    // If error, break.
    //
    if (i32Error != 0 && i32Error != -5)
    {
    break; 
    }

    If you trace the code in EthClientDNSResolve(), it will call the below dns_gethostbyname to resolve server IP address and save the server IP address in SEnet.sResolvedIP. Is it possible that the server address you tried to force is overwritten by dns_gethostbyname call?

    //
    // Resolve host name.
    //
    if(g_sEnet.pcProxyName != 0)
    {
    iRet = dns_gethostbyname(g_sEnet.pcProxyName, &g_sEnet.sResolvedIP,
    DNSServerFound, 0);
    }
    else
    {
    iRet = dns_gethostbyname(g_sEnet.pcHostName, &g_sEnet.sResolvedIP,
    DNSServerFound, 0);
    }


    Finally, it tries to connect with the below call to EthClientTCPConnect(). What does it return?

    //
    // Try to reconnect.
    //
    i32Error = EthClientTCPConnect();

    //
    // If error, break.
    //
    if (i32Error != 0)
    {
    break;
    }


    It is really vague to me as to where in the exoHAL_SocketOpenTCP you failed. If you single step through the code you should get a much better idea. 

    Also wanted to give you a heads-up. I will be out of office for a couple of days. I hope you can do some debug on your own during this time. 

     

  • Hi Anwej,

      I have not heard back from you. I hope you are able to make some progress and resolve your issue. I will close the thread for now. If your issue is not resolved you can reply back with updates to reopen the thread. 

  • Dear Charles, 

    So far the issue is not resolved from my end

    br

    Anwej

  • Hi,

      Can you provide updates to the questions I asked in the post dated Fri, Oct 4 2019 3:12 PM?

  • Hi,

    I think there is some issue with the HTTP stack given in qs_iot. I have moved to the TI-RTOS implementations. It is working now.

    thanks

    Anwej