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

nRF52832 service error

nRF52832 write one service another service will also receive the same data

Parents
  • Hi,

    I'm not sure I understand the problem. Could you elaborate a bit more and share your code and if possible a sniffer log? What device is the central writing to? Is it a Nordic device?

    regards

    Jared

  • Hi,
    Nrf Connect was used as a central.When I send a data (Uart Service) from the app to the characteristic value of a Service (UUID:0x0002), the callback function of another Service (0x0010) receives this data at the same time.And this is a Demo about the error.
    best regards,
    TanSDK16.zip

  • Hi,

    As already mentioned if you should properly check the handles when a Softdevice event is generated. It seems that you call your event handler in the bcon service as long as data_handler is valid, which by itself isn't a good enough check. In addition you are missing some brackets in the if sentence which results in the event handler being called as long as the program passes the if else ( which it will since data handler is valid). 

    static void on_write(ble_bcon_t * p_bcon, ble_evt_t const * p_ble_evt)
    {
        ble_bcon_evt_t                evt;
        ble_bcon_client_context_t     * p_client;
        ble_gatts_evt_write_t const   * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
        uint32_t                      err_code;
        err_code = blcm_link_ctx_get(p_bcon->p_link_ctx_storage,
                                     p_ble_evt->evt.gatts_evt.conn_handle,
                                     (void *) &p_client);
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("Link context for 0x%02X connection handle could not be fetched.",
                          p_ble_evt->evt.gatts_evt.conn_handle);
        }
    
        memset(&evt, 0, sizeof(ble_bcon_evt_t));
        evt.p_bcon       = p_bcon;
        evt.conn_handle  = p_ble_evt->evt.gatts_evt.conn_handle;
        evt.p_link_ctx   = p_client;
    
        if ((p_evt_write->handle == p_bcon->tx_handles.cccd_handle) &&
            (p_evt_write->len == 2))
        {
            if (p_client != NULL)
            {
                if (ble_srv_is_notification_enabled(p_evt_write->data))
                {
                    p_client->is_notification_enabled = true;
                    evt.type                          = BLE_BCON_EVT_COMM_STARTED;
                }
                else
                {
                    p_client->is_notification_enabled = false;
                    evt.type                          = BLE_BCON_EVT_COMM_STOPPED;
                }
    
                if (p_bcon->data_handler != NULL)
                {
                    p_bcon->data_handler(&evt);
                }
    
            }
        }
        else if (p_bcon->data_handler != NULL)
        {
            if(p_evt_write->handle == p_bcon->major_handles.value_handle)
                evt.type = BLE_BCON_EVT_MAJOR_SET;
            else if(p_evt_write->handle == p_bcon->minor_handles.value_handle)
                evt.type = BLE_BCON_EVT_MINOR_SET;
            else if(p_evt_write->handle == p_bcon->rssi_handles.value_handle)
                evt.type = BLE_BCON_EVT_RSSI_SET;
    	      else if((p_evt_write->handle == p_bcon->uuid_handles.value_handle))
                evt.type = BLE_BCON_EVT_UUID_SET;
            evt.params.rx_data.p_data = p_evt_write->data;
            evt.params.rx_data.length = p_evt_write->len;
    				
            p_bcon->data_handler(&evt);
        }
        else
        {
           
        }
    }

    Compare your on_write function with the on_write function from the NUS service, and you'll see that the latter also checks the p_evt_write->handle before it calls the event handler :

    static void on_write(ble_nus_t * p_nus, ble_evt_t const * p_ble_evt)
    {
        ret_code_t                    err_code;
        ble_nus_evt_t                 evt;
        ble_nus_client_context_t    * p_client;
        ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
    
        err_code = blcm_link_ctx_get(p_nus->p_link_ctx_storage,
                                     p_ble_evt->evt.gatts_evt.conn_handle,
                                     (void *) &p_client);
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("Link context for 0x%02X connection handle could not be fetched.",
                          p_ble_evt->evt.gatts_evt.conn_handle);
        }
    
        memset(&evt, 0, sizeof(ble_nus_evt_t));
        evt.p_nus       = p_nus;
        evt.conn_handle = p_ble_evt->evt.gatts_evt.conn_handle;
        evt.p_link_ctx  = p_client;
    
        if ((p_evt_write->handle == p_nus->tx_handles.cccd_handle) &&
            (p_evt_write->len == 2))
        {
            if (p_client != NULL)
            {
                if (ble_srv_is_notification_enabled(p_evt_write->data))
                {
                    p_client->is_notification_enabled = true;
                    evt.type                          = BLE_NUS_EVT_COMM_STARTED;
                }
                else
                {
                    p_client->is_notification_enabled = false;
                    evt.type                          = BLE_NUS_EVT_COMM_STOPPED;
                }
    
                if (p_nus->data_handler != NULL)
                {
                    p_nus->data_handler(&evt);
                }
    
            }
        }
        else if ((p_evt_write->handle == p_nus->rx_handles.value_handle) &&
                 (p_nus->data_handler != NULL))
        {
            evt.type                  = BLE_NUS_EVT_RX_DATA;
            evt.params.rx_data.p_data = p_evt_write->data;
            evt.params.rx_data.length = p_evt_write->len;
    
            p_nus->data_handler(&evt);
        }
        else
        {
            // Do Nothing. This event is not relevant for this service.
        }
    }
    

