Re: nRF52833DK, s113 and nRF5_SDK v16.0.0
It appears that nrf_sdh_freertos.c needs to be modified to support JUST_WORKS and LESC because the softdevice_task() in nrf_sdh_freertos.c never calls nrf_lesc_request_handler() causing attempts to pair and bound to timeout..
After exchanging emails with Daniel Veilleux, we came up the following necessary changes to nrf_sdh_freertos.c:
Two tasks:
- The existing softdevice_task() running at a high priority
- A new lesc_request_task() running at a low priority
The lesc_request_task() is woken by the softdevice_task() to call nrf_ble_lesc_request_handler(), but at a lower priority than the softdevice_task(). Here's an example:
- Softdevice_task() and lesc_request_task() are blocked
- SD_EVT_IRQHandler() sends a notification to softdevice_task()
- Softdevice_task()
- Sends a notification to lesc_tequest_task()
- Calls nrf_sdh_evts_poll()
- Blocks on the next SD_EVT_IRQHandler() notification
- lesc_request_task()
- Calls nrf_ble_lesc_request_handler()
- Blocks on the next Softdevice_task()
- Repeat...
Here's the changes I made to the app_ble_hrs_freertos example to test:
// main.c ... static void gap_params_init(void) { ret_code_t err_code; ble_gap_conn_params_t gap_conn_params; ble_gap_conn_sec_mode_t sec_mode; BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&sec_mode); ... } ... static void services_init(void) { ... // Here the sec level for the Heart Rate Service can be changed/increased. hrs_init.hrm_cccd_wr_sec = SEC_JUST_WORKS; hrs_init.bsl_rd_sec = SEC_JUST_WORKS; ... // Here the sec level for the Battery Service can be changed/increased. bas_init.bl_rd_sec = SEC_JUST_WORKS; bas_init.bl_cccd_wr_sec = SEC_JUST_WORKS; bas_init.bl_report_rd_sec = SEC_JUST_WORKS; ... }
// nrf_sdh_freertos.c static void softdevice_task(void* pvParameter) { NRF_LOG_DEBUG("Enter softdevice_task."); if (m_task_hook != NULL) m_task_hook(pvParameter); while (true) { nrf_sdh_evts_poll(); /* let the handlers run first, incase the EVENT occured before creating this task */ xTaskNotifyGive(m_lesc_task); /* wake the LESC task */ (void) ulTaskNotifyTake(pdTRUE, /* Clear the notification value before exiting (equivalent to the binary semaphore). */ portMAX_DELAY); /* Block indefinitely (INCLUDE_vTaskSuspend has to be enabled).*/ } } static void lesc_task(void* pvParameter) { NRF_LOG_DEBUG("Enter lesc_task."); for(;;) { (void) ulTaskNotifyTake(pdTRUE, portMAX_DELAY); NRF_LOG_INFO("calling nrf_ble_lesc_request_handler()...") nrf_ble_lesc_request_handler(); } } void nrf_sdh_freertos_init(nrf_sdh_freertos_task_hook_t hook_fn, void* p_context) { NRF_LOG_DEBUG("Creating a SoftDevice task."); m_task_hook = hook_fn; BaseType_t xReturned = xTaskCreate( lesc_task, "LESC", NRF_BLE_FREERTOS_LESC_TASK_STACK, p_context, tskIDLE_PRIORITY+1, &m_lesc_task); if (xReturned != pdPASS) { NRF_LOG_ERROR("SoftDevice LESC task not created!"); APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); } xReturned = xTaskCreate(softdevice_task, "BLE", NRF_BLE_FREERTOS_SDH_TASK_STACK, p_context, 2, &m_softdevice_task); if (xReturned != pdPASS) { NRF_LOG_ERROR("SoftDevice task not created."); APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); } }
This seems to work correctly, but I'd like to have it officially blessed by Nordic before I place it production code.