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.

CC3120: iOS clients lead to SL_ERROR_BSD_ESECCLOSED error raising

Part Number: CC3120
Other Parts Discussed in Thread: UNIFLASH

Hello,

I've a board where a host microprocessor runs a web server. The host processor is interfaced via SPI to a CC3120R configured to play AP role.
At the startup, any client device (Windows PC, MAC Book, Android phone, iOS phone) is able to successfully connect to network and exchange data (over HTTPS).
Then, if trying after board has been running for some hours (even without any client connected to in the meanwhile) non-iOS clients are still able to successfully interact; on the contrary, any iOS client results in getting the module stuck.

The behavior is that Status = sl_Recv(i, &rxBuffer, MAX_BUF_SIZE, 0); returns -452 which should mean #define SL_ERROR_BSD_ESECCLOSED (-452L) /* secure layrer is closed by other size , tcp is still connected  */

The service pack used has the following components: NWP 3.10.0.5,MAC 2.0.0.0,PHY 2.2.0.6

The code for module initialization is the following:

  uint8_t max_ap_stations = (uint8_t)configAp.maximumAPStations;
   uint8_t val = SL_WLAN_SEC_TYPE_WPA_WPA2;
   uint8_t channel = configAp.channel;

   /* Set general AP parameters */

   Status = sl_WlanSetMode(ROLE_AP);
   if (Status != 0)
   {
       syslog(LOG_ERR, "[ERROR] -  %d - sl_WlanSetMode ROLE_AP\n", Status);
   }

   Status = sl_WlanSet(SL_WLAN_CFG_AP_ID, SL_WLAN_AP_OPT_SSID, strlen(configAp.ssid),
                        (unsigned char*)configAp.ssid); // ssid max 32 char!
   if (Status != 0)
   {
       syslog(LOG_ERR, "[ERROR] -  %d - sl_WlanSetMode SL_WLAN_AP_OPT_SSID\n", Status);
   }

   Status = sl_WlanSet(SL_WLAN_CFG_AP_ID, SL_WLAN_AP_OPT_CHANNEL, 1, (uint8_t*)(&channel));
   if (Status != 0)
   {
       syslog(LOG_ERR, "[ERROR] -  %d - sl_WlanSetMode SL_WLAN_AP_OPT_CHANNEL\n", Status);
   }

   Status = sl_WlanSet(SL_WLAN_CFG_AP_ID, SL_WLAN_AP_OPT_HIDDEN_SSID, 1, (uint8_t*) &configAp.hidden);
   if (Status != 0)
   {
       syslog(LOG_ERR, "[ERROR] -  %d - sl_WlanSetMode SL_WLAN_AP_OPT_HIDDEN_SSID\n", Status);
   }

   Status = sl_WlanSet(SL_WLAN_CFG_AP_ID, SL_WLAN_AP_OPT_SECURITY_TYPE, 1, (uint8_t*)&val);
   if (Status != 0)
   {
       syslog(LOG_ERR, "[ERROR] -  %d - sl_WlanSetMode SL_WLAN_AP_OPT_SECURITY_TYPE\n", Status);
   }

   Status = sl_WlanSet(SL_WLAN_CFG_AP_ID, SL_WLAN_AP_OPT_PASSWORD, strlen(configAp.password),
                        (uint8_t*)configAp.password);
   if (Status != 0)
   {
       syslog(LOG_ERR, "[ERROR] -  %d - sl_WlanSetMode SL_WLAN_AP_OPT_PASSWORD\n", Status);
   }

   Status = sl_WlanSet(SL_WLAN_CFG_AP_ID, SL_WLAN_AP_OPT_MAX_STATIONS, sizeof(max_ap_stations),
                        (uint8_t*)&max_ap_stations); // default: 4

For TLS handshake, the certificates issued by cc3120 are a chain formed by a custom CA concatenated to the server certificate signed by the custom CA.

May this error be related to some specific way tls is handled in iOS client devices?

Thanks in advance.

BR

