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.

CC3000 SPI Buffer overflow when using recv()

Expert 2260 points

Hello,

I'm curious about something. When calling recv, and passing in a len that is greater than CC3000_RX_BUFFER_SIZE is it expected that a buffer overflow can occur?

I (seemingly mistakenly) assumed that multiple transactions between the CC3000 and the host would occur, but presumably it is never made aware of the length of the host buffers.

My overflow was so great that the checks in the spi driver didn't have a chance to execute :(

If this is the case then perhaps add a warning to any API function where this can occur? 

Presumably the usable space is less than CC3000_RX_BUFFER_SIZE since there are additional headers transmitted. Is there a macro somewhere which is guaranteed to be a safe number of bytes to read? Something along the lines of (CC3000_RX_BUFFER_SIZE - 10) or would be able to suggest a magic number?

Similarly are you aware of such a magic number for sending?

Kind Regards,

Alan 

  • Sorry, there is a comment in cc3000_common.h which seems to be what I'm looking for. I'll have a look at it in more detail when I get a chance. 

    EDIT: Please see below

  • Thank you for verifying your own answer!

  • Chinh Vu said:

    Thank you for verifying your own answer!

    After a seen the comment I assumed it was a stupid question, and wanted to check it out a bit more myself. :)

    However looking at the comment for recv in more detail, I was wondering if some one could confirm a query of mine. I was ideally hoping to create a macro which represents the total user data than can be sent or received from the api calls. I rearranged the macros in the comments to suit this purpose:

    recv() / recvfrom() max:

    CC3000_RX_BUFFER_SIZE - (HEADERS_SIZE_DATA + fromlen+ ucArgsize + 1)

    Where fromlen presumably should be: sizeof(sockaddr)

    But what exactly is ucArgSize going to be, is it variable? Presumably since the buffer also deals with receive events, this stems for the largest event we can read. So for the purposes of recv()/recvfrom() can I ignore it (i.e. treat it as 0)?

    I skimmed the code for it and it seems to be a variable used in the hci_event_handler(), but only if the event is not HCI_TYPE_EVNT (HCI_EVNT_RECV and HCI_EVNT_RECVFROM both seem to be HCI_TYPE_EVNT).

    Send() and sendto() appear to only use literals in their calculations:

    sendto() max:

    CC3000_TX_BUFFER_SIZE - (SPI_HEADER_SIZE+ SOCKET_SENDTO_PARAMS_LEN + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1)

    send() max:

    CC3000_TX_BUFFER_SIZE - (SPI_HEADER_SIZE+ HCI_CMND_SEND_ARG_LENGTH + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1)

    For reference the comment is:

    /*Defines for minimal and maximal RX buffer size. This size includes the spi 
      header and hci header.
      The maximal buffer size derives from:
        MTU + HCI header + SPI header + sendto() agrs size
      The minimum buffer size derives from:
        HCI header + SPI header + max args size
    
      This buffer is used for receiving events and data.
      The packet can not be longer than MTU size and CC3000 does not support 
      fragmentation. Note that the same buffer is used for reception of the data 
      and events from CC3000. That is why the minimum is defined. 
      The calculation for the actual size of buffer for reception is:
      Given the maximal data size MAX_DATA that is expected to be received by
      application, the required buffer is:
      Using recv() or recvfrom():
     
        max(CC3000_MINIMAL_RX_SIZE, MAX_DATA + HEADERS_SIZE_DATA + fromlen
        + ucArgsize + 1)
     
      Using gethostbyname() with minimal buffer size will limit the host name
      returned to 99 bytes only.
      The 1 is used for the overrun detection 
    
      Buffer size increased to 130 following the add_profile() with WEP security
      which requires TX buffer size of 130 bytes: 
      HEADERS_SIZE_EVNT + WLAN_ADD_PROFILE_WEP_PARAM_LEN + MAX SSID LEN + 4 * MAX KEY LEN = 130
      MAX SSID LEN = 32 
      MAX SSID LEN = 13 (with add_profile only ascii key setting is supported, 
      therfore maximum key size is 13)
    */
    
    
    /*Defines for minimal and maximal TX buffer size.
      This buffer is used for sending events and data.
      The packet can not be longer than MTU size and CC3000 does not support 
      fragmentation. Note that the same buffer is used for transmission of the data
      and commands. That is why the minimum is defined.
      The calculation for the actual size of buffer for transmission is:
      Given the maximal data size MAX_DATA, the required buffer is:
      Using Sendto():
     
       max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE
       + SOCKET_SENDTO_PARAMS_LEN + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1)
     
      Using Send():
     
       max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE
       + HCI_CMND_SEND_ARG_LENGTH + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1)
     
      The 1 is used for the overrun detection */ 
    

  • Bump. Sorry for being a pain but it would be nice to know what the safe limits are for certain.

    I guess I could iterate over every number up until the buffer max and see where it breaks, but I'm sure that would be particularly future proof :)

  • Alan said:

    recv() / recvfrom() max:

    CC3000_RX_BUFFER_SIZE - (HEADERS_SIZE_DATA + fromlen+ ucArgsize + 1)

    Where fromlen presumably should be: sizeof(sockaddr)

    But what exactly is ucArgSize going to be, is it variable? Presumably since the buffer also deals with receive events, this stems for the largest event we can read. So for the purposes of recv()/recvfrom() can I ignore it (i.e. treat it as 0)?

    I skimmed the code for it and it seems to be a variable used in the hci_event_handler(), but only if the event is not HCI_TYPE_EVNT (HCI_EVNT_RECV and HCI_EVNT_RECVFROM both seem to be HCI_TYPE_EVNT).

    Send() and sendto() appear to only use literals in their calculations:

    Last bump :|