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.

LAUNCHXL-CC3235S: -111 Error HTTPClient_connect AWS Provisioning Project Cannot complete HTTP POST Request

Part Number: LAUNCHXL-CC3235S
Other Parts Discussed in Thread: CC3235S, UNIFLASH

Hello. I am following this guide on provisioning my CC3235S with AWS using AWS SDK plugin.

I am using the subscribe_publish_sample project straight from Resource Explorer for CC3235S, TIRTOS, and CCS Compiler found here.

I am using latest SI SDK (5.20.00.06), latest AWS Plugin (4.30.00.02), and have the latest Service Pack installed (4.11.0.0).

I am unable to complete my HTTP POST request. Inside sendCSR(), I successfully create the HTTP client, but I am getting -111 Connection Refused error returned by HTTPClient_connect. I understand that one of the arguments for this function is the DEFINE I updated called AWS_IOT_PROVISIONING_HOST. This is a possible source of error, but when the terminal reads “Sending POST HTTP Request to <URL >, that makes sense to me.

My understanding is that this is the API Gateway invoke URL, but I could be wrong. The guide and comments from TI do a poor job of explaining things.

I am getting socket-related errors. When

 

 ret = SlNetSock_startSec(cli->ssock, secAttribs, SLNETSOCK_SEC_START_SECURITY_SESSION_ONLY | SLNETSOCK_SEC_BIND_CONTEXT_ONLY);

Is called inside HTTPClient_connect2, which is inside HTTPClient_connect, the program hangs forever at:

case SL_DEVICE_EVENT_FATAL_DRIVER_ABORT:
/* FATAL ERROR: Driver Abort detected */
while (1);

Inside SlNetSock_startSec, When it gets to

retVal = (netIf->ifConf)->sockstartSec(realSd, sdContext, secAttrib, flags);

, my program seems to hang, but it brings me to the Driver Error above.

This is the entire function:

int32_t SlNetSock_startSec(int16_t sd, SlNetSockSecAttrib_t *secAttrib, uint8_t flags)

{

int32_t retVal = SLNETERR_RET_CODE_OK;
int16_t realSd;
uint8_t sdFlags;
SlNetIf_t *netIf;

void *sdContext;

/* Check if the sd input exists and return it */
retVal = SlNetSock_getVirtualSdConf(sd, &realSd, &sdFlags, &sdContext, &netIf);

/* Check if sd found or if the non mandatory function exists */

if (SLNETERR_RET_CODE_OK != retVal)
{
 return retVal;
 }
 if (NULL == (netIf->ifConf)->sockstartSec)
{
/* Non mandatory function doesn't exists, return error code */
return SLNETERR_RET_CODE_DOESNT_SUPPORT_NON_MANDATORY_FXN;
 }
/* StartSec function called, set bit */

sdFlags |= flags;

/* Function exists in the interface of the socket descriptor, dispatch
 the startSec command */

retVal = (netIf->ifConf)->sockstartSec(realSd, sdContext, secAttrib, flags);

SLNETSOCK_NORMALIZE_RET_VAL(retVal,SLNETSOCK_ERR_SOCKSTARTSEC_FAILED);
return retVal;

}

 I don’t know what this means or how to remedy it.


I have done the following:

  • Used Postman to verify my API gateway URL works and returns expected value (AWS side looks good)
  • Filled in working Wifi credentials (Using Open Guest Network, Confirmed successful POST using this network manually)
  • Filled in aws_iot_config.h to the best of my abilities (possible source of error)
  • Flashed Certificates onto device and verified correct filepath in aws_iot_config.h DEFINEs
  • Tried different variations of URL for POST Request.
  • Increased the HTTP Client Buffer stack size as instructed in the AWS Provision Guide

My code is the entire project straight from Resource Explorer. I will however share my aws_iot_config.h file:

I do not know exactly what my Request URI is, but I am using the URI for the lambda I'm using to provision.

I'm happy to share any more details if I can.

Would someone mind helping with this? I'm sure other people will run into this issue as well, if they haven't already.

