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.

CC3220MOD: CC3220MOD and AT Command Demo ****URGENT****

Part Number: CC3220MOD

Hi.

I'm using the CC3220MOD with AT Command Demo.

I've have spoken in a previous thread, https://e2e.ti.com/support/wireless-connectivity/wifi/f/968/p/711070/2621072#2621072

about the issue when sending byte data using the AT+Sendto command, where the data matches 0x0D, and the AT Command Demo interprets which as the end of the message, when it isn't. 

I implemented a work around for this, where I send double byte formatted data, and strip it back on arrival at the cloud. 

But the issue has resurfaced else where now....

I now need to send Root Certificates to the Flash Storage using the  at+file_write. The files are in .pem format . These are required for a WPA2-Enterprise EAP-TLS network.

These .pem files have LF (0x0A) placed regularly throughout the file. When sending the data using the AT+file_write, the AT slave is determining the 0x0A as end of message.

Now, I thought originally that only the CR (0x0D) was used for end of message in the AT Command Demo, (my codes uses gap timeouts, not terminating characters).

But I was obviously wrong, and it can be 0x0A or 0x0D.

I think an easy fix, would be to amend the AT Command Demo to only response to 0x0D,  so the 0x0A in the .pem files will not effect the handler. But I'm not sure if .pem files will ever have 0x0D characters. All the certificates I have here only contains 0x0A or printable characters, and no 0x0D.

I have a trial required soon at a customer and need help ASAP.

Thoughts please. 

Regards

