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

changing the BLE device name, BLE service and GATT Characteristics dynamically

Hi, I am using nRF52832 module (GAP peripheral, GATT server) with nRF5SDK, ble_app_uart_pca10040_s112 application.

I need some help on dynamically changing the BLE device name, BLE service and GATT Characteristics.

What I tried:
In main(), I initialized only the UART module. Once UART is up, the nRF module receives data from an application chip (MCU).
In uart_event_handle function, I use a function call to process the received data and set the BLE device name accordingly, inside this function call I am initializing BLE stack, GAP parameters, GATT Init, Services Init followed by BLE advertisement.

This way, I was successfully able to set BLE device name and Services dynamically. However, after few minutes of communication with a GATT client, incorrect/incomplete data is being transmitted to that peer device.

Is it good to initialize BLE this way? If not, what should be done?

Also, I have found few of the forum discussions on how to change the BLE Device name in run time, but not seen anything related to changing GATT characteristics dynamically.
Please help, Thank you in advance.

Parents
  • Hi,

    It is possible to add BLE service and characteristics dynamically, but it is not possible to remove them. It is required to send a service change notification to let the gatt client know that the attribute table has been updated.
    Regarding the device name, it is possible to change device name using sd_ble_gap_device_name_set().

    Best regards,
    Dejan

  • I would like to mention that I wanted to change the BLE service and characteristics dynamically so that nRF module connects with different GATT client in run time. In this case, may I know how service change notification would help? Please share any references if possible.

    What I tried:
    In main(), I initialized only the UART module. Once UART is up, the nRF module receives data from an application chip (MCU).
    In uart_event_handle function, I use a function call to process the received data and set the BLE device name accordingly, inside this function call I am initializing BLE stack, GAP parameters, GATT Init, Services Init followed by BLE advertisement.

    This way, I was successfully able to set BLE device name and Services dynamically. However, after few minutes of communication with a GATT client, incorrect/incomplete data is being transmitted to that peer device.

    Is it good to initialize BLE this way? If not, what should be done?

    Also, I would like to know if this method which I followed is correct or not. 

    Please help, Thanks.

  • Hi,

    In addition to the name, could you provide more information about service and characteristics?
    How do you want to change characteristics dynamically and when (in relation to the reset)?

    Best regards,
    Dejan

  • Hi,

    I have added additional information on how I'm changing services and characteristics w.r.t reset in this updated_pseudocode text file. Kindly check.

    Thank you!

  • Hi,

    Your case has been looked into internally. I'll get back to you when I get new information.

    Best regards,
    Dejan

  • Okay, sure. Thank you for the support!

  • Hi,

    Could you please replace your uart_event_handle() with the one provided below and try to reproduce your issue?

    /**@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)
    {
        // Keep static keep word
        static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
        uint8_t process_data_array[BLE_NUS_MAX_DATA_LEN];
        static uint8_t index = 0;
        uint32_t err_code;
        uint16_t length;
    
        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)
                    {
                        if(data_array[0]=='#')
                            {
                            // Copy the array like this
                            memcpy(&process_data_array, &data_array, index);
                            err_code = process_mcu_data(&process_data_array[0]);
                            }
    
                        else
                        {
                            do
                            {
                                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;
                }
                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] */



    Best regards,
    Dejan

Reply
  • Hi,

    Could you please replace your uart_event_handle() with the one provided below and try to reproduce your issue?

    /**@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)
    {
        // Keep static keep word
        static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
        uint8_t process_data_array[BLE_NUS_MAX_DATA_LEN];
        static uint8_t index = 0;
        uint32_t err_code;
        uint16_t length;
    
        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)
                    {
                        if(data_array[0]=='#')
                            {
                            // Copy the array like this
                            memcpy(&process_data_array, &data_array, index);
                            err_code = process_mcu_data(&process_data_array[0]);
                            }
    
                        else
                        {
                            do
                            {
                                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;
                }
                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] */



    Best regards,
    Dejan

Children
  • Thank you so much!!  With this modified changes, communication is taking place for more than an hour now, without an issue. 

    I would like to get clarifications on the following:

    I attempted similar approach as what you have suggested, but the difference is that I copied the contents of data_array to the different buffer and passed that new buffer to ble_nus_data_send() function. 

    For process_mcu_data(), I sent the data_array as it is. Why this change could not make an impact?

  • Hi,

    The main issue seems to be in do-while loop.
    You probably enter "if" part and pass the pointer to the process_mcu_data(), data_array gets somehow changed and in next while iteration you go to ble_nus_data_send() with changed data.

    Best regards,
    Dejan

  • Okay, thank you so much for the support!!

Related