diff --git a/nimble/host/include/host/ble_gatt.h b/nimble/host/include/host/ble_gatt.h index b06344fc2..d5c3269f0 100644 --- a/nimble/host/include/host/ble_gatt.h +++ b/nimble/host/include/host/ble_gatt.h @@ -885,6 +885,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 6c2acfd4d..43979ba57 100644 --- a/nimble/host/include/host/ble_hs.h +++ b/nimble/host/include/host/ble_hs.h @@ -364,6 +364,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 715d32ce7..2201d4ddb 100644 --- a/nimble/host/src/ble_att_priv.h +++ b/nimble/host/src/ble_att_priv.h @@ -179,6 +179,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 d9915d93d..d6f94a246 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -2758,6 +2758,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 45bc40186..36a11b45b 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -5682,3 +5682,9 @@ ble_gap_init(void) err: return rc; } + +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 48a1253fc..4285cfa43 100644 --- a/nimble/host/src/ble_gap_priv.h +++ b/nimble/host/src/ble_gap_priv.h @@ -122,6 +122,7 @@ void ble_gap_conn_broken(uint16_t conn_handle, 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 78980dbaf..88bed4bb2 100644 --- a/nimble/host/src/ble_gatts.c +++ b/nimble/host/src/ble_gatts.c @@ -1167,6 +1167,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 ea3f274c4..6634f4c13 100644 --- a/nimble/host/src/ble_hs.c +++ b/nimble/host/src/ble_hs.c @@ -823,3 +823,17 @@ ble_hs_init(void) ble_monitor_new_index(0, (uint8_t[6]){ }, "nimble0"); #endif } + +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 139957b0e..53712fede 100644 --- a/nimble/host/src/ble_hs_hci.c +++ b/nimble/host/src/ble_hs_hci.c @@ -643,3 +643,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 51ac3e9e4..ff3604727 100644 --- a/nimble/host/src/ble_hs_hci_priv.h +++ b/nimble/host/src/ble_hs_hci_priv.h @@ -87,6 +87,7 @@ int ble_hs_hci_cmd_tx(uint16_t opcode, void *cmd, uint8_t cmd_len, int ble_hs_hci_cmd_tx_empty_ack(uint16_t opcode, void *cmd, uint8_t cmd_len); void ble_hs_hci_rx_ack(uint8_t *ack_ev); 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 c69fb3da9..536cc5af6 100644 --- a/porting/nimble/include/os/os_mempool.h +++ b/porting/nimble/include/os/os_mempool.h @@ -198,6 +198,15 @@ os_error_t os_mempool_ext_init(struct os_mempool_ext *mpe, uint16_t blocks, */ 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 b7a839303..571408170 100644 --- a/porting/nimble/src/nimble_port.c +++ b/porting/nimble/src/nimble_port.c @@ -30,6 +30,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; void nimble_port_init(void) @@ -60,17 +63,75 @@ nimble_port_init(void) #endif } +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 6a9d21851..a02fd6e6b 100644 --- a/porting/nimble/src/os_mempool.c +++ b/porting/nimble/src/os_mempool.c @@ -175,6 +175,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 db8784d95..2bf7b3d23 100644 --- a/porting/npl/freertos/include/nimble/npl_freertos.h +++ b/porting/npl/freertos/include/nimble/npl_freertos.h @@ -36,6 +36,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); @@ -43,6 +44,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); @@ -53,6 +55,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)