Reply
  • Hi,

    As already mentioned if you should properly check the handles when a Softdevice event is generated. It seems that you call your event handler in the bcon service as long as data_handler is valid, which by itself isn't a good enough check. In addition you are missing some brackets in the if sentence which results in the event handler being called as long as the program passes the if else ( which it will since data handler is valid). 

    static void on_write(ble_bcon_t * p_bcon, ble_evt_t const * p_ble_evt)
    {
        ble_bcon_evt_t                evt;
        ble_bcon_client_context_t     * p_client;
        ble_gatts_evt_write_t const   * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
        uint32_t                      err_code;
        err_code = blcm_link_ctx_get(p_bcon->p_link_ctx_storage,
                                     p_ble_evt->evt.gatts_evt.conn_handle,
                                     (void *) &p_client);
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("Link context for 0x%02X connection handle could not be fetched.",
                          p_ble_evt->evt.gatts_evt.conn_handle);
        }
    
        memset(&evt, 0, sizeof(ble_bcon_evt_t));
        evt.p_bcon       = p_bcon;
        evt.conn_handle  = p_ble_evt->evt.gatts_evt.conn_handle;
        evt.p_link_ctx   = p_client;
    
        if ((p_evt_write->handle == p_bcon->tx_handles.cccd_handle) &&
            (p_evt_write->len == 2))
        {
            if (p_client != NULL)
            {
                if (ble_srv_is_notification_enabled(p_evt_write->data))
                {
                    p_client->is_notification_enabled = true;
                    evt.type                          = BLE_BCON_EVT_COMM_STARTED;
                }
                else
                {
                    p_client->is_notification_enabled = false;
                    evt.type                          = BLE_BCON_EVT_COMM_STOPPED;
                }
    
                if (p_bcon->data_handler != NULL)
                {
                    p_bcon->data_handler(&evt);
                }
    
            }
        }
        else if (p_bcon->data_handler != NULL)
        {
            if(p_evt_write->handle == p_bcon->major_handles.value_handle)
                evt.type = BLE_BCON_EVT_MAJOR_SET;
            else if(p_evt_write->handle == p_bcon->minor_handles.value_handle)
                evt.type = BLE_BCON_EVT_MINOR_SET;
            else if(p_evt_write->handle == p_bcon->rssi_handles.value_handle)
                evt.type = BLE_BCON_EVT_RSSI_SET;
    	      else if((p_evt_write->handle == p_bcon->uuid_handles.value_handle))
                evt.type = BLE_BCON_EVT_UUID_SET;
            evt.params.rx_data.p_data = p_evt_write->data;
            evt.params.rx_data.length = p_evt_write->len;
    				
            p_bcon->data_handler(&evt);
        }
        else
        {
           
        }
    }

    Compare your on_write function with the on_write function from the NUS service, and you'll see that the latter also checks the p_evt_write->handle before it calls the event handler :

    static void on_write(ble_nus_t * p_nus, ble_evt_t const * p_ble_evt)
    {
        ret_code_t                    err_code;
        ble_nus_evt_t                 evt;
        ble_nus_client_context_t    * p_client;
        ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
    
        err_code = blcm_link_ctx_get(p_nus->p_link_ctx_storage,
                                     p_ble_evt->evt.gatts_evt.conn_handle,
                                     (void *) &p_client);
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("Link context for 0x%02X connection handle could not be fetched.",
                          p_ble_evt->evt.gatts_evt.conn_handle);
        }
    
        memset(&evt, 0, sizeof(ble_nus_evt_t));
        evt.p_nus       = p_nus;
        evt.conn_handle = p_ble_evt->evt.gatts_evt.conn_handle;
        evt.p_link_ctx  = p_client;
    
        if ((p_evt_write->handle == p_nus->tx_handles.cccd_handle) &&
            (p_evt_write->len == 2))
        {
            if (p_client != NULL)
            {
                if (ble_srv_is_notification_enabled(p_evt_write->data))
                {
                    p_client->is_notification_enabled = true;
                    evt.type                          = BLE_NUS_EVT_COMM_STARTED;
                }
                else
                {
                    p_client->is_notification_enabled = false;
                    evt.type                          = BLE_NUS_EVT_COMM_STOPPED;
                }
    
                if (p_nus->data_handler != NULL)
                {
                    p_nus->data_handler(&evt);
                }
    
            }
        }
        else if ((p_evt_write->handle == p_nus->rx_handles.value_handle) &&
                 (p_nus->data_handler != NULL))
        {
            evt.type                  = BLE_NUS_EVT_RX_DATA;
            evt.params.rx_data.p_data = p_evt_write->data;
            evt.params.rx_data.length = p_evt_write->len;
    
            p_nus->data_handler(&evt);
        }
        else
        {
            // Do Nothing. This event is not relevant for this service.
        }
    }
    

Children
No Data
Related