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.

CC2650MODA: Bluetooth hangs when sending data too fast - SPP server example

Part Number: CC2650MODA
Other Parts Discussed in Thread: CC2650

Hi everyone,

I'm trying to use the SSP server example. Everything seemed fine up until I tried to send data too fast.

It seems the problem is just sending it to the bluetooth too fast. It just stops sending it and I have to reset it to work again.
When calling SerialPortService_SetParameter to send data it returns "MSG_BUFFER_NOT_AVAIL".


Trying to do more tests and figure out where the system hangs but I see no error messages at all...

Anyone has any idea what could be happening?

EDIT:

The example has a periodic task example that blinks an LED. This is takes a while and blocks the main task to send data from the UART queue to the bluetooth. Took this out and problem solved for the most part. At full speed 921600 the system gets broken again instead of discarding bytes to not completely break.
Still what bothers me most is the fact that the system was completely broken without any warning found (at least that I found). I would hope that simply the messages we're missed and the system would keep working just fine.
So my concern now is still figuring out the error itself and solve/contain it in case it happens for some reason

  • Hi Luis,

    How many bytes are you sending? What connection interval are you using?

    Best wishes
  • Hi Zahid,

    I was trying to send a ton of bytes - I will describe better bellow but better what I found to be the problem:

    I found the problem to be related to the SDI/UART buffer was 128bytes and the queue message had also that size (the SDItask to applicationTask queue).

    In the application task, it tried to straight up put all the data to send in the "bluetooth hands" (using SerialPortService_SetParameter). This would return a error MSG_BUFFER_NOT_AVAIL when the data was over the MTU-3 (or was it -4?) which is hardcoded at 65. Since there was no success, the UART message would not be discarded and there would be an attempt to send it again - this of course resulted in continuous failing.

    The LED blinking with a delay should not by itself influence the system to cause this behavior.

    I had a test where some bytes we're sent without issue and then after some time, 200 bytes we're sent at max speed.  This would cause 2 messages queues to be sent with a length of 128 and 72. The first one with 128 bytes would trigger this problem right away.

    I changed the PDU to 255 in both client CC2650 and server C2650 and the issue was gone.

    I strongly suggest this example to be revised. The application should instead of sending the message queue straight up to SerialPortService_SetParameter, it should break it into smaller chunks with max size of the MTU (again for me it had to be PDU-4-3 or MTU-3 for some reason). I found another bug too. I might attempt, if I have time, to make a commit (that's the correct term?) to the github - though I never really done that - with my suggestion.

    Another thing, might it not be best to have the MTU to be just 20? These will surely be used with android, and most apps will not handshake the MTU and keep the default value of 20 without the CC2650 server knowing. (just a thought).

    Here is what I did (for packages with max sizeof 20) to make everything work:

                        uint16_t l = pMsg->length;
                        uint8_t *a = pMsg->data;
                        //send in packets of 20 bytes
                        while(l > 20){
                            retVal = SerialPortService_SetParameter(SERIALPORTSERVICE_CHAR_DATA, 20, a);
                            l -= 20;
                            a+=20;
                        }
                        //send the rest of the bytes
                        if(l != 0)
                            retVal = SerialPortService_SetParameter(SERIALPORTSERVICE_CHAR_DATA, l, a);

    Can you please verify if I will not have issues by calling SerialPortService_SetParameter in a row? As far as I can see the data to be sent reaches the bluetooth task through a queue - so there won't be any problem of sending more data into bluetooth task before the previous one is transmited, right?

  • Hi, 

    For notifications and Write commands, you can call multiple times and it will queue it in the controller, but for other GATT commands, you would have to wait until the response is received from the remote device. 

    The GATT MTU size is PDU size - 4 to account for the 4 bytes of L2CAP header. 

    The controller should automatically fragment/reassemble the packet when sending more than 20 bytes. You should set the MTU size to be at least 128 to avoid data allocation errors. 

    Best wishes

  • Zahid Haq said:
    The GATT MTU size is PDU size - 4 to account for the 4 bytes of L2CAP header. 

    Yes I do know that, but I needed to set the PDU to 27 to be able to send 20 for some reason.


    Zahid Haq said:
    The controller should automatically fragment/reassemble the packet when sending more than 20 bytes. You should set the MTU size to be at least 128 to avoid data allocation errors. 

    Okay thanks. Still the example should have this change.

    For my application I had to change the MTU to be 20 instead (and take other precautions) because the phone application doesn't handshake the MTU and has itself a MTU of 20.

  • Hi,

    So basically lets break it down with default PDU size set to 27.
    If you take off 4 bytes for L2CAP, you get 23 bytes.
    Then there are different headers for different GATT procedure.
    So for GATT notifications, 1 byte is used for opcode(ie. notification packet) and 2 bytes for the handle. That leaves 20 bytes for the actual data.

    So a general rule could be that your actual PDU size should be 7 bytes more than the max amount data bytes. So if you are sending 128 bytes of application data, you should set MAX_PDU_SIZE to at least 135.

    Best wishes
  • Thank you very much Zahid,

    This is my first use with BLE and deadlines don't let me study it with enough. Glad to have TI team helping.
    I will set as verify answer what I think was most useful for future users when searching