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

BLE_NUS_EVT_RX_DATA triggering twice in my handler

Hello

I have a question i cannot figure out. I'm using my phone to send string on my NUS client (NRF52 with SDK15.3.0 and FreeRTOS) and the event BLE_NUS_EVT_RX_DATA is triggered twice in my handler each time i send only one string ? I'm using serial bluetooth terminal application.

I don't know why this happens. Is it a retry from the sender ? Do i need to ack the sender on the first time ?

If you have any idea about this, feel free to share

Regards,

Aurélien

Parents
  • You only need acks from the application level if you're using Indications, notifications, on the other hand does not, and both are ack'ed automatically in the Link Layer. 

    What event handler do you refer to? Maybe you are forwarding the same event to multiple event handlers? 

    Is the data the same in both events, or do they differ? 

    If the characteristic you want to read is longer than the current MTU size the read operation will have to be fragmented and you will probably receive multiple BLE_NUS_EVT_RX_DATA from the NUS service client. 

    See GATTC Characteristic or Descriptor Value Read

  • I think i ve made some progress.  Actually, at the begenning i was working without OS but now, i have ported FreeRTOS in my project and regarding the ble_evt_handler here the code i have : 

    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
        uint16_t conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
        uint16_t role        = ble_conn_state_role(conn_handle);
    
        // Based on the role this device plays in the connection, dispatch to the right handler.
        if (role == BLE_GAP_ROLE_PERIPH || ble_evt_is_advertising_timeout(p_ble_evt))
        {
            ble_nus_on_ble_evt(p_ble_evt, &m_nus);
            on_ble_peripheral_evt(p_ble_evt);
        }
        else if ((role == BLE_GAP_ROLE_CENTRAL) || (p_ble_evt->header.evt_id == BLE_GAP_EVT_ADV_REPORT))
        {
            ble_nus_c_on_ble_evt(p_ble_evt, &m_ble_nus_c);
            on_ble_central_evt(p_ble_evt);
        }
    }

    I guess i need to comment ble_nus_on_ble_evt and ble_nus_c_on_ble_evt since they ? am i right ?

  • Aurele said:
    I guess i need to comment ble_nus_on_ble_evt and ble_nus_c_on_ble_evt since they ? am i right ?

    What were you trying to say, I think there's a typo.

    I'm not that familiar with FreeRTOS, how do you schedule the execution of event handlers?  

  • oups, sorry, it wasn't clear Slight smile

    I have commented line 9 and line 14 in the previous code like this : 

    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
        uint16_t conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
        uint16_t role        = ble_conn_state_role(conn_handle);
    
        // Based on the role this device plays in the connection, dispatch to the right handler.
        if (role == BLE_GAP_ROLE_PERIPH || ble_evt_is_advertising_timeout(p_ble_evt))
        {
            //ble_nus_on_ble_evt(p_ble_evt, &m_nus);
            on_ble_peripheral_evt(p_ble_evt);
        }
        else if ((role == BLE_GAP_ROLE_CENTRAL) || (p_ble_evt->header.evt_id == BLE_GAP_EVT_ADV_REPORT))
        {
            //ble_nus_c_on_ble_evt(p_ble_evt, &m_ble_nus_c);
            on_ble_central_evt(p_ble_evt);
        }
    }

    and now all is working fine. 

    With FreeRTOS, softdevice is scheduled with a specific task and it is started like this : 

    nrf_sdh_freertos_init(NULL, NULL);

    I guess this task is calling my handlers so i think i don't need to schedule them on my own. 

  • "I guess this task is calling my handlers so i think i don't need to schedule them on my own. "
    You're probably on correct, but you should verify it by reading the implementation of nrf_sdh_freertos_init and on_ble_central_evt, one of these must call the event handler of the NUS library. 

Reply Children
No Data
Related