This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

How to read and write long string?

I have a characteristic which is a long string. I need to be able to read and write it.

Below is the function for writing to start with. Please comment on this function. The guesswork it has is inverse proportional to my level of BLE expertise(very low) May be someone already has such function debugged and is willing to share.

#define MAX_MSG_LEN   20
    
    uint32_t long_write (uint16_t  conn_handle, 
                         uint16_t  msg_handle, 
                         uint16_t  len, 
                         uint8_t * p_msg)
    {
        // Send value if connected. notification is assumed
        if (conn_handle != BLE_CONN_HANDLE_INVALID)
        {
            ble_gatts_hvx_params_t  hvx_params;
            uint16_t                block;
    
            for (uint16_t i = 0; i < len; i += MAX_MSG_LEN)
            {  
                block = ((len - i) > MAX_MSG_LEN) ? MAX_MSG_LEN : len - i; 
                memset(&hvx_params, 0, sizeof(hvx_params));
                hvx_params.handle = msg_handle;
                hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
                hvx_params.offset = i;
                hvx_params.p_len  = &block;
                hvx_params.p_data = &msg[i];
    
                err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params);
                if (err_code != NRF_SUCCESS) break;
            }
        else
        {
            err_code = NRF_ERROR_INVALID_STATE;
        }
        return err_code;
    }

Pretty sure it can be optimized, at least I'm guessing that block has value of actually written bytes...

Thank you.

Edit: one sentence question, commas between tags.

  • I don't think that nobody needs nor uses long data. I read this. Not exactly clear though.

  • Hi Barmaley,

    Your code is not "long write" as in the thread title, it's notification.

    Currently we do support long write and long read from S110 v5.x. However, notification is not. I don't think notify long is even described in the Bluetooth spec. If you notify a long characteristic, only the first 20 bytes is sent.

    So, you have three option:

    • Notify the first 20 bytes, and then use the client (the peer device) to do a read long, you should get the value of the long characteristics with that.

    • Create a server on the peer device, and do a write long from the S110 (client) to the server, instead of notifying.

    • Use what you are doing now. Split the long data into 20 bytes trunk and then collect and join them on the peer device.

    On thing I noticed from your code is that you will break when sd_ble_gatts_hvx() doesn't return NRF_SUCCESS. However, there is a case that the buffer is full. And it will, since the buffer is only 7 slots. You may want to wait when you receive BLE_ERROR_NO_TX_BUFFERS, and continue to send (from the point you receive buffer full) when you get BLE_EVT_TX_COMPLETE event which mean one or more slot in the buffer is free.

    I attached here an example of a long characteristics (HRM value). This will support a long write and long read from the client. You can test read long and write long using Master Control panel v3.6. The example should be compiled with SDK v5.2 and S110 v6.0.

    Regarding the example to do a long write from nRF51 as a client, unfortunately we currently don't have one. But it is supported. ble_app_hrs - LongChar.zip

  • Thank you for your quick reply. Will try to get deeper into it. Could you please provide examples of using supported long write and long read. Thanks again,

    Bar

  • Hi Barmaley, I updated the answer with attached example.

Related