This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Problem on notify payload: 8 first bytes repeat for the entire length (custom service)

Hi,

I have been working on nRF since last week now. I've followed the tutorials on how to setup a custom service and custom characterics (Bluetooth low energy Services, a beginner's tutorial and Bluetooth low energy Characteristics, a beginner's tutorial). After setting up, I wanted to do my own thing, but I have been hitting a wall for a day now and I still don't know how to move on.

I'm working on the BLE_peripheral example of the heart rate service and I added the NUS example as well. I've also added a custom service and what I am trying to do is to send a payload of 69 bytes to a custom characteristic upon the writing of a character on the serial port (see code below).

/**@brief   Function for handling app_uart events.
 *
 * @details This function will receive a single character from the app_uart module and append it to
 *          a string. The string will be be sent over BLE when the last character received was a
 *          'new line' '\n' (hex 0x0A) or if the string has reached the maximum data length.
 */
/**@snippet [Handling the data received over UART] */
void uart_event_handle(app_uart_evt_t * p_event)
{
    static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
    static uint8_t index = 0;
    uint32_t       err_code;

    switch (p_event->evt_type)
    {
        case APP_UART_DATA_READY:
            UNUSED_VARIABLE(app_uart_get(&data_array[index]));
            index++;

            if ((data_array[index - 1] == '\n') ||
                (data_array[index - 1] == '\r') ||
                (index >= m_ble_nus_max_data_len))
            {
                if (index > 1)
                {
                    NRF_LOG_DEBUG("Ready to send data over BLE NUS");
                    NRF_LOG_HEXDUMP_DEBUG(data_array, index);

                    do
                    {
                        uint16_t length = (uint16_t)index;
                        err_code = ble_nus_data_send(&m_nus, data_array, &length, m_conn_handle);
                        if ((err_code != NRF_ERROR_INVALID_STATE) &&
                            (err_code != NRF_ERROR_RESOURCES) &&
                            (err_code != NRF_ERROR_NOT_FOUND))
                        {
                            APP_ERROR_CHECK(err_code);
                        }
                    } while (err_code == NRF_ERROR_RESOURCES);
                }

                index = 0;
            }
            //custom code
            else if ((data_array[index - 1] == 'c'))
            {
                index = 69;
                uint16_t length = (uint16_t)index;
                uint8_t data[index];
                memset(data, 0, index);
                data[0] = 0x01;
                data[3] = 0x18;
                data[4] = 0x42;

                err_code = ble_nus_data_send(&m_nus, data, &length, m_conn_handle);
                if ((err_code != NRF_ERROR_INVALID_STATE) &&
                    (err_code != NRF_ERROR_RESOURCES) &&
                    (err_code != NRF_ERROR_NOT_FOUND))
                {
                    APP_ERROR_CHECK(err_code);
                }
                characteristic_data_update(&m_my_service, m_conn_handle, data, &length);

                index = 0;
            }
            break;

        case APP_UART_COMMUNICATION_ERROR:
            APP_ERROR_HANDLER(p_event->data.error_communication);
            break;

        case APP_UART_FIFO_ERROR:
            APP_ERROR_HANDLER(p_event->data.error_code);
            break;

        default:
            break;
    }
}
/**@snippet [Handling the data received over UART] */

void characteristic_data_update(ble_ms_t *p_my_service, uint16_t    conn_handle, uint8_t* data, uint16_t* length)
{
    if (conn_handle != BLE_CONN_HANDLE_INVALID)
    {
        //uint16_t               len = length;
        ble_gatts_hvx_params_t hvx_params;

        memset(&hvx_params, 0, sizeof(hvx_params));

        hvx_params.handle = p_my_service->device_control_handles.value_handle;
        hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
        hvx_params.offset = 0;
        hvx_params.p_len  = length;
        hvx_params.p_data = data;  

        sd_ble_gatts_hvx(conn_handle, &hvx_params);
    }
}

I have added a condition where on 'c' character input it sends a payload full of 0x00 except for 3 bytes. The payload works just fine with the NUS service, but it starts to get itchy when it comes to the custom service. The first 8 bytes (sometimes the first 16 bytes) repeat themselves for the entire length of the payload. I suspected first my parameters but then I took the same as the  NUS function, still the same problem. I also checked for parameters in sdk_config.h file like ATT_MTU but the value seems fine.

On the debugger; I looked for length pointer value once it is returned by hvx_params struct, and it said 8 but still wrote 69 bytes on the characteristic.

I work on Windows 10 with nRF52840 DK with nRF Connect for Mobile on my Android. My SDK is v17.0.2 and my softdevice is the pca10056.

Screens :

Thanks in advance for any tips that might help me.

FM

Parents
  • That did the trick ! Thank you very much Håkon !

    I'll delete my archives and put the ticket back in public so that it might help anyone who makes the same mistake as me and try to seperate cccd and metadata due to lack of space. All it took was to give NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE in sdk_config.h a bigger value.

    Kind regards,

    FM

Reply
  • That did the trick ! Thank you very much Håkon !

    I'll delete my archives and put the ticket back in public so that it might help anyone who makes the same mistake as me and try to seperate cccd and metadata due to lack of space. All it took was to give NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE in sdk_config.h a bigger value.

    Kind regards,

    FM

Children
No Data
Related