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.

RTOS/TI-RTOS-MCU: Creating http post

Part Number: TI-RTOS-MCU


Tool/software: TI-RTOS

Hi,

I am using ccs v6.2 with tm41294xl I want to create "http post" task as like http get, can I get any links or solutions in TI-RTOS. 

Regards,

Raghu DS

  • Hi Raghu,


    Yes, you can find some example POST code in the HTTP client documentation of the Network Services product.  For example, it might be located here:

    C:/ti/tirtos_tivac_2_16_01_14/products/ns_1_11_00_10/docs/html/index.html

    In the HTTP client module you'll find the example:

  • Hi Steven,
    Thanks for the reply, this is the answer for my question but I was not found headers like "sswolfssl.h" and "sssl.h" no where in TI_RTOS or Tivaware.
    So, i was getting an error #1965, can I get any suggestions or alternatives to this.

    Regards,
    Raghu DS
  • Those files should be found in the Network Services product. It's under the products folder of your TIRTOS install.

    C:/tirtos_tivac_2_16_01_14/products/ns_1_11_00_10/

    If you update your project's compiler include path for this, it should find it (e.g. add -IC:/tirtos_tivac_2_16_01_14/products/ns_1_11_00_10/packages and then #include <ti/net/http/sswolfssl.h> should be found).

    Steve
  • Hi Steven,

    Thanks for the reply, I had include path to my compiler as shown in my image

    Am I added to correct place, and I am using tirtos V 2_16_00_08. But till getting same error-  #1965 cannot open source file "ti/net/http/sswolfssl.h". Can you please help me to solve my problem.

    Regards,

    Raghu DS

  • Hi Steven,

    I think what I did on above may be wrong, as you suggest my project already includes the path "C:\ti\tirtos_tivac_2_16_00_08\products\ns_1_11_00_10\packages"

    but I searched in directory also the http folder not contain any of files  like "sswolfssl.h" and "sssl.h" . The below is my directory image

    So, Am I need to update anything, as told any problem with tirtos version.

    Thanks,

    Regards

    Raghu DS

  • Raghu,


    Yes, you actually were very close but that was the wrong place to add the compiler path.  It should be added under the "Include Options" subsection of the compiler settings.  See screen shot.

    Note that if you based your app on the httpget example, the paths should already be set up properly for you.  But if you need to add it, it should be done like the screen shot shows.

    I searched in directory also the http folder not contain any of files  like "sswolfssl.h" and "sssl.h"

    Ok this is the issue - the documentation is out of date. The files “sssl.h” and “sswolfssl.h” morphed into “ti/net/tls.h” in TIRTOS 2.16.  So, you should just need to include "ti/net/tls.h"

    Steve

  • Hi Steven,
    Thanks for the reply. I included the path as you said, now my code is

    HTTPCli_Struct cli;
    struct sockaddr_in addr;
    int status;
    char data[64];
    char buf[64];
    int len;
    int ret;
    bool moreFlag = false;

    /* Request fields */
    HTTPCli_Field fields[2] = {
    { HTTPStd_FIELD_NAME_HOST, HOSTNAME },
    { NULL, NULL }
    };

    /* Response field filters */
    Char respFields[2] = {
    HTTPStd_FIELD_NAME_CONTENT_LENGTH,
    NULL
    };

    //Set up wolfSSL context
    //For SimpleLink, use SSSL_setContext() instead
    // SSWolfssl_context(ctx);

    //Construct a ststic HTTP client instance
    HTTPCli_construct(&cli);
    System_printf("construct \n");
    System_flush();

    HTTPCli_setRequestFields(&cli, fields);
    System_printf("setRequestFields \n");
    System_flush();

    HTTPCli_setResponseFields(&cli, respFields);
    System_printf("setResponseFields \n");
    System_flush();

    //Connect securely to the HTTP Server
    HTTPCli_connect(&cli, &addr, HTTPCli_TYPE_TLS, NULL);
    System_printf("connect \n");
    System_flush();

    //Make HTTP 1.1 POST request
    //
    //Send request to the server
    //
    //POST /index.html HTTp/1.1
    HTTPCli_sendRequest(&cli, HTTPStd_POST, "/index.html", true);
    // HTTPCli_sendRequest(&cli, HTTPStd_POST, REQUEST_URI, false);
    System_printf("sendRequest \n");
    System_flush();

    //Send additional fields
    //
    //Content-Length: <length>
    //<blank line>
    HTTPCli_sendField(&cli, HTTPStd_FIELD_NAME_CONTENT_LENGTH, len, false);
    System_printf("sendField \n");
    System_flush();

    //Send request body
    //
    //<data>
    HTTPCli_sendRequestBody(&cli, data, strlen(data));
    System_printf("sendRequestBody \n");
    System_flush();

    //Get the processed response status
    //
    //HTTP/1.1 200 ok
    status = HTTPCli_getResponseStatus(&cli);
    System_printf("getResponseStatus \n");
    System_flush();

    //Check the HTTP return status and process remaining response
    if(status == HTTPStd_OK){
    do{
    //Filter the response headers and get the set response field
    //
    //...
    //Content-type: text/xml; charset=utf-8\r\n
    //Content-length: 34
    //...
    ret = HTTPCli_getResponseField(&cli, buf, sizeof(buf), &moreFlag);

    //Process data in buf if field is content length
    //Zero is the index of content length in respFields array
    if(ret == 0){
    len = (int)strtoul(buf, NULL, 0);
    }

    }while(ret != HTTPCli_FIELD_ID_END);
    while(len > 0){
    len -= HTTPCli_readRawResponseBody(&cli, buf, sizeof(buf));
    //......process buf data and save.......
    }

    }
    HTTPCli_disconnect(&cli);
    HTTPCli_destruct(&cli);
    System_printf("http post success\n");
    System_flush();

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    when build this:
    error: "#20 identifier "ctx" is undefined"

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
    when include,
    int ctx=1;
    error: "unresolved symbol SSWolfssl_context, first referenced in ./httpget.obj"
    When I run this I was getting the prints on the console:

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    when comment this:
    // SSWolfssl_context(ctx);

    Console prints after run:

    ss in flash
    Starting the HTTP GET example
    System provider is set to SysMin. Halt the target to view any SysMin contents in ROV.
    Service Status: DHCPC : Enabled : : 000
    Service Status: DHCPC : Enabled : Running : 000
    Network Added: If-1:192.168.1.33
    Service Status: DHCPC : Enabled : Running : 017
    construct
    setRequestFields
    setResponseFields
    connect
    sendRequest
    FSR = 0x0000
    HFSR = 0x40000000
    DFSR = 0x0000000b
    MMAR = 0xffffffff
    BFAR = 0xffffffff
    AFSR = 0x00000000
    Terminating execution...
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////

    How can I overcome from this,
    Regards,
    Raghu DS
  • Hi Raghu,

    Ok, I see the problem.  It turns out that the example shown in that documentation was not updated for changes to the TLS set up code.

    You should be able to do the following:

    1. Copy the TLS set up code from the secure HTTP GET example (httpsget for TivaC)

    2. Then use the HTTP code from the example in the documentation for POST

    It should look something like this (note I did not compile this, I just did the work of combining the code of steps 1. and 2. for you):

    Void httpsTask(UArg arg0, UArg arg1)
    {
        bool moreFlag = false;
        char data[64];
        int ret;
        int len;
        struct sockaddr_in addr;
    
        TLS_Params tlsParams;
        TLS_Handle tls;
    
        HTTPCli_Struct cli;
        // Request fields
        HTTPCli_Field fields[2] = {
            { HTTPStd_FIELD_NAME_HOST,  "www.example.com" },
            { NULL, NULL }
        };
    
        // Response field filters
        char respFields[2] = {
            HTTPStd_FIELD_NAME_CONTENT_LENGTH,
            NULL
        };
    
        startNTP();
    
        TLS_Params_init(&tlsParams);
        tlsParams.ca = ca;
        tlsParams.calen = calen;
    
        tls = TLS_create(TLS_METHOD_CLIENT_TLSV1_2, &tlsParams, NULL);
        if (!tls) {
            printError("httpsTask: TLS create failed", -1);
        }
    
        // Construct a static HTTP client instance
        HTTPCli_construct(&cli);
        HTTPCli_setRequestFields(&cli, fields);
        HTTPCli_setResponseFields(&cli, respFields);
        // Connect securely to the HTTPS Server
        HTTPCli_connect(&cli, &addr, HTTPCli_TYPE_TLS, NULL);
        // Make HTTP 1.1 POST request
        //
        // Send request to the server:
        //
        // POST /index.html HTTP/1.1
        // Host: www.example.com
        HTTPCli_sendRequest(&cli, HTTPStd_POST, "/index.html", true);
        // Send additional fields
        //
        // Content-Length: <length>
        // <blank line>
        HTTPCli_sendField(&cli, HTTPStd_FIELD_NAME_CONTENT_LENGTH, len, true);
        // Send request body
        //
        // <data>
        HTTPCli_sendRequestBody(&cli, data, strlen(data));
        // Get the processed response status
        //
        // HTTP/1.1 200 OK
        status = HTTPCli_getResponseStatus(&cli);
        // Check the HTTP return status and process remaining response
        if (status == HTTPStd_OK) {
            do {
                // Filter the response headers and get the set response field
                //
                //...
                // Content-type: text/xml; charset=utf-8\r\n
                // Content-length: 34
                //  ...
                ret = HTTPCli_getResponseField(&cli, buf, sizeof(buf), &moreFlag);
                //  Process data in buf if field is content length
                //  Zero is the index of Content length in respFields array
                if (ret == 0) {
                    len = (int)strtoul(buf, NULL, 0);
                }
            } while (ret != HTTPCli_FIELD_ID_END);
            while (len > 0) {
                len -= HTTPCli_readRawResponseBody(&cli, buf, sizeof(buf));
                // ... process buf data and save ...
            }
         }
         HTTPCli_disconnect(&cli);
         HTTPCli_destruct(&cli);
    
    
    

    Steve

  • HI Steven,
    Thanks for support and reply,
    startNTP();
    Why this function is written, what is its defination.
    I was getting a compilation error:
    unresolved symbol startNTP, first referenced in ./ETHController.obj

    I remove this line , compilation is done but terminating the execution.

    Regards,
    Raghu DS
  • startNTP() is a function used to initiate communication with an NTP server. This is done to get the current time, and is required for TLS to function properly.

    The call to startNTP() comes from the httpsget example.

    Thinking about this more, I think it would serve you well to first import/build/run the httpsget example successfully (it will cover the NTP set up) and then once you have done that come back to your post app.

    Steve
  • Hi Steven,
    Thanks for your support and reply, I had go through your suggestion and made the edits where all need such as startNTP() definition and all its stuff.
    Please read my code:
    ========================================
    bool moreFlag = false;
    int status;
    char data[64];
    int len=0;
    int ret;
    int ca;
    int calen;
    struct sockaddr_in addr;

    TLS_Params tlsParams;
    TLS_Handle tls;

    HTTPCli_Struct cli;
    /* Request fields */
    HTTPCli_Field fields[3] = {
    { HTTPStd_FIELD_NAME_HOST, HOSTNAME },
    { HTTPStd_FIELD_NAME_USER_AGENT, USER_AGENT },
    { NULL, NULL }
    };

    /* Response field filters */
    Char respFields[2] = {
    HTTPStd_FIELD_NAME_CONTENT_LENGTH,
    NULL
    };

    while (WifiAlive != true) {
    Task_sleep(10);
    }

    startNTP();

    TLS_Params_init(&tlsParams);
    tlsParams.ca = ca;
    tlsParams.calen = calen;

    tls = TLS_create(TLS_METHOD_CLIENT_TLSV1_2, &tlsParams, "cert");
    if(!tls){
    System_printf("httpsTask: TLS create failed", -1);
    }

    HTTPCli_construct(&cli);

    HTTPCli_setRequestFields(&cli, fields);

    HTTPCli_setResponseFields(&cli, respFields);

    HTTPCli_connect(&cli, &addr, HTTPCli_TYPE_TLS, NULL);

    HTTPCli_sendRequest(&cli, HTTPStd_POST, "/index.html", false);

    HTTPCli_sendField(&cli, HTTPStd_FIELD_NAME_CONTENT_LENGTH, len, false);

    HTTPCli_sendRequestBody(&cli, data, strlen(data));

    status = HTTPCli_getResponseStatus(&cli);

    if(status == HTTPStd_OK){
    do{
    ret = HTTPCli_getResponseField(&cli, buf, sizeof(buf), &moreFlag);

    if(ret == 0){
    len = (int)strtoul(buf, NULL, 0);
    }

    }while(ret != HTTPCli_FIELD_ID_END);
    while(len > 0){
    len -= HTTPCli_readRawResponseBody(&cli, buf, sizeof(buf));
    //......process buf data and save.......
    }

    }
    HTTPCli_disconnect(&cli);
    HTTPCli_destruct(&cli);

    System_printf("http post on wifi success\n");
    System_flush();
    ==================================================
    It was running fine and was getting last line gets print on the console:
    http post on wifi success
    ===============================================

    I think now HTTP Post may do like this,
    Q1) How can I Know it was posted to my Server, can I try for other than www.example.com, is it need to made any changes?
    Q2) Its for Wifi, how can I change this for Ethernet as I need for on Ethernet, I tried the same it was exiting suddenly?

    Thanks for your support,

    Regards,
    Raghu DS
  • Hi Steven,
    Thanks for the support and reply, I had go through httpsget for wifi and define the startNTP() with all its stuff.
    Please see my code:
    =============================
    bool moreFlag = false;
    int status;
    char data[64];
    int len=0;
    int ret;
    int ca;
    int calen;
    struct sockaddr_in addr;

    TLS_Params tlsParams;
    TLS_Handle tls;

    HTTPCli_Struct cli;
    /* Request fields */
    HTTPCli_Field fields[3] = {
    { HTTPStd_FIELD_NAME_HOST, HOSTNAME },
    { HTTPStd_FIELD_NAME_USER_AGENT, USER_AGENT },
    { NULL, NULL }
    };

    /* Response field filters */
    Char respFields[2] = {
    HTTPStd_FIELD_NAME_CONTENT_LENGTH,
    NULL
    };

    while (WifiAlive != true) {
    Task_sleep(10);
    }

    startNTP();

    TLS_Params_init(&tlsParams);
    tlsParams.ca = ca;
    tlsParams.calen = calen;

    tls = TLS_create(TLS_METHOD_CLIENT_TLSV1_2, &tlsParams, "cert");
    if(!tls){
    System_printf("httpsTask: TLS create failed", -1);
    }

    HTTPCli_construct(&cli);

    HTTPCli_setRequestFields(&cli, fields);

    HTTPCli_setResponseFields(&cli, respFields);

    HTTPCli_connect(&cli, &addr, HTTPCli_TYPE_TLS, NULL);

    HTTPCli_sendRequest(&cli, HTTPStd_POST, "/index.html", false);

    HTTPCli_sendField(&cli, HTTPStd_FIELD_NAME_CONTENT_LENGTH, len, false);

    HTTPCli_sendRequestBody(&cli, data, strlen(data));

    status = HTTPCli_getResponseStatus(&cli);

    //Check the HTTP return status and process remaining response
    if(status == HTTPStd_OK){
    do{
    //Filter the response headers and get the set response field
    //
    //...
    //Content-type: text/xml; charset=utf-8\r\n
    //Content-length: 34
    //...
    ret = HTTPCli_getResponseField(&cli, buf, sizeof(buf), &moreFlag);

    //Process data in buf if field is content length
    //Zero is the index of content length in respFields array
    if(ret == 0){
    len = (int)strtoul(buf, NULL, 0);
    }

    }while(ret != HTTPCli_FIELD_ID_END);
    while(len > 0){
    len -= HTTPCli_readRawResponseBody(&cli, buf, sizeof(buf));
    //......process buf data and save.......
    }

    }
    HTTPCli_disconnect(&cli);
    HTTPCli_destruct(&cli);

    System_printf("http post on wifi success\n");
    System_flush();
    ============================================
    Console print:
    http post on wifi success
    ============================================

    I think this is done of httppost, if any wrong please inform me.
    Q1) How can repeat the same for Ethernet as my need is in Ethernet also.
    Q2) How can I know it was posting to my server, other than www.example.com, is changing is host name is enough to connect to local server or any thing else?

    Thanks for your support,
    Regards,
    Raghu DS
  • Raghu,

    The wired network stack (called the NDK) is a different stack than the wireless (called SimpleLink).

    If you want to use wired, you should import the TivaC HTTP get example under "Ethernet" in the Resource Explorer. This will get you started with the wired side.

    Using both the wireless and wired stacks concurrently is not currently supported.

    However, I have heard of others in the forum community updating the wired (NDK) driver to write out and receive from the wireless using SimpleLink raw sockets. You could certainly try to do this on your own, however support would be limited.

    Steve
  • Hi Steven,
    Thanks for the reply, For running this httpPost on the wifi only I was getting the response:
    response status=-104

    I tried for our local server also it was always giving response status=-104, it was no at all hitting my server.
    Can you please check this once with my above send code.
    Regards,
    Raghu DS
  • Raghu,

    Are you able to get a Wireshark capture of this? Do you see a TCP RST packet being sent from the server?

    Steve
  • Hi Steven,
    Thanks for the support and help.
    Wireshark we not using, now I can able to hit my server and getting response.
    This error 400 is getting because of not specified "content length" and "content type".

    Regards,
    Raghu DS
  • Ok, great that you got past the problem.

    If you feel your question has been resolved, please mark this thread as "answered."