Nick

  • It think the best and easiest solution is to change to AT Command Demo, so it no longer uses CR and LF characters to detect end of message, and using 0x8A stead of 0x0A, and 0x8D instead of 0x0D. This would be fine for the certificate pem files to get through. Would you agree?
  • I just downloaded the latest service pack 2.30 and it states that the termination bug has been fixed.
    reference CC3x20SDK-1316:
    is there more information available on what the fix is, how is the end of message determined.?

    Regards
    Nick
  • Hi Nick,

    II was checking the code and it looks like the end of the messages  (with binary data) is determined according to the [length] parameter that comes before the data.

    br,

    Kobi

      

  • The sendto always had the length of payload in the command, this pre-dates the said fix in SDK 2.30.
    Looking at the code it is still using /n /r characters to determine end of message. This means payload with /n /r in the content will cause the command to fail.
    This is also effecting me on the at+filewrite , and I'm unable to transfer pem format certificates to the device. As certificates always have /r or /n characters.

    I thought the fix would involve gap timeout as the detection method for end of message. This is something I have implemented in my AT master. But I know this breaks compatibility when using a terminal program. Above I have suggested I change the end of message characters from /n /r to unprintable character where are not present in .pem format files. This does not fix the sendto issue, but I already have a fix for the sendto, I send double byte data.

    Please comment
    Nick
  • I have looked at the code again. It looks like the handler is looking for the /n or /r, when it received the first /n or /r, if the command is sendto or send, it then appends to the data rx buf.

    below I have added the filewrite command to this, so I can send .pem files.

    I will test this later.

    Nick

    /*****************************************************************************
    int32_t ATCommands_readCmd(void)
    {
        int32_t lRetVal;
        uint32_t i = 1;
        char *pbuf;
        uint16_t length, readLen, offset;
        int16_t residue;
        uint8_t format = ATCMD_DATA_FORMAT_BASE64;
        char tmpBuf[16], *pTmpBuf;
    
        while(i)
        {
            pbuf = NULL;
            usleep(100);
            /* Poll UART terminal to receive user command terminated by '/r' */
            lRetVal = GetRawCmd((char *)ATCommands_cmdBuffer,ATCOMMANDS_CMD_BUFFER_SIZE);
            if (lRetVal <= 1)
            {
                //UART_PRINT("\n\r");
                continue;
            }
            offset = lRetVal;
    
            /* send */
            /* sendto */
            // Nick ,  16th Oct 2018
            // added ATCmd_fileWriteStr
            //if((strstr(ATCommands_cmdBuffer,ATCmd_sockSendStr))||(strstr(ATCommands_cmdBuffer,ATCmd_sockSendToStr)))
    
            if((strstr(ATCommands_cmdBuffer,ATCmd_sockSendStr))||(strstr(ATCommands_cmdBuffer,ATCmd_sockSendToStr))||(strstr(ATCommands_cmdBuffer,ATCmd_fileWriteStr)))
            {
                pbuf = strchr(ATCommands_cmdBuffer,ATCMD_DELIM_ARG) + 1;
            }
    
            if (pbuf != NULL)
            {
                pTmpBuf = tmpBuf;
                strncpy(pTmpBuf,pbuf,sizeof(tmpBuf));
                /* format */
                StrMpl_getVal(&pTmpBuf, &format , ATCMD_DELIM_ARG,STRMPL_FLAG_PARAM_SIZE_8);
                if (format == ATCMD_DATA_FORMAT_BINARY)
                {
                    /* data length */
                    StrMpl_getVal(&pTmpBuf, &length, ATCMD_DELIM_ARG,STRMPL_FLAG_PARAM_SIZE_16);
                    /* pTmpBuf now points to the beginning of the data portion */
                    // the extra 1 is to account for the NULL character at the end
                    readLen=lRetVal-(pbuf-ATCommands_cmdBuffer)-(pTmpBuf-tmpBuf)-1;
                    residue=length-readLen;
                    offset=lRetVal;
                    // means that the requested length is smaller than the actual payload
                    if (residue < 0)   
                    {
                        //UART_PRINT("\n\rERROR: length smaller than payload\n\r");
                        continue;
                    }
                    while (residue > 0)
                    {
                        /* read the residue */
                        lRetVal=GetRawCmd((char *)&ATCommands_cmdBuffer[offset],residue);
                        if (lRetVal < 1)
                        {
                            //UART_PRINT("\n\r");
                            break;
                        }
                        residue -= lRetVal;
                        offset += lRetVal;
                        // means that the requested length is smaller than the actual payload
                        if (residue < 0)    
                        {
                            //UART_PRINT("ERROR: length smaller than payload\n\r");
                            continue;
                        }
                    }
                    if (lRetVal < 1)   // meaning a non valid break from the while loop
                    {
                        continue;
                    }
                }
            }
            //UART_PRINT("\n\r");
            /* remove last CR or LF character */
            ATCommands_cmdBuffer[offset - 1] = '\0';
            ATCmd_send(ATCommands_cmdBuffer);
        }
        return(0);
    }

  • The "length" was there before but having '\n' or '\r' terminated the input buffer.
    Now, the '\n' or '\r' are stored in the input buffer and the termination is only based on the length (see logic around the "residue" variable in ATCommands_readCmd in case of Binary Data).

    br,
    Kobi
  • Have now, done some testing with the updated At Command Demo in SDK 2.30

    Functionality is now broken with AT+Sendto command. The additional changes made to handle /n and /r data in the payload and using the residual to continuing to load the remaining message.

    New AT demo returns the data send is to short. Looking at the code. The code only works for the AT+Send, where the format and length and in positions 1 and 2. When you use the AT+SendTo, it decodes FAMILY as 0, and the port number as length. In my case my port number is 49125.  Obviously this command was not tested at TI, only the AT+Send command.

    Also, the AT+Filewrite command needs adding to the same change.

    Please command

    Nick

  • Think I've got a fix for this now. 

    below is the code from at_commands.c . The original project from SDK 2.30

    Added extra pointer shifts for sendto, it needs 3 more shifts then send.

    Also added filewrite command, and this send binary data.

    I have not tested it yet. Will let you know if it all works.

    Nick Price.

    int32_t ATCommands_readCmd(void)
    {
        int32_t lRetVal;
        uint32_t i = 1;
        char *pbuf;
        uint16_t length, readLen, offset;
        int16_t residue;
        uint8_t format = ATCMD_DATA_FORMAT_BASE64;
        char tmpBuf[16], *pTmpBuf;
    
        //UART_PRINT("Enter AT Command:\n\r");
        while(i)
        {
            pbuf = NULL;
            usleep(1000);
            /* Poll UART terminal to receive user command terminated by '/r' */
            lRetVal = GetRawCmd((char *)ATCommands_cmdBuffer, ATCOMMANDS_CMD_BUFFER_SIZE);
            if (lRetVal <= 1)
            {
                UART_PRINT("\n\r");
                continue;
            }
            offset = lRetVal;
    
            
           
            // check command send and sendto, both start with the same prefix
            if (strstr(ATCommands_cmdBuffer, ATCmd_sockSendStr))
            {
                /* send */
                /* sendto */
                
                // move past handle
                pbuf = strchr(ATCommands_cmdBuffer,ATCMD_DELIM_ARG) + 1;
                // if sendto, format and length in different position
                if(strstr(ATCommands_cmdBuffer, ATCmd_sockSendToStr))
                {
                    // move past family
                    pbuf = strchr(pbuf,ATCMD_DELIM_ARG) + 1;
                    // move past port
                    pbuf = strchr(pbuf,ATCMD_DELIM_ARG) + 1;
                    // move past address
                    pbuf = strchr(pbuf,ATCMD_DELIM_ARG) + 1;
                }
    
            }
            else if(strstr(ATCommands_cmdBuffer, ATCmd_fileWriteStr))
            {
                // filewrite
                // move past fileID
                pbuf = strchr(ATCommands_cmdBuffer,ATCMD_DELIM_ARG) + 1;
                // move past offset
                pbuf = strchr(ATCommands_cmdBuffer,ATCMD_DELIM_ARG) + 1;
            }
    
            if (pbuf != NULL)
            {
                pTmpBuf = tmpBuf;
                strncpy(pTmpBuf,pbuf,sizeof(tmpBuf));
                /* format */
                StrMpl_getVal(&pTmpBuf, &format , ATCMD_DELIM_ARG,STRMPL_FLAG_PARAM_SIZE_8);
                if (format == ATCMD_DATA_FORMAT_BINARY)
                {
                    /* data length */
                    StrMpl_getVal(&pTmpBuf, &length, ATCMD_DELIM_ARG,STRMPL_FLAG_PARAM_SIZE_16);
                    /* pTmpBuf now points to the beginning of the data portion */
                    // the extra 1 is to account for the NULL character at the end
                    readLen = lRetVal - (pbuf - ATCommands_cmdBuffer) - (pTmpBuf - tmpBuf) - 1;
                    residue = length - readLen;
                    offset = lRetVal;
                    // means that the requested length is smaller than the actual payload
                    if (residue < 0)   
                    {
                        UART_PRINT("\n\rERROR: len < payload\n\r");
                        continue;
                    }
    
                    while (residue > 0)
                    {
                        /* read the residue */
                        lRetVal = GetRawCmd((char *)&ATCommands_cmdBuffer[offset],residue);
                        if (lRetVal < 1)
                        {
                            UART_PRINT("\n\r");
                            break;
                        }
    
                        residue -= lRetVal;
                        offset += lRetVal;
                        // means that the requested length is smaller than the actual payload
                        if (residue < 0)    
                        {
                            UART_PRINT("ERROR: len < payload\n\r");
                            continue;
                        }
                    }
                    if (lRetVal < 1)   // meaning a non valid break from the while loop
                    {
                        continue;
                    }
                }
            }
    
            UART_PRINT("\n\r");
    
            /* remove last CR or LF character */
            ATCommands_cmdBuffer[offset - 1] = '\0';
    
            ATCmd_send(ATCommands_cmdBuffer);
        }
        return(0);
    }
    

  • Thanks Nick!

    Indeed looks like a bug which your code should fix.
    Please let me know if this works.

    Br,
    Kobi
  • Hi Kobi

    This worked on my terminal program I wrote in VB.net, where I use AT+SendTo=

    But when I loaded the code on to my product with the CC3220MOD, the CC3220MOD does not respond to the first AT+SendTo= , and system sends it again, and it responds with  ERROR: command not exist,0

    I'm looking into this still.

    Regards

    Nick

  • didn't get the commands to work. But I don't really need modification for the residual part of the message. When I use +SendTo I have already encoded my data so is always between 0x80 and 0xFF.

    For the .pem file this will not work, but I changed the AT Demo so it uses 0x04 (EOT) End of Transmission as the received message terminator. The .pem files never contain then EOT character. This has been working fine, apart from issues with the AT file system commands in my other posting.
    Nick
  • Hi Nick,

    We'll provide the full fix in one of the coming releases.
    Meanwhile, seems that it everything can work with command-specific fixes to "ATCommands_readCmd()" in the "at_Command.c" (which is part of the application code).

    Br,
    Kobi