Thank you.

  • Hi Tom,

    Take another look at your AWS_IOT_PROVISIONING_HOST and REQ_URI and compare it to the code block comments in task 6, step 2 of the tutorial. It looks like those defines are expecting /Test/proto in a different place.

    Also, in your application, are you using your real device's UDID for MY_THING_NAME?

    Best regards,

    Sarah

  • Sarah,

    Thank you for your reply. 

    You have a good point about the REQ_URI. I was doing it like you mentioned initially, but I somehow forgot the note you mentioned and went rogue and did my own thing. I will keep it at /Test/proto.

    After trying /Test/proto, //Test/proto, and others, it is still exhibiting the same symptoms.

    I am not using the device's UDID. I determined it was easier to create a private key, and CSR using a script similar to the one found in the GitHub from Step 2. I am then flashing the certs onto the device, which are related to each other and pass the API invocation using Postman.

    I have confirmed the ThingName is 12345 on AWS as well as my config header file. Does not using the Real UDID make a difference? It seems to me the UDID is arbitrary to whatever I would prefer it to be.

    I have tried using the device's UDID but got the same results. However, I likely had other parts of the situation wrong.

    NOTE: I also wanted to add that When I use HTTP instead of HTTPS, I get the same error, but my program does not get the DRIVER ABORTED type of errors, it just fails the process and keeps moving on.

    NOTE: I checked out the HTTP Client handle, and the expressions view just gave me a memory location for the client handle. I used memory browser to view the memory, but didn't make out anything significant. Here is cli which is being returned by HTTPClient_Create. Status is returned 0 which is good, but something doesn't add up. I was looking at HTTPClient_CB. This appears all over httpclient.c, but it has no definition. I cannot find its initialization. It seems to be a struct, but I cannot find it. Is this significant?

    NOTE: I tried using the device's CSR, but I am not aware of how to get the device's private key that the CSR is derived from. I can get the public key from the CSR, but I need to private key for that schema to work. If I'm expected to use the device's CSR, I will need to know how to get it's private key, which the instructions for have eluded me.



    Thank you.

  • Hi Tom,

    The device's unique key pair is embedded in hardware (see the security features app note), which is why you need to generate the CSR as shown in task 1 (for CC3235, this is using the ImageCreator tool).

    My biggest concern is that fatal abort error. I don't think that is caused by a bad CSR file. Do you have a recent servicepack flashed to the CC3235?

    Can you add a print statement for that fatal abort error in the event handler, so I can see where it happens in the terminal log?

    Best regards,

    Sarah

  • Thank you. I switched to using the generated CSR and respective Public Key generated from CSR. Same results, but I don't know how to solve my private key problem.

    My concern about the Private Key is not being addressed by your referenced literature. The DEFINE "AWS_IOT_PRIVATE_KEY_FILENAME" inside aws_iot_config.h needs to be satisfied from what I can tell, which would mean I need to flash a file to the controller.

    If this is not the case, and the private key is embedded on the device, which you have said, what do I put for AWS_IOT_PRIVATE_KEY_FILENAME ?

    Also, my Thing already exists at this point. I am assuming I don't need the certificate from the Thing in AWS.

    - -

    I re-flashed the latest service pack with no change in result.

    - - 

    I uninstalled  SL SDK including AWS plugin and re-installed with no change in result.

    - -

    I deleted the project and restarted it, making sure to meticulously follow the instructions (increasing HTML buffer, makefile etc), same result.

    Regarding Step 4, I will say that the instructions say to run gmake after changing the HTTP Client Buffer DEFINE, but gmake does not exist where Step 4 says it does. There is only a makefile in that directory, but I ignored this because I was able to confirm the change I made to httpclient_internal.c in CCS. I also confirmed the changes in a second way regarding a change to the imports.mak file, so I believe this step is not a problem.

    - - 

    I changed the Wifi Network I was using including use of 2.4GHz and 5GHz bands with no change in result.

    - -

    I successfully completed the example project "Http Get" on first try without issue.

    - -

    I am questioning if my HTTPCreate_client function is failing even though it's not returning any errors. I can never see what my HTTPClient_Create function returns. It is as if it is a TI driver structure, but I cannot find a declaration for HTTPClient_Handle or HTTPClient_CB. I'm guessing they are hidden structs, but I made sure httpclient.h was included just to be sure.

    - -

    I can't help but to think that the biggest clue here is the difference in result between using HTTP and HTTPS for my POST Request URL.

    - -

    What event handler are you referring to? In the terminal, the last thing printed is:

    If there is some logging I need to be doing, can you please instruct me on how to do it? I'm not sure if you mean terminal log I've screenshot above or some other log. 

    - -
    FINAL OBSERVATION:
    I really dove into the weeds. The FATAL_DRIVER_ERROR occurs when a TxPayload Is being written to the NetWork Processor. The function _SlDrvMsgWrite occurs several time, usually with a reasonable payload. However, during the function sl_SetSockOpt which is called inside SlNetlfWifi_sockstartSec, _SlDrvMsgWrite encounters a TxPayload that has a length of 54,797 bytes. I'm not yet sure where this payload is coming from, but the TxPayload is breaking my program. This is the cause of death.

    Thank you Sarah.

  • Is there anyway I can take this to a more urgent support format? I don't mean to be unappreciative for the support, but I'm looking to get this answered sooner than later, especially considering I'm using 99% vanilla TI code out of the box. 

    Thank you.

  • Hi,

    The AWS plugin was tested when it last released with the CC32xx SDK 4.30, so there's potential for an issue with the recent 5.20 SDK. I'm still working on reproducing the issue. I can update you tomorrow.

    Best regards,

    Sarah

  • Thank you. I do appreciate it. 

    based on my last observation, I believe the problem presents itself in the driver message TX to the NWP however where the large payload comes from is beyond me so far  

    I’ll update this response if I find out where that obnoxiously large TxPayload is coming from  perhaps it is coming from something was related  


    If you would like some of my specific files, please let me know. I will share anything I can. 

  • Sarah, would you mind helping me with my Private Key question earlier? This may not be a compatibility/driver issue, not sure yet. I apologize for overloading this thread with info, but I believe I've boiled it down to my SecurityAttributes possibly being an issue. 

    I've determined that the 54,797 byte value is my secAttribute for my " PRIVATE_KEY ". Should my private key be this long? This is ultimately what is breaking my program. My problem revolves around my ignorance of the private key as a whole.

    Earlier, I asked this:

    My concern about the Private Key is not being addressed by the referenced literature (from previous reply). The DEFINE "AWS_IOT_PRIVATE_KEY_FILENAME" inside aws_iot_config.h needs to be satisfied from what I can tell, which would mean I need to flash a file to the controller.

    If this is not the case, and the private key is embedded on the device, which you have said, what do I put for AWS_IOT_PRIVATE_KEY_FILENAME ?Also, my Thing already exists at this point. I am assuming I don't need the certificate from the Thing in AWS.


    Would you mind helping me with this concerning the PRIVATE_KEY?

    Thank you.

  • Hi,

    When you generate a CSR, the device private key is added to the file system as a secure file in the location provided in the lab (/sys/cert/iot/key.der). This seems like the confusion and why the demo is failing. This private key file is only readable by the network processor, but you can check the file exists using the filesystem APIs or the Online User Files button in UniFlash ImageCreator (in development mode).

    During provisioning, the device sends the CSR to the AWS provisioning server. The server sends back a client certificate that is used for the connection.

    Best regards,

    Sarah

  • Thank you for this. I never clicked on that before. I now see where the private key and CSR are on the device.  AWESOME !

    However, this did not change the result. I changed my config header file to reflect these changes. I also tried using different Root CAs. Amazon gives me one, but also, TI documentation tells me to use another one, so I tried both. I am leaving AWS_IOT_CERTIFICATE_FILENAME blank so it triggers the provisioning function. I believe this is the cert that gets retrieved from AWS at some point.

    I am still getting the same driver abort error.

    I would like to retrieve the private key from the device to compare it with what is being sent out to the NWP, but I do not know what the "Token" is that UniFlash is looking for. Uniflash will not let me retrieve it.



    My problem is that I cannot establish an HTTP connection. At this point, the CSR is not even being sent yet.

  • Hi,

    What root CA did you use? Due to the way our device verifies the certificate chain, you need to use the Starfield root CA certificate instead of a cross-signed certificate. See the server authentication AWS doc and the AWS IoT Developer Setup section of the AWS Plugin Quick Start Guide.

    Users cannot view the device private key. The secure file is signed by the network processor and is only readable by the network processor. (Other secure files can be created with a token.)

    Also, when the fatal abort occurs in sl_SetSockOpt, what is the full command? What is the content of the payload?

    Best regards,

    Sarah

  • Thank you for the advice about Root CA. The Starfield Root CA I was using came from this TI AWS Document Overview in the last paragraph. It is different than the Starfield Root CA you just pointed me to. Someone might want to revisit the document and make sure it’s correct.

    I am still getting the same result.

    The entire Chain of failure is this:
    HTTPClient_Connect -> HTTPClient_Connect2 -> SlNetSock_connectURI -> (SlNetSock_create and SlNetSock_Connect succeed) ->             
    ret = SlNetSock_startSec(cli->ssock, secAttribs,SLNETSOCK_SEC_START_SECURITY_SESSION_ONLY | SLNETSOCK_SEC_BIND_CONTEXT_ONLY)

     The Arguments that get passed into this function and the variables that get updated are outlined in this screenshot:


    The population of the struct is what fails within this function, but of course we can go deeper into the drivers:


    sockstartSec leads to sl_SetSockOpt ->
    VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlSetSockOptCmdCtrl, &Msg, &CmdExt)); ->
    RetVal = _SlDrvMsgWrite(pCmdCtrl, pCmdExt, pTxRxDescBuff);

    This function is called more than a few times to send messages to the NWP. In this particular case, when failure occurs, the arguments are:


    You can see that the payload is my PRIVATE_KEY and the length is 54,653 . I will say they payload length changed a bit when you educated me on where the private key was located. So changing the private key location did change the payload length a little bit.

    Inside the _SlDrvMsgWrite function ->
     /* Only 1 payload supplied (Payload1) so just align to 4 bytes and send it */
     NWP_IF_WRITE_CHECK(g_pCB->FD, pCmdExt->pTxPayload1, _SL_PROTOCOL_ALIGN_SIZE(pCmdExt->TxPayload1Len));

    -> When this last function is called, the function attempts to RETURN, and the next immediate thing that happens is the _SlDrvHandleFatalError.

    When this function attempts to return, these are the variables:

    So it seems that the SPI transfer completes, however this is the last thing I can see before the error handler gets called. This very well could be a driver issue. This occurs when I’m transferring the Private Key to the NWP, but it does seem that my private key config has been resolved. Despite this, I’m still having the issue.

    Maybe the NWP is rejecting the payload for some reason? I'm unable to speculate why this message is breaking my program. It could be something under the hood.

    Thank you for your help. I believe this is all the detail I can provide. I’m happy to answer any questions, but this is the issue at its core.

    Thank you.

  • Hi,

    Thanks for all the details. I replicated the error and I am debugging this on my end. I'm still digging into the root cause.

    Best regards,

    Sarah

  • Thank you for your efforts. I did notice afterwards that my len variable for the payload to NWP is negative (last screenshot). This might be significant or not.

    I'm hoping we can get this worked out. This thread is two weeks active at this point.
    If there is anything I can do to assist, I am happy to do it.

    Otherwise, I am stuck and waiting on some degree of progress.

    Thank you.

  • Is there an update for this?
    Also, if it is a mismatch with drivers, would a previous version of SL SDK work with my AWS Plugin?

    Thank you.

  • Hi MicroTechEE,

    I will be taking over this thread shortly. I'll provide an update in the next few days.

    Thanks,
    Jacob

  • Thank you for jumping in. What is going on with this? We are working on three to four weeks on this thread. If the drivers need modified, we should get on it. 
    I'm happy to share info or help in any way I can, but I, and others, really need this to get working soon.

    Thank you

  • Hi MicroTechEE,

    I have not made much progress on the thread, but the issue is likely in the transfer of the private key somewhere in the application layer. The best example detailing the proper way to handle private key transfer is the tcpechotls example in our SDK. Can you check this out to see if it resolves your issue?

    I will be out of office for the rest of this week, but I will return to this thread next Monday (November 29).

    Thanks,
    Jacob

  • Jacob,

    I just saw that SL SDK 5.30 came out yesterday, 11/22/21. I will try to use this new SDK and Service pack before I try that example. I'll update the thread. So far, I am having a bunch of errors after switching to the new SDK and also updating to CCS 11.0 . 

    I will make a separate thread, but I am getting the error::
         #error "DeviceFamily_XYZ undefined. You must define a DeviceFamily_XYZ!"

    CC3235S doesn't seem to be a device family #define in DeviceFamily.h . The SDK release documentation says CC3235S is supported hardware.
    I'll try to resolve these issues and update this thread.

    Thank you.

  • Hi,

    Quick comment. Required macro for removing error is defined at new SDK file simplelink.h.

    #ifndef DeviceFamily_CC3220
    #define DeviceFamily_CC3220
    #endif

    Jan

  • Thanks Jan.

    I see what you are saying, but I'm not sure how to remedy my situation. My device is CC3235. I am unsure if I am supposed to include this header into my DeviceFamily.h header file, if I'm supposed to modify the #define, or something else. 

    Would you mind elaborating a bit on what you recommend I do?

    Thank you.

  • Hi,

    It is enough to include latest Simplelink (host) driver from latest SDK into your code. But if you want to set global macro for whole project, feel free do it.

    Jan

  • I included the simplelink.h header file in DeviceFamily.h and it worked.

    #include "C:\ti\simplelink_cc32xx_sdk_5_30_00_08\source\ti\drivers\net\wifi\simplelink.h"

    After fixing that, I am now getting a bunch of unresolved symbols errors. I understand that this means the linker cannot find a definition for these, but is there a good place to start looking? I am unsure where these files usually are, especially on a new SDK.


    Thank you.

  • Hi,

    No. That is not correct way. You should changed SDK version at your project properties.

    Jan

  • SDK Version under project properties is showing 5.30. It is inherited from my tirtos_builds_cc32xx_release_ccs project.


    If this is not what you are referring to, could you elaborate on what you mean? A little bit more detail would help eliminate a lot of miscommunication.

    Thank you.

  • Hi,

    In case you have changed SDK version inside your TIRTOS project, that this is correct way.

    If your previous project is based on older SDK version than 5.10, you need to change your pre-compilled libraries from *.arm4 to *.a.

    Jan

  • I have only ever used 5.20 and now 5.30. I'm not sure how to implement what you are saying, but it sounds like I don't need to know because I have never used below 5.20. 
    Also, I deleted my old tirtos project and this one was automatically imported for me. I did confirm it was showing 5.30.

    I still have all these unresolved symbols errors. Is there any good place to start resolving them? I'm not certain what they all have in common or I would start there.

    Thank you.

  • Jacob,

    I could not get the tcpEchoTls example to work. However, I boiled down my issue to the program not creating my security attributes.The httpclient.c function HTTPClient_Connect chose to "Reconnect" to the server instead of "initially connect". I forced the function to "initial connect" (using if(1)), and now I am getting a proper 200 response along with the response body being my original CSR.

    There is definitely something wrong here, and someone needs to look into it, but for now I will just force the creation of the security attributes. It seems that the security attributes need to be created before the Send_CSR function. A NOT NULL object needs to be passed so that it creates the secAttributes.

    In this project, the third argument of HTTPClient_connect is 0. So the secAttributes are never created. Because they are never created, the connection fails. Now if the drivers were sound, and the code was correct, the process would be error-handled correctly. Why the drivers fail is beyond me. There is a deeper problem, but this will at least help people make it work.

    /* Extract security parameters */
        if (1)//exSecParams != NULL)  // NEEDED TO HAPPEN
        {
            retVal = createSecAttribs(exSecParams, &secAttribs);
            if (retVal < 0)
            {
                return (retVal);
            }
            retVal = parseURI(hostName, &port, domainBuff, &intFlags);
            if ((retVal == 0) && (intFlags & ISDOMAIN))
            {
                /*
                 * Copy the domain into malloced memory to avoid pointing to the
                 * stack's memory inside secAttribs.
                 */
                domainPtr = malloc((strlen(domainBuff) + 1));
                if(!domainPtr)
                {
                    SlNetSock_secAttribDelete(secAttribs);
                    return (SLNETERR_RET_CODE_MALLOC_ERROR);
                }
                memcpy(domainPtr, domainBuff, (strlen(domainBuff) + 1));
                retVal = SlNetSock_secAttribSet(secAttribs, SLNETSOCK_SEC_ATTRIB_DOMAIN_NAME,
                                                domainPtr, strlen(domainPtr) + 1);
                if (retVal < 0)
                {
                    free(domainPtr);
                    SlNetSock_secAttribDelete(secAttribs);
                    return (retVal);
                }
            }
            cli->secAttribs = secAttribs;
            cli->secAttribsAllocated = true;
        }
        else if (cli->secAttribs != NULL)  // WAS HAPPENING
        {
            /* We're attempting to reconnect to a server */ WAS HAPPENING
            secAttribs = cli->secAttribs; // WAS HAPPENING
        }
    
        retVal = HTTPClient_connect2(client, hostName, secAttribs, flags, NULL);
        if (retVal < 0)
        {
            HTTPClient_disconnect(client);
        }
        return (retVal);
    }

    Now I am having a problem parsing the JSON packet returned. I can make a separate thread for that issue.

    How this program was ever released to the public is beyond me.