Lorenzo.

  • Hi Lorenzo,

    Few comments:

    • What do you mean by "module stuck"? Module is not responding to sl_ API calls? Do you see any error via asynchronous handler?
    • Service pack 3.10.0.5 is more than 4 years old. Are you able to test with latest ServicePack? Latest service pack for CC3120 you can find at CC32xx SDK (version 3.22.0.1).
    • What are you doing when error -452 is returned from sl_Recv()? Did you close socket by sl_Close()? Do you use linger option (SL_SO_LINGER) with socket?

    Jan

  • Hi Jan,

    below my answers:

    • I summarized too much briefly. The module is not stuck. It is the SW driver in the host processor that after sl_Recv returns -542 calls the sl_Close and then exit the program.
    • I've installed the SDK. But when I try to program the sp_3.22.0.1_2.7.0.0_2.2.0.7.ucf via bootloader through UART connection I get:

    Updating CC3120 Firmware
    File /usr/share/cc3120-fw/cc3120.ucf.new opened. Size: 74852 bytes
    Start Programming
    Error: Error occurred while programming, statusCode:-673378496 = 0xd7dd0f40, read_buffer[0]=0x00, read_buffer[1]=0xcc

    when sending the first chunk of file. The same updater works with old .ucf Below the function from the SW updater in host processor.

    static bool flashProgrammingCmd(const uint8_t* bin, size_t size)
    {
       uint8_t read_buffer[READ_BUFFER_SIZE] = {0};
       uint16_t readBytes = 0;
    
       const uint8_t* addrOffset = bin;
    
       size_t imageSize = size;
       size_t writtenBytes = 0;
    
       printf("Start Programming\n");
    
       while (size > 0)
       {
          size_t toReadBytes =
              MIN(size,
                  MAX_CHUNK_SIZE); // Chunk size must be 4096 B except for the last chunk
    
          uint16_t cmdLen = toReadBytes + PARTIAL_HEADER_CMD_LEN;              // Len field of command
          uint8_t flashProgram_cmd[MAX_CHUNK_SIZE + TOT_HEADER_CMD_LEN] = {0}; // max: 4107
    
          memcpy((flashProgram_cmd + CMD_CHUNK_START_INDEX), addrOffset, toReadBytes);
    
          flashProgram_cmd[CMD_LEN_INDEX] = cmdLen >> 8;
          flashProgram_cmd[CMD_LEN_INDEX + 1] = cmdLen;
    
          flashProgram_cmd[CMD_OPCODE_INDEX] = PROGRAM_CMD_OPCODE;
    
          flashProgram_cmd[CMD_CHUNK_SIZE_INDEX] = toReadBytes >> 8;
          flashProgram_cmd[CMD_CHUNK_SIZE_INDEX + 1] = toReadBytes;
    
          uint8_t checkSum = computeCheckSum((flashProgram_cmd + CMD_OPCODE_INDEX), (toReadBytes + 9));
          flashProgram_cmd[CMD_CS_INDEX] = checkSum;
    
          serialWrite((unsigned char*)flashProgram_cmd, (toReadBytes + TOT_HEADER_CMD_LEN));
          while (readBytes == 0)
          {
             readBytes = serialRead(read_buffer, PROGRAM_CMD_ASW_LEN);
          }
          readBytes = 0;
    
          int32_t statusCode;
          statusCode =
              read_buffer[2] << 24 | read_buffer[3] << 16 | read_buffer[4] << 8 | read_buffer[5];
    
          if ((statusCode < 0) || (read_buffer[0] != 0x00) || (read_buffer[1] != 0xCC))
          {
             //fprintf(stderr, "Error: Error occurred while programming\n");
    e
             return 1;
          }
    
          size -= toReadBytes;
          addrOffset += toReadBytes;
          writtenBytes += toReadBytes;
    
          int progress = (int)(((float)writtenBytes / imageSize) * 100);
          printf("\rProgress: %d %% \t", progress);
    
    #ifdef SERIAL_DEBUG
          printf(" - Written bytes: %d (%02x)\n", statusCode, statusCode);
    #endif
    
          fflush(stdout);
       }
    
       int32_t statusCode;
       statusCode = read_buffer[2] << 24 | read_buffer[3] << 16 | read_buffer[4] << 8 | read_buffer[5];
    
       if (statusCode == 0)
       {
          fprintf(stderr, "\nFinished programming\n");
       }
       else
       {
          return 1;
       }
    
       return 0;
    }
    

    • I call sl_Close. yes, tcpServerSocket is set with SL_SO_LINGER

    Lorenzo

  • Hello Lorenzo,

    when you close the socket die to error and reopen it so the peer device can reconnect, does it start working again?

    The SP is really mandatory since you are using an archive one. The process you describe via bootloader is called Embedder Programming and you need to go into bootloader mode by introducing a break signal on UART. Are you implementing what is described in swpa230?  Can you use Uniflash instead?

    Shlomi

  • Hello Shlomi,

    Finally I was able to flash the new service pack. The problem was due to the fact I was making the .ucf file with an old Uniflash version (6.4 instead of newest 8.3).

    Now the version are:

    NWP 3.22.0.1
    MAC 2.7.0.0
    PHY 2.2.0.7

    Anyway, the behaviour is the same.

    sl_Recv

    _i16 sl_Recv(_i16 sd, void *pBuf, _i16 Len, _i16 flags)
    {
        _SlRecvMsg_u   Msg;
        _SlCmdExt_t    CmdExt;
        _SlReturnVal_t status;
    
        /* verify that this api is allowed. if not allowed then
        ignore the API execution and return immediately with an error */
        VERIFY_API_ALLOWED(SL_OPCODE_SILO_SOCKET);
    
        _SlDrvResetCmdExt(&CmdExt);
        CmdExt.RxPayloadLen = Len;
        CmdExt.pRxPayload = (_u8 *)pBuf;
    
        Msg.Cmd.Sd = (_u8)sd;
        Msg.Cmd.StatusOrLen = (_u16)Len;
    
        /*  no size truncation in recv path */
        CmdExt.RxPayloadLen = (_i16)Msg.Cmd.StatusOrLen;
    
        Msg.Cmd.FamilyAndFlags = (_u8)(flags & 0x0F);
    
        status = _SlDrvDataReadOp((_SlSd_t)sd, (_SlCmdCtrl_t *)&_SlRecvCmdCtrl, &Msg, &CmdExt);
        if( status != SL_OS_RET_CODE_OK )
        {
            return status;
        }
         
        /*  if the Device side sends less than expected it is not the Driver's role */
        /*  the returned value could be smaller than the requested size */
        syslog(LOG_INFO, "[INFO] -  sl_Recv, line:%d, Msg.Rsp.StatusOrLen:%d,\n", __LINE__, Msg.Rsp.StatusOrLen);
        return (_i16)Msg.Rsp.StatusOrLen;
    }

    return -452.

    wifi_bridge_log[5815]: [INFO] -  sl_Recv, line:912, Msg.Rsp.StatusOrLen:-452,

    That happens after some minutes of data exchange with iOS devices; probably it may be happen also once from Windows PC.
    Is there anything I can fetch to help investigation?

    Thanks.

    Lorenzo.

  • Hi,

    next steps would be to try and fetch some logs from the NWP but before this step, can you comment on "when you close the socket die to error and reopen it so the peer device can reconnect, does it start working again?"

    Shlomi

  • Hi Shlomi,

    I've taken some days to do some testing and study the current code.

    It seems that avoiding to close the socket when the sl_Recv fails prevents the problem: the client remains connected and data exchange continues. Do you know when the sl_Recv returns -452 (SL_ERROR_BSD_ESECCLOSED) ?

    BR

    Lorenzo

  • Hi Lorenzo,

    It is good to hear that by not closing the socket you are able to recover but it is a little strange.

    SL_ERROR_BSD_ESECCLOSED means that the other side closed the SSL/TLS connection but not the socket itself. So what you are describing here is that it continues to exchange data so either the data exchange is on a non-secured socket or that the TLS handshake is triggered in the NWP so you don't see it.

    Regards,

    Shlomi

  • Hi Shlomi,

    I think I might have figured out what happens.

    It seems that the client sometime tries to establish more than 6 connections. When that occurs, as usual,  the client initiates a TLS handshake which indeed ends with a premature Encrypted Alert sent from the client. It is there when sl_Receive returns SL_ERROR_BSD_ESECCLOSED (-452L).

    I've now modified my host processor code to close the client sockets returning SL_ERROR_BSD_ESECCLOSED; the master server socket is never closed since server always wants to be able to accept new connections.

    Once other client sockets are normally closed by the client then additional secure sockets on the module become again available and new client sockets are correctly accepted.

    It seems that the general behavior is ok, and no socket is used unsecured.

    Do you consider the analysis as correct or there might be something else to be investigated?

    Thanks in advance.

    BR

    Lorenzo

  • Hi Lorenzo,

    makes more sense now with the additional information of the 6 secured sockets.

    The DS does state "6 Simultaneous TLS and SSL Sockets" so beyonf this number you get an alert and you need to wait until a socket gets free before establishing a new one.

    Regards,

    Shlomi