From 56f4975a22cbe26f11c96dbc52d480b4b5482955 Mon Sep 17 00:00:00 2001 From: Hrishikesh Dhayagude Date: Tue, 4 Jun 2019 22:16:02 +0800 Subject: [PATCH] NimBLE-component: Add support to disable/deinit NimBLE host and port --- nimble/host/include/host/ble_gatt.h | 6 ++ nimble/host/include/host/ble_hs.h | 6 ++ nimble/host/src/ble_att_priv.h | 1 + nimble/host/src/ble_att_svr.c | 6 ++ nimble/host/src/ble_gap.c | 6 ++ nimble/host/src/ble_gap_priv.h | 1 + nimble/host/src/ble_gatts.c | 14 +++++ nimble/host/src/ble_hs.c | 14 +++++ nimble/host/src/ble_hs_hci.c | 8 +++ nimble/host/src/ble_hs_hci_priv.h | 1 + nimble/host/store/config/src/ble_store_nvs.c | 2 +- nimble/include/nimble/nimble_npl.h | 6 ++ porting/nimble/include/nimble/nimble_port.h | 4 ++ porting/nimble/include/os/os_mempool.h | 9 +++ porting/nimble/src/nimble_port.c | 61 +++++++++++++++++++ porting/nimble/src/os_mempool.c | 10 +++ .../freertos/include/nimble/nimble_npl_os.h | 23 +++++++ .../include/nimble/nimble_port_freertos.h | 1 + .../freertos/include/nimble/npl_freertos.h | 4 ++ .../npl/freertos/src/nimble_port_freertos.c | 8 +++ porting/npl/freertos/src/npl_os_freertos.c | 35 +++++++++++ 21 files changed, 225 insertions(+), 1 deletion(-) diff --git a/nimble/host/include/host/ble_gatt.h b/nimble/host/include/host/ble_gatt.h index b3bea2bdc..a720c37f5 100644 --- a/nimble/host/include/host/ble_gatt.h +++ b/nimble/host/include/host/ble_gatt.h @@ -1062,6 +1062,12 @@ int ble_gatts_reset(void); */ int ble_gatts_start(void); +/** + * Resets the GATT configuration parameters and deallocates the memory of attributes. + * + */ +void ble_gatts_stop(void); + #ifdef __cplusplus } #endif diff --git a/nimble/host/include/host/ble_hs.h b/nimble/host/include/host/ble_hs.h index 09900fd39..3014db159 100644 --- a/nimble/host/include/host/ble_hs.h +++ b/nimble/host/include/host/ble_hs.h @@ -449,6 +449,12 @@ void ble_hs_evq_set(struct ble_npl_eventq *evq); */ void ble_hs_init(void); +/** + * Deinitializes the NimBLE host. This function must be called after the + * NimBLE host stop procedure is complete. + */ +void ble_hs_deinit(void); + /** * @brief Called when the system is shutting down. Stops the BLE host. * diff --git a/nimble/host/src/ble_att_priv.h b/nimble/host/src/ble_att_priv.h index a2a9f9797..73b6aeab0 100644 --- a/nimble/host/src/ble_att_priv.h +++ b/nimble/host/src/ble_att_priv.h @@ -173,6 +173,7 @@ int ble_att_init(void); /*** @svr */ int ble_att_svr_start(void); +void ble_att_svr_stop(void); struct ble_att_svr_entry * ble_att_svr_find_by_uuid(struct ble_att_svr_entry *start_at, diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c index 8612d3696..0cf9b040a 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -2746,6 +2746,12 @@ err: return rc; } +void +ble_att_svr_stop(void) +{ + ble_att_svr_free_start_mem(); +} + int ble_att_svr_init(void) { diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 9390708f9..3720cafd6 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -6748,3 +6748,9 @@ ble_gap_set_transmit_power_reporting_enable(uint16_t conn_handle, return BLE_HS_ENOTSUP; #endif } + +void +ble_gap_deinit(void) +{ + ble_npl_mutex_deinit(&preempt_done_mutex); +} diff --git a/nimble/host/src/ble_gap_priv.h b/nimble/host/src/ble_gap_priv.h index 0be949da6..e34c99e14 100644 --- a/nimble/host/src/ble_gap_priv.h +++ b/nimble/host/src/ble_gap_priv.h @@ -152,6 +152,7 @@ void ble_gap_reset_state(int reason); int32_t ble_gap_timer(void); int ble_gap_init(void); +void ble_gap_deinit(void); #if MYNEWT_VAL(BLE_HS_DEBUG) int ble_gap_dbg_update_active(uint16_t conn_handle); diff --git a/nimble/host/src/ble_gatts.c b/nimble/host/src/ble_gatts.c index 6732bc166..a465e9445 100644 --- a/nimble/host/src/ble_gatts.c +++ b/nimble/host/src/ble_gatts.c @@ -1170,6 +1170,20 @@ ble_gatts_free_mem(void) ble_gatts_svc_entries = NULL; } + +void +ble_gatts_stop(void) +{ + + ble_hs_max_services = 0; + ble_hs_max_attrs = 0; + ble_hs_max_client_configs = 0; + + ble_gatts_free_mem(); + ble_gatts_free_svc_defs(); + ble_att_svr_stop(); +} + int ble_gatts_start(void) { diff --git a/nimble/host/src/ble_hs.c b/nimble/host/src/ble_hs.c index 026adbcc0..6d640ec9d 100644 --- a/nimble/host/src/ble_hs.c +++ b/nimble/host/src/ble_hs.c @@ -823,3 +823,17 @@ ble_transport_hs_init(void) { ble_hs_init(); } + +void +ble_hs_deinit(void) +{ + ble_gatts_stop(); + + ble_npl_callout_deinit(&ble_hs_timer); + + ble_npl_mutex_deinit(&ble_hs_mutex); + + ble_gap_deinit(); + + ble_hs_hci_deinit(); +} diff --git a/nimble/host/src/ble_hs_hci.c b/nimble/host/src/ble_hs_hci.c index a3a7d2529..50bb55e6c 100644 --- a/nimble/host/src/ble_hs_hci.c +++ b/nimble/host/src/ble_hs_hci.c @@ -651,3 +651,11 @@ ble_hs_hci_init(void) "ble_hs_hci_frag"); BLE_HS_DBG_ASSERT_EVAL(rc == 0); } + +void +ble_hs_hci_deinit(void) +{ + ble_npl_mutex_deinit(&ble_hs_hci_mutex); + + ble_npl_sem_deinit(&ble_hs_hci_sem); +} diff --git a/nimble/host/src/ble_hs_hci_priv.h b/nimble/host/src/ble_hs_hci_priv.h index 356f3a538..31216af99 100644 --- a/nimble/host/src/ble_hs_hci_priv.h +++ b/nimble/host/src/ble_hs_hci_priv.h @@ -86,6 +86,7 @@ int ble_hs_hci_cmd_tx_no_rsp(uint16_t opcode, const void *cmd, uint8_t cmd_len); int ble_hs_hci_cmd_tx(uint16_t opcode, const void *cmd, uint8_t cmd_len, void *rsp, uint8_t rsp_len); void ble_hs_hci_init(void); +void ble_hs_hci_deinit(void); void ble_hs_hci_set_le_supported_feat(uint32_t feat); uint32_t ble_hs_hci_get_le_supported_feat(void); diff --git a/nimble/host/store/config/src/ble_store_nvs.c b/nimble/host/store/config/src/ble_store_nvs.c index 702c25d6f..e3e8bed9d 100644 --- a/nimble/host/store/config/src/ble_store_nvs.c +++ b/nimble/host/store/config/src/ble_store_nvs.c @@ -149,7 +149,7 @@ get_nvs_db_attribute(int obj_type, bool empty, void *value, int num_value) /* Check if the user is searching for empty index to write to */ if (err == ESP_ERR_NVS_NOT_FOUND) { if (empty) { - ESP_LOGI(TAG, "Empty NVS index found = %d", i); + ESP_LOGD(TAG, "Empty NVS index found = %d for obj_type = %d", i, obj_type); return i; } } else if (err == ESP_OK) { diff --git a/nimble/include/nimble/nimble_npl.h b/nimble/include/nimble/nimble_npl.h index 4582adc79..8d5c8de6d 100644 --- a/nimble/include/nimble/nimble_npl.h +++ b/nimble/include/nimble/nimble_npl.h @@ -66,6 +66,8 @@ void *ble_npl_get_current_task_id(void); void ble_npl_eventq_init(struct ble_npl_eventq *evq); +void ble_npl_eventq_deinit(struct ble_npl_eventq *evq); + struct ble_npl_event *ble_npl_eventq_get(struct ble_npl_eventq *evq, ble_npl_time_t tmo); @@ -98,6 +100,8 @@ ble_npl_error_t ble_npl_mutex_pend(struct ble_npl_mutex *mu, ble_npl_error_t ble_npl_mutex_release(struct ble_npl_mutex *mu); +ble_npl_error_t ble_npl_mutex_deinit(struct ble_npl_mutex *mu); + /* * Semaphores */ @@ -109,6 +113,8 @@ ble_npl_error_t ble_npl_sem_pend(struct ble_npl_sem *sem, ble_npl_error_t ble_npl_sem_release(struct ble_npl_sem *sem); +ble_npl_error_t ble_npl_sem_deinit(struct ble_npl_sem *sem); + uint16_t ble_npl_sem_get_count(struct ble_npl_sem *sem); /* diff --git a/porting/nimble/include/nimble/nimble_port.h b/porting/nimble/include/nimble/nimble_port.h index 79cf5f563..e1282d55f 100644 --- a/porting/nimble/include/nimble/nimble_port.h +++ b/porting/nimble/include/nimble/nimble_port.h @@ -24,13 +24,17 @@ #define NIMBLE_CORE (CONFIG_BT_NIMBLE_PINNED_TO_CORE < portNUM_PROCESSORS ? CONFIG_BT_NIMBLE_PINNED_TO_CORE : tskNO_AFFINITY) +#define NIMBLE_PORT_DEINIT_EV_ARG -1 + #ifdef __cplusplus extern "C" { #endif void nimble_port_init(void); +void nimble_port_deinit(void); void nimble_port_run(void); +int nimble_port_stop(void); struct ble_npl_eventq *nimble_port_get_dflt_eventq(void); diff --git a/porting/nimble/include/os/os_mempool.h b/porting/nimble/include/os/os_mempool.h index 71d77065a..cb77583b3 100644 --- a/porting/nimble/include/os/os_mempool.h +++ b/porting/nimble/include/os/os_mempool.h @@ -220,6 +220,15 @@ os_error_t os_mempool_unregister(struct os_mempool *mp); */ os_error_t os_mempool_clear(struct os_mempool *mp); +/** + * Clears an extended memory pool. + * + * @param mpe The extended memory pool to clear. + * + * @return os_error_t + */ +os_error_t os_mempool_ext_clear(struct os_mempool_ext *mpe); + /** * Performs an integrity check of the specified mempool. This function * attempts to detect memory corruption in the specified memory pool. diff --git a/porting/nimble/src/nimble_port.c b/porting/nimble/src/nimble_port.c index ca81f0f8f..ef2574b40 100644 --- a/porting/nimble/src/nimble_port.c +++ b/porting/nimble/src/nimble_port.c @@ -31,6 +31,9 @@ #endif static struct ble_npl_eventq g_eventq_dflt; +static struct ble_hs_stop_listener stop_listener; +static struct ble_npl_sem ble_hs_stop_sem; +static struct ble_npl_event ble_hs_ev_stop; extern void os_msys_init(void); extern void os_mempool_module_init(void); @@ -62,17 +65,75 @@ nimble_port_init(void) } +void +nimble_port_deinit(void) +{ + ble_npl_eventq_deinit(&g_eventq_dflt); + + ble_hs_deinit(); +} + void nimble_port_run(void) { struct ble_npl_event *ev; + int arg; while (1) { ev = ble_npl_eventq_get(&g_eventq_dflt, BLE_NPL_TIME_FOREVER); ble_npl_event_run(ev); + arg = (int)ble_npl_event_get_arg(ev); + if (arg == NIMBLE_PORT_DEINIT_EV_ARG) { + break; + } } } +/** + * Called when the host stop procedure has completed. + */ +static void +ble_hs_stop_cb(int status, void *arg) +{ + ble_npl_sem_release(&ble_hs_stop_sem); +} + +static void +nimble_port_stop_cb(struct ble_npl_event *ev) +{ + ble_npl_sem_release(&ble_hs_stop_sem); +} + +int +nimble_port_stop(void) +{ + int rc; + + ble_npl_sem_init(&ble_hs_stop_sem, 0); + /* Initiate a host stop procedure. */ + rc = ble_hs_stop(&stop_listener, ble_hs_stop_cb, + NULL); + if (rc != 0) { + ble_npl_sem_deinit(&ble_hs_stop_sem); + return rc; + } + + /* Wait till the host stop procedure is complete */ + ble_npl_sem_pend(&ble_hs_stop_sem, BLE_NPL_TIME_FOREVER); + + ble_npl_event_init(&ble_hs_ev_stop, nimble_port_stop_cb, + (void *)NIMBLE_PORT_DEINIT_EV_ARG); + ble_npl_eventq_put(&g_eventq_dflt, &ble_hs_ev_stop); + + /* Wait till the event is serviced */ + ble_npl_sem_pend(&ble_hs_stop_sem, BLE_NPL_TIME_FOREVER); + + ble_npl_sem_deinit(&ble_hs_stop_sem); + + return rc; +} + + struct ble_npl_eventq * nimble_port_get_dflt_eventq(void) { diff --git a/porting/nimble/src/os_mempool.c b/porting/nimble/src/os_mempool.c index 09d5e3526..00fb08a0e 100644 --- a/porting/nimble/src/os_mempool.c +++ b/porting/nimble/src/os_mempool.c @@ -283,6 +283,16 @@ os_mempool_clear(struct os_mempool *mp) return OS_OK; } +os_error_t +os_mempool_ext_clear(struct os_mempool_ext *mpe) +{ + mpe->mpe_mp.mp_flags = 0; + mpe->mpe_put_cb = NULL; + mpe->mpe_put_arg = NULL; + + return os_mempool_clear(&mpe->mpe_mp); +} + bool os_mempool_is_sane(const struct os_mempool *mp) { diff --git a/porting/npl/freertos/include/nimble/nimble_npl_os.h b/porting/npl/freertos/include/nimble/nimble_npl_os.h index 38a7abac4..f24371653 100644 --- a/porting/npl/freertos/include/nimble/nimble_npl_os.h +++ b/porting/npl/freertos/include/nimble/nimble_npl_os.h @@ -91,6 +91,12 @@ ble_npl_eventq_init(struct ble_npl_eventq *evq) evq->q = xQueueCreate(32, sizeof(struct ble_npl_eventq *)); } +static inline void +ble_npl_eventq_deinit(struct ble_npl_eventq *evq) +{ + vQueueDelete(evq->q); +} + static inline struct ble_npl_event * ble_npl_eventq_get(struct ble_npl_eventq *evq, ble_npl_time_t tmo) { @@ -154,6 +160,12 @@ ble_npl_mutex_init(struct ble_npl_mutex *mu) return npl_freertos_mutex_init(mu); } +static inline ble_npl_error_t +ble_npl_mutex_deinit(struct ble_npl_mutex *mu) +{ + return npl_freertos_mutex_deinit(mu); +} + static inline ble_npl_error_t ble_npl_mutex_pend(struct ble_npl_mutex *mu, ble_npl_time_t timeout) { @@ -172,6 +184,12 @@ ble_npl_sem_init(struct ble_npl_sem *sem, uint16_t tokens) return npl_freertos_sem_init(sem, tokens); } +static inline ble_npl_error_t +ble_npl_sem_deinit(struct ble_npl_sem *sem) +{ + return npl_freertos_sem_deinit(sem); +} + static inline ble_npl_error_t ble_npl_sem_pend(struct ble_npl_sem *sem, ble_npl_time_t timeout) { @@ -196,6 +214,11 @@ ble_npl_callout_init(struct ble_npl_callout *co, struct ble_npl_eventq *evq, { npl_freertos_callout_init(co, evq, ev_cb, ev_arg); } +static inline void +ble_npl_callout_deinit(struct ble_npl_callout *co) +{ + npl_freertos_callout_deinit(co); +} static inline ble_npl_error_t ble_npl_callout_reset(struct ble_npl_callout *co, ble_npl_time_t ticks) diff --git a/porting/npl/freertos/include/nimble/nimble_port_freertos.h b/porting/npl/freertos/include/nimble/nimble_port_freertos.h index 43cbf2915..ddeefc71c 100644 --- a/porting/npl/freertos/include/nimble/nimble_port_freertos.h +++ b/porting/npl/freertos/include/nimble/nimble_port_freertos.h @@ -27,6 +27,7 @@ extern "C" { #endif void nimble_port_freertos_init(TaskFunction_t host_task_fn); +void nimble_port_freertos_deinit(void); #ifdef __cplusplus } diff --git a/porting/npl/freertos/include/nimble/npl_freertos.h b/porting/npl/freertos/include/nimble/npl_freertos.h index fb3fd2dd1..3b5ce9584 100644 --- a/porting/npl/freertos/include/nimble/npl_freertos.h +++ b/porting/npl/freertos/include/nimble/npl_freertos.h @@ -34,6 +34,7 @@ void npl_freertos_eventq_remove(struct ble_npl_eventq *evq, struct ble_npl_event *ev); ble_npl_error_t npl_freertos_mutex_init(struct ble_npl_mutex *mu); +ble_npl_error_t npl_freertos_mutex_deinit(struct ble_npl_mutex *mu); ble_npl_error_t npl_freertos_mutex_pend(struct ble_npl_mutex *mu, ble_npl_time_t timeout); @@ -41,6 +42,7 @@ ble_npl_error_t npl_freertos_mutex_pend(struct ble_npl_mutex *mu, ble_npl_error_t npl_freertos_mutex_release(struct ble_npl_mutex *mu); ble_npl_error_t npl_freertos_sem_init(struct ble_npl_sem *sem, uint16_t tokens); +ble_npl_error_t npl_freertos_sem_deinit(struct ble_npl_sem *sem); ble_npl_error_t npl_freertos_sem_pend(struct ble_npl_sem *sem, ble_npl_time_t timeout); @@ -51,6 +53,8 @@ void npl_freertos_callout_init(struct ble_npl_callout *co, struct ble_npl_eventq *evq, ble_npl_event_fn *ev_cb, void *ev_arg); +void npl_freertos_callout_deinit(struct ble_npl_callout *co); + ble_npl_error_t npl_freertos_callout_reset(struct ble_npl_callout *co, ble_npl_time_t ticks); diff --git a/porting/npl/freertos/src/nimble_port_freertos.c b/porting/npl/freertos/src/nimble_port_freertos.c index a8b50ea13..d837ca85a 100644 --- a/porting/npl/freertos/src/nimble_port_freertos.c +++ b/porting/npl/freertos/src/nimble_port_freertos.c @@ -49,3 +49,11 @@ nimble_port_freertos_init(TaskFunction_t host_task_fn) xTaskCreatePinnedToCore(host_task_fn, "ble", 4096, NULL, (configMAX_PRIORITIES - 4), &host_task_h, NIMBLE_CORE); } + +void +nimble_port_freertos_deinit(void) +{ + if (host_task_h) { + vTaskDelete(host_task_h); + } +} diff --git a/porting/npl/freertos/src/npl_os_freertos.c b/porting/npl/freertos/src/npl_os_freertos.c index 53c0426df..07f1294e7 100644 --- a/porting/npl/freertos/src/npl_os_freertos.c +++ b/porting/npl/freertos/src/npl_os_freertos.c @@ -159,6 +159,20 @@ npl_freertos_mutex_init(struct ble_npl_mutex *mu) return BLE_NPL_OK; } +ble_npl_error_t +npl_freertos_mutex_deinit(struct ble_npl_mutex *mu) +{ + if (!mu) { + return BLE_NPL_INVALID_PARAM; + } + + if (mu->handle) { + vSemaphoreDelete(mu->handle); + } + + return BLE_NPL_OK; +} + ble_npl_error_t npl_freertos_mutex_pend(struct ble_npl_mutex *mu, ble_npl_time_t timeout) { @@ -213,6 +227,20 @@ npl_freertos_sem_init(struct ble_npl_sem *sem, uint16_t tokens) return BLE_NPL_OK; } +ble_npl_error_t +npl_freertos_sem_deinit(struct ble_npl_sem *sem) +{ + if (!sem) { + return BLE_NPL_INVALID_PARAM; + } + + if (sem->handle) { + vSemaphoreDelete(sem->handle); + } + + return BLE_NPL_OK; +} + ble_npl_error_t npl_freertos_sem_pend(struct ble_npl_sem *sem, ble_npl_time_t timeout) { @@ -288,6 +316,13 @@ npl_freertos_callout_init(struct ble_npl_callout *co, struct ble_npl_eventq *evq co->evq = evq; ble_npl_event_init(&co->ev, ev_cb, ev_arg); } +void +npl_freertos_callout_deinit(struct ble_npl_callout *co) +{ + if (co->handle) { + xTimerDelete(co->handle, portMAX_DELAY); + } +} ble_npl_error_t npl_freertos_callout_reset(struct ble_npl_callout *co, ble_npl_time_t ticks)