From e2f8239def9fc39b03dd5c719f6c794b1d675c23 Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Wed, 26 Nov 2025 12:21:42 +0530 Subject: [PATCH] fix(nimble): Memory optimization + dynamic memory support --- nimble/host/include/host/ble_gap.h | 8 + nimble/host/include/host/ble_gatt.h | 5 + nimble/host/include/host/ble_hs.h | 11 + nimble/host/include/host/ble_hs_adv.h | 1 + nimble/host/include/host/ble_hs_hci.h | 2 + nimble/host/include/host/ble_sm.h | 5 + nimble/host/include/host/ble_store.h | 3 +- nimble/host/services/ans/src/ble_svc_ans.c | 37 +- nimble/host/services/bas/src/ble_svc_bas.c | 27 +- nimble/host/services/bleuart/src/bleuart.c | 2 +- nimble/host/services/cte/src/ble_svc_cte.c | 98 ++-- nimble/host/services/cts/src/ble_svc_cts.c | 30 +- .../dis/include/services/dis/ble_svc_dis.h | 5 +- nimble/host/services/dis/src/ble_svc_dis.c | 205 +++++--- .../gap/include/services/gap/ble_svc_gap.h | 6 - nimble/host/services/gap/src/ble_svc_gap.c | 214 +++++++- nimble/host/services/gatt/src/ble_svc_gatt.c | 35 +- nimble/host/services/hid/src/ble_svc_hid.c | 120 +++-- nimble/host/services/hr/src/ble_svc_hr.c | 29 +- nimble/host/services/ias/src/ble_svc_ias.c | 31 +- nimble/host/services/ipss/src/ble_svc_ipss.c | 4 +- nimble/host/services/lls/src/ble_svc_lls.c | 28 +- nimble/host/services/ras/src/ble_svc_ras.c | 38 +- .../sps/include/services/sps/ble_svc_sps.h | 3 + nimble/host/services/sps/src/ble_svc_sps.c | 113 ++++- nimble/host/services/tps/src/ble_svc_tps.c | 28 +- nimble/host/src/ble_att.c | 15 +- nimble/host/src/ble_att_clt.c | 18 +- nimble/host/src/ble_att_priv.h | 5 +- nimble/host/src/ble_att_svr.c | 127 ++++- nimble/host/src/ble_eatt.c | 127 ++++- nimble/host/src/ble_eatt_priv.h | 7 +- nimble/host/src/ble_gap.c | 466 +++++++++++++++--- nimble/host/src/ble_gap_priv.h | 4 + nimble/host/src/ble_gatt_priv.h | 10 + nimble/host/src/ble_gattc.c | 441 +++++++++++++++-- nimble/host/src/ble_gattc_cache.c | 136 ++++- nimble/host/src/ble_gattc_cache_conn.c | 115 ++++- nimble/host/src/ble_gattc_cache_priv.h | 3 + nimble/host/src/ble_gatts.c | 348 ++++++++++--- nimble/host/src/ble_gatts_lcl.c | 7 +- nimble/host/src/ble_hs.c | 256 ++++++++-- nimble/host/src/ble_hs_adv.c | 80 ++- nimble/host/src/ble_hs_conn.c | 113 ++++- nimble/host/src/ble_hs_conn_priv.h | 16 +- nimble/host/src/ble_hs_flow.c | 49 +- nimble/host/src/ble_hs_hci.c | 145 ++++-- nimble/host/src/ble_hs_hci_evt.c | 280 +++++++++-- nimble/host/src/ble_hs_hci_priv.h | 4 + nimble/host/src/ble_hs_hci_util.c | 6 + nimble/host/src/ble_hs_id.c | 80 ++- nimble/host/src/ble_hs_id_priv.h | 1 + nimble/host/src/ble_hs_iso.c | 2 +- nimble/host/src/ble_hs_misc.c | 6 +- nimble/host/src/ble_hs_periodic_sync.c | 104 +++- nimble/host/src/ble_hs_periodic_sync_priv.h | 2 +- nimble/host/src/ble_hs_priv.h | 19 + nimble/host/src/ble_hs_pvcy.c | 63 ++- nimble/host/src/ble_hs_pvcy_priv.h | 5 + nimble/host/src/ble_hs_resolv.c | 16 +- nimble/host/src/ble_hs_startup.c | 6 +- nimble/host/src/ble_hs_stop.c | 45 +- nimble/host/src/ble_l2cap.c | 130 ++++- nimble/host/src/ble_l2cap_coc.c | 77 ++- nimble/host/src/ble_l2cap_coc_priv.h | 4 + nimble/host/src/ble_l2cap_priv.h | 13 + nimble/host/src/ble_l2cap_sig.c | 84 +++- nimble/host/src/ble_l2cap_sig_priv.h | 3 + nimble/host/src/ble_sm.c | 196 +++++++- nimble/host/src/ble_sm_alg.c | 38 +- nimble/host/src/ble_sm_cmd.c | 6 + nimble/host/src/ble_sm_priv.h | 11 +- nimble/host/src/ble_sm_sc.c | 87 +++- nimble/host/src/ble_store.c | 180 ++++++- nimble/host/src/ble_store_util.c | 38 ++ nimble/host/src/ble_uuid.c | 57 +++ nimble/host/src/ble_uuid_priv.h | 1 + .../host/store/config/src/ble_store_config.c | 43 +- .../store/config/src/ble_store_config_conf.c | 26 +- .../store/config/src/ble_store_config_priv.h | 113 ++++- nimble/host/store/config/src/ble_store_nvs.c | 2 - nimble/transport/esp_ipc/src/hci_esp_ipc.c | 5 +- nimble/transport/socket/src/ble_hci_socket.c | 6 +- nimble/transport/src/transport.c | 174 ++++++- nimble/transport/uart/src/hci_uart.c | 2 + porting/nimble/src/hal_uart.c | 13 +- porting/nimble/src/nimble_port.c | 78 ++- porting/nimble/src/os_mbuf.c | 33 ++ porting/nimble/src/os_mempool.c | 100 +++- porting/nimble/src/os_msys_init.c | 126 ++++- porting/npl/freertos/src/npl_os_freertos.c | 213 +++++--- 91 files changed, 5206 insertions(+), 868 deletions(-) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index b21899ed8..47297cd32 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -3199,6 +3199,7 @@ int ble_gap_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr, const struct ble_gap_conn_params *params, ble_gap_event_fn *cb, void *cb_arg); +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) /** * Initiates an Sync connect procedure for PAwR. * @@ -3264,6 +3265,7 @@ int ble_gap_connect_with_synced(uint8_t own_addr_type, uint8_t advertising_handl const struct ble_gap_conn_params *phy_2m_conn_params, const struct ble_gap_conn_params *phy_coded_conn_params, ble_gap_event_fn *cb, void *cb_arg); +#endif /** * Initiates an extended connect procedure. * @@ -4031,6 +4033,7 @@ int ble_gap_set_path_loss_reporting_param(uint16_t conn_handle, uint8_t high_thr uint8_t low_hysteresis, uint16_t min_time_spent); #endif +#if MYNEWT_VAL(BLE_UTIL_API) /** * Set Data Related Address Changes Param * @@ -4040,7 +4043,9 @@ int ble_gap_set_path_loss_reporting_param(uint16_t conn_handle, uint8_t high_thr * @return 0 on success; nonzero on failure. */ int ble_gap_set_data_related_addr_change_param(uint8_t adv_handle, uint8_t change_reason); +#endif +#if MYNEWT_VAL(BLE_DTM_MODE_TEST) /** * Start a test where the DUT generates reference packets at a fixed interval. * @@ -4105,6 +4110,7 @@ int ble_gap_dtm_enh_tx_start(uint8_t tx_chan, uint8_t test_data_len, uint8_t pay * @return 0 on success; nonzero on failure */ int ble_gap_dtm_enh_rx_start(uint8_t rx_chan, uint8_t index, uint8_t phy); +#endif /** * Set Read Remote Version Information is used to retrieve the version, manufacturer, @@ -4120,6 +4126,7 @@ int ble_gap_dtm_enh_rx_start(uint8_t rx_chan, uint8_t index, uint8_t phy); int ble_gap_read_rem_ver_info(uint16_t conn_handle, uint8_t *version, uint16_t *manufacturer, uint16_t *subversion); +#if MYNEWT_VAL(BLE_UTIL_API) /** * Read local resolvable address command * @@ -4134,6 +4141,7 @@ int ble_gap_read_rem_ver_info(uint16_t conn_handle, uint8_t *version, uint16_t * int ble_gap_rd_local_resolv_addr(uint8_t peer_addr_type, const ble_addr_t *peer_addr, uint8_t *out_addr); +#endif #if MYNEWT_VAL(BLE_CHANNEL_SOUNDING) /** diff --git a/nimble/host/include/host/ble_gatt.h b/nimble/host/include/host/ble_gatt.h index 961f190b4..bfa27dfc3 100644 --- a/nimble/host/include/host/ble_gatt.h +++ b/nimble/host/include/host/ble_gatt.h @@ -197,6 +197,8 @@ struct ble_hs_cfg; #define BLE_GATT_SVC_TYPE_SECONDARY 2 /** @} */ + +#if MYNEWT_VAL(BLE_CPFD_CAFD) /** * Client Presentation Format * GATT Format Types @@ -394,6 +396,7 @@ struct ble_hs_cfg; #define BLE_GATT_CHR_BT_SIG_DESC_RIGHT 0x010E #define BLE_GATT_CHR_BT_SIG_DESC_INTERNAL 0x010F #define BLE_GATT_CHR_BT_SIG_DESC_EXTERNAL 0x0110 +#endif /*** @server. */ /** Represents one notification tuple in a multi notification PDU */ @@ -1129,6 +1132,7 @@ struct ble_gatt_dsc_def { void *arg; }; +#if MYNEWT_VAL(BLE_CPFD_CAFD) /** * Client Presentation Format Descriptor * Defines the format of the Characteristic Value. @@ -1162,6 +1166,7 @@ struct ble_gatt_cpfd { /** The description of this characteristic. Depends on name space. */ uint16_t description; }; +#endif /** * Context for an access to a GATT characteristic or descriptor. When a client diff --git a/nimble/host/include/host/ble_hs.h b/nimble/host/include/host/ble_hs.h index adc2efd8d..44f9ef032 100644 --- a/nimble/host/include/host/ble_hs.h +++ b/nimble/host/include/host/ble_hs.h @@ -509,7 +509,18 @@ void ble_hs_init(void); * @return SYSDOWN_IN_PROGRESS. */ int ble_hs_shutdown(int reason); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +/** + * Get the current enabled state of the BLE host. + * + * In dynamic memory mode, the host state is stored in a dynamically allocated + * context. Returns the current value of the enabled_state field. If the + * context or its internal variables are not yet initialized, 0 is returned. + * + */ +uint8_t ble_hs_get_enabled_state(void); +#endif #ifdef __cplusplus } #endif diff --git a/nimble/host/include/host/ble_hs_adv.h b/nimble/host/include/host/ble_hs_adv.h index 5d2ca2a6a..77c6174a4 100644 --- a/nimble/host/include/host/ble_hs_adv.h +++ b/nimble/host/include/host/ble_hs_adv.h @@ -236,6 +236,7 @@ int ble_hs_adv_parse(const uint8_t *data, uint8_t length, int ble_hs_adv_find_field(uint8_t type, const uint8_t *data, uint8_t length, const struct ble_hs_adv_field **out); +void ble_hs_adv_parse_free(void); #ifdef __cplusplus } #endif diff --git a/nimble/host/include/host/ble_hs_hci.h b/nimble/host/include/host/ble_hs_hci.h index d5a8ee5b9..0be6a2ee7 100644 --- a/nimble/host/include/host/ble_hs_hci.h +++ b/nimble/host/include/host/ble_hs_hci.h @@ -120,6 +120,7 @@ int ble_hs_hci_send_vs_cmd(uint16_t ocf, const void *cmdbuf, uint8_t cmdlen, void *rspbuf, uint8_t rsplen); #endif +#if MYNEWT_VAL(BLE_UTIL_API) /** * Instructs the controller to set or clear a bit controlled by the Host in the * Link Layer FeatureSet stored in the Controller. @@ -129,6 +130,7 @@ int ble_hs_hci_send_vs_cmd(uint16_t ocf, const void *cmdbuf, uint8_t cmdlen, * @return 0 on success, error code on failure */ int ble_hs_hci_set_host_feature(uint8_t bit_num, uint8_t bit_val); +#endif #ifdef __cplusplus } diff --git a/nimble/host/include/host/ble_sm.h b/nimble/host/include/host/ble_sm.h index 8cdb85ca9..e61b391b0 100644 --- a/nimble/host/include/host/ble_sm.h +++ b/nimble/host/include/host/ble_sm.h @@ -156,6 +156,11 @@ int ble_sm_get_static_passkey_config(uint32_t *passkey, bool *enabled); #endif #endif +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void ble_sm_proc_deinit(void); +#endif + + #ifdef __cplusplus } #endif diff --git a/nimble/host/include/host/ble_store.h b/nimble/host/include/host/ble_store.h index 814bdcb89..a6c1a8e03 100644 --- a/nimble/host/include/host/ble_store.h +++ b/nimble/host/include/host/ble_store.h @@ -70,8 +70,9 @@ struct ble_store_key_sec { */ struct ble_store_value_sec { ble_addr_t peer_addr; +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) uint16_t bond_count; - +#endif uint8_t key_size; uint16_t ediv; uint64_t rand_num; diff --git a/nimble/host/services/ans/src/ble_svc_ans.c b/nimble/host/services/ans/src/ble_svc_ans.c index 0b02b9a93..51abbdb3f 100644 --- a/nimble/host/services/ans/src/ble_svc_ans.c +++ b/nimble/host/services/ans/src/ble_svc_ans.c @@ -26,7 +26,7 @@ #include "host/ble_gap.h" #include "services/ans/ble_svc_ans.h" -#if MYNEWT_VAL(BLE_GATTS) +#if MYNEWT_VAL(BLE_GATTS) && CONFIG_BT_NIMBLE_ANS_SERVICE /* Max length of new alert info string */ #define BLE_SVC_ANS_INFO_STR_MAX_LEN 18 /* Max length of a new alert notification, max string length + 2 bytes @@ -77,18 +77,21 @@ static int ble_svc_ans_chr_write(struct os_mbuf *om, uint16_t min_len, uint16_t max_len, void *dst, uint16_t *len); -static const struct ble_gatt_svc_def ble_svc_ans_defs[] = { - { - /*** Alert Notification Service. */ - .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = BLE_UUID16_DECLARE(BLE_SVC_ANS_UUID16), - .characteristics = (struct ble_gatt_chr_def[]) { { +static const ble_uuid16_t uuid_svc_ans = BLE_UUID16_INIT(BLE_SVC_ANS_UUID16); +static const ble_uuid16_t uuid_chr_new_alert_cat = BLE_UUID16_INIT(BLE_SVC_ANS_CHR_UUID16_SUP_NEW_ALERT_CAT); +static const ble_uuid16_t uuid_chr_new_alert = BLE_UUID16_INIT(BLE_SVC_ANS_CHR_UUID16_NEW_ALERT); +static const ble_uuid16_t uuid_chr_unr_alert_cat = BLE_UUID16_INIT(BLE_SVC_ANS_CHR_UUID16_SUP_UNR_ALERT_CAT); +static const ble_uuid16_t uuid_chr_unr_alert_stat = BLE_UUID16_INIT(BLE_SVC_ANS_CHR_UUID16_UNR_ALERT_STAT); +static const ble_uuid16_t uuid_chr_alert_notif_ctrl_pt = BLE_UUID16_INIT(BLE_SVC_ANS_CHR_UUID16_ALERT_NOT_CTRL_PT); + +static const struct ble_gatt_chr_def ans_characteristics[] = { + { /** Supported New Alert Catagory * * This characteristic exposes what categories of new * alert are supported in the server. */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_ANS_CHR_UUID16_SUP_NEW_ALERT_CAT), + .uuid = &uuid_chr_new_alert_cat.u, .access_cb = ble_svc_ans_access, .flags = BLE_GATT_CHR_F_READ, }, { @@ -97,7 +100,7 @@ static const struct ble_gatt_svc_def ble_svc_ans_defs[] = { * This characteristic exposes information about * the count of new alerts (for a given category). */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_ANS_CHR_UUID16_NEW_ALERT), + .uuid = &uuid_chr_new_alert.u, .access_cb = ble_svc_ans_access, .val_handle = &ble_svc_ans_new_alert_val_handle, .flags = BLE_GATT_CHR_F_NOTIFY, @@ -107,7 +110,7 @@ static const struct ble_gatt_svc_def ble_svc_ans_defs[] = { * This characteristic exposes what categories of * unread alert are supported in the server. */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_ANS_CHR_UUID16_SUP_UNR_ALERT_CAT), + .uuid = &uuid_chr_unr_alert_cat.u, .access_cb = ble_svc_ans_access, .flags = BLE_GATT_CHR_F_READ, }, { @@ -116,7 +119,7 @@ static const struct ble_gatt_svc_def ble_svc_ans_defs[] = { * This characteristic exposes the count of unread * alert events existing in the server. */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_ANS_CHR_UUID16_UNR_ALERT_STAT), + .uuid = &uuid_chr_unr_alert_stat.u, .access_cb = ble_svc_ans_access, .val_handle = &ble_svc_ans_unr_alert_val_handle, .flags = BLE_GATT_CHR_F_NOTIFY, @@ -130,12 +133,20 @@ static const struct ble_gatt_svc_def ble_svc_ans_defs[] = { * Client Characteristic Configuration for each alert * characteristic. */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_ANS_CHR_UUID16_ALERT_NOT_CTRL_PT), + .uuid = &uuid_chr_alert_notif_ctrl_pt.u, .access_cb = ble_svc_ans_access, .flags = BLE_GATT_CHR_F_WRITE, }, { 0, /* No more characteristics in this service. */ - } }, + } +}; + +static const struct ble_gatt_svc_def ble_svc_ans_defs[] = { + { + /*** Alert Notification Service. */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &uuid_svc_ans.u, + .characteristics = ans_characteristics, }, { diff --git a/nimble/host/services/bas/src/ble_svc_bas.c b/nimble/host/services/bas/src/ble_svc_bas.c index 468e433b6..9b97953dd 100644 --- a/nimble/host/services/bas/src/ble_svc_bas.c +++ b/nimble/host/services/bas/src/ble_svc_bas.c @@ -40,14 +40,13 @@ static int ble_svc_bas_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); -static const struct ble_gatt_svc_def ble_svc_bas_defs[] = { +static const ble_uuid16_t uuid_svc_bas = BLE_UUID16_INIT(BLE_SVC_BAS_UUID16); +static const ble_uuid16_t uuid_chr_bat_lvl = BLE_UUID16_INIT(BLE_SVC_BAS_CHR_UUID16_BATTERY_LEVEL); + +static const struct ble_gatt_chr_def bas_characteristics[] = { { - /*** Battery Service. */ - .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = BLE_UUID16_DECLARE(BLE_SVC_BAS_UUID16), - .characteristics = (struct ble_gatt_chr_def[]) { { /*** Battery level characteristic */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_BAS_CHR_UUID16_BATTERY_LEVEL), + .uuid = &uuid_chr_bat_lvl.u, .access_cb = ble_svc_bas_access, #if MYNEWT_VAL(BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE) > 0 .val_handle = &ble_svc_bas_battery_handle, @@ -57,12 +56,19 @@ static const struct ble_gatt_svc_def ble_svc_bas_defs[] = { BLE_GATT_CHR_F_NOTIFY | #endif MYNEWT_VAL(BLE_SVC_BAS_BATTERY_LEVEL_READ_PERM), - }, { - 0, /* No more characteristics in this service. */ - } }, }, - { + 0, /* No more characteristics in this service. */ + }, +}; + +static const struct ble_gatt_svc_def ble_svc_bas_defs[] = { + { + /*** Battery Service. */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &uuid_svc_bas.u, + .characteristics = bas_characteristics, + }, { 0, /* No more services. */ }, }; @@ -109,6 +115,7 @@ ble_svc_bas_battery_level_set(uint8_t level) { return 0; } + /** * Initialize the Battery Service. */ diff --git a/nimble/host/services/bleuart/src/bleuart.c b/nimble/host/services/bleuart/src/bleuart.c index 0b4f107b2..891d5faef 100644 --- a/nimble/host/services/bleuart/src/bleuart.c +++ b/nimble/host/services/bleuart/src/bleuart.c @@ -200,7 +200,7 @@ bleuart_init(void) rc = console_init(bleuart_uart_read); SYSINIT_PANIC_ASSERT(rc == 0); - console_buf = nimble_platform_mem_malloc(MYNEWT_VAL(BLEUART_MAX_INPUT)); + console_buf = nimble_platform_mem_calloc(1,MYNEWT_VAL(BLEUART_MAX_INPUT)); SYSINIT_PANIC_ASSERT(console_buf != NULL); } #endif diff --git a/nimble/host/services/cte/src/ble_svc_cte.c b/nimble/host/services/cte/src/ble_svc_cte.c index 6446fdde7..f751469fc 100644 --- a/nimble/host/services/cte/src/ble_svc_cte.c +++ b/nimble/host/services/cte/src/ble_svc_cte.c @@ -119,54 +119,64 @@ static int ble_svc_cte_adv_cte_phy_access(uint16_t conn_handle, uint16_t attr_ha /** * @brief Constant Tone Extensio Service definition */ + +static const ble_uuid16_t uuid_svc_cte = BLE_UUID16_INIT(BLE_SVC_CTE_UUID16); +static const ble_uuid16_t uuid_chr_cte_enable = BLE_UUID16_INIT(BLE_SVC_CTE_CHR_UUID16_ENABLE); +static const ble_uuid16_t uuid_chr_cte_min_len = BLE_UUID16_INIT(BLE_SVC_CTE_CHR_UUID16_MINIMUM_LENGTH); +static const ble_uuid16_t uuid_chr_cte_min_trans_cnt = BLE_UUID16_INIT(BLE_SVC_CTE_CHR_UUID16_MINIMUM_TRANSMIT_COUNT); +static const ble_uuid16_t uuid_chr_cte_trans_dur = BLE_UUID16_INIT(BLE_SVC_CTE_CHR_UUID16_TRANSMIT_DURATION); +static const ble_uuid16_t uuid_chr_cte_ext_itvl = BLE_UUID16_INIT(BLE_SVC_CTE_CHR_UUID16_INTERVAL); +static const ble_uuid16_t uuid_chr_cte_ext_phy = BLE_UUID16_INIT(BLE_SVC_CTE_CHR_UUID16_PHY); + +static const struct ble_gatt_chr_def cte_characteristics[] = { + { + /*** Characteristic: Constant Tone Extension Enable. */ + .uuid = &uuid_chr_cte_enable.u, + .access_cb = ble_svc_cte_enable_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE, + }, + { + /*** Characteristic: Advertising Constant Tone Extension Minimum Length. */ + .uuid = &uuid_chr_cte_min_len.u, + .access_cb = ble_svc_cte_adv_cte_min_length_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE, + }, + { + /*** Characteristic: Advertising Constant Tone Extension Minimum Transmit Count. */ + .uuid = &uuid_chr_cte_min_trans_cnt.u, + .access_cb = ble_svc_cte_adv_cte_min_transmit_count_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE, + }, + { + /*** Characteristic: Advertising Constant Tone Extension Transmit Duration. */ + .uuid = &uuid_chr_cte_trans_dur.u, + .access_cb = ble_svc_cte_adv_cte_transmit_duration_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE, + }, + { + /*** Characteristic: Advertising Constant Tone Extension Interval. */ + .uuid = &uuid_chr_cte_ext_itvl.u, + .access_cb = ble_svc_cte_adv_cte_interval_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE, + }, + { + /*** Characteristic: Advertising Constant Tone Extension PHY. */ + .uuid = &uuid_chr_cte_ext_phy.u, + .access_cb = ble_svc_cte_adv_cte_phy_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE, + }, + { + 0, /* No more characteristics in this service. */ + } +}; + static const struct ble_gatt_svc_def ble_svc_cte_defs[] = { { /*** Service: Asset Tracking Service. */ .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = BLE_UUID16_DECLARE(BLE_SVC_CTE_UUID16), - .characteristics = (struct ble_gatt_chr_def[]) { - { - /*** Characteristic: Constant Tone Extension Enable. */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_CTE_CHR_UUID16_ENABLE), - .access_cb = ble_svc_cte_enable_access, - .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE, - }, - { - /*** Characteristic: Advertising Constant Tone Extension Minimum Length. */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_CTE_CHR_UUID16_MINIMUM_LENGTH), - .access_cb = ble_svc_cte_adv_cte_min_length_access, - .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE, - }, - { - /*** Characteristic: Advertising Constant Tone Extension Minimum Transmit Count. */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_CTE_CHR_UUID16_MINIMUM_TRANSMIT_COUNT), - .access_cb = ble_svc_cte_adv_cte_min_transmit_count_access, - .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE, - }, - { - /*** Characteristic: Advertising Constant Tone Extension Transmit Duration. */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_CTE_CHR_UUID16_TRANSMIT_DURATION), - .access_cb = ble_svc_cte_adv_cte_transmit_duration_access, - .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE, - }, - { - /*** Characteristic: Advertising Constant Tone Extension Interval. */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_CTE_CHR_UUID16_INTERVAL), - .access_cb = ble_svc_cte_adv_cte_interval_access, - .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE, - }, - { - /*** Characteristic: Advertising Constant Tone Extension PHY. */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_CTE_CHR_UUID16_PHY), - .access_cb = ble_svc_cte_adv_cte_phy_access, - .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE, - }, - { - 0, /* No more characteristics in this service. */ - } - }, + .uuid = &uuid_svc_cte.u, + .characteristics = cte_characteristics, }, - { 0, /* No more services. */ }, @@ -570,4 +580,4 @@ ble_svc_cte_init(void) } -#endif \ No newline at end of file +#endif diff --git a/nimble/host/services/cts/src/ble_svc_cts.c b/nimble/host/services/cts/src/ble_svc_cts.c index 29119c5f7..95d5559ec 100644 --- a/nimble/host/services/cts/src/ble_svc_cts.c +++ b/nimble/host/services/cts/src/ble_svc_cts.c @@ -46,14 +46,15 @@ static int ble_svc_cts_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); -static const struct ble_gatt_svc_def ble_svc_cts_defs[] = { +static const ble_uuid16_t uuid_svc_cts = BLE_UUID16_INIT(BLE_SVC_CTS_UUID16); +static const ble_uuid16_t uuid_chr_current_time = BLE_UUID16_INIT(BLE_SVC_CTS_CHR_UUID16_CURRENT_TIME); +static const ble_uuid16_t uuid_chr_loc_time_info = BLE_UUID16_INIT(BLE_SVC_CTS_CHR_UUID16_LOCAL_TIME_INFO); +static const ble_uuid16_t uuid_chr_ref_time_info = BLE_UUID16_INIT(BLE_SVC_CTS_CHR_UUID16_REF_TIME_INFO); + +static const struct ble_gatt_chr_def cts_characteristics[] = { { - /*** Current Time Service. */ - .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = BLE_UUID16_DECLARE(BLE_SVC_CTS_UUID16), - .characteristics = (struct ble_gatt_chr_def[]) { { - /*** Current Time characteristic */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_CTS_CHR_UUID16_CURRENT_TIME), + /*** Current Time characteristic */ + .uuid = &uuid_chr_current_time.u, .access_cb = ble_svc_cts_access, .val_handle = &ble_svc_cts_curr_time_handle, .flags = BLE_GATT_CHR_F_READ | @@ -61,22 +62,29 @@ static const struct ble_gatt_svc_def ble_svc_cts_defs[] = { BLE_GATT_CHR_F_NOTIFY }, { /*** Local info characteristic */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_CTS_CHR_UUID16_LOCAL_TIME_INFO), + .uuid = &uuid_chr_loc_time_info.u, .access_cb = ble_svc_cts_access, .val_handle = &ble_svc_cts_local_time_info_handle, .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE }, { /*** Reference time info Characteristic */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_CTS_CHR_UUID16_REF_TIME_INFO), + .uuid = &uuid_chr_ref_time_info.u, .access_cb = ble_svc_cts_access, .val_handle = &ble_svc_cts_ref_time_handle, .flags = BLE_GATT_CHR_F_READ }, { 0, /* No more characteristics in this service. */ - } }, - }, + }, +}; +static const struct ble_gatt_svc_def ble_svc_cts_defs[] = { + { + /*** Current Time Service. */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &uuid_svc_cts.u, + .characteristics = cts_characteristics, + }, { 0, /* No more services. */ }, diff --git a/nimble/host/services/dis/include/services/dis/ble_svc_dis.h b/nimble/host/services/dis/include/services/dis/ble_svc_dis.h index 749c439f1..5e0a855c8 100644 --- a/nimble/host/services/dis/include/services/dis/ble_svc_dis.h +++ b/nimble/host/services/dis/include/services/dis/ble_svc_dis.h @@ -119,8 +119,11 @@ struct ble_svc_dis_data { /** * Variable holding data for the main characteristics. */ +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +extern struct ble_svc_dis_data *ble_svc_dis_data; +#else extern struct ble_svc_dis_data ble_svc_dis_data; - +#endif /** * Service initialisation. * Automatically called during package initialisation. diff --git a/nimble/host/services/dis/src/ble_svc_dis.c b/nimble/host/services/dis/src/ble_svc_dis.c index 2abf5bf2a..6d0163b7e 100644 --- a/nimble/host/services/dis/src/ble_svc_dis.c +++ b/nimble/host/services/dis/src/ble_svc_dis.c @@ -24,8 +24,14 @@ #include "services/dis/ble_svc_dis.h" #if MYNEWT_VAL(BLE_GATTS) && CONFIG_BT_NIMBLE_DIS_SERVICE + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#include "esp_nimble_mem.h" +struct ble_svc_dis_data *ble_svc_dis_data_ptr = NULL; +#define ble_svc_dis_data (*ble_svc_dis_data_ptr) +#else /* Device information */ -struct ble_svc_dis_data ble_svc_dis_data = { +struct ble_svc_dis_data _ble_svc_dis_data = { .model_number = MYNEWT_VAL(BLE_SVC_DIS_MODEL_NUMBER_DEFAULT), .serial_number = MYNEWT_VAL(BLE_SVC_DIS_SERIAL_NUMBER_DEFAULT), .firmware_revision = MYNEWT_VAL(BLE_SVC_DIS_FIRMWARE_REVISION_DEFAULT), @@ -37,6 +43,8 @@ struct ble_svc_dis_data ble_svc_dis_data = { .ieee = "dummy_data", .udi = NULL, /** For now no UID fields are supported */ }; +#define ble_svc_dis_data _ble_svc_dis_data +#endif /* Access function */ #if (MYNEWT_VAL(BLE_SVC_DIS_MODEL_NUMBER_READ_PERM) >= 0) || \ @@ -52,96 +60,116 @@ ble_svc_dis_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); #endif -static const struct ble_gatt_svc_def ble_svc_dis_defs[] = { - { /*** Service: Device Information Service (DIS). */ - .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_UUID16), - .characteristics = (struct ble_gatt_chr_def[]) { { +/* Pre-defined UUIDs to avoid compound literals in DRAM */ +static const ble_uuid16_t uuid_svc_dis = BLE_UUID16_INIT(BLE_SVC_DIS_UUID16); +static const ble_uuid16_t uuid_chr_model_number = BLE_UUID16_INIT(BLE_SVC_DIS_CHR_UUID16_MODEL_NUMBER); +static const ble_uuid16_t uuid_chr_serial_number = BLE_UUID16_INIT(BLE_SVC_DIS_CHR_UUID16_SERIAL_NUMBER); +static const ble_uuid16_t uuid_chr_firmware_revision = BLE_UUID16_INIT(BLE_SVC_DIS_CHR_UUID16_FIRMWARE_REVISION); +static const ble_uuid16_t uuid_chr_hardware_revision = BLE_UUID16_INIT(BLE_SVC_DIS_CHR_UUID16_HARDWARE_REVISION); +static const ble_uuid16_t uuid_chr_software_revision = BLE_UUID16_INIT(BLE_SVC_DIS_CHR_UUID16_SOFTWARE_REVISION); +static const ble_uuid16_t uuid_chr_manufacturer_name = BLE_UUID16_INIT(BLE_SVC_DIS_CHR_UUID16_MANUFACTURER_NAME); +static const ble_uuid16_t uuid_chr_system_id = BLE_UUID16_INIT(BLE_SVC_DIS_CHR_UUID16_SYSTEM_ID); +static const ble_uuid16_t uuid_chr_ieee_cert = BLE_UUID16_INIT(BLE_SVC_DIS_CHR_UUID16_IEEE_REG_CERT_LIST); +static const ble_uuid16_t uuid_chr_pnp_id = BLE_UUID16_INIT(BLE_SVC_DIS_CHR_UUID16_PNP_ID); +static const ble_uuid16_t uuid_chr_udi = BLE_UUID16_INIT(BLE_SVC_DIS_CHR_UUID16_UDI); + +/* Pre-defined characteristics array to avoid compound literal in DRAM */ +static const struct ble_gatt_chr_def dis_characteristics[] = { #if (MYNEWT_VAL(BLE_SVC_DIS_MODEL_NUMBER_READ_PERM) >= 0) - /*** Characteristic: Model Number String */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_CHR_UUID16_MODEL_NUMBER), - .access_cb = ble_svc_dis_access, - .flags = BLE_GATT_CHR_F_READ | - MYNEWT_VAL(BLE_SVC_DIS_MODEL_NUMBER_READ_PERM), - }, { + { + /*** Characteristic: Model Number String */ + .uuid = &uuid_chr_model_number.u, + .access_cb = ble_svc_dis_access, + .flags = BLE_GATT_CHR_F_READ | MYNEWT_VAL(BLE_SVC_DIS_MODEL_NUMBER_READ_PERM), + }, #endif #if (MYNEWT_VAL(BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM) >= 0) - /*** Characteristic: Serial Number String */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_CHR_UUID16_SERIAL_NUMBER), - .access_cb = ble_svc_dis_access, - .flags = BLE_GATT_CHR_F_READ | - MYNEWT_VAL(BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM), - }, { + { + /*** Characteristic: Serial Number String */ + .uuid = &uuid_chr_serial_number.u, + .access_cb = ble_svc_dis_access, + .flags = BLE_GATT_CHR_F_READ | MYNEWT_VAL(BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM), + }, #endif #if (MYNEWT_VAL(BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM) >= 0) - /*** Characteristic: Hardware Revision String */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_CHR_UUID16_HARDWARE_REVISION), - .access_cb = ble_svc_dis_access, - .flags = BLE_GATT_CHR_F_READ | - MYNEWT_VAL(BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM), - }, { + { + /*** Characteristic: Hardware Revision String */ + .uuid = &uuid_chr_hardware_revision.u, + .access_cb = ble_svc_dis_access, + .flags = BLE_GATT_CHR_F_READ | MYNEWT_VAL(BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM), + }, #endif #if (MYNEWT_VAL(BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM) >= 0) - /*** Characteristic: Firmware Revision String */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_CHR_UUID16_FIRMWARE_REVISION), - .access_cb = ble_svc_dis_access, - .flags = BLE_GATT_CHR_F_READ | - MYNEWT_VAL(BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM), - }, { + { + /*** Characteristic: Firmware Revision String */ + .uuid = &uuid_chr_firmware_revision.u, + .access_cb = ble_svc_dis_access, + .flags = BLE_GATT_CHR_F_READ | MYNEWT_VAL(BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM), + }, #endif #if (MYNEWT_VAL(BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM) >= 0) - /*** Characteristic: Software Revision String */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_CHR_UUID16_SOFTWARE_REVISION), - .access_cb = ble_svc_dis_access, - .flags = BLE_GATT_CHR_F_READ | - MYNEWT_VAL(BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM), - }, { + { + /*** Characteristic: Software Revision String */ + .uuid = &uuid_chr_software_revision.u, + .access_cb = ble_svc_dis_access, + .flags = BLE_GATT_CHR_F_READ | MYNEWT_VAL(BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM), + }, #endif #if (MYNEWT_VAL(BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM) >= 0) - /*** Characteristic: Manufacturer Name */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_CHR_UUID16_MANUFACTURER_NAME), - .access_cb = ble_svc_dis_access, - .flags = BLE_GATT_CHR_F_READ | - MYNEWT_VAL(BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM), - }, { + { + /*** Characteristic: Manufacturer Name */ + .uuid = &uuid_chr_manufacturer_name.u, + .access_cb = ble_svc_dis_access, + .flags = BLE_GATT_CHR_F_READ | MYNEWT_VAL(BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM), + }, #endif #if (MYNEWT_VAL(BLE_SVC_DIS_SYSTEM_ID_READ_PERM) >= 0) - /*** Characteristic: System Id */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_CHR_UUID16_SYSTEM_ID), - .access_cb = ble_svc_dis_access, - .flags = BLE_GATT_CHR_F_READ | - MYNEWT_VAL(BLE_SVC_DIS_SYSTEM_ID_READ_PERM), - }, { -#endif - /*** Chatacteristic: IEEE 11073-20601 Regulatory Certification Data List */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_CHR_UUID16_IEEE_REG_CERT_LIST), - .access_cb = ble_svc_dis_access, - .flags = BLE_GATT_CHR_F_READ, - }, { -#if (MYNEWT_VAL(BLE_SVC_DIS_PNP_ID_READ_PERM) >= 0) - /*** Characteristic: PNP Id */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_CHR_UUID16_PNP_ID), - .access_cb = ble_svc_dis_access, - .flags = BLE_GATT_CHR_F_READ | - MYNEWT_VAL(BLE_SVC_DIS_PNP_ID_READ_PERM), - }, { -#endif - /*** UDI for Medical Devices */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_DIS_CHR_UUID16_UDI), - .access_cb = ble_svc_dis_access, - .flags = BLE_GATT_CHR_F_READ - }, { - - 0, /* No more characteristics in this service */ - }, } + { + /*** Characteristic: System Id */ + .uuid = &uuid_chr_system_id.u, + .access_cb = ble_svc_dis_access, + .flags = BLE_GATT_CHR_F_READ | MYNEWT_VAL(BLE_SVC_DIS_SYSTEM_ID_READ_PERM), }, +#endif + { + /*** Characteristic: IEEE 11073-20601 Regulatory Certification Data List */ + .uuid = &uuid_chr_ieee_cert.u, + .access_cb = ble_svc_dis_access, + .flags = BLE_GATT_CHR_F_READ, + }, +#if (MYNEWT_VAL(BLE_SVC_DIS_PNP_ID_READ_PERM) >= 0) + { + /*** Characteristic: PNP Id */ + .uuid = &uuid_chr_pnp_id.u, + .access_cb = ble_svc_dis_access, + .flags = BLE_GATT_CHR_F_READ | MYNEWT_VAL(BLE_SVC_DIS_PNP_ID_READ_PERM), + }, +#endif + { + /*** Characteristic: UDI for Medical Devices */ + .uuid = &uuid_chr_udi.u, + .access_cb = ble_svc_dis_access, + .flags = BLE_GATT_CHR_F_READ, + }, + { + 0, /* Terminator: No more characteristics in this service */ + }, +}; +static const struct ble_gatt_svc_def ble_svc_dis_defs[] = { + { + /*** Service: Device Information Service (DIS). */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &uuid_svc_dis.u, + .characteristics = dis_characteristics, + }, { 0, /* No more services. */ }, }; -const struct ble_gatt_svc_def *included_services[] = {ble_svc_dis_defs, NULL}; +/* Make pointer array itself constant to place in Flash instead of DRAM */ +static const struct ble_gatt_svc_def *included_services[] = {ble_svc_dis_defs, NULL}; const struct ble_gatt_svc_def ble_svc_dis_include_def[] = { { .type = BLE_GATT_SVC_TYPE_PRIMARY, @@ -395,6 +423,31 @@ ble_svc_dis_included_init(void) SYSINIT_PANIC_ASSERT(rc == 0); } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +int +ble_svc_dis_init_dynamic(void) +{ + ble_svc_dis_data_ptr = nimble_platform_mem_calloc(1, sizeof(ble_svc_dis_data)); + if (!ble_svc_dis_data_ptr) { + return BLE_HS_ENOMEM; + } + + + /* Initialize default fields */ + ble_svc_dis_data_ptr->model_number = MYNEWT_VAL(BLE_SVC_DIS_MODEL_NUMBER_DEFAULT); + ble_svc_dis_data_ptr->serial_number = MYNEWT_VAL(BLE_SVC_DIS_SERIAL_NUMBER_DEFAULT); + ble_svc_dis_data_ptr->firmware_revision = MYNEWT_VAL(BLE_SVC_DIS_FIRMWARE_REVISION_DEFAULT); + ble_svc_dis_data_ptr->hardware_revision = MYNEWT_VAL(BLE_SVC_DIS_HARDWARE_REVISION_DEFAULT); + ble_svc_dis_data_ptr->software_revision = MYNEWT_VAL(BLE_SVC_DIS_SOFTWARE_REVISION_DEFAULT); + ble_svc_dis_data_ptr->manufacturer_name = MYNEWT_VAL(BLE_SVC_DIS_MANUFACTURER_NAME_DEFAULT); + ble_svc_dis_data_ptr->system_id = MYNEWT_VAL(BLE_SVC_DIS_SYSTEM_ID_DEFAULT); + ble_svc_dis_data_ptr->pnp_id = MYNEWT_VAL(BLE_SVC_DIS_PNP_ID_DEFAULT); + ble_svc_dis_data_ptr->ieee = "dummy_data"; + ble_svc_dis_data_ptr->udi = NULL; + + return 0; +} +#endif /** * Initialize the DIS package. @@ -404,6 +457,16 @@ ble_svc_dis_init(void) { int rc; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_svc_dis_data_ptr != NULL) { + nimble_platform_mem_free(ble_svc_dis_data_ptr); + ble_svc_dis_data_ptr = NULL; + } + + rc = ble_svc_dis_init_dynamic(); + SYSINIT_PANIC_ASSERT(rc == 0); +#endif + /* Ensure this function only gets called by sysinit. */ SYSINIT_ASSERT_ACTIVE(); diff --git a/nimble/host/services/gap/include/services/gap/ble_svc_gap.h b/nimble/host/services/gap/include/services/gap/ble_svc_gap.h index bef500456..e2166ee9e 100644 --- a/nimble/host/services/gap/include/services/gap/ble_svc_gap.h +++ b/nimble/host/services/gap/include/services/gap/ble_svc_gap.h @@ -54,7 +54,6 @@ void ble_svc_gap_set_chr_changed_cb(ble_svc_gap_chr_changed_fn *cb); uint16_t ble_svc_gap_device_appearance(void); -#ifdef CONFIG_BT_NIMBLE_GAP_SERVICE void ble_svc_gap_init(void); int ble_svc_gap_device_name_set(const char *name); const char *ble_svc_gap_device_name(void); @@ -63,11 +62,6 @@ int ble_svc_gap_device_appearance_set(uint16_t appearance); int ble_svc_gap_device_key_material_set(uint8_t *session_key, uint8_t *iv); #endif -#else -#include "ble_svc_gap_stub.h" - -#endif - void ble_svc_gap_deinit(void); #ifdef __cplusplus diff --git a/nimble/host/services/gap/src/ble_svc_gap.c b/nimble/host/services/gap/src/ble_svc_gap.c index b0693eb98..798162603 100644 --- a/nimble/host/services/gap/src/ble_svc_gap.c +++ b/nimble/host/services/gap/src/ble_svc_gap.c @@ -39,9 +39,32 @@ static ble_svc_gap_chr_changed_fn *ble_svc_gap_chr_changed_cb_fn; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#include "esp_nimble_mem.h" + +typedef struct { + char *svc_gap_name; + uint16_t svc_gap_appearance; +#if MYNEWT_VAL(ENC_ADV_DATA) + struct key_material km; +#endif +} ble_hs_gap_svc_ctx_t ; + +ble_hs_gap_svc_ctx_t *ble_hs_gap_svc_ctx = NULL; + +#define ble_svc_gap_name (ble_hs_gap_svc_ctx->svc_gap_name) +#define ble_svc_gap_appearance (ble_hs_gap_svc_ctx->svc_gap_appearance) +#if MYNEWT_VAL(ENC_ADV_DATA) +#define km (ble_hs_gap_svc_ctx->km) +#endif // ENC_ADV_DATA +#if MYNEWT_VAL(ENC_ADV_DATA) +static uint16_t ble_svc_gap_enc_adv_data_handle; +#endif +#else +static uint16_t ble_svc_gap_appearance = MYNEWT_VAL(BLE_SVC_GAP_APPEARANCE); + static char ble_svc_gap_name[BLE_SVC_GAP_NAME_MAX_LEN + 1] = MYNEWT_VAL(BLE_SVC_GAP_DEVICE_NAME); -static uint16_t ble_svc_gap_appearance = MYNEWT_VAL(BLE_SVC_GAP_APPEARANCE); #if MYNEWT_VAL(ENC_ADV_DATA) static uint16_t ble_svc_gap_enc_adv_data_handle; @@ -49,9 +72,34 @@ static struct key_material km = { .session_key = {0}, .iv = {0}, }; +#endif // ENC_ADV_DATA +#endif // BLE_STATIC_TO_DYNAMIC + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +int ble_svc_gap_appearance_init(void); #endif #if NIMBLE_BLE_CONNECT + +static const ble_uuid16_t uuid_svc_gap = BLE_UUID16_INIT(BLE_SVC_GAP_UUID16); +static const ble_uuid16_t uuid_chr_device_name = BLE_UUID16_INIT(BLE_SVC_GAP_CHR_UUID16_DEVICE_NAME); +static const ble_uuid16_t uuid_chr_appearance = BLE_UUID16_INIT(BLE_SVC_GAP_CHR_UUID16_APPEARANCE); +#if PPCP_ENABLED +static const ble_uuid16_t uuid_chr_ppcp = BLE_UUID16_INIT(BLE_SVC_GAP_CHR_UUID16_PERIPH_PREF_CONN_PARAMS); +#endif +#if MYNEWT_VAL(BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION) >= 0 +static const ble_uuid16_t uuid_chr_central_addr_res = BLE_UUID16_INIT(BLE_SVC_GAP_CHR_UUID16_CENTRAL_ADDRESS_RESOLUTION); +#endif +#if MYNEWT_VAL(BLE_SVC_GAP_RPA_ONLY) +static const ble_uuid16_t uuid_chr_rpa_only = BLE_UUID16_INIT(BLE_SVC_GAP_CHR_UUID16_RPA_ONLY); +#endif +#if MYNEWT_VAL(ENC_ADV_DATA) +static const ble_uuid16_t uuid_chr_key_material = BLE_UUID16_INIT(BLE_SVC_GAP_CHR_UUID16_KEY_MATERIAL); +#endif +#if MYNEWT_VAL(BLE_SVC_GAP_GATT_SECURITY_LEVEL) +static const ble_uuid16_t uuid_chr_security = BLE_UUID16_INIT(BLE_SVC_GAP_CHR_UUID16_LE_GATT_SECURITY_LEVELS); +#endif + static int ble_svc_gap_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); @@ -60,10 +108,10 @@ static const struct ble_gatt_svc_def ble_svc_gap_defs[] = { { /*** Service: GAP. */ .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = BLE_UUID16_DECLARE(BLE_SVC_GAP_UUID16), + .uuid = &uuid_svc_gap.u, .characteristics = (struct ble_gatt_chr_def[]) { { /*** Characteristic: Device Name. */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_GAP_CHR_UUID16_DEVICE_NAME), + .uuid = &uuid_chr_device_name.u, .access_cb = ble_svc_gap_access, .flags = BLE_GATT_CHR_F_READ | #if MYNEWT_VAL(BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM) >= 0 @@ -73,7 +121,7 @@ static const struct ble_gatt_svc_def ble_svc_gap_defs[] = { 0, }, { /*** Characteristic: Appearance. */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_GAP_CHR_UUID16_APPEARANCE), + .uuid = &uuid_chr_appearance.u, .access_cb = ble_svc_gap_access, .flags = BLE_GATT_CHR_F_READ | #if MYNEWT_VAL(BLE_SVC_GAP_APPEARANCE_WRITE_PERM) >= 0 @@ -81,47 +129,54 @@ static const struct ble_gatt_svc_def ble_svc_gap_defs[] = { MYNEWT_VAL(BLE_SVC_GAP_APPEARANCE_WRITE_PERM) | #endif 0, - }, { + }, #if PPCP_ENABLED + { /*** Characteristic: Peripheral Preferred Connection Parameters. */ - .uuid = - BLE_UUID16_DECLARE(BLE_SVC_GAP_CHR_UUID16_PERIPH_PREF_CONN_PARAMS), + .uuid = &uuid_chr_ppcp.u, .access_cb = ble_svc_gap_access, .flags = BLE_GATT_CHR_F_READ, - }, { + }, #endif #if MYNEWT_VAL(BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION) >= 0 + { /*** Characteristic: Central Address Resolution. */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_GAP_CHR_UUID16_CENTRAL_ADDRESS_RESOLUTION), + .uuid = &uuid_chr_central_addr_res.u, .access_cb = ble_svc_gap_access, .flags = BLE_GATT_CHR_F_READ, - }, { + }, #endif #if MYNEWT_VAL(BLE_SVC_GAP_RPA_ONLY) + { /*** Characteristic: Resolvable Private Address Only. */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_GAP_CHR_UUID16_RPA_ONLY), + .uuid = &uuid_chr_rpa_only.u, .access_cb = ble_svc_gap_access, .flags = BLE_GATT_CHR_F_READ, - }, { + }, #endif #if MYNEWT_VAL(ENC_ADV_DATA) - .uuid = BLE_UUID16_DECLARE(BLE_SVC_GAP_CHR_UUID16_KEY_MATERIAL), + { + /*** Characteristic: Key Material. */ + .uuid = &uuid_chr_key_material.u, .access_cb = ble_svc_gap_access, .val_handle = &ble_svc_gap_enc_adv_data_handle, - .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC | BLE_GATT_CHR_F_READ_AUTHEN | BLE_GATT_CHR_F_READ_AUTHOR | BLE_GATT_CHR_F_INDICATE, - }, { + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC | + BLE_GATT_CHR_F_READ_AUTHEN | BLE_GATT_CHR_F_READ_AUTHOR | + BLE_GATT_CHR_F_INDICATE, + }, #endif #if MYNEWT_VAL(BLE_SVC_GAP_GATT_SECURITY_LEVEL) + { /*** Characteristic: LE GATT Security Levels. */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_GAP_CHR_UUID16_LE_GATT_SECURITY_LEVELS), + .uuid = &uuid_chr_security.u, .access_cb = ble_svc_gap_access, .flags = BLE_GATT_CHR_F_READ, - }, { + }, #endif + { 0, /* No more characteristics in this service. */ } }, }, - { 0, /* No more services. */ }, @@ -132,7 +187,12 @@ ble_svc_gap_device_name_read_access(struct ble_gatt_access_ctxt *ctxt) { int rc; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + rc = os_mbuf_append(ctxt->om, ble_svc_gap_name ? ble_svc_gap_name : "", + strlen(ble_svc_gap_name ? ble_svc_gap_name : "")); +#else rc = os_mbuf_append(ctxt->om, ble_svc_gap_name, strlen(ble_svc_gap_name)); +#endif return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; } @@ -152,7 +212,20 @@ ble_svc_gap_device_name_write_access(struct ble_gatt_access_ctxt *ctxt) return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + // Free old name if already allocated + if (ble_hs_gap_svc_ctx->svc_gap_name) { + nimble_platform_mem_free(ble_hs_gap_svc_ctx->svc_gap_name); + } + + ble_hs_gap_svc_ctx->svc_gap_name = nimble_platform_mem_calloc(1, om_len + 1); + if (!ble_hs_gap_svc_ctx->svc_gap_name) { + return BLE_HS_ENOMEM; + } +#endif + rc = ble_hs_mbuf_to_flat(ctxt->om, ble_svc_gap_name, om_len, NULL); + if (rc != 0) { return BLE_ATT_ERR_UNLIKELY; } @@ -214,20 +287,19 @@ ble_svc_gap_security_level_read_access(uint16_t conn_handle, struct os_mbuf * om { uint8_t security_level[2]; int rc; - + /* Currently this characteristic is only supported for * Security Mode 1 */ security_level[0] = 0x01; //Mode 1 security_level[1] = ble_gatts_security_mode_1_level(); //Mode 1 Level - + rc = os_mbuf_append(om, security_level, sizeof(security_level)); return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; } #endif - static int ble_svc_gap_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) @@ -340,6 +412,25 @@ ble_svc_gap_device_name_set(const char *name) return BLE_HS_EINVAL; } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_hs_gap_svc_ctx == NULL) { + ble_hs_gap_svc_ctx = nimble_platform_mem_calloc ( 1, sizeof(*ble_hs_gap_svc_ctx)); + + if (!ble_hs_gap_svc_ctx) { + return BLE_HS_ENOMEM; + } + } + // Free old name if already allocated + if (ble_hs_gap_svc_ctx->svc_gap_name) { + nimble_platform_mem_free(ble_hs_gap_svc_ctx->svc_gap_name); + } + + ble_hs_gap_svc_ctx->svc_gap_name = nimble_platform_mem_calloc(1, len + 1); + if (!ble_hs_gap_svc_ctx->svc_gap_name) { + return BLE_HS_ENOMEM; + } +#endif + memcpy(ble_svc_gap_name, name, len); ble_svc_gap_name[len] = '\0'; @@ -349,13 +440,24 @@ ble_svc_gap_device_name_set(const char *name) uint16_t ble_svc_gap_device_appearance(void) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (!ble_hs_gap_svc_ctx) { + ble_svc_gap_appearance_init(); + } +#endif return ble_svc_gap_appearance; } int ble_svc_gap_device_appearance_set(uint16_t appearance) { - ble_svc_gap_appearance = appearance; + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (!ble_hs_gap_svc_ctx) { + ble_svc_gap_appearance_init(); + } +#endif + ble_svc_gap_appearance = appearance; return 0; } @@ -377,28 +479,94 @@ ble_svc_gap_device_key_material_set(uint8_t *session_key, uint8_t *iv) } #endif +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +int +ble_svc_gap_appearance_init(void) +{ + if (ble_hs_gap_svc_ctx == NULL) { + ble_hs_gap_svc_ctx = nimble_platform_mem_calloc ( 1, sizeof(*ble_hs_gap_svc_ctx)); + + if (!ble_hs_gap_svc_ctx) { + return BLE_HS_ENOMEM; + } + } + + ble_svc_gap_appearance = MYNEWT_VAL(BLE_SVC_GAP_APPEARANCE); + + return 0; +} + +int +ble_svc_gap_init_name(void) +{ + const char *default_name = MYNEWT_VAL(BLE_SVC_GAP_DEVICE_NAME); + size_t len = strlen(default_name); + + if (len > BLE_SVC_GAP_NAME_MAX_LEN) { + len = BLE_SVC_GAP_NAME_MAX_LEN; + } + + ble_hs_gap_svc_ctx->svc_gap_name = nimble_platform_mem_calloc(1, len + 1); + if (!ble_hs_gap_svc_ctx->svc_gap_name) { + return BLE_HS_ENOMEM; + } + + memcpy(ble_svc_gap_name, default_name, len); + ble_svc_gap_name[len] = '\0'; + return 0; +} + +void +ble_svc_gap_deinit_name(void) +{ + if (!ble_hs_gap_svc_ctx) { + return; + } + if (ble_hs_gap_svc_ctx->svc_gap_name) { + nimble_platform_mem_free(ble_hs_gap_svc_ctx->svc_gap_name); + ble_hs_gap_svc_ctx->svc_gap_name = NULL; + } +} +#endif + void ble_svc_gap_init(void) { #if NIMBLE_BLE_CONNECT int rc; #endif - /* Ensure this function only gets called by sysinit. */ SYSINIT_ASSERT_ACTIVE(); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + rc = ble_svc_gap_appearance_init(); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = ble_svc_gap_init_name(); + SYSINIT_PANIC_ASSERT(rc == 0); +#endif + #if NIMBLE_BLE_CONNECT + rc = ble_gatts_count_cfg(ble_svc_gap_defs); SYSINIT_PANIC_ASSERT(rc == 0); rc = ble_gatts_add_svcs(ble_svc_gap_defs); SYSINIT_PANIC_ASSERT(rc == 0); #endif + } void ble_svc_gap_deinit(void) { ble_gatts_free_svcs(); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_hs_gap_svc_ctx ) { + ble_svc_gap_deinit_name(); + nimble_platform_mem_free(ble_hs_gap_svc_ctx); + ble_hs_gap_svc_ctx = NULL; + } +#endif } #endif diff --git a/nimble/host/services/gatt/src/ble_svc_gatt.c b/nimble/host/services/gatt/src/ble_svc_gatt.c index c76bc9019..7f2821ce7 100644 --- a/nimble/host/services/gatt/src/ble_svc_gatt.c +++ b/nimble/host/services/gatt/src/ble_svc_gatt.c @@ -56,24 +56,28 @@ static int ble_svc_gatt_cl_sup_feat_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); -static const struct ble_gatt_svc_def ble_svc_gatt_defs[] = { - { - /*** Service: GATT */ - .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = BLE_UUID16_DECLARE(BLE_GATT_SVC_UUID16), - .characteristics = (struct ble_gatt_chr_def[]) { { - .uuid = BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_SERVICE_CHANGED_UUID16), +static const ble_uuid16_t uuid_svc_gatt = BLE_UUID16_INIT(BLE_GATT_SVC_UUID16); +static const ble_uuid16_t uuid_chr_svc_change = BLE_UUID16_INIT(BLE_SVC_GATT_CHR_SERVICE_CHANGED_UUID16); +static const ble_uuid16_t uuid_chr_svr_supp_feat = BLE_UUID16_INIT(BLE_SVC_GATT_CHR_SERVER_SUPPORTED_FEAT_UUID16); +static const ble_uuid16_t uuid_chr_cli_supp_feat = BLE_UUID16_INIT(BLE_SVC_GATT_CHR_CLIENT_SUPPORTED_FEAT_UUID16); +#if MYNEWT_VAL(BLE_GATT_CACHING) +static const ble_uuid16_t uuid_chr_db_hash = BLE_UUID16_INIT(BLE_SVC_GATT_CHR_DATABASE_HASH_UUID16); +#endif + +static const struct ble_gatt_chr_def gatt_characteristics[] = { + { + .uuid = &uuid_chr_svc_change.u, .access_cb = ble_svc_gatt_access, .val_handle = &ble_svc_gatt_changed_val_handle, .flags = BLE_GATT_CHR_F_INDICATE, }, { - .uuid = BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_SERVER_SUPPORTED_FEAT_UUID16), + .uuid = &uuid_chr_svr_supp_feat.u, .access_cb = ble_svc_gatt_srv_sup_feat_access, .flags = BLE_GATT_CHR_F_READ, }, { - .uuid = BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_CLIENT_SUPPORTED_FEAT_UUID16), + .uuid = &uuid_chr_cli_supp_feat.u, .access_cb = ble_svc_gatt_cl_sup_feat_access, #if MYNEWT_VAL(BLE_GATT_CACHING) .val_handle = &ble_svc_gatt_client_supp_feature_handle, @@ -82,7 +86,7 @@ static const struct ble_gatt_svc_def ble_svc_gatt_defs[] = { }, #if MYNEWT_VAL(BLE_GATT_CACHING) { - .uuid = BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_DATABASE_HASH_UUID16), + .uuid = &uuid_chr_db_hash.u, .access_cb = ble_svc_gatt_access, .val_handle = &ble_svc_gatt_db_hash_handle, .flags = BLE_GATT_CHR_F_READ, @@ -90,9 +94,16 @@ static const struct ble_gatt_svc_def ble_svc_gatt_defs[] = { #endif { 0, /* No more characteristics in this service. */ - } }, - }, + } +}; +static const struct ble_gatt_svc_def ble_svc_gatt_defs[] = { + { + /*** Service: GATT */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &uuid_svc_gatt.u, + .characteristics = gatt_characteristics, + }, { 0, /* No more services. */ }, diff --git a/nimble/host/services/hid/src/ble_svc_hid.c b/nimble/host/services/hid/src/ble_svc_hid.c index bb5d11b6b..43cfe3997 100644 --- a/nimble/host/services/hid/src/ble_svc_hid.c +++ b/nimble/host/services/hid/src/ble_svc_hid.c @@ -29,6 +29,9 @@ #include "host/ble_hs.h" #include "host/ble_gap.h" #include "services/hid/ble_svc_hid.h" +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#include "esp_nimble_mem.h" +#endif /* 1 more instance for empty service */ #define HID_MAX_SVC_INSTANCES (MYNEWT_VAL(BLE_SVC_HID_MAX_SVC_INSTANCES) + 1) @@ -37,33 +40,55 @@ #define HID_MAX_CHRS (HID_MAX_SVC_INSTANCES * \ ((MYNEWT_VAL(BLE_SVC_HID_MAX_RPTS) + 7))) /* 16 bit UUIDs */ -static ble_uuid_t *uuid_ext_rpt_ref = BLE_UUID16_DECLARE(BLE_SVC_HID_DSC_UUID16_EXT_RPT_REF); -static ble_uuid_t *uuid_report_map = BLE_UUID16_DECLARE(BLE_SVC_HID_CHR_UUID16_REPORT_MAP); -static ble_uuid_t *uuid_rpt_ref = BLE_UUID16_DECLARE(BLE_SVC_HID_DSC_UUID16_RPT_REF); -static ble_uuid_t *uuid_report = BLE_UUID16_DECLARE(BLE_SVC_HID_CHR_UUID16_RPT); -static ble_uuid_t *uuid_hid_info = BLE_UUID16_DECLARE(BLE_SVC_HID_CHR_UUID16_HID_INFO); -static ble_uuid_t *uuid_hid_ctrl_pt = BLE_UUID16_DECLARE(BLE_SVC_HID_CHR_UUID16_HID_CTRL_PT); -static ble_uuid_t *uuid_proto_mode = BLE_UUID16_DECLARE(BLE_SVC_HID_CHR_UUID16_PROTOCOL_MODE); -static ble_uuid_t *uuid_boot_kbd_inp = BLE_UUID16_DECLARE(BLE_SVC_HID_CHR_UUID16_BOOT_KBD_INP); -static ble_uuid_t *uuid_boot_kbd_out = BLE_UUID16_DECLARE(BLE_SVC_HID_CHR_UUID16_BOOT_KBD_OUT); -static ble_uuid_t *uuid_boot_mouse_inp = BLE_UUID16_DECLARE(BLE_SVC_HID_CHR_UUID16_BOOT_MOUSE_INP); -static ble_uuid_t *uuid_hid_svc = BLE_UUID16_DECLARE(BLE_SVC_HID_UUID16); +static const ble_uuid16_t uuid_ext_rpt_ref = BLE_UUID16_INIT(BLE_SVC_HID_DSC_UUID16_EXT_RPT_REF); +static const ble_uuid16_t uuid_report_map = BLE_UUID16_INIT(BLE_SVC_HID_CHR_UUID16_REPORT_MAP); +static const ble_uuid16_t uuid_rpt_ref = BLE_UUID16_INIT(BLE_SVC_HID_DSC_UUID16_RPT_REF); +static const ble_uuid16_t uuid_report = BLE_UUID16_INIT(BLE_SVC_HID_CHR_UUID16_RPT); +static const ble_uuid16_t uuid_hid_info = BLE_UUID16_INIT(BLE_SVC_HID_CHR_UUID16_HID_INFO); +static const ble_uuid16_t uuid_hid_ctrl_pt = BLE_UUID16_INIT(BLE_SVC_HID_CHR_UUID16_HID_CTRL_PT); +static const ble_uuid16_t uuid_proto_mode = BLE_UUID16_INIT(BLE_SVC_HID_CHR_UUID16_PROTOCOL_MODE); +static const ble_uuid16_t uuid_boot_kbd_inp = BLE_UUID16_INIT(BLE_SVC_HID_CHR_UUID16_BOOT_KBD_INP); +static const ble_uuid16_t uuid_boot_kbd_out = BLE_UUID16_INIT(BLE_SVC_HID_CHR_UUID16_BOOT_KBD_OUT); +static const ble_uuid16_t uuid_boot_mouse_inp = BLE_UUID16_INIT(BLE_SVC_HID_CHR_UUID16_BOOT_MOUSE_INP); +static const ble_uuid16_t uuid_hid_svc = BLE_UUID16_INIT(BLE_SVC_HID_UUID16); -uint8_t ble_svc_hid_rpt_val[RPT_MAX_LEN]; -uint8_t ble_svc_hid_rpt_len; +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) static struct ble_svc_hid_params hid_instances[HID_MAX_SVC_INSTANCES]; +static uint8_t ble_svc_hid_dsc_index = 0; // used to store the current index in the dscs array +static struct ble_gatt_dsc_def ble_svc_hid_dscs[HID_MAX_CHRS]; +static struct ble_gatt_chr_def ble_svc_hid_chrs[HID_MAX_CHRS]; +static struct ble_gatt_svc_def ble_svc_hid_defs[HID_MAX_SVC_INSTANCES]; +static uint8_t ble_svc_hid_chr_index = 0; // used to store the current index in the chrs array +static uint8_t ble_svc_hid_svc_index = 0; // used to store the current index in the svcs array +#endif + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +typedef struct { + struct ble_svc_hid_params _hid_instances[HID_MAX_SVC_INSTANCES]; + uint8_t _ble_svc_hid_dsc_index; + struct ble_gatt_dsc_def _ble_svc_hid_dscs[HID_MAX_CHRS]; + struct ble_gatt_chr_def _ble_svc_hid_chrs[HID_MAX_CHRS]; + struct ble_gatt_svc_def _ble_svc_hid_defs[HID_MAX_SVC_INSTANCES]; + uint8_t _ble_svc_hid_chr_index; + uint8_t _ble_svc_hid_svc_index; +} ble_svc_hid_static_vars_t; + +static ble_svc_hid_static_vars_t * ble_svc_hid_static_vars = NULL; + +#define hid_instances (ble_svc_hid_static_vars->_hid_instances) +#define ble_svc_hid_dsc_index (ble_svc_hid_static_vars->_ble_svc_hid_dsc_index) +#define ble_svc_hid_dscs (ble_svc_hid_static_vars->_ble_svc_hid_dscs) +#define ble_svc_hid_chrs (ble_svc_hid_static_vars->_ble_svc_hid_chrs) +#define ble_svc_hid_defs (ble_svc_hid_static_vars->_ble_svc_hid_defs) +#define ble_svc_hid_chr_index (ble_svc_hid_static_vars->_ble_svc_hid_chr_index) +#define ble_svc_hid_svc_index (ble_svc_hid_static_vars->_ble_svc_hid_svc_index) + +#endif /* MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) */ /* Access function */ static int ble_svc_hid_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); -static struct ble_gatt_dsc_def ble_svc_hid_dscs[HID_MAX_CHRS]; -static uint8_t ble_svc_hid_dsc_index = 0; // used to store the current index in the dscs array -static struct ble_gatt_chr_def ble_svc_hid_chrs[HID_MAX_CHRS]; -static uint8_t ble_svc_hid_chr_index = 0; // used to store the current index in the chrs array -static uint8_t ble_svc_hid_svc_index = 0; // used to store the current index in the svcs array - -static struct ble_gatt_svc_def ble_svc_hid_defs[HID_MAX_SVC_INSTANCES]; static int ble_svc_hid_chr_write(struct os_mbuf *om, uint16_t min_len, @@ -160,7 +185,7 @@ fill_proto_mode(uint8_t instance) } demo_chr = (struct ble_gatt_chr_def) { /*** Report Map characteristic */ - .uuid = uuid_proto_mode, + .uuid = &uuid_proto_mode.u, .access_cb = ble_svc_hid_access, .val_handle = &hid_instances[instance].proto_mode_handle, .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE_NO_RSP | @@ -199,7 +224,7 @@ fill_boot_kbd_inp(uint8_t instance) demo_chr = (struct ble_gatt_chr_def) { /*** Report Map characteristic */ - .uuid = uuid_boot_kbd_inp, + .uuid = &uuid_boot_kbd_inp.u, .access_cb = ble_svc_hid_access, .val_handle = &hid_instances[instance].kbd_inp_handle, .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY | @@ -227,7 +252,7 @@ fill_boot_kbd_out(uint8_t instance) } demo_chr = (struct ble_gatt_chr_def) { /*** Report Map characteristic */ - .uuid = uuid_boot_kbd_out, + .uuid = &uuid_boot_kbd_out.u, .access_cb = ble_svc_hid_access, .val_handle = &hid_instances[instance].kbd_out_handle, .flags = BLE_GATT_CHR_F_READ | @@ -266,7 +291,7 @@ fill_boot_mouse_inp(uint8_t instance) demo_chr = (struct ble_gatt_chr_def) { /*** Report Map characteristic */ - .uuid = uuid_boot_mouse_inp, + .uuid = &uuid_boot_mouse_inp.u, .access_cb = ble_svc_hid_access, .val_handle = &hid_instances[instance].mouse_inp_handle, .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY | @@ -291,7 +316,7 @@ fill_rpt_map(uint8_t instance) struct ble_gatt_dsc_def *demo_dsc = (struct ble_gatt_dsc_def[]) { { /* External Report Reference descriptor */ - .uuid = uuid_ext_rpt_ref, + .uuid = &uuid_ext_rpt_ref.u, .access_cb = ble_svc_hid_access, .att_flags = BLE_ATT_F_READ, .arg = &hid_instances[instance].report_map_handle, @@ -301,7 +326,7 @@ fill_rpt_map(uint8_t instance) }; demo_chr = (struct ble_gatt_chr_def) { /*** Report Map characteristic */ - .uuid = uuid_report_map, + .uuid = &uuid_report_map.u, .access_cb = ble_svc_hid_access, .val_handle = &hid_instances[instance].report_map_handle, .flags = BLE_GATT_CHR_F_READ | @@ -333,7 +358,7 @@ fill_reports(uint8_t instance) struct ble_gatt_dsc_def *demo_dsc = (struct ble_gatt_dsc_def[]) { { /* Report Reference descriptor */ - .uuid = uuid_rpt_ref, + .uuid = &uuid_rpt_ref.u, .access_cb = ble_svc_hid_access, .att_flags = BLE_ATT_F_READ }, { @@ -342,7 +367,7 @@ fill_reports(uint8_t instance) }; demo_chr = (struct ble_gatt_chr_def) { /*** Report characteristic */ - .uuid = uuid_report, + .uuid = &uuid_report.u, .access_cb = ble_svc_hid_access, }; /* Multiple instances of this characteristic are allowed*/ @@ -390,7 +415,7 @@ fill_hid_info(uint8_t instance) demo_chr = (struct ble_gatt_chr_def) { /*** HID Information Characteristic */ - .uuid = uuid_hid_info, + .uuid = &uuid_hid_info.u, .access_cb = ble_svc_hid_access, .val_handle = &hid_instances[instance].hid_info_handle, .flags = BLE_GATT_CHR_F_READ | @@ -413,7 +438,7 @@ fill_ctrl_pt(uint8_t instance) demo_chr = (struct ble_gatt_chr_def) { /*** HID Control Point Characteristic */ - .uuid = uuid_hid_ctrl_pt, + .uuid = &uuid_hid_ctrl_pt.u, .access_cb = ble_svc_hid_access, .val_handle = &hid_instances[instance].ctrl_pt_handle, .flags = BLE_GATT_CHR_F_WRITE_NO_RSP | @@ -626,11 +651,22 @@ ble_svc_hid_add(struct ble_svc_hid_params params) struct ble_gatt_svc_def *svc; uint8_t chr_idx; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_svc_hid_static_vars == NULL) { + ble_svc_hid_static_vars = nimble_platform_mem_calloc(1, sizeof(ble_svc_hid_static_vars_t)); + if (ble_svc_hid_static_vars == NULL) { + rc = BLE_HS_ENOMEM; + goto error; + } + } +#endif + svc_idx = get_curr_svc_idx(); /* one instance is required for empty service */ if (HID_MAX_SVC_INSTANCES - 1 <= svc_idx) { /* increase instances count */ - return BLE_HS_ENOMEM; + rc = BLE_HS_ENOMEM; + goto error; } memcpy(&hid_instances[svc_idx], ¶ms, sizeof(struct ble_svc_hid_params)); @@ -659,8 +695,14 @@ ble_svc_hid_add(struct ble_svc_hid_params params) svc = ble_svc_get_svc_block(); svc->type = BLE_GATT_SVC_TYPE_PRIMARY; - svc->uuid = uuid_hid_svc; + svc->uuid = &uuid_hid_svc.u; svc->characteristics = ble_svc_hid_chrs + chr_idx; + + return 0; +error: +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + ble_svc_hid_reset(); +#endif return rc; } @@ -688,9 +730,22 @@ ble_svc_hid_end(void) void ble_svc_hid_reset(void) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_svc_hid_static_vars == NULL) { + return; + } +#endif + ble_svc_hid_dsc_index = 0; ble_svc_hid_chr_index = 0; ble_svc_hid_svc_index = 0; + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_svc_hid_static_vars != NULL) { + nimble_platform_mem_free(ble_svc_hid_static_vars); + ble_svc_hid_static_vars = NULL; + } +#endif } /** @@ -712,6 +767,7 @@ ble_svc_hid_init(void) rc = ble_gatts_add_svcs(ble_svc_hid_defs); SYSINIT_PANIC_ASSERT(rc == 0); + } #endif #endif // CONFIG_BT_NIMBLE_HID_SERVICE diff --git a/nimble/host/services/hr/src/ble_svc_hr.c b/nimble/host/services/hr/src/ble_svc_hr.c index 6fa6c6b89..4c1aefaa7 100644 --- a/nimble/host/services/hr/src/ble_svc_hr.c +++ b/nimble/host/services/hr/src/ble_svc_hr.c @@ -36,19 +36,19 @@ ble_svc_hr_chr_write(struct os_mbuf *om, uint16_t min_len, uint16_t max_len, void *dst, uint16_t *len); -static const struct ble_gatt_svc_def ble_svc_hr_defs[] = { - { - /*** Heart Rate Measurement Service. */ - .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = BLE_UUID16_DECLARE(BLE_SVC_HR_UUID16), - .characteristics = (struct ble_gatt_chr_def[]) - { { +static const ble_uuid16_t uuid_svc_hr = BLE_UUID16_INIT(BLE_SVC_HR_UUID16); +static const ble_uuid16_t uuid_chr_hr_measure = BLE_UUID16_INIT(BLE_SVC_HR_CHR_UUID16_MEASUREMENT); +static const ble_uuid16_t uuid_chr_body_sensor = BLE_UUID16_INIT(BLE_SVC_HR_CHR_UUID16_BODY_SENSOR_LOC); +static const ble_uuid16_t uuid_chr_hr_cp = BLE_UUID16_INIT(BLE_SVC_HR_CHR_UUID16_CTRL_PT); + +static const struct ble_gatt_chr_def hr_characteristics[] = { + { /** Heart Rate Measurement * * This characteristic exposes heart rate measurement value * by notifying. */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_HR_CHR_UUID16_MEASUREMENT), + .uuid = &uuid_chr_hr_measure.u, .access_cb = ble_svc_hr_access, .val_handle = &ble_svc_hr_measurement_val_handle, .flags = BLE_GATT_CHR_F_NOTIFY, @@ -58,7 +58,7 @@ static const struct ble_gatt_svc_def ble_svc_hr_defs[] = { * This characteristic exposes information about * the location of the heart rate measurement device. */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_HR_CHR_UUID16_BODY_SENSOR_LOC), + .uuid = &uuid_chr_body_sensor.u, .access_cb = ble_svc_hr_access, .val_handle = &ble_svc_hr_body_sensor_loc_val_handle, .flags = BLE_GATT_CHR_F_READ, @@ -68,14 +68,21 @@ static const struct ble_gatt_svc_def ble_svc_hr_defs[] = { * This characteristic enable a Client to write control * points to a Server to control behavior */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_HR_CHR_UUID16_CTRL_PT), + .uuid = &uuid_chr_hr_cp.u, .access_cb = ble_svc_hr_access, .val_handle = &ble_svc_hr_ctrl_pt_val_handle, .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE, }, { 0, /* No more characteristics in this service. */ } - }, +}; + +static const struct ble_gatt_svc_def ble_svc_hr_defs[] = { + { + /*** Heart Rate Measurement Service. */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &uuid_svc_hr.u, + .characteristics = hr_characteristics, }, { diff --git a/nimble/host/services/ias/src/ble_svc_ias.c b/nimble/host/services/ias/src/ble_svc_ias.c index f9154976e..ddd1656d0 100644 --- a/nimble/host/services/ias/src/ble_svc_ias.c +++ b/nimble/host/services/ias/src/ble_svc_ias.c @@ -41,23 +41,28 @@ static int ble_svc_ias_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); +static const ble_uuid16_t uuid_svc_ias = BLE_UUID16_INIT(BLE_SVC_IAS_UUID16); +static const ble_uuid16_t uuid_chr_alert_level = BLE_UUID16_INIT(BLE_SVC_IAS_CHR_UUID16_ALERT_LEVEL); + +static const struct ble_gatt_chr_def alert_characteristics[] = { + { + /*** Characteristic: Alert Level. */ + .uuid = &uuid_chr_alert_level.u, + .access_cb = ble_svc_ias_access, + .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, + }, { + 0, + } +}; + static const struct ble_gatt_svc_def ble_svc_ias_defs[] = { { /*** Service: Immediate Alert Service (IAS). */ .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = BLE_UUID16_DECLARE(BLE_SVC_IAS_UUID16), - .characteristics = (struct ble_gatt_chr_def[]) { { - /*** Characteristic: Alert Level. */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_IAS_CHR_UUID16_ALERT_LEVEL), - .access_cb = ble_svc_ias_access, - .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, - }, { - 0, /* No more characteristics in this service. */ - } }, - }, - - { - 0, /* No more services. */ + .uuid = &uuid_svc_ias.u, + .characteristics = alert_characteristics, + }, { + 0, /* No more characteristics in this service. */ }, }; diff --git a/nimble/host/services/ipss/src/ble_svc_ipss.c b/nimble/host/services/ipss/src/ble_svc_ipss.c index d883bf483..3cdaccf92 100644 --- a/nimble/host/services/ipss/src/ble_svc_ipss.c +++ b/nimble/host/services/ipss/src/ble_svc_ipss.c @@ -24,11 +24,13 @@ #include "services/ipss/ble_svc_ipss.h" #if MYNEWT_VAL(BLE_GATTS) && CONFIG_BT_NIMBLE_IPSS_SERVICE +static const ble_uuid16_t uuid_svc_ipss = BLE_UUID16_INIT(BLE_SVC_IPSS_UUID16); + static const struct ble_gatt_svc_def ble_svc_ipss_defs[] = { { /*** Service: GATT */ .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = BLE_UUID16_DECLARE(BLE_SVC_IPSS_UUID16), + .uuid = &uuid_svc_ipss.u, .characteristics = NULL, }, { diff --git a/nimble/host/services/lls/src/ble_svc_lls.c b/nimble/host/services/lls/src/ble_svc_lls.c index 335a79277..d298d77b2 100644 --- a/nimble/host/services/lls/src/ble_svc_lls.c +++ b/nimble/host/services/lls/src/ble_svc_lls.c @@ -41,21 +41,27 @@ static int ble_svc_lls_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); +static const ble_uuid16_t uuid_svc_lls = BLE_UUID16_INIT(BLE_SVC_LLS_UUID16); +static const ble_uuid16_t uuid_chr_alert_level = BLE_UUID16_INIT(BLE_SVC_LLS_CHR_UUID16_ALERT_LEVEL); + +static const struct ble_gatt_chr_def lls_characteristics[] = { + { + /*** Characteristic: Alert Level. */ + .uuid = &uuid_chr_alert_level.u, + .access_cb = ble_svc_lls_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE, + }, { + 0, /* No more characteristics in this service. */ + }, +}; + static const struct ble_gatt_svc_def ble_svc_lls_defs[] = { { - /*** Service: Link Loss Service (LLS). */ + /*** Service: Link Loss Service (LLS). */ .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = BLE_UUID16_DECLARE(BLE_SVC_LLS_UUID16), - .characteristics = (struct ble_gatt_chr_def[]) { { - /*** Characteristic: Alert Level. */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_LLS_CHR_UUID16_ALERT_LEVEL), - .access_cb = ble_svc_lls_access, - .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE, - }, { - 0, /* No more characteristics in this service. */ - } }, + .uuid = &uuid_svc_lls.u, + .characteristics = lls_characteristics, }, - { 0, /* No more services. */ }, diff --git a/nimble/host/services/ras/src/ble_svc_ras.c b/nimble/host/services/ras/src/ble_svc_ras.c index 9190afdba..1f5749d8b 100644 --- a/nimble/host/services/ras/src/ble_svc_ras.c +++ b/nimble/host/services/ras/src/ble_svc_ras.c @@ -113,29 +113,32 @@ struct ranging_buffer *ranging_buffer_alloc(uint16_t conn_handle , uint16_t rang static int gatt_svr_chr_access_ras_val(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); -static const struct ble_gatt_svc_def gatt_svr_svcs[] = { - { - /* Service: Ranging Data Service */ - .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = BLE_UUID16_DECLARE(BLE_SVC_RAS_RANGING_SERVICE_VAL), - .characteristics = (struct ble_gatt_chr_def[]) { +static const ble_uuid16_t uuid_svc_ras = BLE_UUID16_INIT(BLE_SVC_RAS_RANGING_SERVICE_VAL); +static const ble_uuid16_t uuid_chr_feat_value = BLE_UUID16_INIT(BLE_SVC_RAS_CHR_UUID_FEATURES_VAL); +static const ble_uuid16_t uuid_chr_demand_rd = BLE_UUID16_INIT(BLE_SVC_RAS_CHR_UUID_ONDEMAND_RD_VAL); +static const ble_uuid16_t uuid_chr_real_rd = BLE_UUID16_INIT(BLE_SVC_RAS_CHR_UUID_REALTIME_RD_VAL); +static const ble_uuid16_t uuid_chr_ctrl_pt = BLE_UUID16_INIT(BLE_SVC_RAS_CHR_UUID_CP_VAL); +static const ble_uuid16_t uuid_chr_data_rdy = BLE_UUID16_INIT(BLE_SVC_RAS_CHR_UUID_RD_READY_VAL); +static const ble_uuid16_t uuid_chr_data_ow = BLE_UUID16_INIT(BLE_SVC_RAS_CHR_UUID_RD_OVERWRITTEN_VAL); + +static const struct ble_gatt_chr_def ras_characteristics[] = { { /* Characteristic: Feature Value */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_RAS_CHR_UUID_FEATURES_VAL), + .uuid = &uuid_chr_feat_value.u, .access_cb = gatt_svr_chr_access_ras_val, .val_handle = &ble_svc_ras_feat_val_handle, .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC, }, { /* Characteristic: On demand ranging data */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_RAS_CHR_UUID_ONDEMAND_RD_VAL), + .uuid = &uuid_chr_demand_rd.u, .access_cb = gatt_svr_chr_access_ras_val, .val_handle = &ble_svc_ras_od_rd_val_handle, .flags = BLE_GATT_CHR_F_NOTIFY | BLE_GATT_CHR_F_INDICATE , }, { /* Characteristic: On realtime ranging data */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_RAS_CHR_UUID_REALTIME_RD_VAL), + .uuid = &uuid_chr_real_rd.u, .access_cb = gatt_svr_chr_access_ras_val, .val_handle = &ble_svc_ras_rt_rd_val_handle, .flags = BLE_GATT_CHR_F_NOTIFY | BLE_GATT_CHR_F_INDICATE , @@ -143,21 +146,21 @@ static const struct ble_gatt_svc_def gatt_svr_svcs[] = { { /* Characteristic: RAS Control Point */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_RAS_CHR_UUID_CP_VAL), + .uuid = &uuid_chr_ctrl_pt.u, .access_cb = gatt_svr_chr_access_ras_val, .val_handle = &ble_svc_ras_cp_val_handle, .flags = BLE_GATT_CHR_F_WRITE_NO_RSP | BLE_GATT_CHR_F_INDICATE, }, { /* Characteristic: RAS Ranging Data Ready */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_RAS_CHR_UUID_RD_READY_VAL), + .uuid = &uuid_chr_data_rdy.u, .access_cb = gatt_svr_chr_access_ras_val, .val_handle = &ble_svc_ras_rd_val_handle, .flags = BLE_GATT_CHR_F_INDICATE | BLE_GATT_CHR_F_READ_ENC | BLE_GATT_CHR_F_READ , }, { /* Characteristic: RAS Ranging data overwritten */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_RAS_CHR_UUID_RD_OVERWRITTEN_VAL), + .uuid = &uuid_chr_data_ow.u, .access_cb = gatt_svr_chr_access_ras_val, .val_handle = &ble_svc_ras_rd_ov_val_handle, .flags = BLE_GATT_CHR_F_INDICATE | BLE_GATT_CHR_F_READ_ENC | BLE_GATT_CHR_F_READ, @@ -165,7 +168,14 @@ static const struct ble_gatt_svc_def gatt_svr_svcs[] = { { 0, /* No more characteristics in this service */ }, - }, +}; + +static const struct ble_gatt_svc_def gatt_svr_svcs[] = { + { + /* Service: Ranging Data Service */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &uuid_svc_ras.u, + .characteristics = ras_characteristics, }, { 0, /* No more services */ @@ -411,7 +421,7 @@ void ble_gatts_store_ranging_data(struct ble_cs_event ranging_subevent) { uint16_t max_data_len = ble_att_mtu(ranging_subevent.subev_result.conn_handle) - sizeof(struct segment_header) - 4; MODLOG_DFLT(INFO, "Max data len : %d\n", max_data_len); - ras_segment= nimble_platform_mem_malloc(sizeof(struct segment)+ max_data_len); + ras_segment= nimble_platform_mem_calloc(1,sizeof(struct segment)+ max_data_len); if (ras_segment == NULL) { MODLOG_DFLT(INFO, "Failed to allocate memory for RAS segment\n"); return; diff --git a/nimble/host/services/sps/include/services/sps/ble_svc_sps.h b/nimble/host/services/sps/include/services/sps/ble_svc_sps.h index 5daa96ef4..8345985cf 100644 --- a/nimble/host/services/sps/include/services/sps/ble_svc_sps.h +++ b/nimble/host/services/sps/include/services/sps/ble_svc_sps.h @@ -35,6 +35,9 @@ typedef int ble_svc_sps_event_fn(uint16_t scan_interval, uint16_t scan_window); void ble_svc_sps_scan_refresh(void); void ble_svc_sps_init(uint16_t scan_itvl, uint16_t scan_window); void ble_svc_sps_set_cb(ble_svc_sps_event_fn *cb); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void ble_svc_sps_reset(void); +#endif #ifdef __cplusplus } diff --git a/nimble/host/services/sps/src/ble_svc_sps.c b/nimble/host/services/sps/src/ble_svc_sps.c index c8ac0ad45..034975c4e 100644 --- a/nimble/host/services/sps/src/ble_svc_sps.c +++ b/nimble/host/services/sps/src/ble_svc_sps.c @@ -22,43 +22,70 @@ #include "sysinit/sysinit.h" #include "host/ble_hs.h" #include "services/sps/ble_svc_sps.h" +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#include "esp_nimble_mem.h" +#endif #if MYNEWT_VAL(BLE_GATTS) && CONFIG_BT_NIMBLE_SPS_SERVICE -static uint16_t ble_scan_itvl; -static uint16_t ble_scan_window; -static uint8_t ble_scan_refresh; static uint16_t ble_scan_itvl_handle; static uint16_t ble_scan_refresh_handle; +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +static uint16_t ble_scan_itvl; +static uint16_t ble_scan_window; +static uint8_t ble_scan_refresh; + static ble_svc_sps_event_fn *ble_svc_sps_cb_fn; +#else /* !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) */ +typedef struct { + uint16_t _ble_scan_itvl; + uint16_t _ble_scan_window; + uint8_t _ble_scan_refresh; + ble_svc_sps_event_fn *_ble_svc_sps_cb_fn; +} ble_svc_sps_static_vars_t; + +static ble_svc_sps_static_vars_t * ble_svc_sps_static_vars = NULL; + +#define ble_scan_itvl (ble_svc_sps_static_vars->_ble_scan_itvl) +#define ble_scan_window (ble_svc_sps_static_vars->_ble_scan_window) +#define ble_scan_refresh (ble_svc_sps_static_vars->_ble_scan_refresh) +#define ble_svc_sps_cb_fn (ble_svc_sps_static_vars->_ble_svc_sps_cb_fn) + +#endif /* !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) */ /* Access function */ static int ble_svc_sps_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); +static const ble_uuid16_t uuid_svc_sps = BLE_UUID16_INIT(BLE_SVC_SPS_UUID16); +static const ble_uuid16_t uuid_chr_scan_itvl = BLE_UUID16_INIT(BLE_SVC_SPS_CHR_UUID16_SCAN_ITVL_WINDOW); +static const ble_uuid16_t uuid_chr_scan_refresh = BLE_UUID16_INIT(BLE_SVC_SPS_CHR_UUID16_SCAN_REFRESH); + +static const struct ble_gatt_chr_def sps_characteristics[] = { + { + /*** Characteristic: Scan Interval */ + .uuid = &uuid_chr_scan_itvl.u, + .access_cb = ble_svc_sps_access, + .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, + .val_handle = &ble_scan_itvl_handle, + }, { + /*** Characteristic: Scan Refresh */ + .uuid = &uuid_chr_scan_refresh.u, + .access_cb = ble_svc_sps_access, + .flags = BLE_GATT_CHR_F_NOTIFY, + .val_handle = &ble_scan_refresh_handle, + }, { + 0, /* No more characteristics in this service */ + }, +}; + static const struct ble_gatt_svc_def ble_svc_sps_defs[] = { { /*** Service: Device Information Service (SPS). */ .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = BLE_UUID16_DECLARE(BLE_SVC_SPS_UUID16), - .characteristics = (struct ble_gatt_chr_def[]) { { - /*** Characteristic: Scan Interval */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_SPS_CHR_UUID16_SCAN_ITVL_WINDOW), - .access_cb = ble_svc_sps_access, - .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, - .val_handle = &ble_scan_itvl_handle, - }, { - /*** Characteristic: Scan Refresh */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_SPS_CHR_UUID16_SCAN_REFRESH), - .access_cb = ble_svc_sps_access, - .flags = BLE_GATT_CHR_F_NOTIFY, - .val_handle = &ble_scan_refresh_handle, - }, { - 0, /* No more characteristics in this service */ - }, } - }, - - { + .uuid = &uuid_svc_sps.u, + .characteristics = sps_characteristics, + }, { 0, /* No more services. */ }, }; @@ -123,9 +150,47 @@ ble_svc_sps_access(uint16_t conn_handle, uint16_t attr_handle, return 0; } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +/** + * Init SPS dynamic memory. + */ +static void +ble_svc_sps_ensure_static_vars(void) +{ + if (ble_svc_sps_static_vars == NULL) { + ble_svc_sps_static_vars = nimble_platform_mem_calloc(1, sizeof(ble_svc_sps_static_vars_t)); + if (ble_svc_sps_static_vars == NULL) { + return; + } + } +} + +/** + * Deinit SPS dynamic memory. + */ +void +ble_svc_sps_reset(void) +{ + if (!ble_svc_sps_static_vars) { + return; + } + + ble_scan_itvl = 0; + ble_scan_window = 0; + if (ble_svc_sps_static_vars) { + nimble_platform_mem_free(ble_svc_sps_static_vars); + ble_svc_sps_static_vars = NULL; + } +} +#endif + void ble_svc_sps_set_cb(ble_svc_sps_event_fn *cb) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + ble_svc_sps_ensure_static_vars(); +#endif + ble_svc_sps_cb_fn = cb; } @@ -137,6 +202,10 @@ ble_svc_sps_init(uint16_t scan_itvl, uint16_t scan_window) { int rc; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + ble_svc_sps_ensure_static_vars(); +#endif + /* Ensure this function only gets called by sysinit. */ SYSINIT_ASSERT_ACTIVE(); diff --git a/nimble/host/services/tps/src/ble_svc_tps.c b/nimble/host/services/tps/src/ble_svc_tps.c index 313eb7fb9..77efdc284 100644 --- a/nimble/host/services/tps/src/ble_svc_tps.c +++ b/nimble/host/services/tps/src/ble_svc_tps.c @@ -38,21 +38,27 @@ static int ble_svc_tps_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); +static const ble_uuid16_t uuid_chr_power_level = BLE_UUID16_INIT(BLE_SVC_TPS_CHR_UUID16_TX_POWER_LEVEL); +static const ble_uuid16_t uuid_svc_tps = BLE_UUID16_INIT(BLE_SVC_TPS_UUID16); + +static const struct ble_gatt_chr_def tps_characteristics[] = { + { + /*** Characteristic: Tx Power Level. */ + .uuid = &uuid_chr_power_level.u, + .access_cb = ble_svc_tps_access, + .flags = BLE_GATT_CHR_F_READ, + }, { + 0, /* No more characeteristics in this service */ + }, +}; + static const struct ble_gatt_svc_def ble_svc_tps_defs[] = { { - /*** Service: Tx Power Service. */ + /*** Service: Tx Power Service */ .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = BLE_UUID16_DECLARE(BLE_SVC_TPS_UUID16), - .characteristics = (struct ble_gatt_chr_def[]) { { - /*** Characteristic: Tx Power Level. */ - .uuid = BLE_UUID16_DECLARE(BLE_SVC_TPS_CHR_UUID16_TX_POWER_LEVEL), - .access_cb = ble_svc_tps_access, - .flags = BLE_GATT_CHR_F_READ, - }, { - 0, /* No more characteristics in this service. */ - } }, + .uuid = &uuid_svc_tps.u, + .characteristics = tps_characteristics, }, - { 0, /* No more services. */ }, diff --git a/nimble/host/src/ble_att.c b/nimble/host/src/ble_att.c index 06b331da5..c37cb6bba 100644 --- a/nimble/host/src/ble_att.c +++ b/nimble/host/src/ble_att.c @@ -41,7 +41,7 @@ struct ble_att_rx_dispatch_entry { ble_att_rx_fn *bde_fn; }; -/** Dispatch table for incoming ATT commands. Must be ordered by op code. */ +/** Dispatch table for incoming ATT commands.*/ static const struct ble_att_rx_dispatch_entry ble_att_rx_dispatch[] = { #if MYNEWT_VAL(BLE_GATTC) { BLE_ATT_OP_ERROR_RSP, ble_att_clt_rx_error }, @@ -76,8 +76,10 @@ static const struct ble_att_rx_dispatch_entry ble_att_rx_dispatch[] = { { BLE_ATT_OP_INDICATE_RSP, ble_att_clt_rx_indicate }, { BLE_ATT_OP_READ_MULT_VAR_REQ, ble_att_svr_rx_read_mult_var }, { BLE_ATT_OP_WRITE_CMD, ble_att_svr_rx_write_no_rsp }, +#if MYNEWT_VAL(BLE_ATT_SVR_SIGNED_WRITE) { BLE_ATT_OP_SIGNED_WRITE_CMD, ble_att_svr_rx_signed_write }, #endif +#endif }; #define BLE_ATT_RX_DISPATCH_SZ \ @@ -147,9 +149,9 @@ static const struct ble_att_rx_dispatch_entry * ble_att_rx_dispatch_entry_find(uint8_t op) { const struct ble_att_rx_dispatch_entry *entry; - unsigned int i; + int i; - for (i = 0; i < BLE_ATT_RX_DISPATCH_SZ; i++) { + for (i = 0; i < (int)BLE_ATT_RX_DISPATCH_SZ; i++) { entry = ble_att_rx_dispatch + i; if (entry->bde_op == op) { return entry; @@ -767,4 +769,11 @@ ble_att_init(void) return 0; } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void ble_att_deinit(void) +{ + ble_eatt_deinit(); +} +#endif + #endif diff --git a/nimble/host/src/ble_att_clt.c b/nimble/host/src/ble_att_clt.c index 5fdb9c72f..b44e5c152 100644 --- a/nimble/host/src/ble_att_clt.c +++ b/nimble/host/src/ble_att_clt.c @@ -776,13 +776,12 @@ ble_att_clt_rx_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) return 0; } + +#if NIMBLE_BLE_ATT_CLT_SIGNED_WRITE int ble_att_clt_tx_signed_write_cmd(uint16_t conn_handle, uint16_t cid, uint16_t handle, uint8_t *csrk, uint32_t counter, struct os_mbuf *txom) { -#if !NIMBLE_BLE_ATT_CLT_SIGNED_WRITE - return BLE_HS_ENOTSUP; -#endif struct ble_att_signed_write_cmd *cmd; struct os_mbuf *txom2; @@ -809,7 +808,7 @@ ble_att_clt_tx_signed_write_cmd(uint16_t conn_handle, uint16_t cid, uint16_t han * where || represents concatenation */ len = BLE_ATT_SIGNED_WRITE_DATA_OFFSET + OS_MBUF_PKTLEN(txom) + sizeof(counter); - message = nimble_platform_mem_malloc(len); + message = nimble_platform_mem_calloc(1,len); /** Copying opcode and handle */ rc = os_mbuf_copydata(txom2, 0, BLE_ATT_SIGNED_WRITE_DATA_OFFSET, message); @@ -862,14 +861,21 @@ ble_att_clt_tx_signed_write_cmd(uint16_t conn_handle, uint16_t cid, uint16_t han goto err; } - if(message != NULL) nimble_platform_mem_free(message); + if (message != NULL) { + nimble_platform_mem_free(message); + message = NULL; + } os_mbuf_concat(txom2, txom); return ble_att_tx(conn_handle, cid, txom2); err: - if(message != NULL) nimble_platform_mem_free(message); + if (message != NULL) { + nimble_platform_mem_free(message); + message = NULL; + } os_mbuf_free_chain(txom2); return rc; } +#endif /***************************************************************************** * $prepare write request * diff --git a/nimble/host/src/ble_att_priv.h b/nimble/host/src/ble_att_priv.h index 7494cb6e9..bc3248cf2 100644 --- a/nimble/host/src/ble_att_priv.h +++ b/nimble/host/src/ble_att_priv.h @@ -183,7 +183,7 @@ void ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu); uint16_t ble_att_chan_mtu(const struct ble_l2cap_chan *chan); uint16_t ble_att_mtu_by_cid(uint16_t conn_handle, uint16_t cid); int ble_att_init(void); - +void ble_att_deinit(void); /*** @svr */ int ble_att_svr_start(void); @@ -234,6 +234,9 @@ int ble_att_svr_read_handle(uint16_t conn_handle, uint16_t attr_handle, void ble_att_svr_reset(void); int ble_att_svr_init(void); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void ble_att_svr_deinit(void); +#endif void ble_att_svr_hide_range(uint16_t start_handle, uint16_t end_handle); void ble_att_svr_restore_range(uint16_t start_handle, uint16_t end_handle); diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c index 3ccb96105..98bd03679 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -50,6 +50,29 @@ */ STAILQ_HEAD(ble_att_svr_entry_list, ble_att_svr_entry); + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +typedef struct { + os_membuf_t *prep_entry_mem; + struct os_mempool prep_entry_pool; + void *entry_mem; + struct os_mempool entry_pool; + struct ble_att_svr_entry_list list; + struct ble_att_svr_entry_list hidden_list; + uint16_t id; +} ble_att_svr_ctx_t; + +static ble_att_svr_ctx_t *ble_att_svr_ctx; + +#define ble_att_svr_prep_entry_mem (ble_att_svr_ctx->prep_entry_mem) +#define ble_att_svr_prep_entry_pool (ble_att_svr_ctx->prep_entry_pool) +#define ble_att_svr_entry_mem (ble_att_svr_ctx->entry_mem) +#define ble_att_svr_entry_pool (ble_att_svr_ctx->entry_pool) +#define ble_att_svr_list (ble_att_svr_ctx->list) +#define ble_att_svr_hidden_list (ble_att_svr_ctx->hidden_list) +#define ble_att_svr_id (ble_att_svr_ctx->id) + +#else static struct ble_att_svr_entry_list ble_att_svr_list; static struct ble_att_svr_entry_list ble_att_svr_hidden_list; @@ -68,6 +91,25 @@ static os_membuf_t ble_att_svr_prep_entry_mem[ #endif static struct os_mempool ble_att_svr_prep_entry_pool; +static struct os_mempool ble_att_svr_entry_pool; +#endif + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +static int +ble_att_svr_ensure_ctx(void) +{ + if (ble_att_svr_ctx != NULL) { + return 0; + } + + ble_att_svr_ctx = nimble_platform_mem_calloc(1, sizeof(*ble_att_svr_ctx)); + if (ble_att_svr_ctx == NULL) { + return BLE_HS_ENOMEM; + } + + return 0; +} +#endif static struct ble_att_svr_entry * ble_att_svr_entry_alloc(void) @@ -78,7 +120,7 @@ ble_att_svr_entry_alloc(void) #if MYNEWT_VAL(BLE_DYNAMIC_SERVICE) && !MYNEWT_VAL(MP_RUNTIME_ALLOC) /* if dynamic services are enabled, try to allocate from heap */ if (entry == NULL) { - entry = nimble_platform_mem_malloc(sizeof *entry); + entry = nimble_platform_mem_calloc(1,sizeof *entry); } #endif if (entry != NULL) { @@ -288,7 +330,6 @@ ble_att_svr_get_sec_state(uint16_t conn_handle, ble_hs_unlock(); } - #if MYNEWT_VAL(BLE_GATTS) static int ble_att_svr_check_perms(uint16_t conn_handle, int is_read, @@ -2412,13 +2453,10 @@ ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, uint16_t cid, struct os_mbuf * return ble_att_svr_write_handle(conn_handle, handle, 0, rxom, &att_err); } +#if MYNEWT_VAL(BLE_ATT_SVR_SIGNED_WRITE) int ble_att_svr_rx_signed_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { -#if !MYNEWT_VAL(BLE_ATT_SVR_SIGNED_WRITE) - return BLE_HS_ENOTSUP; -#endif - if (MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 && ble_hs_cfg.eatt) { return BLE_HS_ENOTSUP; } @@ -2473,7 +2511,7 @@ ble_att_svr_rx_signed_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf * /* Authentication procedure */ len = OS_MBUF_PKTLEN(*rxom) + sizeof(value_sec.sign_counter) + 1; - message = nimble_platform_mem_malloc(len); + message = nimble_platform_mem_calloc(1,len); message[0] = BLE_ATT_OP_SIGNED_WRITE_CMD; os_mbuf_copydata(*rxom, 0, OS_MBUF_PKTLEN(*rxom), &message[1]); @@ -2507,11 +2545,13 @@ ble_att_svr_rx_signed_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf * goto err; } +#if MYNEWT_VAL(BLE_SM_SIGN_CNT) /* Signature matches, increment sign counter and pass the data to the upper layer */ rc = ble_sm_incr_peer_sign_counter(conn_handle); if (rc != 0) { goto err; } +#endif /* Strip the request base from the front of the mbuf. */ os_mbuf_adj(*rxom, sizeof(*req)); @@ -2527,6 +2567,7 @@ err: nimble_platform_mem_free(message); return rc; } +#endif int ble_att_svr_write_local(uint16_t attr_handle, struct os_mbuf *om) @@ -3325,8 +3366,18 @@ ble_att_svr_reset(void) static void ble_att_svr_free_start_mem(void) { - nimble_platform_mem_free(ble_att_svr_entry_mem); - ble_att_svr_entry_mem = NULL; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_att_svr_ctx == NULL) { + return; + } +#endif + if (ble_att_svr_entry_mem) { + nimble_platform_mem_free(ble_att_svr_entry_mem); + ble_att_svr_entry_mem = NULL; + } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + memset(&ble_att_svr_entry_pool, 0, sizeof(ble_att_svr_entry_pool)); +#endif } int @@ -3334,11 +3385,18 @@ ble_att_svr_start(void) { int rc; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + rc = ble_att_svr_ensure_ctx(); + if (rc != 0) { + return rc; + } +#endif + ble_att_svr_free_start_mem(); if (ble_hs_max_attrs > 0) { #if !MYNEWT_VAL(MP_RUNTIME_ALLOC) - ble_att_svr_entry_mem = nimble_platform_mem_malloc( + ble_att_svr_entry_mem = nimble_platform_mem_calloc(1, OS_MEMPOOL_BYTES(ble_hs_max_attrs, sizeof (struct ble_att_svr_entry))); if (ble_att_svr_entry_mem == NULL) { @@ -3351,6 +3409,9 @@ ble_att_svr_start(void) sizeof (struct ble_att_svr_entry), ble_att_svr_entry_mem, "ble_att_svr_entry_pool"); if (rc != 0) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + memset(&ble_att_svr_entry_pool, 0, sizeof(ble_att_svr_entry_pool)); +#endif rc = BLE_HS_EOS; goto err; } @@ -3363,6 +3424,26 @@ err: return rc; } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void +ble_att_svr_deinit(void) +{ + if (ble_att_svr_ctx == NULL) { + return; + } + + if (ble_att_svr_prep_entry_mem) { + nimble_platform_mem_free(ble_att_svr_prep_entry_mem); + ble_att_svr_prep_entry_mem = NULL; + } + memset(&ble_att_svr_prep_entry_pool, 0, sizeof(ble_att_svr_prep_entry_pool)); + ble_att_svr_free_start_mem(); + + nimble_platform_mem_free(ble_att_svr_ctx); + ble_att_svr_ctx = NULL; +} +#endif + void ble_att_svr_stop(void) { @@ -3374,13 +3455,39 @@ ble_att_svr_init(void) { int rc; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + rc = ble_att_svr_ensure_ctx(); + if (rc != 0) { + return rc; + } +#endif + if (MYNEWT_VAL(BLE_ATT_SVR_MAX_PREP_ENTRIES) > 0) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + size_t mem_size = OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ATT_SVR_MAX_PREP_ENTRIES), + sizeof(struct ble_att_prep_entry)) * sizeof(os_membuf_t); + ble_att_svr_prep_entry_mem = (os_membuf_t *)nimble_platform_mem_calloc(1, mem_size); + if (!ble_att_svr_prep_entry_mem) { + return BLE_HS_ENOMEM; + } +#endif +#endif rc = os_mempool_init(&ble_att_svr_prep_entry_pool, MYNEWT_VAL(BLE_ATT_SVR_MAX_PREP_ENTRIES), sizeof (struct ble_att_prep_entry), ble_att_svr_prep_entry_mem, "ble_att_svr_prep_entry_pool"); if (rc != 0) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + nimble_platform_mem_free(ble_att_svr_prep_entry_mem); + ble_att_svr_prep_entry_mem = NULL; +#endif + memset(&ble_att_svr_prep_entry_pool, 0, + sizeof(ble_att_svr_prep_entry_pool)); +#endif + return BLE_HS_EOS; } } diff --git a/nimble/host/src/ble_eatt.c b/nimble/host/src/ble_eatt.c index ccf2ce744..4ccc7202c 100644 --- a/nimble/host/src/ble_eatt.c +++ b/nimble/host/src/ble_eatt.c @@ -29,6 +29,9 @@ #include "ble_l2cap_priv.h" #include "ble_eatt_priv.h" #include "services/gatt/ble_svc_gatt.h" +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#include "esp_nimble_mem.h" +#endif struct ble_eatt { SLIST_ENTRY(ble_eatt) next; @@ -45,14 +48,13 @@ struct ble_eatt { SLIST_HEAD(ble_eatt_list, ble_eatt); -static struct ble_eatt_list g_ble_eatt_list; static ble_eatt_att_rx_fn ble_eatt_att_rx_cb; -#define BLE_EATT_DATABUF_SIZE ( \ - MYNEWT_VAL(BLE_EATT_MTU) + \ - 2 + \ - sizeof (struct os_mbuf_pkthdr) + \ - sizeof (struct os_mbuf)) +#define BLE_EATT_DATABUF_SIZE ( \ + MYNEWT_VAL(BLE_EATT_MTU) + \ + 2 + \ + sizeof(struct os_mbuf_pkthdr) + \ + sizeof(struct os_mbuf)) #define BLE_EATT_MEMBLOCK_SIZE \ (OS_ALIGN(BLE_EATT_DATABUF_SIZE, 4)) @@ -60,6 +62,7 @@ static ble_eatt_att_rx_fn ble_eatt_att_rx_cb; #define BLE_EATT_MEMPOOL_SIZE \ OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_EATT_CHAN_NUM) + 1, BLE_EATT_MEMBLOCK_SIZE) +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) #if MYNEWT_VAL(MP_RUNTIME_ALLOC) static os_membuf_t *ble_eatt_conn_mem = NULL; static os_membuf_t *ble_eatt_sdu_coc_mem = NULL; @@ -73,11 +76,44 @@ static os_membuf_t ble_eatt_sdu_coc_mem[BLE_EATT_MEMPOOL_SIZE]; static struct os_mempool ble_eatt_conn_pool; struct os_mbuf_pool ble_eatt_sdu_os_mbuf_pool; static struct os_mempool ble_eatt_sdu_mbuf_mempool; - static struct ble_gap_event_listener ble_eatt_listener; - +struct os_mbuf_pool ble_eatt_sdu_os_mbuf_pool; static struct ble_npl_event g_read_sup_cl_feat_ev; static struct ble_npl_event g_read_sup_srv_feat_ev; +static struct ble_eatt_list g_ble_eatt_list; +#endif + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +typedef struct { + /* Connection pool and memory */ + os_membuf_t *conn_mem; + struct os_mempool conn_pool; + + /* SDU memory and mbuf pool */ + os_membuf_t *sdu_coc_mem; + struct os_mbuf_pool sdu_os_mbuf_pool; + struct os_mempool sdu_mbuf_mempool; + + /* GAP listener */ + struct ble_gap_event_listener eatt_listener; + + /* Events */ + struct ble_npl_event read_sup_cl_feat_ev; + struct ble_npl_event read_sup_srv_feat_ev; + struct ble_eatt_list eatt_list; +} ble_eatt_ctx_t; + +static ble_eatt_ctx_t *ble_eatt_ctx; +#define ble_eatt_conn_pool (ble_eatt_ctx->conn_pool) +#define ble_eatt_conn_mem (ble_eatt_ctx->conn_mem) +#define ble_eatt_sdu_coc_mem (ble_eatt_ctx->sdu_coc_mem) +#define ble_eatt_sdu_os_mbuf_pool (ble_eatt_ctx->sdu_os_mbuf_pool) +#define ble_eatt_sdu_mbuf_mempool (ble_eatt_ctx->sdu_mbuf_mempool) +#define ble_eatt_listener (ble_eatt_ctx->eatt_listener) +#define g_read_sup_cl_feat_ev (ble_eatt_ctx->read_sup_cl_feat_ev) +#define g_read_sup_srv_feat_ev (ble_eatt_ctx->read_sup_srv_feat_ev) +#define g_ble_eatt_list (ble_eatt_ctx->eatt_list) +#endif static void ble_eatt_setup_cb(struct ble_npl_event *ev); static void ble_eatt_start(uint16_t conn_handle); @@ -133,7 +169,7 @@ ble_eatt_find(uint16_t conn_handle, uint16_t cid) (eatt->chan) && (eatt->chan->scid == cid)) { return eatt; - } + } } return NULL; @@ -277,7 +313,7 @@ ble_eatt_l2cap_event_fn(struct ble_l2cap_event *event, void *arg) return BLE_HS_EREJECT; } - assert (!ble_gap_conn_find(event->receive.conn_handle, &desc)); + assert(!ble_gap_conn_find(event->receive.conn_handle, &desc)); /* As per BLE 5.4 Standard, Vol. 3, Part G, section 5.3.2 * (ENHANCED ATT BEARER L2CAP INTEROPERABILITY REQUIREMENTS: * Channel Requirements): @@ -298,7 +334,7 @@ ble_eatt_l2cap_event_fn(struct ble_l2cap_event *event, void *arg) } rc = ble_eatt_prepare_rx_sdu(event->receive.chan); if (rc) { - /* Receiving L2CAP data is no longer possible, terminate connection */ + /* Receiving L2CAP data is no longer possible, terminate connection */ ble_l2cap_disconnect(eatt->chan); return BLE_HS_ENOMEM; } @@ -498,12 +534,13 @@ ble_eatt_get_available_chan_cid(uint16_t conn_handle, uint8_t op) void ble_eatt_release_chan(uint16_t conn_handle, uint8_t op) { - struct ble_eatt * eatt; + struct ble_eatt *eatt; eatt = ble_eatt_find_by_conn_handle_and_busy_op(conn_handle, op); if (!eatt) { BLE_EATT_LOG_DEBUG("ble_eatt_release_chan:" - "EATT not found for conn_handle 0x%04x, operation 0x%02\n", conn_handle, op); + "EATT not found for conn_handle 0x%04x, operation 0x%02\n", + conn_handle, op); return; } @@ -524,7 +561,7 @@ ble_eatt_tx(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom) goto error; } - ble_att_truncate_to_mtu(eatt->chan, txom); + ble_att_truncate_to_mtu(eatt->chan, txom); rc = ble_l2cap_send(eatt->chan, txom); if (rc == 0) { goto done; @@ -577,11 +614,69 @@ ble_eatt_start(uint16_t conn_handle) } } -void +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void ble_eatt_deinit(void) +{ + if (ble_eatt_ctx == NULL) + { + return; + } + +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + if (ble_eatt_sdu_coc_mem) { + nimble_platform_mem_free(ble_eatt_sdu_coc_mem); + ble_eatt_sdu_coc_mem = NULL; + } + + if (ble_eatt_conn_mem) { + nimble_platform_mem_free(ble_eatt_conn_mem); + ble_eatt_conn_mem = NULL; + } +#endif + nimble_platform_mem_free(ble_eatt_ctx); + ble_eatt_ctx = NULL; +} +#endif // BLE_STATIC_TO_DYNAMIC + +int ble_eatt_init(ble_eatt_att_rx_fn att_rx_cb) { int rc; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (!ble_eatt_ctx) { + ble_eatt_ctx = nimble_platform_mem_calloc(1, sizeof(*ble_eatt_ctx)); + if (!ble_eatt_ctx) { + return BLE_HS_ENOMEM; + } + } + +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + size_t ble_eatt_conn_mem_size = OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_EATT_CHAN_NUM), sizeof(struct ble_eatt)); + + if (!ble_eatt_conn_mem) { + ble_eatt_conn_mem = nimble_platform_mem_calloc(1, ble_eatt_conn_mem_size * sizeof(os_membuf_t)); + if (!ble_eatt_conn_mem) { + // free the allocated memory + nimble_platform_mem_free(ble_eatt_ctx); + ble_eatt_ctx = NULL; + return BLE_HS_ENOMEM; + } + } + + if (!ble_eatt_sdu_coc_mem) { + ble_eatt_sdu_coc_mem = nimble_platform_mem_calloc(1, BLE_EATT_MEMPOOL_SIZE * sizeof(os_membuf_t)); + if (!ble_eatt_sdu_coc_mem) { + // free the allocated memory + nimble_platform_mem_free(ble_eatt_conn_mem); + nimble_platform_mem_free(ble_eatt_ctx); + ble_eatt_conn_mem = NULL; + ble_eatt_ctx = NULL; + return BLE_HS_ENOMEM; + } + } +#endif +#endif // BLE_STATIC_TO_DYNAMIC rc = os_mempool_init(&ble_eatt_sdu_mbuf_mempool, MYNEWT_VAL(BLE_EATT_CHAN_NUM) + 1, BLE_EATT_MEMBLOCK_SIZE, @@ -607,5 +702,7 @@ ble_eatt_init(ble_eatt_att_rx_fn att_rx_cb) ble_npl_event_init(&g_read_sup_cl_feat_ev, ble_gatt_eatt_read_cl_uuid, NULL); ble_eatt_att_rx_cb = att_rx_cb; + + return 0; } #endif diff --git a/nimble/host/src/ble_eatt_priv.h b/nimble/host/src/ble_eatt_priv.h index 1797ce670..024f97f3c 100644 --- a/nimble/host/src/ble_eatt_priv.h +++ b/nimble/host/src/ble_eatt_priv.h @@ -32,14 +32,16 @@ typedef int (* ble_eatt_att_rx_fn)(uint16_t conn_handle, uint16_t cid, struct os #define BLE_GATT_OP_DUMMY 0xF2 #if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 -void ble_eatt_init(ble_eatt_att_rx_fn att_rx_fn); +int ble_eatt_init(ble_eatt_att_rx_fn att_rx_fn); +void ble_eatt_deinit(void); uint16_t ble_eatt_get_available_chan_cid(uint16_t conn_handle, uint8_t op); void ble_eatt_release_chan(uint16_t conn_handle, uint8_t op); int ble_eatt_tx(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom); #else -static inline void +static inline int ble_eatt_init(ble_eatt_att_rx_fn att_rx_fn) { + return 0; } static inline void @@ -54,5 +56,6 @@ ble_eatt_get_available_chan_cid(uint16_t conn_handle, uint8_t op) return BLE_L2CAP_CID_ATT; } +static inline void ble_eatt_deinit(void) {} #endif #endif diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index b865c122b..506727fe1 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -38,6 +38,10 @@ #include "host/ble_hs_iso_hci.h" #endif /* MYNEWT_VAL(BLE_ISO) */ +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#include "esp_nimble_mem.h" +#endif + #ifndef min #define min(a, b) ((a) < (b) ? (a) : (b)) #endif @@ -146,7 +150,11 @@ struct ble_gap_connect_reattempt_ctxt { int count; struct ble_gap_periodic_sync_params periodic_params; #endif // MYNEWT_VAL(BLE_PERIODIC_ADV) -}ble_conn_reattempt; +}; + +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +struct ble_gap_connect_reattempt_ctxt ble_conn_reattempt; +#endif struct ble_gap_adv_reattempt_ctxt { uint8_t type; @@ -160,7 +168,6 @@ struct ble_gap_adv_reattempt_ctxt { #if MYNEWT_VAL(BLE_EXT_ADV) uint8_t instance; - struct ble_gap_ext_adv_params params; int8_t selected_tx_power; uint8_t selected_tx_power_present:1; int duration; @@ -170,7 +177,13 @@ struct ble_gap_adv_reattempt_ctxt { bool retry; ble_gap_event_fn *cb; void *cb_arg; -}ble_adv_reattempt; +}; + +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +struct ble_gap_adv_reattempt_ctxt ble_adv_reattempt; +#endif + + #endif /** @@ -205,7 +218,10 @@ struct ble_gap_master_state { } disc; }; }; + +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) static bssnz_t struct ble_gap_master_state ble_gap_master; +#endif #if MYNEWT_VAL(BLE_PERIODIC_ADV) /** @@ -220,8 +236,10 @@ struct ble_gap_sync_state { void *cb_arg; }; +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) static bssnz_t struct ble_gap_sync_state ble_gap_sync; #endif +#endif /** * The state of the in-progress slave connection. If no slave connection is @@ -256,29 +274,38 @@ struct ble_gap_slave_state { void *cb_arg; }; +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) static bssnz_t struct ble_gap_slave_state ble_gap_slave[BLE_ADV_INSTANCES]; +#endif #if MYNEWT_VAL(BLE_ISO) + struct ble_gap_cis_state { ble_gap_event_fn *cb; void *cb_arg; }; +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) static bssnz_t struct ble_gap_cis_state ble_gap_cis; +#endif struct ble_gap_big_brd_state { ble_gap_event_fn *cb; void *cb_arg; }; +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) static bssnz_t struct ble_gap_big_brd_state ble_gap_big_brd; +#endif struct ble_gap_big_snc_state { ble_gap_event_fn *cb; void *cb_arg; }; +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) static bssnz_t struct ble_gap_big_snc_state ble_gap_big_snc; +#endif #endif /* MYNEWT_VAL(BLE_ISO) */ struct ble_gap_update_entry { @@ -295,6 +322,8 @@ struct ble_gap_snapshot { void *cb_arg; }; +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +static struct ble_gap_hook_list ble_gap_event_listener_list; static SLIST_HEAD(ble_gap_hook_list, ble_gap_event_listener) ble_gap_event_listener_list; #if MYNEWT_VAL(MP_RUNTIME_ALLOC) static os_membuf_t *ble_gap_update_entry_mem = NULL; @@ -304,7 +333,11 @@ static os_membuf_t ble_gap_update_entry_mem[ sizeof (struct ble_gap_update_entry))]; #endif static struct os_mempool ble_gap_update_entry_pool; + static struct ble_gap_update_entry_list ble_gap_update_entries; +#else +SLIST_HEAD(ble_gap_hook_list, ble_gap_event_listener); +#endif #if MYNEWT_VAL(OPTIMIZE_MULTI_CONN) struct ble_gap_multi_conn_state @@ -314,17 +347,132 @@ struct ble_gap_multi_conn_state uint32_t common_factor; }; +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) static struct ble_gap_multi_conn_state ble_gap_multi_conn; #endif +#endif #if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) static uint8_t pawr_adv_handle; static uint16_t pawr_sync_handle; #endif +#endif + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +struct ble_gap_adv_slave { + ble_gap_event_fn *cb; + void *arg; +}; + +typedef struct { +#if NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) + struct ble_gap_connect_reattempt_ctxt _ble_conn_reattempt; + struct ble_gap_adv_reattempt_ctxt _ble_adv_reattempt; +#endif + bssnz_t struct ble_gap_master_state _ble_gap_master; + +#if MYNEWT_VAL(BLE_PERIODIC_ADV) + bssnz_t struct ble_gap_sync_state _ble_gap_sync; +#endif + + bssnz_t struct ble_gap_slave_state _ble_gap_slave[BLE_ADV_INSTANCES]; + +#if MYNEWT_VAL(BLE_ISO) + bssnz_t struct ble_gap_cis_state _ble_gap_cis; + bssnz_t struct ble_gap_big_brd_state _ble_gap_big_brd; + bssnz_t struct ble_gap_big_snc_state _ble_gap_big_snc; +#endif /* MYNEWT_VAL(BLE_ISO) */ + + struct ble_gap_hook_list _ble_gap_event_listener_list; + os_membuf_t *_ble_gap_update_entry_mem; + struct os_mempool _ble_gap_update_entry_pool; + + struct ble_gap_update_entry_list _ble_gap_update_entries; + +#if MYNEWT_VAL(OPTIMIZE_MULTI_CONN) + struct ble_gap_multi_conn_state _ble_gap_multi_conn; +#endif + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) + uint8_t _pawr_adv_handle; + uint16_t _pawr_sync_handle; +#endif + struct ble_npl_mutex _preempt_done_mutex; + +#if MYNEWT_VAL(BLE_EXT_ADV) +#if MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE) <= BLE_HCI_MAX_EXT_ADV_DATA_LEN + uint8_t _ext_buf[sizeof(struct ble_hci_le_set_ext_adv_data_cp) + \ + MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE)]; +#else + uint8_t _ext_buf[sizeof(struct ble_hci_le_set_ext_adv_data_cp) + \ + BLE_HCI_MAX_EXT_ADV_DATA_LEN]; +#endif +#endif + +#if MYNEWT_VAL(BLE_PERIODIC_ADV) +#if MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE) <= BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN + uint8_t _per_buf[sizeof(struct ble_hci_le_set_periodic_adv_data_cp) + + MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE)]; +#else + uint8_t _per_buf[sizeof(struct ble_hci_le_set_periodic_adv_data_cp) + + BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN]; +#endif +#endif + struct ble_gap_adv_slave slaves[BLE_ADV_INSTANCES]; +} ble_gap_vars_t; + +static ble_gap_vars_t * ble_gap_vars; + +#if NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) +#define ble_conn_reattempt (ble_gap_vars->_ble_conn_reattempt) +#define ble_adv_reattempt (ble_gap_vars->_ble_adv_reattempt) +#endif + +#define ble_gap_master (ble_gap_vars->_ble_gap_master) + +#if MYNEWT_VAL(BLE_PERIODIC_ADV) +#define ble_gap_sync (ble_gap_vars->_ble_gap_sync) +#endif // BLE_PERIODIC_ADV + +#define ble_gap_slave (ble_gap_vars->_ble_gap_slave) + +#if MYNEWT_VAL(BLE_ISO) +#define ble_gap_cis (ble_gap_vars->_ble_gap_cis) +#define ble_gap_big_brd (ble_gap_vars->_ble_gap_big_brd) +#define ble_gap_big_snc (ble_gap_vars->_ble_gap_big_snc) +#endif // BLE_ISO + +#define ble_gap_event_listener_list (ble_gap_vars->_ble_gap_event_listener_list) +#define ble_gap_update_entry_mem (ble_gap_vars->_ble_gap_update_entry_mem) +#define ble_gap_update_entry_pool (ble_gap_vars->_ble_gap_update_entry_pool) +#define ble_gap_update_entries (ble_gap_vars->_ble_gap_update_entries) + +#if MYNEWT_VAL(OPTIMIZE_MULTI_CONN) +#define ble_gap_multi_conn (ble_gap_vars->_ble_gap_multi_conn) +#endif // OPTIMIZE_MULTI_CONN + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) +#define pawr_adv_handle (ble_gap_vars->_pawr_adv_handle) +#define pawr_sync_handle (ble_gap_vars->_pawr_sync_handle) +#endif // BLE_PERIODIC_ADV_WITH_RESPONSES + +#define preempt_done_mutex (ble_gap_vars->_preempt_done_mutex) + +#if MYNEWT_VAL(BLE_EXT_ADV) +#define ext_buf (ble_gap_vars->_ext_buf) +#endif + +#if MYNEWT_VAL(BLE_PERIODIC_ADV) +#define per_buf (ble_gap_vars->_per_buf) +#endif + +#define slaves (ble_gap_vars->slaves) +#endif /* MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) */ static void ble_gap_update_entry_free(struct ble_gap_update_entry *entry); -#if NIMBLE_BLE_CONNECT +#if NIMBLE_BLE_CONNECT || MYNEWT_VAL(BLE_HS_DEBUG) static struct ble_gap_update_entry * ble_gap_update_entry_find(uint16_t conn_handle, struct ble_gap_update_entry **out_prev); @@ -746,11 +894,15 @@ ble_gap_set_priv_mode(const ble_addr_t *peer_addr, uint8_t priv_mode) if (!ble_hs_is_enabled()) { return BLE_HS_EDISABLED; } - +#if MYNEWT_VAL(BLE_HS_PVCY) return ble_hs_pvcy_set_mode(peer_addr, priv_mode); #else return BLE_HS_ENOTSUP; #endif + +#else + return BLE_HS_ENOTSUP; +#endif } int @@ -1037,7 +1189,7 @@ ble_gap_slave_reset_state(uint8_t instance) } #endif -#if MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_ROLE_OBSERVER) +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_OBSERVER) || NIMBLE_BLE_SCAN || MYNEWT_VAL(BLE_ISO) static bool ble_gap_has_client(struct ble_gap_master_state *out_state) { @@ -1047,9 +1199,7 @@ ble_gap_has_client(struct ble_gap_master_state *out_state) return out_state->cb != NULL; } -#endif -#if MYNEWT_VAL(BLE_ROLE_OBSERVER) || NIMBLE_BLE_CONNECT static void ble_gap_master_extract_state(struct ble_gap_master_state *out_state, int reset_state) @@ -1110,6 +1260,7 @@ ble_gap_adv_finished(uint8_t instance, int reason, uint16_t conn_handle, #endif #if NIMBLE_BLE_CONNECT +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_OBSERVER) static int ble_gap_master_connect_failure(int status) { @@ -1145,7 +1296,9 @@ ble_gap_master_connect_failure(int status) return rc; } +#endif +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_OBSERVER) static void ble_gap_master_connect_cancelled(void) { @@ -1189,11 +1342,13 @@ ble_gap_master_connect_cancelled(void) state.cb(&event, state.cb_arg); } } +#endif #if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT static void ble_gap_update_notify(uint16_t conn_handle, int status); +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_OBSERVER) int ble_gap_master_connect_reattempt(uint16_t conn_handle) { @@ -1272,7 +1427,7 @@ ble_gap_master_connect_reattempt(uint16_t conn_handle) return rc; } - +#endif void ble_gap_reattempt_count(uint16_t conn_handle, uint8_t count) { struct ble_gap_event event; @@ -1287,6 +1442,7 @@ void ble_gap_reattempt_count(uint16_t conn_handle, uint8_t count) ble_gap_call_conn_event_cb(&event, handle); } +#if MYNEWT_VAL(BLE_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_ROLE_BROADCASTER) int ble_gap_slave_adv_reattempt(void) { int rc = 0; @@ -1302,25 +1458,19 @@ int ble_gap_slave_adv_reattempt(void) rc = ble_gap_adv_start(ble_adv_reattempt.own_addr_type, (ble_adv_reattempt.direct_addr_present == 1 ? &ble_adv_reattempt.direct_addr: NULL), - ble_adv_reattempt.duration_ms, &ble_adv_reattempt.adv_params, + ble_adv_reattempt.duration_ms, NULL, ble_adv_reattempt.cb, ble_adv_reattempt.cb_arg); if (rc != 0) { return rc; } + + ble_adv_reattempt.retry = 1 ; break; case 1: #if MYNEWT_VAL(BLE_EXT_ADV) ble_gap_ext_adv_stop(ble_adv_reattempt.instance); - rc = ble_gap_ext_adv_configure(ble_adv_reattempt.instance, &ble_adv_reattempt.params, - (ble_adv_reattempt.selected_tx_power_present == 1 ? &ble_adv_reattempt.selected_tx_power : NULL), - ble_adv_reattempt.cb, ble_adv_reattempt.cb_arg); - - if (rc != 0) { - return rc; - } - ble_adv_reattempt.retry = 1; rc = ble_gap_ext_adv_start(ble_adv_reattempt.instance, ble_adv_reattempt.duration, @@ -1338,6 +1488,7 @@ int ble_gap_slave_adv_reattempt(void) } #endif +#endif #endif @@ -1530,7 +1681,9 @@ ble_gap_master_failed(int status) #if NIMBLE_BLE_CONNECT case BLE_GAP_OP_M_CONN: STATS_INC(ble_gap_stats, initiate_fail); +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_OBSERVER) ble_gap_master_connect_failure(status); +#endif break; #endif @@ -1623,9 +1776,15 @@ ble_gap_conn_broken(uint16_t conn_handle, int reason) ble_hs_unlock(); // Send disconnect event in slave role if connect was sent +#if MYNEWT_VAL(BT_NIMBLE_MEM_OPTIMIZATION) if ((conn != NULL) && !(conn->bhc_flags & BLE_HS_CONN_F_MASTER)) { if (conn->slave_conn) { conn->slave_conn = 0; +#else + if ((conn != NULL) && !(conn->bhc_flags & BLE_HS_CONN_F_MASTER)) { + if (conn->slave_conn) { + conn->slave_conn = 0; +#endif } else { send = 0; } @@ -1821,6 +1980,7 @@ int ble_gap_ext_adv_active(uint8_t instance) void ble_gap_reset_state(int reason) { +#if NIMBLE_BLE_CONNECT uint16_t conn_handle; while (1) { @@ -1831,6 +1991,7 @@ ble_gap_reset_state(int reason) ble_gap_conn_broken(conn_handle, reason); } +#endif #if NIMBLE_BLE_ADVERTISE #if MYNEWT_VAL(BLE_EXT_ADV) @@ -2939,7 +3100,9 @@ ble_gap_rx_conn_complete(struct ble_gap_conn_complete *evt, uint8_t instance) #if MYNEWT_VAL(BLE_GATT_CACHING) struct ble_hs_conn_addrs addrs; #endif - + if(evt == NULL) { + return BLE_HS_EINVAL; + } STATS_INC(ble_gap_stats, rx_conn_complete); #if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) uint8_t v1_evt = 0; @@ -2967,6 +3130,7 @@ ble_gap_rx_conn_complete(struct ble_gap_conn_complete *evt, uint8_t instance) #endif break; case BLE_ERR_UNK_CONN_ID: +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_OBSERVER) /* master role */ if (ble_gap_master_in_progress()) { /* Connect procedure successfully cancelled. */ @@ -2976,6 +3140,7 @@ ble_gap_rx_conn_complete(struct ble_gap_conn_complete *evt, uint8_t instance) ble_gap_master_connect_cancelled(); } } +#endif break; #if MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) case BLE_ERR_CONN_ESTABLISHMENT: @@ -3134,7 +3299,7 @@ ble_gap_event_connect_call(uint16_t conn_handle, int status) event.connect.sync_handle = pawr_sync_handle; event.connect.adv_handle = pawr_adv_handle; #endif - + ble_gap_event_listener_call(&event); #if NIMBLE_BLE_CONNECT ble_gap_call_conn_event_cb(&event, handle); @@ -3179,14 +3344,23 @@ ble_gap_rx_rd_rem_sup_feat_complete(const struct ble_hci_ev_le_subev_rd_rem_used } if ((conn != NULL) && (conn->bhc_flags & BLE_HS_CONN_F_MASTER)) { +#if MYNEWT_VAL(BT_NIMBLE_MEM_OPTIMIZATION) + conn->supported_feat = !!(get_le32(ev->features) & BLE_HS_HCI_LE_FEAT_CONN_PARAM_REQUEST); +#else conn->supported_feat = get_le32(ev->features); +#endif ble_gap_rd_rem_ver_tx(ev->conn_handle); + } else { if ((conn != NULL) && (ev->status == 0)) { - conn->supported_feat = get_le32(ev->features); +#if MYNEWT_VAL(BT_NIMBLE_MEM_OPTIMIZATION) + conn->supported_feat = !!(get_le32(ev->features) & BLE_HS_HCI_LE_FEAT_CONN_PARAM_REQUEST); +#else + conn->supported_feat = get_le32(ev->features); +#endif } - if (conn != NULL) { + if (conn != NULL) { ble_gap_event_connect_call(ev->conn_handle, ev->status); conn->slave_conn = 1; } @@ -3269,8 +3443,9 @@ ble_gap_rx_data_len_change(const struct ble_hci_ev_le_subev_data_len_chg *ev) { #if NIMBLE_BLE_CONNECT struct ble_gap_event event; - uint16_t conn_handle = le16toh(ev->conn_handle); struct ble_hs_conn *conn; + uint16_t conn_handle = le16toh(ev->conn_handle); + memset(&event, 0, sizeof event); event.type = BLE_GAP_EVENT_DATA_LEN_CHG; event.data_len_chg.max_tx_octets = le16toh(ev->max_tx_octets); @@ -3894,11 +4069,19 @@ ble_gap_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr, ble_hs_lock(); +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT + if (!ble_adv_reattempt.retry) { +#endif + rc = ble_gap_adv_validate(own_addr_type, direct_addr, adv_params); if (rc != 0) { goto done; } +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT + } +#endif + #if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT ble_adv_reattempt.type = 0; ble_adv_reattempt.own_addr_type = own_addr_type; @@ -3911,7 +4094,6 @@ ble_gap_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr, } ble_adv_reattempt.duration_ms = duration_ms; - memcpy(&ble_adv_reattempt.adv_params , adv_params, sizeof(struct ble_gap_adv_params)); ble_adv_reattempt.cb = cb; ble_adv_reattempt.cb_arg = cb_arg; #endif @@ -3936,7 +4118,15 @@ ble_gap_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr, } BLE_HS_LOG(INFO, "GAP procedure initiated: advertise; "); +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT + if (!ble_adv_reattempt.retry) { +#endif + ble_gap_log_adv(own_addr_type, direct_addr, adv_params); +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT + } +#endif + BLE_HS_LOG(INFO, "\n"); ble_gap_slave[0].cb = cb; @@ -3949,11 +4139,20 @@ ble_gap_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr, ble_gap_slave[0].connectable = 0; } +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT + if (!ble_adv_reattempt.retry) { +#endif + rc = ble_gap_adv_params_tx(own_addr_type, direct_addr, adv_params); if (rc != 0) { goto done; } +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT + } +#endif + + ble_gap_slave[0].op = BLE_GAP_OP_S_ADV; rc = ble_gap_adv_enable_tx(1); @@ -3968,6 +4167,13 @@ ble_gap_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr, rc = 0; +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT + if (ble_adv_reattempt.retry) { + ble_adv_reattempt.retry = 0; + } +#endif + + done: ble_hs_unlock(); @@ -4367,8 +4573,6 @@ ble_gap_ext_adv_configure(uint8_t instance, #if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT ble_adv_reattempt.instance = instance; - memcpy(&ble_adv_reattempt.params, params, sizeof(struct ble_gap_ext_adv_params)); - if (selected_tx_power) { ble_adv_reattempt.selected_tx_power = *selected_tx_power; ble_adv_reattempt.selected_tx_power_present = 1 ; @@ -4707,9 +4911,11 @@ ble_gap_ext_adv_set(uint8_t instance, uint16_t opcode, struct os_mbuf **data) { /* in that case we always fit all data in single HCI command */ #if MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE) <= BLE_HCI_MAX_EXT_ADV_DATA_LEN - static uint8_t buf[sizeof(struct ble_hci_le_set_ext_adv_data_cp) + \ +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + static uint8_t ext_buf[sizeof(struct ble_hci_le_set_ext_adv_data_cp) + \ MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE)]; - struct ble_hci_le_set_ext_adv_data_cp *cmd = (void *)buf; +#endif /*MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) */ + struct ble_hci_le_set_ext_adv_data_cp *cmd = (void *)ext_buf; uint16_t len = OS_MBUF_PKTLEN(*data); opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, opcode); @@ -4725,9 +4931,11 @@ ble_gap_ext_adv_set(uint8_t instance, uint16_t opcode, struct os_mbuf **data) return ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, NULL, 0); #else - static uint8_t buf[sizeof(struct ble_hci_le_set_ext_adv_data_cp) + \ +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + static uint8_t ext_buf[sizeof(struct ble_hci_le_set_ext_adv_data_cp) + \ BLE_HCI_MAX_EXT_ADV_DATA_LEN]; - struct ble_hci_le_set_ext_adv_data_cp *cmd = (void *)buf; +#endif /*MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) */ + struct ble_hci_le_set_ext_adv_data_cp *cmd = (void *)ext_buf; uint16_t len = OS_MBUF_PKTLEN(*data); uint8_t op; int rc; @@ -4746,8 +4954,9 @@ ble_gap_ext_adv_set(uint8_t instance, uint16_t opcode, struct os_mbuf **data) os_mbuf_adj(*data, len); *data = os_mbuf_trim_front(*data); - return ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, + rc = ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, NULL, 0); + goto done; } /* first fragment */ @@ -4765,7 +4974,7 @@ ble_gap_ext_adv_set(uint8_t instance, uint16_t opcode, struct os_mbuf **data) rc = ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, NULL, 0); if (rc) { - return rc; + goto done; } len -= BLE_HCI_MAX_EXT_ADV_DATA_LEN; @@ -4781,8 +4990,11 @@ ble_gap_ext_adv_set(uint8_t instance, uint16_t opcode, struct os_mbuf **data) os_mbuf_adj(*data, len); *data = os_mbuf_trim_front(*data); - return ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, + rc = ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, NULL, 0); + goto done; +done: + return rc; #endif } @@ -4800,7 +5012,6 @@ ble_gap_ext_adv_set_data(uint8_t instance, struct os_mbuf *data) rc = BLE_HS_EDISABLED; goto done; } - #if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && NIMBLE_BLE_CONNECT ble_adv_reattempt.type = 1; ble_adv_reattempt.instance = instance; @@ -4980,7 +5191,12 @@ ble_gap_ext_adv_clear(void) return rc; } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + memset(ble_gap_slave, 0, BLE_ADV_INSTANCES * sizeof(struct ble_gap_slave_state)); +#else memset(ble_gap_slave, 0, sizeof(ble_gap_slave)); +#endif + ble_hs_unlock(); return 0; @@ -5175,9 +5391,11 @@ ble_gap_periodic_adv_set(uint8_t instance, struct os_mbuf **data) { /* In that case we always fit all data in single HCI command */ #if MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE) <= BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN - static uint8_t buf[sizeof(struct ble_hci_le_set_periodic_adv_data_cp) + +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + static uint8_t per_buf[sizeof(struct ble_hci_le_set_periodic_adv_data_cp) + MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE)]; - struct ble_hci_le_set_periodic_adv_data_cp *cmd = (void *) buf; +#endif /*MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) */ + struct ble_hci_le_set_periodic_adv_data_cp *cmd = (void *) per_buf; uint16_t len = 0; uint16_t opcode; @@ -5200,9 +5418,11 @@ ble_gap_periodic_adv_set(uint8_t instance, struct os_mbuf **data) return ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, NULL, 0); #else - static uint8_t buf[sizeof(struct ble_hci_le_set_periodic_adv_data_cp) + +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + static uint8_t per_buf[sizeof(struct ble_hci_le_set_periodic_adv_data_cp) + BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN]; - struct ble_hci_le_set_periodic_adv_data_cp *cmd = (void *) buf; +#endif /*MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) */ + struct ble_hci_le_set_periodic_adv_data_cp *cmd = (void *) per_buf; uint16_t len = 0; uint16_t opcode; uint8_t op; @@ -5226,8 +5446,9 @@ ble_gap_periodic_adv_set(uint8_t instance, struct os_mbuf **data) *data = os_mbuf_trim_front(*data); } - return ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, + rc = ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, NULL, 0); + goto done; } /* If the periodic advertising is already enabled, the periodic advertising @@ -5253,7 +5474,7 @@ ble_gap_periodic_adv_set(uint8_t instance, struct os_mbuf **data) rc = ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, NULL, 0); if (rc) { - return rc; + goto done; } len -= BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN; @@ -5268,8 +5489,11 @@ ble_gap_periodic_adv_set(uint8_t instance, struct os_mbuf **data) os_mbuf_adj(*data, len); *data = os_mbuf_trim_front(*data); - return ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, + rc = ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, NULL, 0); + goto done; +done: + return rc; #endif } @@ -5503,7 +5727,7 @@ ble_gap_periodic_adv_sync_create(const ble_addr_t *addr, uint8_t adv_sid, cmd.sync_timeout = htole16(params->sync_timeout); #if MYNEWT_VAL(BLE_AOA_AOD) cmd.sync_cte_type = params->sync_cte_type; -#else +#else cmd.sync_cte_type = 0x00; #endif @@ -5799,7 +6023,7 @@ periodic_adv_set_default_sync_params(const struct ble_gap_periodic_sync_params * if (params != NULL) { #if MYNEWT_VAL(BLE_AOA_AOD) cmd.sync_cte_type = params->sync_cte_type; -#else +#else cmd.sync_cte_type = 0x00; #endif cmd.mode = params->reports_disabled ? 0x01 : 0x02; @@ -6241,7 +6465,7 @@ ble_gap_set_connless_cte_transmit_params(uint8_t instance, const struct ble_gap_ return ble_hs_hci_cmd_tx(opcode, cmd, len, NULL, 0); } -int +int ble_gap_set_connless_cte_transmit_enable(uint8_t instance, uint8_t cte_enable) { struct ble_hci_le_set_connless_cte_tx_enable_cp cmd; @@ -6259,7 +6483,7 @@ ble_gap_set_connless_cte_transmit_enable(uint8_t instance, uint8_t cte_enable) return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); } -int +int ble_gap_set_connless_iq_sampling_enable(uint16_t sync_handle, uint8_t sampling_enable, uint8_t max_sampled_ctes, const struct ble_gap_cte_sampling_params *cte_sampling_params) { @@ -6284,7 +6508,7 @@ ble_gap_set_connless_iq_sampling_enable(uint16_t sync_handle, uint8_t sampling_e return ble_hs_hci_cmd_tx(opcode, cmd, len, &rsp, sizeof(rsp)); } -int +int ble_gap_set_conn_cte_recv_param(uint16_t conn_handle, uint8_t sampling_enable, const struct ble_gap_cte_sampling_params *cte_sampling_params) { uint8_t buf[sizeof(struct ble_hci_le_set_conn_cte_rx_params_cp) + cte_sampling_params->switching_pattern_length]; @@ -6308,7 +6532,7 @@ ble_gap_set_conn_cte_recv_param(uint16_t conn_handle, uint8_t sampling_enable, c return ble_hs_hci_cmd_tx(opcode, cmd, len, &rsp, sizeof(rsp)); } -int +int ble_gap_set_conn_cte_transmit_param(uint16_t conn_handle, uint8_t cte_types, uint8_t switching_pattern_len, const uint8_t *antenna_ids) { uint8_t buf[sizeof(struct ble_hci_le_set_conn_cte_tx_params_cp) + switching_pattern_len]; @@ -6361,7 +6585,7 @@ ble_gap_conn_cte_req_enable(uint16_t conn_handle, uint8_t enable, uint16_t cte_r return ble_hs_hci_cmd_tx(opcode, cmd, len, &rsp, sizeof(rsp)); } -int +int ble_gap_conn_cte_rsp_enable(uint16_t conn_handle, uint8_t enable) { struct ble_hci_le_set_conn_cte_rsp_enable_cp cmd; @@ -6499,10 +6723,10 @@ ble_gap_disc_cancel(void) return BLE_HS_EDISABLED; } -#if MYNEWT_VAL(BLE_QUEUE_CONG_CHECK) +#if MYNEWT_VAL(BLE_QUEUE_CONG_CHECK) ble_adv_list_refresh(); #endif - + ble_hs_lock(); rc = ble_gap_disc_cancel_no_lock(); ble_hs_unlock(); @@ -6730,7 +6954,7 @@ ble_gap_disc(uint8_t own_addr_type, int32_t duration_ms, #if MYNEWT_VAL(BLE_QUEUE_CONG_CHECK) ble_adv_list_refresh(); -#endif +#endif #if MYNEWT_VAL(BLE_EXT_ADV) struct ble_gap_ext_disc_params p = {0}; @@ -7445,7 +7669,7 @@ ble_gap_ext_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr, STATS_INC(ble_gap_stats, initiate); #if MYNEWT_VAL(OPTIMIZE_MULTI_CONN) - /* If the optimization is enabled, we disallow to invoke this API directly. + /* If the optimization is enabled, we disallow to invoke this API directly. * See @ble_gap_multi_connect() */ if (ble_gap_multi_conn.enabled && !ble_gap_multi_conn.scheduling_len_set) { @@ -7625,7 +7849,7 @@ ble_gap_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr, STATS_INC(ble_gap_stats, initiate); #if MYNEWT_VAL(OPTIMIZE_MULTI_CONN) - /* If the optimization is enabled, we disallow to invoke this API directly. + /* If the optimization is enabled, we disallow to invoke this API directly. * See @ble_gap_multi_connect() */ if (ble_gap_multi_conn.enabled && !ble_gap_multi_conn.scheduling_len_set) { @@ -7835,7 +8059,7 @@ ble_gap_common_factor_set(bool enable, uint32_t common_factor) #if MYNEWT_VAL(BLE_ROLE_CENTRAL) int -ble_gap_multi_connect(struct ble_gap_multi_conn_params *multi_conn_params, +ble_gap_multi_connect(struct ble_gap_multi_conn_params *multi_conn_params, ble_gap_event_fn *cb, void *cb_arg) { int rc; @@ -7864,22 +8088,22 @@ ble_gap_multi_connect(struct ble_gap_multi_conn_params *multi_conn_params, scheduling_len_us = multi_conn_params->scheduling_len_us; /* `scheduling_len_us == 0` is allowed. It indicates that the optimization for this connection - * is disabled. The connection interval must be an integer multiple of `common factor`. Note + * is disabled. The connection interval must be an integer multiple of `common factor`. Note * that the unit of the connection interval is 1.25ms, while the common factor's unit is 0.625ms. */ if (scheduling_len_us != 0) { #if MYNEWT_VAL(BLE_EXT_ADV) if (phy_mask & BLE_GAP_LE_PHY_1M_MASK) { conn_params = multi_conn_params->phy_1m_conn_params; - if ((conn_params == NULL) || - !ble_gap_interval_is_integer_multiple(conn_params->itvl_min << 1, + if ((conn_params == NULL) || + !ble_gap_interval_is_integer_multiple(conn_params->itvl_min << 1, conn_params->itvl_max << 1)) { return BLE_HS_EINVAL; } } if (phy_mask & BLE_GAP_LE_PHY_2M_MASK) { conn_params = multi_conn_params->phy_2m_conn_params; - if ((conn_params == NULL) || + if ((conn_params == NULL) || !ble_gap_interval_is_integer_multiple(conn_params->itvl_min << 1, conn_params->itvl_max << 1)) { return BLE_HS_EINVAL; @@ -7887,7 +8111,7 @@ ble_gap_multi_connect(struct ble_gap_multi_conn_params *multi_conn_params, } if (phy_mask & BLE_GAP_LE_PHY_CODED_MASK) { conn_params = multi_conn_params->phy_coded_conn_params; - if ((conn_params == NULL) || + if ((conn_params == NULL) || !ble_gap_interval_is_integer_multiple(conn_params->itvl_min << 1, conn_params->itvl_max << 1)) { return BLE_HS_EINVAL; @@ -7895,8 +8119,8 @@ ble_gap_multi_connect(struct ble_gap_multi_conn_params *multi_conn_params, } #else conn_params = multi_conn_params->phy_1m_conn_params; - if ((conn_params == NULL) || - !ble_gap_interval_is_integer_multiple(conn_params->itvl_min << 1, + if ((conn_params == NULL) || + !ble_gap_interval_is_integer_multiple(conn_params->itvl_min << 1, conn_params->itvl_max << 1)) { return BLE_HS_EINVAL; } @@ -8097,6 +8321,7 @@ ble_gap_update_entry_alloc(void) struct ble_gap_update_entry *entry; entry = os_memblock_get(&ble_gap_update_entry_pool); + if (entry != NULL) { memset(entry, 0, sizeof *entry); } @@ -8108,17 +8333,23 @@ ble_gap_update_entry_alloc(void) static void ble_gap_update_entry_free(struct ble_gap_update_entry *entry) { +#if NIMBLE_BLE_CONNECT int rc; if (entry != NULL) { #if MYNEWT_VAL(BLE_HS_DEBUG) memset(entry, 0xff, sizeof *entry); #endif + rc = os_memblock_put(&ble_gap_update_entry_pool, entry); - BLE_HS_DBG_ASSERT_EVAL(rc == 0); + + BLE_HS_DBG_ASSERT_EVAL(rc == 0); } +#endif } + +#if NIMBLE_BLE_CONNECT || MYNEWT_VAL(BLE_HS_DEBUG) static struct ble_gap_update_entry * ble_gap_update_entry_find(uint16_t conn_handle, struct ble_gap_update_entry **out_prev) @@ -8143,10 +8374,12 @@ ble_gap_update_entry_find(uint16_t conn_handle, return entry; } +#endif static struct ble_gap_update_entry * ble_gap_update_entry_remove(uint16_t conn_handle) { +#if NIMBLE_BLE_CONNECT struct ble_gap_update_entry *entry; struct ble_gap_update_entry *prev; @@ -8161,6 +8394,9 @@ ble_gap_update_entry_remove(uint16_t conn_handle) } return entry; +#else + return NULL; +#endif } #if NIMBLE_BLE_CONNECT @@ -8380,8 +8616,13 @@ ble_gap_update_params(uint16_t conn_handle, * If LL update procedure is not supported on this connection and we are * the slave, fail over to the L2CAP update procedure. */ +#if MYNEWT_VAL(BT_NIMBLE_MEM_OPTIMIZATION) + if (conn->supported_feat == 0 && + !(conn->bhc_flags & BLE_HS_CONN_F_MASTER)) { +#else if ((conn->supported_feat & BLE_HS_HCI_LE_FEAT_CONN_PARAM_REQUEST) == 0 && !(conn->bhc_flags & BLE_HS_CONN_F_MASTER)) { +#endif l2cap_update = 1; rc = 0; } else { @@ -8415,6 +8656,7 @@ done: #endif } +#if NIMBLE_BLE_CONNECT int ble_gap_set_data_len(uint16_t conn_handle, uint16_t tx_octets, uint16_t tx_time) @@ -8442,29 +8684,36 @@ ble_gap_set_data_len(uint16_t conn_handle, uint16_t tx_octets, event.data_len_chg.conn_handle = conn_handle; ble_gap_event_listener_call(&event); -#if NIMBLE_BLE_CONNECT ble_gap_call_conn_event_cb(&event, conn_handle); -#endif return 0; } return ble_hs_hci_util_set_data_len(conn_handle, tx_octets, tx_time); } +#endif int ble_gap_read_sugg_def_data_len(uint16_t *out_sugg_max_tx_octets, uint16_t *out_sugg_max_tx_time) { +#if NIMBLE_BLE_CONNECT return ble_hs_hci_util_read_sugg_def_data_len(out_sugg_max_tx_octets, out_sugg_max_tx_time); +#else + return BLE_HS_ENOTSUP; +#endif } int ble_gap_write_sugg_def_data_len(uint16_t sugg_max_tx_octets, uint16_t sugg_max_tx_time) { +#if NIMBLE_BLE_CONNECT return ble_hs_hci_util_write_sugg_def_data_len(sugg_max_tx_octets, sugg_max_tx_time); +#else + return BLE_HS_ENOTSUP; +#endif } /***************************************************************************** @@ -8652,6 +8901,7 @@ ble_gap_reset_irk(void) ble_store_delete_local_irk(&key_local_irk); +#if MYNEWT_VAL(BLE_HS_PVCY) ble_hs_pvcy_set_default_irk(); //Remove the previous entry pertaining to 00:00:00:00:00:00 address @@ -8665,6 +8915,7 @@ ble_gap_reset_irk(void) ble_hs_pvcy_set_our_irk(NULL); BLE_HS_LOG(INFO,"Local IRK Reset"); +#endif } #endif @@ -8724,11 +8975,13 @@ ble_gap_unpair(const ble_addr_t *peer_addr) return BLE_HS_EBUSY; } +#if MYNEWT_VAL(BLE_HS_PVCY) // Delete the IRK as it is Distributed rc = ble_hs_pvcy_remove_entry(key.sec.peer_addr.type,key.sec.peer_addr.val); if (rc != 0) { BLE_HS_LOG(ERROR, "Error while removing IRK , rc = %x\n",rc); } +#endif } // Delete the Peer record from store as LTK is present @@ -9155,9 +9408,15 @@ ble_hs_send_vs_event_mask(uint32_t event_mask) } #endif +#if MYNEWT_VAL(BT_NIMBLE_MEM_OPTIMIZATION) +uint8_t +ble_gap_authorize_event(uint16_t conn_handle, uint16_t attr_handle, + uint8_t is_read) +#else int ble_gap_authorize_event(uint16_t conn_handle, uint16_t attr_handle, int is_read) +#endif { #if MYNEWT_VAL(BLE_ROLE_PERIPHERAL) struct ble_gap_event event; @@ -9181,6 +9440,7 @@ ble_gap_authorize_event(uint16_t conn_handle, uint16_t attr_handle, return BLE_GAP_AUTHORIZE_REJECT; } +#if MYNEWT_VAL(BLE_DTM_MODE_TEST) void ble_gap_rx_test_evt(const void *buf, uint8_t len) { @@ -9239,6 +9499,7 @@ ble_gap_end_test_evt(const void *buf, uint8_t len) ble_gap_event_listener_call(&event); } +#endif /***************************************************************************** * EATT * @@ -9335,7 +9596,9 @@ ble_gap_preempt(void) * `ble_gap_preempt()`. */ +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) static struct ble_npl_mutex preempt_done_mutex; +#endif void ble_gap_preempt_done(void) @@ -9345,10 +9608,12 @@ ble_gap_preempt_done(void) void *master_arg; int disc_preempted; int i; +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) static struct { ble_gap_event_fn *cb; void *arg; } slaves[BLE_ADV_INSTANCES]; +#endif master_cb = NULL; master_arg = NULL; @@ -9357,7 +9622,10 @@ ble_gap_preempt_done(void) /* Protects slaves from accessing by multiple threads */ ble_npl_mutex_pend(&preempt_done_mutex, 0xFFFFFFFF); + +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) memset(slaves, 0, sizeof(slaves)); +#endif ble_hs_lock(); @@ -9659,7 +9927,29 @@ ble_gap_init(void) { int rc; - memset(&ble_gap_master, 0, sizeof(ble_gap_master)); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gap_vars == NULL) { + ble_gap_vars = nimble_platform_mem_calloc(1, sizeof(ble_gap_vars_t)); + if (ble_gap_vars == NULL) { + rc = BLE_HS_ENOMEM; + goto err; + } + } + +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + size_t update_entry_mem_size = OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE), + sizeof(struct ble_gap_update_entry)) * sizeof(os_membuf_t); + + if (!ble_gap_update_entry_mem) { + ble_gap_update_entry_mem = nimble_platform_mem_calloc(1, update_entry_mem_size); + if (!ble_gap_update_entry_mem) { + rc = BLE_HS_ENOMEM; + goto err; + } + } +#endif +#endif + memset(ble_gap_slave, 0, sizeof(ble_gap_slave)); #if MYNEWT_VAL(OPTIMIZE_MULTI_CONN) @@ -9680,7 +9970,7 @@ ble_gap_init(void) if (rc) { BLE_HS_LOG(ERROR, "mutex init failed with reason %d \n", rc); - return rc; + goto err; } SLIST_INIT(&ble_gap_update_entries); @@ -9691,6 +9981,10 @@ ble_gap_init(void) sizeof (struct ble_gap_update_entry), ble_gap_update_entry_mem, "ble_gap_update"); + if (rc != 0) { + goto err; + } + switch (rc) { case 0: break; @@ -9712,6 +10006,18 @@ ble_gap_init(void) return 0; err: +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gap_vars != NULL) { +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) // Doubt + if (ble_gap_update_entry_mem != NULL) { + nimble_platform_mem_free(ble_gap_update_entry_mem); + ble_gap_update_entry_mem = NULL; + } +#endif + nimble_platform_mem_free(ble_gap_vars); + ble_gap_vars = NULL; + } +#endif return rc; } @@ -9833,6 +10139,8 @@ ble_gap_set_transmit_power_reporting_enable(uint16_t conn_handle, return BLE_HS_ENOTSUP; #endif } + +#if MYNEWT_VAL(BLE_UTIL_API) int ble_gap_rd_local_resolv_addr(uint8_t peer_addr_type, const ble_addr_t *peer_addr, uint8_t *out_addr) @@ -9858,6 +10166,8 @@ ble_gap_rd_local_resolv_addr(uint8_t peer_addr_type, const ble_addr_t *peer_addr return 0; } +#endif + #if MYNEWT_VAL(BLE_HCI_VS) #if MYNEWT_VAL(BLE_POWER_CONTROL) static int @@ -9990,12 +10300,15 @@ int ble_gap_set_scan_chan(uint8_t state, uint8_t *bitmap) } #endif +#if MYNEWT_VAL(BLE_UTIL_API) int ble_gap_set_data_related_addr_change_param(uint8_t adv_handle, uint8_t change_reason) { return ble_hs_hci_util_set_data_addr_change(adv_handle, change_reason); } +#endif +#if MYNEWT_VAL(BLE_DTM_MODE_TEST) int ble_gap_dtm_tx_start(uint8_t tx_chan, uint8_t test_data_len, uint8_t payload) { @@ -10026,6 +10339,7 @@ ble_gap_dtm_enh_rx_start(uint8_t rx_chan, uint8_t index, uint8_t phy) { return ble_hs_hci_dtm_enh_rx_start(rx_chan, index, phy); } +#endif int ble_gap_rd_all_local_supp_features(uint8_t *status, uint8_t *max_page, uint8_t *le_features) @@ -10043,8 +10357,22 @@ void ble_gap_deinit(void) { ble_npl_mutex_deinit(&preempt_done_mutex); + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gap_vars != NULL) { +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) // Doubt + if (ble_gap_update_entry_mem != NULL) { + nimble_platform_mem_free(ble_gap_update_entry_mem); + ble_gap_update_entry_mem = NULL; + } +#endif + nimble_platform_mem_free(ble_gap_vars); + ble_gap_vars = NULL; + } +#endif } +#if MYNEWT_VAL(BLE_HOST_STATUS) int ble_gap_host_check_status(void) { @@ -10149,12 +10477,16 @@ ble_gap_host_check_status(void) return status; } +#endif #if MYNEWT_VAL(BLE_CHANNEL_SOUNDING) -int ble_gap_set_host_feat(uint8_t bit_num,uint8_t bit_val) { +int ble_gap_set_host_feat(uint8_t bit_num, uint8_t bit_val) +{ struct ble_hci_le_set_host_feature_cp cmd; + cmd.bit_num=bit_num; cmd.bit_val=bit_val; + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_HOST_FEATURE),&cmd, sizeof(cmd), NULL, 0); } diff --git a/nimble/host/src/ble_gap_priv.h b/nimble/host/src/ble_gap_priv.h index 0e40b62c5..2d471ec20 100644 --- a/nimble/host/src/ble_gap_priv.h +++ b/nimble/host/src/ble_gap_priv.h @@ -175,7 +175,11 @@ void ble_gap_identity_event(uint16_t conn_handle, const ble_addr_t *peer_id_addr int ble_gap_repeat_pairing_event(const struct ble_gap_repeat_pairing *rp); void ble_gap_pairing_complete_event(uint16_t conn_handle, int status); void ble_gap_vs_hci_event(const void *buf, uint8_t len); +#if MYNEWT_VAL(BT_NIMBLE_MEM_OPTIMIZATION) +uint8_t ble_gap_authorize_event(uint16_t conn_handle, uint16_t attr_handle, uint8_t is_read); +#else int ble_gap_authorize_event(uint16_t conn_handle, uint16_t attr_handle, int is_read); +#endif void ble_gap_eatt_event(uint16_t conn_handle, uint8_t status, uint16_t cid); int ble_gap_master_in_progress(void); diff --git a/nimble/host/src/ble_gatt_priv.h b/nimble/host/src/ble_gatt_priv.h index 1f2649e0a..3391ed178 100644 --- a/nimble/host/src/ble_gatt_priv.h +++ b/nimble/host/src/ble_gatt_priv.h @@ -161,6 +161,9 @@ int32_t ble_gattc_timer(void); int ble_gattc_any_jobs(void); int ble_gattc_init(void); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void ble_gattc_deinit(void); +#endif #if MYNEWT_VAL(BLE_GATTC) && MYNEWT_VAL(BLE_GATTC_AUTO_PAIR) void ble_gattc_recover_gatt_proc(uint16_t conn_handle, int enc_status); #endif @@ -198,6 +201,7 @@ struct ble_gatt_resources { */ uint16_t cccds; +#if MYNEWT_VAL(BLE_CPFD_CAFD) /** * Number of client presentation format descriptors. Each of * these also contributes to the total descriptor count. @@ -209,6 +213,7 @@ struct ble_gatt_resources { * these also contributes to the total descriptor count. */ uint16_t cafds; +#endif /** Total number of ATT attributes. */ uint16_t attrs; @@ -234,8 +239,13 @@ struct ble_gatts_aware_state { bool aware; uint8_t half_aware:1; }; + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +extern struct ble_gatts_aware_state * ble_gatts_conn_aware_states; +#else extern struct ble_gatts_aware_state ble_gatts_conn_aware_states[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; #endif +#endif /*** @misc. */ int ble_gatts_conn_can_alloc(void); diff --git a/nimble/host/src/ble_gattc.c b/nimble/host/src/ble_gattc.c index c31d4e5dd..cb5f7cb98 100644 --- a/nimble/host/src/ble_gattc.c +++ b/nimble/host/src/ble_gattc.c @@ -271,14 +271,18 @@ static ble_gattc_err_fn ble_gattc_read_mult_var_err; static ble_gattc_err_fn ble_gattc_write_err; static ble_gattc_err_fn ble_gattc_write_long_err; static ble_gattc_err_fn ble_gattc_write_reliable_err; +#if MYNEWT_VAL(BLE_STORE_MAX_CCCDS) static bool gatt_proc_active = false; #endif +#endif #if MYNEWT_VAL(BLE_GATTS) static ble_gattc_err_fn ble_gatts_indicate_err; #endif +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) static ble_gattc_err_fn * const ble_gattc_err_dispatch[BLE_GATT_OP_CNT] = { + #if MYNEWT_VAL(BLE_GATTC) [BLE_GATT_OP_MTU] = ble_gattc_mtu_err, [BLE_GATT_OP_DISC_ALL_SVCS] = ble_gattc_disc_all_svcs_err, @@ -300,6 +304,7 @@ static ble_gattc_err_fn * const ble_gattc_err_dispatch[BLE_GATT_OP_CNT] = { [BLE_GATT_OP_INDICATE] = ble_gatts_indicate_err, #endif }; +#endif #if MYNEWT_VAL(BLE_GATTC) /** @@ -318,26 +323,6 @@ static ble_gattc_resume_fn ble_gattc_read_long_resume; static ble_gattc_resume_fn ble_gattc_write_long_resume; static ble_gattc_resume_fn ble_gattc_write_reliable_resume; -static ble_gattc_resume_fn * const -ble_gattc_resume_dispatch[BLE_GATT_OP_CNT] = { - [BLE_GATT_OP_MTU] = NULL, - [BLE_GATT_OP_DISC_ALL_SVCS] = ble_gattc_disc_all_svcs_resume, - [BLE_GATT_OP_DISC_SVC_UUID] = ble_gattc_disc_svc_uuid_resume, - [BLE_GATT_OP_FIND_INC_SVCS] = ble_gattc_find_inc_svcs_resume, - [BLE_GATT_OP_DISC_ALL_CHRS] = ble_gattc_disc_all_chrs_resume, - [BLE_GATT_OP_DISC_CHR_UUID] = ble_gattc_disc_chr_uuid_resume, - [BLE_GATT_OP_DISC_ALL_DSCS] = ble_gattc_disc_all_dscs_resume, - [BLE_GATT_OP_READ] = NULL, - [BLE_GATT_OP_READ_UUID] = NULL, - [BLE_GATT_OP_READ_LONG] = ble_gattc_read_long_resume, - [BLE_GATT_OP_READ_MULT] = NULL, - [BLE_GATT_OP_READ_MULT_VAR] = NULL, - [BLE_GATT_OP_WRITE] = NULL, - [BLE_GATT_OP_WRITE_LONG] = ble_gattc_write_long_resume, - [BLE_GATT_OP_WRITE_RELIABLE] = ble_gattc_write_reliable_resume, - [BLE_GATT_OP_INDICATE] = NULL, -}; - #endif /** * Timeout functions - these notify the application that a GATT procedure has @@ -367,6 +352,101 @@ static ble_gattc_tmo_fn ble_gattc_write_reliable_tmo; static ble_gattc_tmo_fn ble_gatts_indicate_tmo; #endif + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +typedef struct { + struct ble_gattc_proc_list procs; +#if MYNEWT_VAL(BLE_GATTC_AUTO_PAIR) + struct ble_gattc_proc_list cached_procs; +#endif + os_membuf_t *proc_mem; + struct os_mempool proc_pool; +#if MYNEWT_VAL(BLE_GATTC) + ble_npl_time_t resume_at; + ble_gattc_resume_fn **resume_dispatch; +#endif + ble_gattc_err_fn **err_dispatch; + ble_gattc_tmo_fn **tmo_dispatch; +} ble_gattc_ctx_t; + +static ble_gattc_ctx_t *ble_gattc_ctx; + +#define ble_gattc_procs (ble_gattc_ctx->procs) +#if MYNEWT_VAL(BLE_GATTC_AUTO_PAIR) +#define ble_gattc_cached_procs (ble_gattc_ctx->cached_procs) +#endif +#define ble_gattc_proc_mem (ble_gattc_ctx->proc_mem) +#define ble_gattc_proc_pool (ble_gattc_ctx->proc_pool) +#if MYNEWT_VAL(BLE_GATTC) +#define ble_gattc_resume_at (ble_gattc_ctx->resume_at) +#define ble_gattc_resume_dispatch (ble_gattc_ctx->resume_dispatch) +#endif +#define ble_gattc_err_dispatch (ble_gattc_ctx->err_dispatch) +#define ble_gattc_tmo_dispatch (ble_gattc_ctx->tmo_dispatch) +#endif + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#if MYNEWT_VAL(BLE_GATTC) || MYNEWT_VAL(BLE_GATTS) +static int +ble_gattc_ensure_ctx(void) +{ + if (ble_gattc_ctx != NULL) { + return 0; + } + + ble_gattc_ctx = nimble_platform_mem_calloc(1, sizeof(*ble_gattc_ctx)); + if (ble_gattc_ctx == NULL) { + return BLE_HS_ENOMEM; + } + + return 0; +} +#endif +#else +#if MYNEWT_VAL(MP_RUNTIME_ALLOC) +static os_membuf_t *ble_gattc_proc_mem = NULL; +#else +static os_membuf_t ble_gattc_proc_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_GATT_MAX_PROCS), + sizeof (struct ble_gattc_proc)) +]; +#endif + +static struct os_mempool ble_gattc_proc_pool; + +/* The list of active GATT client procedures. */ +static struct ble_gattc_proc_list ble_gattc_procs; + +#if MYNEWT_VAL(BLE_GATTC_AUTO_PAIR) +/** Retry procedure after encryption response. */ +static struct ble_gattc_proc_list ble_gattc_cached_procs; +#endif +#if MYNEWT_VAL(BLE_GATTC) +static ble_npl_time_t ble_gattc_resume_at; +static ble_gattc_resume_fn * const +ble_gattc_resume_dispatch[BLE_GATT_OP_CNT] = { + [BLE_GATT_OP_MTU] = NULL, + [BLE_GATT_OP_DISC_ALL_SVCS] = ble_gattc_disc_all_svcs_resume, + [BLE_GATT_OP_DISC_SVC_UUID] = ble_gattc_disc_svc_uuid_resume, + [BLE_GATT_OP_FIND_INC_SVCS] = ble_gattc_find_inc_svcs_resume, + [BLE_GATT_OP_DISC_ALL_CHRS] = ble_gattc_disc_all_chrs_resume, + [BLE_GATT_OP_DISC_CHR_UUID] = ble_gattc_disc_chr_uuid_resume, + [BLE_GATT_OP_DISC_ALL_DSCS] = ble_gattc_disc_all_dscs_resume, + [BLE_GATT_OP_READ] = NULL, + [BLE_GATT_OP_READ_UUID] = NULL, + [BLE_GATT_OP_READ_LONG] = ble_gattc_read_long_resume, + [BLE_GATT_OP_READ_MULT] = NULL, + [BLE_GATT_OP_READ_MULT_VAR] = NULL, + [BLE_GATT_OP_WRITE] = NULL, + [BLE_GATT_OP_WRITE_LONG] = ble_gattc_write_long_resume, + [BLE_GATT_OP_WRITE_RELIABLE] = ble_gattc_write_reliable_resume, + [BLE_GATT_OP_INDICATE] = NULL, +}; +#endif +#endif + + +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) static ble_gattc_tmo_fn * const ble_gattc_tmo_dispatch[BLE_GATT_OP_CNT] = { #if MYNEWT_VAL(BLE_GATTC) @@ -390,6 +470,7 @@ ble_gattc_tmo_dispatch[BLE_GATT_OP_CNT] = { [BLE_GATT_OP_INDICATE] = ble_gatts_indicate_tmo, #endif }; +#endif #if MYNEWT_VAL(BLE_GATTC) /** @@ -469,34 +550,9 @@ static const struct ble_gattc_rx_exec_entry { { BLE_GATT_OP_WRITE_LONG, ble_gattc_write_long_rx_exec }, { BLE_GATT_OP_WRITE_RELIABLE, ble_gattc_write_reliable_rx_exec }, }; - -#endif - -#if MYNEWT_VAL(MP_RUNTIME_ALLOC) -static os_membuf_t *ble_gattc_proc_mem = NULL; -#else -static os_membuf_t ble_gattc_proc_mem[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_GATT_MAX_PROCS), - sizeof (struct ble_gattc_proc)) -]; -#endif - -static struct os_mempool ble_gattc_proc_pool; - -/* The list of active GATT client procedures. */ -static struct ble_gattc_proc_list ble_gattc_procs; - -#if MYNEWT_VAL(BLE_GATTC_AUTO_PAIR) -/** Retry procedure after encryption response. */ -static struct ble_gattc_proc_list ble_gattc_cached_procs; #endif #if MYNEWT_VAL(BLE_GATTC) -/* The time when we should attempt to resume stalled procedures, in OS ticks. - * A value of 0 indicates no stalled procedures. - */ -static ble_npl_time_t ble_gattc_resume_at; - /* Statistics. */ STATS_SECT_DECL(ble_gattc_stats) ble_gattc_stats; STATS_NAME_START(ble_gattc_stats) @@ -714,6 +770,7 @@ ble_gattc_log_write_reliable(struct ble_gattc_proc *proc) } #endif +#if MYNEWT_VAL(BLE_GATTS) static void ble_gattc_log_notify(uint16_t att_handle) { @@ -721,8 +778,6 @@ ble_gattc_log_notify(uint16_t att_handle) BLE_HS_LOG(INFO, "att_handle=%d\n", att_handle); } - -#if MYNEWT_VAL(BLE_GATTS) static void ble_gattc_log_multi_notify(struct ble_gatt_notif * tuples, uint16_t num) { @@ -780,7 +835,13 @@ ble_gattc_proc_alloc(void) { struct ble_gattc_proc *proc; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gattc_ctx == NULL) { + return NULL; + } +#endif proc = os_memblock_get(&ble_gattc_proc_pool); + if (proc != NULL) { memset(proc, 0, sizeof *proc); } @@ -844,7 +905,14 @@ ble_gattc_proc_free(struct ble_gattc_proc *proc) #if MYNEWT_VAL(BLE_HS_DEBUG) memset(proc, 0xff, sizeof *proc); #endif + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gattc_ctx == NULL) { + return; + } +#endif rc = os_memblock_put(&ble_gattc_proc_pool, proc); + BLE_HS_DBG_ASSERT_EVAL(rc == 0); } } @@ -888,6 +956,7 @@ ble_gattc_proc_set_resume_timer(struct ble_gattc_proc *proc) #endif +#if MYNEWT_VAL(BLE_GATTS) || MYNEWT_VAL(BLE_GATTC) static void ble_gattc_process_status(struct ble_gattc_proc *proc, int status) { @@ -906,6 +975,7 @@ ble_gattc_process_status(struct ble_gattc_proc *proc, int status) break; } } +#endif #if MYNEWT_VAL(BLE_GATTC) /** @@ -953,6 +1023,11 @@ static ble_gattc_resume_fn * ble_gattc_resume_dispatch_get(uint8_t op) { BLE_HS_DBG_ASSERT(op < BLE_GATT_OP_CNT); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gattc_ctx == NULL || ble_gattc_resume_dispatch == NULL) { + return NULL; + } +#endif return ble_gattc_resume_dispatch[op]; } @@ -960,6 +1035,11 @@ static ble_gattc_tmo_fn * ble_gattc_tmo_dispatch_get(uint8_t op) { BLE_HS_DBG_ASSERT(op < BLE_GATT_OP_CNT); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gattc_ctx == NULL || ble_gattc_tmo_dispatch == NULL) { + return NULL; + } +#endif return ble_gattc_tmo_dispatch[op]; } @@ -1268,11 +1348,24 @@ ble_gattc_extract_with_rx_entry(uint16_t conn_handle, uint16_t cid, * @return The matching proc entry on success; * null on failure. */ +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) #define BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, cid, rx_entries, out_rx_entry) \ ble_gattc_extract_with_rx_entry( \ (conn_handle), (cid), (rx_entries), \ sizeof (rx_entries) / sizeof (rx_entries)[0], \ (const void **)(out_rx_entry)) +#else +/* + * When memory optimization flag is enabled: + * RX entry table is dynamically allocated with 4 entries + * to optimize memory usage and reduce static allocation. + */ +#define BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, cid, rx_entries, out_rx_entry) \ + ble_gattc_extract_with_rx_entry( \ + (conn_handle), (cid), (rx_entries), \ + 4, \ + (const void **)(out_rx_entry)) +#endif #endif /** @@ -4364,6 +4457,7 @@ ble_gattc_write_no_rsp_flat(uint16_t conn_handle, uint16_t attr_handle, return 0; } +#if NIMBLE_BLE_ATT_CLT_SIGNED_WRITE /***************************************************************************** * $signed write * ****************************************************************************/ @@ -4424,6 +4518,7 @@ err: return rc; } +#endif /***************************************************************************** * $write * *****************************************************************************/ @@ -5175,6 +5270,7 @@ static int ble_gatts_check_conn_aware(uint16_t conn_handle, bool *aware) { } #endif +#if MYNEWT_VAL(BLE_GATTS) int ble_gatts_notify_custom(uint16_t conn_handle, uint16_t chr_val_handle, struct os_mbuf *txom) @@ -5242,7 +5338,6 @@ done: } -#if MYNEWT_VAL(BLE_GATTS) int ble_gatts_notify_multiple_custom(uint16_t conn_handle, size_t chr_count, @@ -5367,8 +5462,8 @@ ble_gattc_notify_custom(uint16_t conn_handle, uint16_t chr_val_handle, return ble_gatts_notify_custom(conn_handle, chr_val_handle, txom); } - #if MYNEWT_VAL(BLE_GATTC) +#if MYNEWT_VAL(BLE_STORE_MAX_CCCDS) static int ble_gattc_cccd_write_complete_cb(uint16_t conn_handle, const struct ble_gatt_error *error, @@ -5432,7 +5527,7 @@ int ble_gattc_register_for_notification(uint16_t conn_handle, uint16_t char_val_ return BLE_HS_EBUSY; } - bool *cccd_reg_flag = (bool *)nimble_platform_mem_malloc(sizeof(bool)); + bool *cccd_reg_flag = (bool *)nimble_platform_mem_calloc(1,sizeof(bool)); if (!cccd_reg_flag) { BLE_HS_LOG(ERROR, "Failed to allocate memory for CCCD Reg Flag."); return BLE_HS_ENOMEM; @@ -5502,7 +5597,7 @@ int ble_gattc_unregister_for_notification(uint16_t conn_handle, uint16_t char_va } int rc; - bool *cccd_unreg_flag = (bool *)nimble_platform_mem_malloc(sizeof(bool)); + bool *cccd_unreg_flag = (bool *)nimble_platform_mem_calloc(1,sizeof(bool)); if (!cccd_unreg_flag) { BLE_HS_LOG(ERROR, "Failed to allocate memory for CCCD Reg Flag"); @@ -5521,8 +5616,10 @@ int ble_gattc_unregister_for_notification(uint16_t conn_handle, uint16_t char_va return rc; } -#endif +#endif //MYNEWT_VAL(BLE_STORE_MAX_CCCDS) +#endif //MYNEWT_VAL(BLE_GATTC) +#if MYNEWT_VAL(BLE_GATTS) int ble_gatts_notify(uint16_t conn_handle, uint16_t chr_val_handle) { @@ -5549,7 +5646,6 @@ ble_gattc_notify(uint16_t conn_handle, uint16_t chr_val_handle) /***************************************************************************** * $indicate * *****************************************************************************/ -#if MYNEWT_VAL(BLE_GATTS) /** * Handles an incoming ATT error response for the specified indication proc. * A device should never send an error in response to an indication. If this @@ -6201,14 +6297,168 @@ ble_gattc_any_jobs(void) { return !STAILQ_EMPTY(&ble_gattc_procs); } +#endif +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#if MYNEWT_VAL(BLE_GATTC) || MYNEWT_VAL(BLE_GATTS) +static int +ble_gattc_err_dispatch_init(void) +{ + + if (ble_gattc_ctx == NULL) { + return BLE_HS_EINVAL; + } + + ble_gattc_err_dispatch = nimble_platform_mem_calloc(1, BLE_GATT_OP_CNT * sizeof(ble_gattc_err_fn *)); + + if (!ble_gattc_err_dispatch) { + return BLE_HS_ENOMEM; + } + +#if MYNEWT_VAL(BLE_GATTC) + ble_gattc_err_dispatch[BLE_GATT_OP_MTU] = ble_gattc_mtu_err; + ble_gattc_err_dispatch[BLE_GATT_OP_DISC_ALL_SVCS] = ble_gattc_disc_all_svcs_err; + ble_gattc_err_dispatch[BLE_GATT_OP_DISC_SVC_UUID] = ble_gattc_disc_svc_uuid_err; + ble_gattc_err_dispatch[BLE_GATT_OP_FIND_INC_SVCS] = ble_gattc_find_inc_svcs_err; + ble_gattc_err_dispatch[BLE_GATT_OP_DISC_ALL_CHRS] = ble_gattc_disc_all_chrs_err; + ble_gattc_err_dispatch[BLE_GATT_OP_DISC_CHR_UUID] = ble_gattc_disc_chr_uuid_err; + ble_gattc_err_dispatch[BLE_GATT_OP_DISC_ALL_DSCS] = ble_gattc_disc_all_dscs_err; + ble_gattc_err_dispatch[BLE_GATT_OP_READ] = ble_gattc_read_err; + ble_gattc_err_dispatch[BLE_GATT_OP_READ_UUID] = ble_gattc_read_uuid_err; + ble_gattc_err_dispatch[BLE_GATT_OP_READ_LONG] = ble_gattc_read_long_err; + ble_gattc_err_dispatch[BLE_GATT_OP_READ_MULT] = ble_gattc_read_mult_err; + ble_gattc_err_dispatch[BLE_GATT_OP_READ_MULT_VAR] = ble_gattc_read_mult_var_err; + ble_gattc_err_dispatch[BLE_GATT_OP_WRITE] = ble_gattc_write_err; + ble_gattc_err_dispatch[BLE_GATT_OP_WRITE_LONG] = ble_gattc_write_long_err; + ble_gattc_err_dispatch[BLE_GATT_OP_WRITE_RELIABLE] = ble_gattc_write_reliable_err; +#endif +#if MYNEWT_VAL(BLE_GATTS) + ble_gattc_err_dispatch[BLE_GATT_OP_INDICATE] = ble_gatts_indicate_err; +#endif + + return 0; +} +#endif + +#if MYNEWT_VAL(BLE_GATTC) || MYNEWT_VAL(BLE_GATTS) +static void +ble_gattc_err_dispatch_deinit(void) +{ + if (ble_gattc_ctx != NULL && ble_gattc_err_dispatch) { + nimble_platform_mem_free(ble_gattc_err_dispatch); + ble_gattc_err_dispatch = NULL; + } +} +#endif + +#if MYNEWT_VAL(BLE_GATTC) +static int +ble_gattc_resume_dispatch_init(void) +{ + if (ble_gattc_ctx == NULL) { + return BLE_HS_EINVAL; + } + + ble_gattc_resume_dispatch = nimble_platform_mem_calloc(1, BLE_GATT_OP_CNT * sizeof(ble_gattc_resume_fn *)); + + if (!ble_gattc_resume_dispatch) { + return BLE_HS_ENOMEM; + } + ble_gattc_resume_dispatch[BLE_GATT_OP_MTU] = NULL; + ble_gattc_resume_dispatch[BLE_GATT_OP_DISC_ALL_SVCS] = ble_gattc_disc_all_svcs_resume; + ble_gattc_resume_dispatch[BLE_GATT_OP_DISC_SVC_UUID] = ble_gattc_disc_svc_uuid_resume; + ble_gattc_resume_dispatch[BLE_GATT_OP_FIND_INC_SVCS] = ble_gattc_find_inc_svcs_resume; + ble_gattc_resume_dispatch[BLE_GATT_OP_DISC_ALL_CHRS] = ble_gattc_disc_all_chrs_resume; + ble_gattc_resume_dispatch[BLE_GATT_OP_DISC_CHR_UUID] = ble_gattc_disc_chr_uuid_resume; + ble_gattc_resume_dispatch[BLE_GATT_OP_DISC_ALL_DSCS] = ble_gattc_disc_all_dscs_resume; + ble_gattc_resume_dispatch[BLE_GATT_OP_READ] = NULL; + ble_gattc_resume_dispatch[BLE_GATT_OP_READ_UUID] = NULL; + ble_gattc_resume_dispatch[BLE_GATT_OP_READ_LONG] = ble_gattc_read_long_resume; + ble_gattc_resume_dispatch[BLE_GATT_OP_READ_MULT] = NULL; + ble_gattc_resume_dispatch[BLE_GATT_OP_READ_MULT_VAR] = NULL; + ble_gattc_resume_dispatch[BLE_GATT_OP_WRITE] = NULL; + ble_gattc_resume_dispatch[BLE_GATT_OP_WRITE_LONG] = ble_gattc_write_long_resume; + ble_gattc_resume_dispatch[BLE_GATT_OP_WRITE_RELIABLE] = ble_gattc_write_reliable_resume; +#if MYNEWT_VAL(BLE_GATTS) + ble_gattc_resume_dispatch[BLE_GATT_OP_INDICATE] = NULL; +#endif + return 0; +} + +static void +ble_gattc_resume_dispatch_deinit(void) +{ + if (ble_gattc_ctx != NULL && ble_gattc_resume_dispatch) { + nimble_platform_mem_free(ble_gattc_resume_dispatch); + ble_gattc_resume_dispatch = NULL; + } +} +#endif + +#if MYNEWT_VAL(BLE_GATTC) || MYNEWT_VAL(BLE_GATTS) +static int +ble_gattc_tmo_dispatch_init(void) +{ + if (ble_gattc_ctx == NULL) { + return BLE_HS_EINVAL; + } + + ble_gattc_tmo_dispatch = nimble_platform_mem_calloc(1, BLE_GATT_OP_CNT * sizeof(ble_gattc_tmo_fn *)); + + if (!ble_gattc_tmo_dispatch) { + return BLE_HS_ENOMEM; + } + +#if MYNEWT_VAL(BLE_GATTC) + ble_gattc_tmo_dispatch[BLE_GATT_OP_MTU] = ble_gattc_mtu_tmo; + ble_gattc_tmo_dispatch[BLE_GATT_OP_DISC_ALL_SVCS] = ble_gattc_disc_all_svcs_tmo; + ble_gattc_tmo_dispatch[BLE_GATT_OP_DISC_SVC_UUID] = ble_gattc_disc_svc_uuid_tmo; + ble_gattc_tmo_dispatch[BLE_GATT_OP_FIND_INC_SVCS] = ble_gattc_find_inc_svcs_tmo; + ble_gattc_tmo_dispatch[BLE_GATT_OP_DISC_ALL_CHRS] = ble_gattc_disc_all_chrs_tmo; + ble_gattc_tmo_dispatch[BLE_GATT_OP_DISC_CHR_UUID] = ble_gattc_disc_chr_uuid_tmo; + ble_gattc_tmo_dispatch[BLE_GATT_OP_DISC_ALL_DSCS] = ble_gattc_disc_all_dscs_tmo; + ble_gattc_tmo_dispatch[BLE_GATT_OP_READ] = ble_gattc_read_tmo; + ble_gattc_tmo_dispatch[BLE_GATT_OP_READ_UUID] = ble_gattc_read_uuid_tmo; + ble_gattc_tmo_dispatch[BLE_GATT_OP_READ_LONG] = ble_gattc_read_long_tmo; + ble_gattc_tmo_dispatch[BLE_GATT_OP_READ_MULT] = ble_gattc_read_mult_tmo; + ble_gattc_tmo_dispatch[BLE_GATT_OP_READ_MULT_VAR] = ble_gattc_read_mult_var_tmo; + ble_gattc_tmo_dispatch[BLE_GATT_OP_WRITE] = ble_gattc_write_tmo; + ble_gattc_tmo_dispatch[BLE_GATT_OP_WRITE_LONG] = ble_gattc_write_long_tmo; + ble_gattc_tmo_dispatch[BLE_GATT_OP_WRITE_RELIABLE] = ble_gattc_write_reliable_tmo; +#endif +#if MYNEWT_VAL(BLE_GATTS) + ble_gattc_tmo_dispatch[BLE_GATT_OP_INDICATE] = ble_gatts_indicate_tmo; +#endif + + return 0; +} +#endif + +#if MYNEWT_VAL(BLE_GATTC) || MYNEWT_VAL(BLE_GATTS) +static void +ble_gattc_tmo_dispatch_deinit(void) +{ + if (ble_gattc_ctx != NULL && ble_gattc_tmo_dispatch) { + nimble_platform_mem_free(ble_gattc_tmo_dispatch); + ble_gattc_tmo_dispatch = NULL; + } +} +#endif #endif int ble_gattc_init(void) { +#if MYNEWT_VAL(BLE_GATTC) || MYNEWT_VAL(BLE_GATTS) int rc; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + rc = ble_gattc_ensure_ctx(); + if (rc != 0) { + return rc; + } +#endif + #if MYNEWT_VAL(BLE_GATTC_PROC_PREEMPTION_PROTECT) STAILQ_INIT(&temp_proc_list); #endif @@ -6218,14 +6468,60 @@ ble_gattc_init(void) #endif if (MYNEWT_VAL(BLE_GATT_MAX_PROCS) > 0) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + size_t mem_bytes = OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_GATT_MAX_PROCS), + sizeof (struct ble_gattc_proc)); + if (ble_gattc_proc_mem == NULL) { + ble_gattc_proc_mem = (os_membuf_t *)nimble_platform_mem_calloc(mem_bytes, sizeof(os_membuf_t)); + if (ble_gattc_proc_mem == NULL) { + return BLE_HS_ENOMEM; + } + } +#endif +#endif rc = os_mempool_init(&ble_gattc_proc_pool, MYNEWT_VAL(BLE_GATT_MAX_PROCS), sizeof (struct ble_gattc_proc), ble_gattc_proc_mem, "ble_gattc_proc_pool"); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (rc != 0) { +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + nimble_platform_mem_free(ble_gattc_proc_mem); + ble_gattc_proc_mem = NULL; +#endif + memset(&ble_gattc_proc_pool, 0, sizeof(ble_gattc_proc_pool)); + return rc; + } +#if MYNEWT_VAL(BLE_GATTC) || MYNEWT_VAL(BLE_GATTS) + rc = ble_gattc_err_dispatch_init(); + if (rc != 0) { + ble_gattc_deinit(); + return rc; + } +#endif + +#if MYNEWT_VAL(BLE_GATTC) + rc = ble_gattc_resume_dispatch_init(); + if (rc != 0) { + ble_gattc_deinit(); + return rc; + } +#endif +#if MYNEWT_VAL(BLE_GATTC) || MYNEWT_VAL(BLE_GATTS) + rc = ble_gattc_tmo_dispatch_init(); + if (rc != 0) { + ble_gattc_deinit(); + return rc; + } +#endif + +#else if (rc != 0) { return rc; } +#endif } rc = stats_init_and_reg( @@ -6236,6 +6532,45 @@ ble_gattc_init(void) } return 0; +#else + return BLE_HS_ENOTSUP; +#endif } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void +ble_gattc_deinit(void) +{ +#if MYNEWT_VAL(BLE_GATTC) || MYNEWT_VAL(BLE_GATTS) + if (ble_gattc_ctx == NULL) { + return; + } +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + if (ble_gattc_proc_mem != NULL) { + nimble_platform_mem_free(ble_gattc_proc_mem); + ble_gattc_proc_mem = NULL; + } +#endif + memset(&ble_gattc_proc_pool, 0, sizeof(ble_gattc_proc_pool)); + STAILQ_INIT(&ble_gattc_procs); +#if MYNEWT_VAL(BLE_GATTC_AUTO_PAIR) + STAILQ_INIT(&ble_gattc_cached_procs); +#endif + + ble_gattc_err_dispatch_deinit(); + +#if MYNEWT_VAL(BLE_GATTC) + ble_gattc_resume_dispatch_deinit(); +#endif + + ble_gattc_tmo_dispatch_deinit(); + + nimble_platform_mem_free(ble_gattc_ctx); + ble_gattc_ctx = NULL; +#else + return ; +#endif +} +#endif + #endif diff --git a/nimble/host/src/ble_gattc_cache.c b/nimble/host/src/ble_gattc_cache.c index 99901e97e..037c01861 100644 --- a/nimble/host/src/ble_gattc_cache.c +++ b/nimble/host/src/ble_gattc_cache.c @@ -38,8 +38,10 @@ static const char *cache_key = "key"; static const char *cache_addr = "cache_addr_tab"; static uint8_t ble_gattc_cache_find_addr(ble_addr_t addr); static uint8_t ble_gattc_cache_find_hash(uint8_t * hash_key); +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) static uint8_t svc_end_handle; struct cache_fn_mapping cache_fn; +#endif typedef struct { /*Save the service data in the list according to the address */ @@ -57,7 +59,23 @@ typedef struct { cache_addr_info_t cache_addr[MAX_DEVICE_IN_CACHE]; } cache_env_t; +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) static cache_env_t *cache_env = NULL; +#endif + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +typedef struct { + uint8_t _svc_end_handle; + struct cache_fn_mapping _cache_fn; + cache_env_t * _cache_env; +} ble_gattc_cache_static_vars_t; + +static ble_gattc_cache_static_vars_t * ble_gattc_cache_static_vars = NULL; + +#define svc_end_handle (ble_gattc_cache_static_vars->_svc_end_handle) +#define cache_fn (ble_gattc_cache_static_vars->_cache_fn) +#define cache_env (ble_gattc_cache_static_vars->_cache_env) +#endif static void print_hash_key(uint8_t * hash_key) @@ -222,7 +240,7 @@ ble_gattc_cacheReset(ble_addr_t *addr) /* Update addr list to storage flash */ if (cache_env->num_addr > 0) { - uint8_t *p_buf = nimble_platform_mem_malloc(MAX_ADDR_LIST_CACHE_BUF); + uint8_t *p_buf = nimble_platform_mem_calloc(1,MAX_ADDR_LIST_CACHE_BUF); if (!p_buf) { BLE_HS_LOG(ERROR, "%s malloc error", __func__); return; @@ -263,10 +281,41 @@ ble_gattc_cacheReset(ble_addr_t *addr) } } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +static int +ble_gattc_cache_static_vars_init(void) +{ + if (ble_gattc_cache_static_vars == NULL) { + + ble_gattc_cache_static_vars = nimble_platform_mem_calloc(1, sizeof(ble_gattc_cache_static_vars_t)); + if (ble_gattc_cache_static_vars == NULL) { + return BLE_HS_ENOMEM; + } + } + + return 0; +} +#endif + static uint8_t ble_gattc_cache_find_addr(ble_addr_t addr) { uint8_t addr_index = 0; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + uint8_t rc = 0; + rc = ble_gattc_cache_static_vars_init(); + if (rc != 0) { + return rc; + } +#endif + + if (cache_env == NULL) { + cache_env = nimble_platform_mem_calloc(1, sizeof(cache_env_t)); + if (cache_env == NULL) { + return BLE_HS_ENOMEM; + } + } + uint8_t num = cache_env->num_addr; cache_addr_info_t *addr_info = &cache_env->cache_addr[0]; @@ -427,7 +476,7 @@ ble_gattc_cache_addr_save(uint8_t *out_index, ble_addr_t addr, uint8_t * hash_ke uint8_t i = 0; uint8_t *p_buf; - p_buf = nimble_platform_mem_malloc(MAX_ADDR_LIST_CACHE_BUF); + p_buf = nimble_platform_mem_calloc(1,MAX_ADDR_LIST_CACHE_BUF); if (p_buf == NULL) { return BLE_HS_ENOMEM; } @@ -529,7 +578,7 @@ ble_gattc_cache_save(struct ble_gattc_cache_conn *peer, size_t num_attr) uint8_t index = INVALID_ADDR_NUM; struct ble_gatt_nv_attr *nv_attr; - nv_attr = (struct ble_gatt_nv_attr *) nimble_platform_mem_malloc(num_attr * sizeof(ble_gatt_nv_attr)); + nv_attr = (struct ble_gatt_nv_attr *) nimble_platform_mem_calloc(1,num_attr * sizeof(ble_gatt_nv_attr)); if (nv_attr == NULL) { BLE_HS_LOG(DEBUG, "Failed to allocate memory to nv_attr"); return; @@ -577,7 +626,7 @@ ble_gattc_cache_load_nv_attr(uint8_t index, int *num_attr) *num_attr = length / (sizeof(ble_gatt_nv_attr)); - nv_attr = (struct ble_gatt_nv_attr *) nimble_platform_mem_malloc((*num_attr) * sizeof(struct ble_gatt_nv_attr)); + nv_attr = (struct ble_gatt_nv_attr *) nimble_platform_mem_calloc(1,(*num_attr) * sizeof(struct ble_gatt_nv_attr)); if (nv_attr == NULL) { return NULL; } @@ -594,7 +643,7 @@ ble_gattc_add_svc_from_cache(ble_addr_t peer_addr, struct ble_gatt_nv_attr nv_at struct ble_gatt_svc *gatt_svc; int rc; - gatt_svc = (struct ble_gatt_svc *)nimble_platform_mem_malloc(sizeof(struct ble_gatt_svc)); + gatt_svc = (struct ble_gatt_svc *)nimble_platform_mem_calloc(1,sizeof(struct ble_gatt_svc)); if (gatt_svc == NULL) { return BLE_HS_ENOMEM; } @@ -615,7 +664,7 @@ ble_gattc_add_inc_from_cache(ble_addr_t peer_addr, struct ble_gatt_nv_attr nv_at int rc; struct ble_gatt_incl_svc *gatt_incl_svc; - gatt_incl_svc = (struct ble_gatt_incl_svc *)nimble_platform_mem_malloc(sizeof(struct ble_gatt_incl_svc)); + gatt_incl_svc = (struct ble_gatt_incl_svc *)nimble_platform_mem_calloc(1,sizeof(struct ble_gatt_incl_svc)); if (gatt_incl_svc == NULL) { return BLE_HS_ENOMEM; } @@ -636,7 +685,7 @@ ble_gattc_add_chr_from_cache(ble_addr_t peer_addr, struct ble_gatt_nv_attr nv_at { struct ble_gatt_chr *gatt_chr; int rc; - gatt_chr = (struct ble_gatt_chr *)nimble_platform_mem_malloc(sizeof(struct ble_gatt_chr)); + gatt_chr = (struct ble_gatt_chr *)nimble_platform_mem_calloc(1,sizeof(struct ble_gatt_chr)); if (gatt_chr == NULL) { return BLE_HS_ENOMEM; } @@ -656,7 +705,7 @@ ble_gattc_add_dsc_from_cache(ble_addr_t peer_addr, struct ble_gatt_nv_attr nv_at { struct ble_gatt_dsc *gatt_dsc; int rc; - gatt_dsc = (struct ble_gatt_dsc *)nimble_platform_mem_malloc(sizeof(struct ble_gatt_dsc)); + gatt_dsc = (struct ble_gatt_dsc *)nimble_platform_mem_calloc(1,sizeof(struct ble_gatt_dsc)); if (gatt_dsc == NULL) { return BLE_HS_ENOMEM; } @@ -721,6 +770,11 @@ ble_gattc_cache_assoc_load(ble_addr_t src_addr, uint8_t src_index, ble_addr_t as cache_env->cache_addr[src_index].hash_key); BLE_HS_LOG(DEBUG, "Successfully associated cache from src_addr to assoc_addr."); + + if (rc != 0) { + return rc; + } + return 0; } @@ -814,32 +868,54 @@ ble_gattc_cache_check_hash(struct ble_gattc_cache_conn *peer, struct os_mbuf *om return -1; } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void +ble_gattc_cache_free_mem(void) +{ + if (ble_gattc_cache_static_vars) { + if (cache_env) { + nimble_platform_mem_free(cache_env); + cache_env = NULL; + } + nimble_platform_mem_free(ble_gattc_cache_static_vars); + ble_gattc_cache_static_vars = NULL; + } +} +#endif + int ble_gattc_cache_init(void *storage_cb) { + int rc = 0; + cache_handle_t fp; + uint8_t num_addr; + size_t length = MAX_ADDR_LIST_CACHE_BUF; + uint8_t *p_buf = NULL; + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + rc = ble_gattc_cache_static_vars_init(); + if (rc != 0) { + return rc; + } +#endif + /* Point where to store data */ cache_fn = link_storage_fn(storage_cb); - cache_handle_t fp; - int rc = 0; - uint8_t num_addr; - size_t length = MAX_ADDR_LIST_CACHE_BUF; - svc_end_handle = 0; - uint8_t *p_buf = nimble_platform_mem_malloc(MAX_ADDR_LIST_CACHE_BUF); + p_buf = nimble_platform_mem_calloc(1,MAX_ADDR_LIST_CACHE_BUF); if (p_buf == NULL) { BLE_HS_LOG(ERROR, "%s malloc failed!", __func__); rc = BLE_HS_ENOMEM; - return rc; + goto error; } - cache_env = (cache_env_t *)nimble_platform_mem_malloc(sizeof(cache_env_t)); + cache_env = (cache_env_t *)nimble_platform_mem_calloc(1,sizeof(cache_env_t)); if (cache_env == NULL) { BLE_HS_LOG(ERROR, "%s malloc failed!", __func__); - nimble_platform_mem_free(p_buf); rc = BLE_HS_ENOMEM; - return rc; + goto error; } memset(cache_env, 0x0, sizeof(cache_env_t)); @@ -855,8 +931,7 @@ ble_gattc_cache_init(void *storage_cb) BLE_HS_LOG(DEBUG, "%s, Line = %d, storage flash get blob data fail, err_code = 0x%x", __func__, __LINE__, rc); } - nimble_platform_mem_free(p_buf); - return rc; + goto error; } num_addr = length / (sizeof(ble_addr_t) + sizeof(uint8_t) * 16); @@ -880,11 +955,28 @@ ble_gattc_cache_init(void *storage_cb) } else { BLE_HS_LOG(ERROR, "%s, Line = %d, storage flash open fail, err_code = %x", __func__, __LINE__, rc); - nimble_platform_mem_free(p_buf); - return rc; + goto error; } nimble_platform_mem_free(p_buf); return 0; +error: + if (p_buf) { + nimble_platform_mem_free(p_buf); + p_buf = NULL; + } + if (cache_env) { + nimble_platform_mem_free(cache_env); + cache_env = NULL; + } + + #if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gattc_cache_static_vars) { + nimble_platform_mem_free(ble_gattc_cache_static_vars); + ble_gattc_cache_static_vars = NULL; + } +#endif + + return rc; } #endif /* MYNEWT_VAL(BLE_GATT_CACHING) */ diff --git a/nimble/host/src/ble_gattc_cache_conn.c b/nimble/host/src/ble_gattc_cache_conn.c index f3e11b05d..81171535c 100644 --- a/nimble/host/src/ble_gattc_cache_conn.c +++ b/nimble/host/src/ble_gattc_cache_conn.c @@ -87,6 +87,10 @@ break; \ } #define BLE_SVC_GATT_CHR_SERVICE_CHANGED_UUID16 0x2a05 + +SLIST_HEAD(ble_gattc_cache_conn_struct, ble_gattc_cache_conn); + +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) static void *ble_gattc_cache_conn_svc_mem; static struct os_mempool ble_gattc_cache_conn_svc_pool; @@ -103,8 +107,52 @@ static struct os_mempool ble_gattc_cache_conn_dsc_pool; static void *ble_gattc_cache_conn_mem; static struct os_mempool ble_gattc_cache_conn_pool; + static SLIST_HEAD(, ble_gattc_cache_conn) ble_gattc_cache_conns; +static struct ble_gatt_error ble_gattc_cache_conn_error; +#endif + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +typedef struct { + void *_ble_gattc_cache_conn_svc_mem; + struct os_mempool _ble_gattc_cache_conn_svc_pool; + +#if MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES) + void *_ble_gattc_cache_conn_incl_svc_mem; + struct os_mempool _ble_gattc_cache_conn_incl_svc_pool; +#endif + + void *_ble_gattc_cache_conn_chr_mem; + struct os_mempool _ble_gattc_cache_conn_chr_pool; + + void *_ble_gattc_cache_conn_dsc_mem; + struct os_mempool _ble_gattc_cache_conn_dsc_pool; + + void *_ble_gattc_cache_conn_mem; + struct os_mempool _ble_gattc_cache_conn_pool; + + SLIST_HEAD(, ble_gattc_cache_conn) _ble_gattc_cache_conns; + + struct ble_gatt_error _ble_gattc_cache_conn_error; +} ble_gattc_cache_conn_static_vars_t; + +static ble_gattc_cache_conn_static_vars_t * ble_gattc_cache_conn_static_vars = NULL; + +#define ble_gattc_cache_conn_svc_mem (ble_gattc_cache_conn_static_vars->_ble_gattc_cache_conn_svc_mem) +#define ble_gattc_cache_conn_svc_pool (ble_gattc_cache_conn_static_vars->_ble_gattc_cache_conn_svc_pool) +#define ble_gattc_cache_conn_incl_svc_mem (ble_gattc_cache_conn_static_vars->_ble_gattc_cache_conn_incl_svc_mem) +#define ble_gattc_cache_conn_incl_svc_pool (ble_gattc_cache_conn_static_vars->_ble_gattc_cache_conn_incl_svc_pool) +#define ble_gattc_cache_conn_chr_mem (ble_gattc_cache_conn_static_vars->_ble_gattc_cache_conn_chr_mem) +#define ble_gattc_cache_conn_chr_pool (ble_gattc_cache_conn_static_vars->_ble_gattc_cache_conn_chr_pool) +#define ble_gattc_cache_conn_dsc_mem (ble_gattc_cache_conn_static_vars->_ble_gattc_cache_conn_dsc_mem) +#define ble_gattc_cache_conn_dsc_pool (ble_gattc_cache_conn_static_vars->_ble_gattc_cache_conn_dsc_pool) +#define ble_gattc_cache_conn_mem (ble_gattc_cache_conn_static_vars->_ble_gattc_cache_conn_mem) +#define ble_gattc_cache_conn_pool (ble_gattc_cache_conn_static_vars->_ble_gattc_cache_conn_pool) +#define ble_gattc_cache_conns (ble_gattc_cache_conn_static_vars->_ble_gattc_cache_conns) +#define ble_gattc_cache_conn_error (ble_gattc_cache_conn_static_vars->_ble_gattc_cache_conn_error) +#endif + static struct ble_gattc_cache_conn_svc * ble_gattc_cache_conn_svc_find_range(struct ble_gattc_cache_conn *ble_gattc_cache_conn, uint16_t attr_handle); @@ -136,11 +184,41 @@ static void ble_gattc_cache_conn_disc_dscs(struct ble_gattc_cache_conn *peer); #endif +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void +ble_gattc_cache_conn_free_mem(void); + +static ble_gattc_cache_conn_static_vars_t * +ble_gattc_cache_conn_static_vars_init(void) +{ + if (ble_gattc_cache_conn_static_vars == NULL) { + ble_gattc_cache_conn_static_vars = + nimble_platform_mem_calloc(1, sizeof(ble_gattc_cache_conn_static_vars_t)); + if (ble_gattc_cache_conn_static_vars == NULL) { + return NULL; + } + } + + return ble_gattc_cache_conn_static_vars; +} +#endif + struct ble_gattc_cache_conn * ble_gattc_cache_conn_find(uint16_t conn_handle) { struct ble_gattc_cache_conn *ble_gattc_cache_conn; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gattc_cache_conn_static_vars == NULL) { + if (ble_gattc_cache_conn_static_vars_init() == NULL) { + return NULL; + } + SLIST_INIT(&ble_gattc_cache_conn_static_vars->_ble_gattc_cache_conns); + } + else if (SLIST_FIRST(&ble_gattc_cache_conns) == NULL) { + SLIST_INIT(&ble_gattc_cache_conns); + } +#endif SLIST_FOREACH(ble_gattc_cache_conn, &ble_gattc_cache_conns, next) { if (ble_gattc_cache_conn->conn_handle == conn_handle) { return ble_gattc_cache_conn; @@ -1388,6 +1466,10 @@ ble_gattc_cache_conn_broken(uint16_t conn_handle) } os_memblock_put(&ble_gattc_cache_conn_pool, conn); + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + ble_gattc_cache_conn_free_mem(); +#endif } void @@ -2123,6 +2205,9 @@ ble_gattc_cache_conn_get_svc_changed_handle(uint16_t conn_handle) void ble_gattc_cache_conn_free_mem(void) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gattc_cache_conn_static_vars != NULL) { +#endif if (ble_gattc_cache_conn_mem) { nimble_platform_mem_free(ble_gattc_cache_conn_mem); ble_gattc_cache_conn_mem = NULL; @@ -2149,6 +2234,19 @@ ble_gattc_cache_conn_free_mem(void) nimble_platform_mem_free(ble_gattc_cache_conn_dsc_mem); ble_gattc_cache_conn_dsc_mem = NULL; } + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + } +#endif + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gattc_cache_conn_static_vars != NULL) { + nimble_platform_mem_free(ble_gattc_cache_conn_static_vars); + ble_gattc_cache_conn_static_vars = NULL; + } + + ble_gattc_cache_free_mem(); +#endif } int @@ -2178,6 +2276,15 @@ ble_gattc_cache_conn_init() /* Free memory first in case this function gets called more than once. */ ble_gattc_cache_conn_free_mem(); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gattc_cache_conn_static_vars == NULL) { + if (ble_gattc_cache_conn_static_vars_init() == NULL) { + rc = BLE_HS_ENOMEM; + goto err; + } + } +#endif + #if !MYNEWT_VAL(MP_RUNTIME_ALLOC) ble_gattc_cache_conn_mem = nimble_platform_mem_malloc( OS_MEMPOOL_BYTES(max_ble_gattc_cache_conns, sizeof(struct ble_gattc_cache_conn))); @@ -2283,16 +2390,14 @@ err: static struct ble_gatt_error * ble_gattc_cache_error(int status, uint16_t att_handle) { - static struct ble_gatt_error error; - /* For consistency, always indicate a handle of 0 on success. */ if (status == 0 || status == BLE_HS_EDONE) { att_handle = 0; } - error.status = status; - error.att_handle = att_handle; - return &error; + ble_gattc_cache_conn_error.status = status; + ble_gattc_cache_conn_error.att_handle = att_handle; + return &ble_gattc_cache_conn_error; } /* gattc discovery apis */ diff --git a/nimble/host/src/ble_gattc_cache_priv.h b/nimble/host/src/ble_gattc_cache_priv.h index 7dde2192d..6330629de 100644 --- a/nimble/host/src/ble_gattc_cache_priv.h +++ b/nimble/host/src/ble_gattc_cache_priv.h @@ -284,6 +284,9 @@ uint16_t ble_gattc_cache_conn_get_svc_changed_handle(uint16_t conn_handle); /* cache store */ void ble_gattc_cache_save(struct ble_gattc_cache_conn *peer, size_t num_attr); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void ble_gattc_cache_free_mem(void); +#endif int ble_gattc_cache_init(void *storage_cb); int ble_gattc_cache_load(ble_addr_t peer_addr); int ble_gattc_cache_check_hash(struct ble_gattc_cache_conn *peer, struct os_mbuf *om); diff --git a/nimble/host/src/ble_gatts.c b/nimble/host/src/ble_gatts.c index eb15e7a3b..4a865956a 100644 --- a/nimble/host/src/ble_gatts.c +++ b/nimble/host/src/ble_gatts.c @@ -35,6 +35,10 @@ #if MYNEWT_VAL(BLE_SVC_HID_SERVICE) #include "services/hid/ble_svc_hid.h" #endif +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +/* Declaration for de-init API */ +#include "services/sps/ble_svc_sps.h" +#endif #define BLE_GATTS_INCLUDE_SZ 6 #define BLE_GATTS_CHR_MAX_SZ 19 @@ -49,8 +53,12 @@ enum { #if MYNEWT_VAL(BLE_GATT_CACHING) /* store the aware state only for the bonded peers */ +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +struct ble_gatts_aware_state * ble_gatts_conn_aware_states; +#else struct ble_gatts_aware_state ble_gatts_conn_aware_states[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; #endif +#endif #if MYNEWT_VAL(BLE_GATTS) static const ble_uuid_t *uuid_pri = @@ -63,18 +71,14 @@ static const ble_uuid_t *uuid_chr = BLE_UUID16_DECLARE(BLE_ATT_UUID_CHARACTERISTIC); static const ble_uuid_t *uuid_ccc = BLE_UUID16_DECLARE(BLE_GATT_DSC_CLT_CFG_UUID16); +#if MYNEWT_VAL(BLE_CPFD_CAFD) static const ble_uuid_t *uuid_cpf = BLE_UUID16_DECLARE(BLE_GATT_DSC_CLT_PRE_FMT16); static const ble_uuid_t *uuid_caf = BLE_UUID16_DECLARE(BLE_GATT_DSC_CLT_AGG_FMT16); +#endif static const struct ble_gatt_svc_def **ble_gatts_svc_defs; -static int ble_gatts_num_svc_defs; - -#if MYNEWT_VAL(BLE_GATT_CACHING) -/* index of latest bonded peer */ -static int last_conn_aware_state_index; -#endif struct ble_gatts_svc_entry { #if MYNEWT_VAL(BLE_DYNAMIC_SERVICE) @@ -85,8 +89,72 @@ struct ble_gatts_svc_entry { uint16_t end_group_handle; /* 0xffff means unset. */ }; +#if !MYNEWT_VAL(BLE_DYNAMIC_SERVICE) +struct ble_gatts_clt_cfg { + uint16_t chr_val_handle; + uint8_t flags; + uint8_t allowed; +}; +#endif + #if MYNEWT_VAL(BLE_DYNAMIC_SERVICE) STAILQ_HEAD(ble_gatts_svc_entry_list, ble_gatts_svc_entry); +#endif + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +typedef struct { + int _ble_gatts_num_svc_defs; + +#if MYNEWT_VAL(BLE_GATT_CACHING) + /* index of latest bonded peer */ + int _last_conn_aware_state_index; +#endif + +#if MYNEWT_VAL(BLE_DYNAMIC_SERVICE) + struct ble_gatts_svc_entry_list _ble_gatts_svc_entries; + void *_ble_gatts_svc_entry_mem; + struct os_mempool _ble_gatts_svc_entry_pool; +#else + struct ble_gatts_svc_entry *_ble_gatts_svc_entries; + uint16_t _ble_gatts_num_svc_entries; +#endif + + os_membuf_t *_ble_gatts_clt_cfg_mem; + struct os_mempool _ble_gatts_clt_cfg_pool; + +#if MYNEWT_VAL(BLE_DYNAMIC_SERVICE) + /** A cached list of handles for the configurable characteristics. */ + struct ble_gatts_clt_cfg_list _ble_gatts_clt_cfgs; +#else + struct ble_gatts_clt_cfg *_ble_gatts_clt_cfgs; +#endif + + int _ble_gatts_num_cfgable_chrs; +} ble_gatts_static_vars_t; + +static ble_gatts_static_vars_t * ble_gatts_static_vars = NULL; + +#define ble_gatts_num_svc_defs (ble_gatts_static_vars->_ble_gatts_num_svc_defs) +#define last_conn_aware_state_index (ble_gatts_static_vars->_last_conn_aware_state_index) +#define ble_gatts_svc_entries (ble_gatts_static_vars->_ble_gatts_svc_entries) +#define ble_gatts_svc_entry_mem (ble_gatts_static_vars->_ble_gatts_svc_entry_mem) +#define ble_gatts_svc_entry_pool (ble_gatts_static_vars->_ble_gatts_svc_entry_pool) +#define ble_gatts_num_svc_entries (ble_gatts_static_vars->_ble_gatts_num_svc_entries) +#define ble_gatts_clt_cfg_mem (ble_gatts_static_vars->_ble_gatts_clt_cfg_mem) +#define ble_gatts_clt_cfg_pool (ble_gatts_static_vars->_ble_gatts_clt_cfg_pool) +#define ble_gatts_clt_cfgs (ble_gatts_static_vars->_ble_gatts_clt_cfgs) +#define ble_gatts_num_cfgable_chrs (ble_gatts_static_vars->_ble_gatts_num_cfgable_chrs) +#endif /* MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) */ + +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +static int ble_gatts_num_svc_defs; + +#if MYNEWT_VAL(BLE_GATT_CACHING) +/* index of latest bonded peer */ +static int last_conn_aware_state_index; +#endif + +#if MYNEWT_VAL(BLE_DYNAMIC_SERVICE) static struct ble_gatts_svc_entry_list ble_gatts_svc_entries; static void *ble_gatts_svc_entry_mem; static struct os_mempool ble_gatts_svc_entry_pool; @@ -102,16 +170,12 @@ static struct os_mempool ble_gatts_clt_cfg_pool; /** A cached list of handles for the configurable characteristics. */ static struct ble_gatts_clt_cfg_list ble_gatts_clt_cfgs; #else -struct ble_gatts_clt_cfg { - uint16_t chr_val_handle; - uint8_t flags; - uint8_t allowed; -}; - /** A cached array of handles for the configurable characteristics. */ static struct ble_gatts_clt_cfg *ble_gatts_clt_cfgs; #endif + static int ble_gatts_num_cfgable_chrs; +#endif /* !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) */ STATS_SECT_DECL(ble_gatts_stats) ble_gatts_stats; STATS_NAME_START(ble_gatts_stats) @@ -127,6 +191,26 @@ STATS_NAME_START(ble_gatts_stats) STATS_NAME(ble_gatts_stats, dsc_writes) STATS_NAME_END(ble_gatts_stats) + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +static int +ble_gatts_ensure_ctx(void) +{ + if (ble_gatts_static_vars) { + return 0; + } + + ble_gatts_static_vars = nimble_platform_mem_calloc(1, sizeof(ble_gatts_static_vars_t)); + + if (!ble_gatts_static_vars) { + return BLE_HS_ENOMEM; + } + + return 0; +} +#endif + + #if MYNEWT_VAL(BLE_DYNAMIC_SERVICE) static struct ble_gatts_svc_entry * ble_gatts_svc_entry_alloc(void) @@ -137,7 +221,7 @@ ble_gatts_svc_entry_alloc(void) #if !MYNEWT_VAL(MP_RUNTIME_ALLOC) /* if dynamic services are enabled, try to allocate from heap */ if (entry == NULL) { - entry = nimble_platform_mem_malloc(sizeof *entry); + entry = nimble_platform_mem_calloc(1,sizeof *entry); } #endif if (entry != NULL) { @@ -158,6 +242,7 @@ ble_gatts_svc_entry_free(struct ble_gatts_svc_entry *entry) } else { nimble_platform_mem_free(entry); + entry = NULL; } #endif } @@ -168,15 +253,17 @@ ble_gatts_clt_cfg_alloc(void) struct ble_gatts_clt_cfg *cfg; cfg = os_memblock_get(&ble_gatts_clt_cfg_pool); + #if !MYNEWT_VAL(MP_RUNTIME_ALLOC) /* if dynamic services are enabled, try to allocate from heap */ if (cfg == NULL) { - cfg = nimble_platform_mem_malloc(sizeof *cfg); + cfg = nimble_platform_mem_calloc(1,sizeof *cfg); } #endif if (cfg != NULL) { memset(cfg, 0, sizeof *cfg); } + return cfg; } @@ -188,9 +275,9 @@ ble_gatts_clt_cfg_free(struct ble_gatts_clt_cfg *cfg) #else if (os_memblock_from(&ble_gatts_clt_cfg_pool, cfg)) { os_memblock_put(&ble_gatts_clt_cfg_pool, cfg); - } - else { + } else { nimble_platform_mem_free(cfg); + cfg = NULL; } #endif } @@ -639,7 +726,7 @@ ble_gatts_calculate_hash(uint8_t *out_hash_key) if(rc != 0) { return rc; } - buf = nimble_platform_mem_malloc(sizeof(uint8_t) * size); + buf = nimble_platform_mem_calloc(1,sizeof(uint8_t) * size); if(buf == NULL) { rc = BLE_HS_ENOMEM; return rc; @@ -787,6 +874,7 @@ ble_gatts_register_dsc(const struct ble_gatt_svc_def *svc, } +#if MYNEWT_VAL(BLE_CPFD_CAFD) static int ble_gatts_cpfd_is_sane(const struct ble_gatt_cpfd *cpfd) { @@ -813,15 +901,17 @@ ble_gatts_cpfd_is_sane(const struct ble_gatt_cpfd *cpfd) return 1; } +#endif + #if MYNEWT_VAL(BLE_DYNAMIC_SERVICE) static struct ble_gatts_clt_cfg * -ble_gatts_clt_cfg_find(struct ble_gatts_clt_cfg_list *ble_gatts_clt_cfgs, +ble_gatts_clt_cfg_find(struct ble_gatts_clt_cfg_list *ble_gatts_clt_cfgs_local, uint16_t chr_val_handle) { struct ble_gatts_clt_cfg *cfg; - STAILQ_FOREACH(cfg, ble_gatts_clt_cfgs, next) { + STAILQ_FOREACH(cfg, ble_gatts_clt_cfgs_local, next) { if (cfg->chr_val_handle == chr_val_handle) { return cfg; } @@ -1057,6 +1147,7 @@ ble_gatts_register_clt_cfg_dsc(uint16_t *att_handle, uint8_t cccd_flags) return 0; } +#if MYNEWT_VAL(BLE_CPFD_CAFD) static int ble_gatts_cafd_access(uint16_t conn_handle, uint16_t attr_handle, uint8_t op, uint16_t offset, struct os_mbuf **om, @@ -1159,7 +1250,7 @@ ble_gatts_register_cpfds(const struct ble_gatt_cpfd *cpfds) return 0; } - +#endif static int ble_gatts_register_chr(const struct ble_gatt_svc_def *svc, @@ -1229,12 +1320,13 @@ ble_gatts_register_chr(const struct ble_gatt_svc_def *svc, } BLE_HS_DBG_ASSERT(dsc_handle == def_handle + 2); } - +#if MYNEWT_VAL(BLE_CPFD_CAFD) /* Register each Client Presentation Format Descriptor. */ rc = ble_gatts_register_cpfds(chr->cpfd); if (rc != 0) { return rc; } +#endif /* Register each descriptor. */ if (chr->descriptors != NULL) { @@ -1444,6 +1536,10 @@ ble_gatts_register_svcs(const struct ble_gatt_svc_def *svcs, int i; #if MYNEWT_VAL(BLE_DYNAMIC_SERVICE) struct ble_gatts_svc_entry *entry; + + if (STAILQ_EMPTY(&ble_gatts_svc_entries)) { + STAILQ_INIT(&ble_gatts_svc_entries); + } #else int idx; #endif @@ -1600,6 +1696,7 @@ ble_gatts_connection_broken(uint16_t conn_handle) } rc = os_memblock_put(&ble_gatts_clt_cfg_pool, clt_cfgs); + BLE_HS_DBG_ASSERT_EVAL(rc == 0); } #endif @@ -1608,15 +1705,22 @@ ble_gatts_connection_broken(uint16_t conn_handle) static void ble_gatts_free_svc_defs(void) { - nimble_platform_mem_free(ble_gatts_svc_defs); - ble_gatts_svc_defs = NULL; - ble_gatts_num_svc_defs = 0; + if (ble_gatts_svc_defs) { + nimble_platform_mem_free(ble_gatts_svc_defs); + ble_gatts_svc_defs = NULL; + } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gatts_static_vars != NULL) { +#endif + ble_gatts_num_svc_defs = 0; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + } +#endif } static void ble_gatts_free_mem(void) { - #if MYNEWT_VAL(BLE_DYNAMIC_SERVICE) struct ble_gatts_svc_entry *entry; struct ble_gatts_clt_cfg *clt_cfg; @@ -1629,8 +1733,14 @@ ble_gatts_free_mem(void) } } #endif - nimble_platform_mem_free(ble_gatts_clt_cfg_mem); - ble_gatts_clt_cfg_mem = NULL; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_hs_max_client_configs > 0) { +#endif + nimble_platform_mem_free(ble_gatts_clt_cfg_mem); + ble_gatts_clt_cfg_mem = NULL; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + } +#endif #if MYNEWT_VAL(BLE_DYNAMIC_SERVICE) /* free services memory */ @@ -1641,30 +1751,60 @@ ble_gatts_free_mem(void) ble_gatts_svc_entry_free(entry); } } - nimble_platform_mem_free(ble_gatts_svc_entry_mem); - ble_gatts_svc_entry_mem = NULL; + if (ble_gatts_svc_entry_mem) { + nimble_platform_mem_free(ble_gatts_svc_entry_mem); + ble_gatts_svc_entry_mem = NULL; + } #else - nimble_platform_mem_free(ble_gatts_svc_entries); - ble_gatts_svc_entries = NULL; - ble_gatts_num_svc_entries = 0; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_hs_max_services > 0) { +#endif + nimble_platform_mem_free(ble_gatts_svc_entries); + ble_gatts_svc_entries = NULL; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + } +#endif + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gatts_static_vars != NULL) { +#endif + ble_gatts_num_svc_entries = 0; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + } +#endif + #endif } - void ble_gatts_stop(void) { + ble_gatts_free_mem(); 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(); #if MYNEWT_VAL(MP_RUNTIME_ALLOC) ble_att_svr_reset(); #endif ble_att_svr_stop(); + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gatts_static_vars != NULL) { + nimble_platform_mem_free(ble_gatts_static_vars); + ble_gatts_static_vars = NULL; + } + +#if MYNEWT_VAL(BLE_GATT_CACHING) + if (ble_gatts_conn_aware_states) { + nimble_platform_mem_free(ble_gatts_conn_aware_states); + ble_gatts_conn_aware_states = NULL; + } +#endif +#endif + } int @@ -1675,6 +1815,12 @@ ble_gatts_start(void) uint16_t allowed_flags; ble_uuid16_t uuid = BLE_UUID16_INIT(BLE_ATT_UUID_CHARACTERISTIC); int num_elems; +#if MYNEWT_VAL(BLE_DYNAMIC_SERVICE) + if (STAILQ_EMPTY(&ble_gatts_clt_cfgs)) { + STAILQ_INIT(&ble_gatts_clt_cfgs); + } +#endif + #if MYNEWT_VAL(BLE_DYNAMIC_SERVICE) struct ble_gatts_clt_cfg *clt_cfg; #else @@ -1696,9 +1842,28 @@ ble_gatts_start(void) goto done; } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gatts_ensure_ctx()) { + rc = BLE_HS_ENOMEM; + goto done; + } +#endif + +#if MYNEWT_VAL(BLE_GATT_CACHING) +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gatts_conn_aware_states == NULL) { + ble_gatts_conn_aware_states = nimble_platform_mem_calloc(1, sizeof(struct ble_gatts_aware_state) * MYNEWT_VAL(BLE_STORE_MAX_BONDS)); + } +#else + memset(ble_gatts_conn_aware_states, 0, sizeof ble_gatts_conn_aware_states); +#endif + + last_conn_aware_state_index = 0; +#endif + #if !MYNEWT_VAL(MP_RUNTIME_ALLOC) if (ble_hs_max_client_configs > 0) { - ble_gatts_clt_cfg_mem = nimble_platform_mem_malloc( + ble_gatts_clt_cfg_mem = nimble_platform_mem_calloc(1, OS_MEMPOOL_BYTES(ble_hs_max_client_configs, sizeof (struct ble_gatts_clt_cfg))); if (ble_gatts_clt_cfg_mem == NULL) { @@ -1720,7 +1885,7 @@ ble_gatts_start(void) #endif #else ble_gatts_svc_entries = - nimble_platform_mem_malloc(ble_hs_max_services * sizeof *ble_gatts_svc_entries); + nimble_platform_mem_calloc(1,ble_hs_max_services * sizeof *ble_gatts_svc_entries); if (ble_gatts_svc_entries == NULL) { rc = BLE_HS_ENOMEM; goto done; @@ -1729,12 +1894,14 @@ ble_gatts_start(void) } #if MYNEWT_VAL(BLE_DYNAMIC_SERVICE) - rc = os_mempool_init(&ble_gatts_svc_entry_pool, ble_hs_max_services, - sizeof (struct ble_gatts_svc_entry), - ble_gatts_svc_entry_mem, "ble_gatts_svc_entry_pool"); - if (rc != 0) { - rc = BLE_HS_EOS; - goto done; + if (ble_hs_max_services > 0 ) { + rc = os_mempool_init(&ble_gatts_svc_entry_pool, ble_hs_max_services, + sizeof (struct ble_gatts_svc_entry), + ble_gatts_svc_entry_mem, "ble_gatts_svc_entry_pool"); + if (rc != 0) { + rc = BLE_HS_EOS; + goto done; + } } #else @@ -1759,15 +1926,18 @@ ble_gatts_start(void) /* Initialize client-configuration memory pool. */ #if MYNEWT_VAL(BLE_DYNAMIC_SERVICE) num_elems = ble_hs_max_client_configs; + rc = os_mempool_init(&ble_gatts_clt_cfg_pool, num_elems, - sizeof(struct ble_gatts_clt_cfg), - ble_gatts_clt_cfg_mem, - "ble_gatts_clt_cfg_pool"); + sizeof(struct ble_gatts_clt_cfg), + ble_gatts_clt_cfg_mem, + "ble_gatts_clt_cfg_pool"); #else num_elems = ble_hs_max_client_configs / ble_gatts_num_cfgable_chrs; + rc = os_mempool_init(&ble_gatts_clt_cfg_pool, num_elems, - ble_gatts_clt_cfg_size(), ble_gatts_clt_cfg_mem, + ble_gatts_clt_cfg_size(), ble_gatts_clt_cfg_mem, "ble_gatts_clt_cfg_pool"); + #endif if (rc != 0) { rc = BLE_HS_EOS; @@ -1778,7 +1948,9 @@ ble_gatts_start(void) /* Allocate the cached array of handles for the configuration * characteristics. */ + ble_gatts_clt_cfgs = os_memblock_get(&ble_gatts_clt_cfg_pool); + if (ble_gatts_clt_cfgs == NULL) { rc = BLE_HS_ENOMEM; goto done; @@ -1830,6 +2002,12 @@ done: int ble_gatts_conn_can_alloc(void) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gatts_ensure_ctx()) { + return 0; + } +#endif + return ble_gatts_num_cfgable_chrs == 0 || ble_gatts_clt_cfg_pool.mp_num_free > 0; } @@ -1876,7 +2054,8 @@ done: #else if (ble_gatts_num_cfgable_chrs > 0) { gatts_conn->clt_cfgs = os_memblock_get(&ble_gatts_clt_cfg_pool); - if (gatts_conn->clt_cfgs == NULL) { + + if (gatts_conn->clt_cfgs == NULL) { return BLE_HS_ENOMEM; } @@ -2443,7 +2622,9 @@ ble_gatts_bonding_established(uint16_t conn_handle) #endif #if MYNEWT_VAL(BLE_GATT_CACHING) struct ble_hs_conn_addrs addrs; +#if (MYNEWT_VAL(BLE_STORE_MAX_BONDS) > 0) int new_idx; +#endif #endif ble_hs_lock(); @@ -2496,16 +2677,23 @@ ble_gatts_bonding_established(uint16_t conn_handle) /* store the bonded peer aware_state if space not available delete the oldest bond */ - ble_hs_conn_addrs(conn, &addrs); - new_idx = (last_conn_aware_state_index + 1) % - MYNEWT_VAL(BLE_STORE_MAX_BONDS); - memset(&ble_gatts_conn_aware_states[new_idx], 0, - sizeof(struct ble_gatts_aware_state)); - memcpy(ble_gatts_conn_aware_states[new_idx].peer_id_addr, - addrs.peer_id_addr.val, sizeof addrs.peer_id_addr.val); - ble_gatts_conn_aware_states[new_idx].aware = conn->bhc_gatt_svr.aware_state; - ble_gatts_conn_aware_states[new_idx].half_aware = conn->bhc_gatt_svr.half_aware; - last_conn_aware_state_index = new_idx; +#if (MYNEWT_VAL(BLE_STORE_MAX_BONDS) > 0) + ble_hs_conn_addrs(conn, &addrs); + new_idx = (last_conn_aware_state_index + 1) % + MYNEWT_VAL(BLE_STORE_MAX_BONDS); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gatts_conn_aware_states == NULL) { + ble_gatts_conn_aware_states = nimble_platform_mem_calloc(1, sizeof(struct ble_gatts_aware_state) * MYNEWT_VAL(BLE_STORE_MAX_BONDS)); + } +#endif + memset(&ble_gatts_conn_aware_states[new_idx], 0, + sizeof(struct ble_gatts_aware_state)); + memcpy(ble_gatts_conn_aware_states[new_idx].peer_id_addr, + addrs.peer_id_addr.val, sizeof addrs.peer_id_addr.val); + ble_gatts_conn_aware_states[new_idx].aware = conn->bhc_gatt_svr.aware_state; + ble_gatts_conn_aware_states[new_idx].half_aware = conn->bhc_gatt_svr.half_aware; + last_conn_aware_state_index = new_idx; +#endif #endif ble_hs_unlock(); } @@ -2870,11 +3058,11 @@ static int ble_gatts_update_conn_clt_cfg(struct ble_hs_conn *conn, void *arg) { } return 0; } -static struct ble_gatts_clt_cfg * ble_gatts_get_last_cfg(struct ble_gatts_clt_cfg_list *ble_gatts_clt_cfgs) +static struct ble_gatts_clt_cfg * ble_gatts_get_last_cfg(struct ble_gatts_clt_cfg_list *ble_gatts_clt_cfgs_local) { struct ble_gatts_clt_cfg *cfg, *prev; prev = NULL; - STAILQ_FOREACH(cfg, ble_gatts_clt_cfgs, next) { + STAILQ_FOREACH(cfg, ble_gatts_clt_cfgs_local, next) { prev = cfg; } return prev; @@ -2892,7 +3080,7 @@ int ble_gatts_add_dynamic_svcs(const struct ble_gatt_svc_def *svcs) { uint16_t arg[3]; uint16_t start_handle, end_handle; - p = nimble_platform_mem_malloc(sizeof *ble_gatts_svc_defs); + p = nimble_platform_mem_calloc(1,sizeof *ble_gatts_svc_defs); if (p == NULL) { rc = BLE_HS_ENOMEM; goto done; @@ -3064,7 +3252,14 @@ ble_gatts_add_svcs(const struct ble_gatt_svc_def *svcs) goto done; } - p = realloc(ble_gatts_svc_defs, +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gatts_ensure_ctx()) { + rc = BLE_HS_ENOMEM; + goto done; + } +#endif + + p = nimble_platform_mem_realloc(ble_gatts_svc_defs, (ble_gatts_num_svc_defs + 1) * sizeof *ble_gatts_svc_defs); if (p == NULL) { rc = BLE_HS_ENOMEM; @@ -3150,7 +3345,9 @@ ble_gatts_count_resources(const struct ble_gatt_svc_def *svcs, int i; int c; int d; +#if MYNEWT_VAL(BLE_CPFD_CAFD) int pf; +#endif for (s = 0; svcs[s].type != BLE_GATT_SVC_TYPE_END; s++) { svc = svcs + s; @@ -3225,7 +3422,7 @@ ble_gatts_count_resources(const struct ble_gatt_svc_def *svcs, res->attrs++; } } - +#if MYNEWT_VAL(BLE_CPFD_CAFD) if (chr->cpfd != NULL) { for (pf = 0; chr->cpfd[pf].format != 0; pf++) { if (!ble_gatts_cpfd_is_sane(chr->cpfd + pf)) { @@ -3250,6 +3447,7 @@ ble_gatts_count_resources(const struct ble_gatt_svc_def *svcs, res->attrs++; } } +#endif } } } @@ -3277,11 +3475,18 @@ ble_gatts_count_cfg(const struct ble_gatt_svc_def *defs) return 0; } +#if MYNEWT_VAL(BLE_HOST_STATUS) int ble_gatts_get_cfgable_chrs(void) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gatts_static_vars == NULL) { + return 0; + } +#endif return ble_gatts_num_cfgable_chrs; } +#endif void ble_gatts_lcl_svc_foreach(ble_gatt_svc_foreach_fn cb, void *arg) @@ -3324,6 +3529,12 @@ ble_gatts_reset(void) struct ble_gatts_svc_entry *entry; #endif +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gatts_ensure_ctx()) { + return BLE_HS_ENOMEM; + } +#endif + ble_hs_lock(); if (!ble_gatts_mutable()) { @@ -3347,6 +3558,9 @@ ble_gatts_reset(void) #if MYNEWT_VAL(BLE_SVC_HID_SERVICE) ble_svc_hid_reset(); +#endif +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + ble_svc_sps_reset(); #endif ble_hs_unlock(); @@ -3358,6 +3572,12 @@ ble_gatts_init(void) { int rc; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_gatts_ensure_ctx()) { + return BLE_HS_ENOMEM; + } +#endif + ble_gatts_num_cfgable_chrs = 0; #if MYNEWT_VAL(BLE_DYNAMIC_SERVICE) STAILQ_INIT(&ble_gatts_clt_cfgs); @@ -3375,10 +3595,6 @@ ble_gatts_init(void) #if MYNEWT_VAL(BLE_DYNAMIC_SERVICE) STAILQ_INIT(&ble_gatts_svc_entries); #endif -#if MYNEWT_VAL(BLE_GATT_CACHING) - memset(ble_gatts_conn_aware_states, 0, sizeof ble_gatts_conn_aware_states); - last_conn_aware_state_index = 0; -#endif return 0; } diff --git a/nimble/host/src/ble_gatts_lcl.c b/nimble/host/src/ble_gatts_lcl.c index 8c71da3d3..7e636f81f 100644 --- a/nimble/host/src/ble_gatts_lcl.c +++ b/nimble/host/src/ble_gatts_lcl.c @@ -29,11 +29,13 @@ static const ble_uuid_t *uuid_ccc = BLE_UUID16_DECLARE(BLE_GATT_DSC_CLT_CFG_UUID16); +#if MYNEWT_VAL(BLE_CPFD_CAFD) static const ble_uuid_t *uuid_cpfd = BLE_UUID16_DECLARE(BLE_GATT_DSC_CLT_PRE_FMT16); static const ble_uuid_t *uuid_cafd = BLE_UUID16_DECLARE(BLE_GATT_DSC_CLT_AGG_FMT16); +#endif static const char * const ble_gatt_chr_f_names[] = { "BROADCAST", @@ -97,7 +99,6 @@ ble_gatts_flags_to_str(uint16_t flags, char *buf, return buf; } - #define STRINGIFY(X) #X #define FIELD_NAME_LEN STRINGIFY(12) #define FIELD_INDENT STRINGIFY(2) @@ -108,8 +109,10 @@ ble_gatt_show_local_chr(const struct ble_gatt_svc_def *svc, { const struct ble_gatt_chr_def *chr; const struct ble_gatt_dsc_def *dsc; +#if MYNEWT_VAL(BLE_CPFD_CAFD) const struct ble_gatt_cpfd *cpfd; int cpfd_count; +#endif for (chr = svc->characteristics; chr && chr->uuid; ++chr) { console_printf("characteristic\n"); @@ -145,6 +148,7 @@ ble_gatt_show_local_chr(const struct ble_gatt_svc_def *svc, handle++; } +#if MYNEWT_VAL(BLE_CPFD_CAFD) cpfd_count = 0; for (cpfd = chr->cpfd; cpfd && cpfd->format; ++cpfd) { console_printf("cpf descriptor\n"); @@ -178,6 +182,7 @@ ble_gatt_show_local_chr(const struct ble_gatt_svc_def *svc, flags_buf, ble_gatt_dsc_f_names)); handle++; } +#endif for (dsc = chr->descriptors; dsc && dsc->uuid; ++dsc) { console_printf("descriptor\n"); diff --git a/nimble/host/src/ble_hs.c b/nimble/host/src/ble_hs.c index 8d2a7f5e7..b3f875a9f 100644 --- a/nimble/host/src/ble_hs.c +++ b/nimble/host/src/ble_hs.c @@ -36,12 +36,25 @@ #include "hci_log/bt_hci_log.h" #endif // (BT_HCI_LOG_INCLUDED == TRUE) +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#include "host/ble_hs_hci.h" +#include "host/ble_sm.h" +#endif + #if MYNEWT_VAL(BLE_ISO) #include "host/ble_hs_iso.h" #endif /* MYNEWT_VAL(BLE_ISO) */ +#if MYNEWT_VAL(BLE_GATTS) && CONFIG_BT_NIMBLE_GAP_SERVICE +#include "services/gap/ble_svc_gap.h" +#endif + #include "esp_nimble_mem.h" +#if MYNEWT_VAL(BLE_HS_DEBUG) +#define MAX_NESTED_LOCKS 5 +#endif + #define BLE_HS_HCI_EVT_COUNT (MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT) + \ MYNEWT_VAL(BLE_TRANSPORT_EVT_DISCARDABLE_COUNT)) @@ -54,12 +67,84 @@ static void ble_hs_event_start_stage1(struct ble_npl_event *ev); static void ble_hs_event_start_stage2(struct ble_npl_event *ev); static void ble_hs_timer_sched(int32_t ticks_from_now); +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) struct os_mempool ble_hs_hci_ev_pool; /* It is not recommended to use MP_RUNTIME_ALLOC when the block size is 4 bytes. */ static os_membuf_t ble_hs_hci_os_event_buf[ OS_MEMPOOL_SIZE(BLE_HS_HCI_EVT_COUNT, sizeof (struct ble_npl_event)) ]; +#endif +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +typedef struct { + /* Shared queue that the host uses for work items. */ + struct ble_npl_eventq *ev_queue; /* event queue */ + + /* BLE event context */ + struct ble_npl_event ev_tx_notifications; /* TX pending notifications */ + struct ble_npl_event ev_reset; /* Full reset */ + struct ble_npl_event ev_start_stage1; /* Host start stage1 */ + struct ble_npl_event ev_start_stage2; /* Host start stage2 */ + + /* Synchronization context */ + struct ble_npl_callout timer; /* Timer for unresponsive timeouts */ + struct ble_mqueue rx_q; /* RX queue */ + struct ble_npl_mutex mutex; /* Mutex for shared resource protection */ + +#if MYNEWT_VAL(BLE_HS_DEBUG) + /* Debug context */ + TaskHandle_t task_handles[MAX_NESTED_LOCKS]; + int task_handle_index; + uint8_t mutex_locked; + uint8_t counter_lock; + TaskHandle_t task_handle; + uint8_t dbg_mutex_locked; +#endif + /* Reset and HCI memory pool */ + int reset_reason; + struct os_mempool hci_ev_pool; /* HCI event pool */ + os_membuf_t *hci_os_event_buf; /* HCI event buffer */ + void *parent_task; +} ble_hs_ctx_t; + +/* Global pointer to dynamic context */ +static ble_hs_ctx_t *ble_hs_ctx; + +/* Macros for easy access */ +#define ble_hs_evq (ble_hs_ctx->ev_queue) +#define ble_hs_ev_tx_notifications (ble_hs_ctx->ev_tx_notifications) +#define ble_hs_ev_reset (ble_hs_ctx->ev_reset) +#define ble_hs_ev_start_stage1 (ble_hs_ctx->ev_start_stage1) +#define ble_hs_ev_start_stage2 (ble_hs_ctx->ev_start_stage2) +#define ble_hs_timer (ble_hs_ctx->timer) +#define ble_hs_rx_q (ble_hs_ctx->rx_q) +#define ble_hs_mutex (ble_hs_ctx->mutex) + +#if MYNEWT_VAL(BLE_HS_DEBUG) +#define ble_hs_task_handles (ble_hs_ctx->task_handles) +#define ble_hs_task_handle_index (ble_hs_ctx->task_handle_index) +#define ble_hs_mutex_locked (ble_hs_ctx->mutex_locked) +#define counter_lock (ble_hs_ctx->counter_lock) +#define ble_hs_task_handle (ble_hs_ctx->task_handle) +#define ble_hs_dbg_mutex_locked (ble_hs_ctx->dbg_mutex_locked) +#endif //BLE_HS_DEBUG + +#define ble_hs_reset_reason (ble_hs_ctx->reset_reason) +#define ble_hs_hci_ev_pool (ble_hs_ctx->hci_ev_pool) +#define ble_hs_hci_os_event_buf (ble_hs_ctx->hci_os_event_buf) +#define ble_hs_parent_task (ble_hs_ctx->parent_task) + + +/** Pointer to BLE host state context */ +ble_hs_state_ctx_t *ble_hs_state_ctx; +uint8_t ble_hs_get_enabled_state(void) +{ + return (ble_hs_state_ctx) ? + ble_hs_state_ctx->enabled_state : 0; + +} + +#else /** OS event - triggers tx of pending notifications and indications. */ static struct ble_npl_event ble_hs_ev_tx_notifications; @@ -71,7 +156,15 @@ static struct ble_npl_event ble_hs_ev_start_stage2; uint8_t ble_hs_sync_state; uint8_t ble_hs_enabled_state; -static int ble_hs_reset_reason; +/** These values keep track of required ATT and GATT resources counts. They + * increase as services are added, and are read when the ATT server and GATT + * server are started. + */ +uint16_t ble_hs_max_attrs; +uint16_t ble_hs_max_services; +uint16_t ble_hs_max_client_configs; +static void *ble_hs_parent_task; +#endif // BLE_STATIC_TO_DYNAMIC #define BLE_HS_SYNC_RETRY_TIMEOUT_MS 100 /* ms */ @@ -83,38 +176,32 @@ extern void ble_hs_flow_init(void); extern void ble_hs_flow_deinit(void); extern void ble_monitor_deinit(void); -static void *ble_hs_parent_task; - -/** - * Handles unresponsive timeouts and periodic retries in case of resource - * shortage. - */ -static struct ble_npl_callout ble_hs_timer; - -/* Shared queue that the host uses for work items. */ -static struct ble_npl_eventq *ble_hs_evq; - -static struct ble_mqueue ble_hs_rx_q; - -static struct ble_npl_mutex ble_hs_mutex; - -/** These values keep track of required ATT and GATT resources counts. They - * increase as services are added, and are read when the ATT server and GATT - * server are started. - */ -uint16_t ble_hs_max_attrs; -uint16_t ble_hs_max_services; -uint16_t ble_hs_max_client_configs; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void ble_store_config_deinit(void); +extern void ble_hs_hci_ctx_free(void); +#endif +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) #if MYNEWT_VAL(BLE_HS_DEBUG) -#define MAX_NESTED_LOCKS 5 static TaskHandle_t ble_hs_task_handles[MAX_NESTED_LOCKS]; static int ble_hs_task_handle_index = 0; static uint8_t ble_hs_mutex_locked; static uint8_t counter_lock = 0; static TaskHandle_t ble_hs_task_handle; static uint8_t ble_hs_dbg_mutex_locked; -#endif +#endif // BLE_HS_DEBUG +static int ble_hs_reset_reason; +static struct ble_npl_eventq *ble_hs_evq; +/** + * Handles unresponsive timeouts and periodic retries in case of resource + * shortage. + */ +static struct ble_npl_callout ble_hs_timer; + +static struct ble_mqueue ble_hs_rx_q; + +static struct ble_npl_mutex ble_hs_mutex; +#endif // BLE_STATIC_TO_DYNAMIC STATS_SECT_DECL(ble_hs_stats) ble_hs_stats; STATS_NAME_START(ble_hs_stats) @@ -261,6 +348,7 @@ ble_hs_unlock(void) ble_hs_unlock_nested(); } +#if NIMBLE_BLE_CONNECT void ble_hs_process_rx_data_queue(void) { @@ -339,6 +427,7 @@ ble_hs_wakeup_tx(void) done: ble_hs_unlock(); } +#endif static void ble_hs_clear_rx_queue(void) @@ -385,12 +474,13 @@ ble_hs_sync(void) ble_hs_timer_sched(retry_tmo_ticks); if (rc == 0) { +#if NIMBLE_BLE_CONNECT rc = ble_hs_misc_restore_irks(); if (rc != 0) { BLE_HS_LOG(INFO, "Failed to restore IRKs from store; status=%d\n", rc); } - +#endif if (ble_hs_cfg.sync_cb != NULL) { ble_hs_cfg.sync_cb(); } @@ -434,7 +524,9 @@ ble_hs_reset(void) static void ble_hs_timer_exp(struct ble_npl_event *ev) { +#if NIMBLE_BLE_CONNECT int32_t ticks_until_next; +#endif switch (ble_hs_sync_state) { case BLE_HS_SYNC_STATE_GOOD: @@ -451,11 +543,10 @@ ble_hs_timer_exp(struct ble_npl_event *ev) ticks_until_next = ble_hs_conn_timer(); ble_hs_timer_sched(ticks_until_next); -#endif ticks_until_next = ble_gap_timer(); ble_hs_timer_sched(ticks_until_next); - +#endif break; case BLE_HS_SYNC_STATE_BAD: @@ -562,13 +653,13 @@ ble_hs_event_tx_notify(struct ble_npl_event *ev) ble_gatts_tx_notifications(); } #endif -#endif static void ble_hs_event_rx_data(struct ble_npl_event *ev) { ble_hs_process_rx_data_queue(); } +#endif static void ble_hs_event_reset(struct ble_npl_event *ev) @@ -613,6 +704,7 @@ ble_hs_enqueue_hci_event(uint8_t *hci_evt) struct ble_npl_event *ev; ev = os_memblock_get(&ble_hs_hci_ev_pool); + if (ev && ble_hs_evq->eventq) { memset (ev, 0, sizeof *ev); ble_npl_event_init(ev, ble_hs_event_rx_hci_ev, hci_evt); @@ -714,6 +806,7 @@ ble_hs_start(void) return 0; } +#if NIMBLE_BLE_CONNECT /** * Called when a data packet is received from the controller. This function * consumes the supplied mbuf, regardless of the outcome. @@ -777,19 +870,52 @@ ble_hs_tx_data(struct os_mbuf *om) return ble_transport_to_ll_acl(om); } +#endif void ble_hs_init(void) { int rc; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + size_t event_buf_size = OS_MEMPOOL_SIZE(BLE_HS_HCI_EVT_COUNT, sizeof(struct ble_npl_event)) * sizeof(os_membuf_t); + + if (!ble_hs_ctx) { + ble_hs_ctx = nimble_platform_mem_calloc(1, sizeof(*ble_hs_ctx)); + if (!ble_hs_ctx) { + MODLOG_DFLT(ERROR, "Failed to allocate ble_hs_ctx (%zu bytes)\n", sizeof(*ble_hs_ctx)); + return; + } + } + + if (!ble_hs_ctx->hci_os_event_buf) { + ble_hs_ctx->hci_os_event_buf = (os_membuf_t *)nimble_platform_mem_calloc(1, event_buf_size); + if (!ble_hs_ctx->hci_os_event_buf) { + MODLOG_DFLT(ERROR, "Failed to allocate memory for hci_os_event_buf (%zu bytes)\n", event_buf_size); + nimble_platform_mem_free(ble_hs_ctx); + ble_hs_ctx = NULL; + return; + } + } + + if (!ble_hs_state_ctx) { + ble_hs_state_ctx = nimble_platform_mem_calloc(1, sizeof(*ble_hs_state_ctx)); + if (!ble_hs_state_ctx) { + MODLOG_DFLT(ERROR, "Failed to allocate ble_hs_state_ctx (%zu bytes)\n", sizeof(*ble_hs_state_ctx)); + return; + } + } + + ble_hs_ctx->parent_task = NULL; +#endif + /* Ensure this function only gets called by sysinit. */ SYSINIT_ASSERT_ACTIVE(); - /* Create memory pool of OS events */ rc = os_mempool_init(&ble_hs_hci_ev_pool, BLE_HS_HCI_EVT_COUNT, sizeof (struct ble_npl_event), ble_hs_hci_os_event_buf, "ble_hs_hci_ev_pool"); + SYSINIT_PANIC_ASSERT(rc == 0); /* These get initialized here to allow unit tests to run without a zeroed @@ -812,8 +938,10 @@ ble_hs_init(void) ble_hs_hci_init(); +#if NIMBLE_BLE_CONNECT rc = ble_hs_conn_init(); SYSINIT_PANIC_ASSERT(rc == 0); +#endif #if MYNEWT_VAL(BLE_PERIODIC_ADV) rc = ble_hs_periodic_sync_init(); @@ -838,8 +966,10 @@ ble_hs_init(void) SYSINIT_PANIC_ASSERT(rc == 0); #endif +#if MYNEWT_VAL(BLE_GATTC) || MYNEWT_VAL(BLE_GATTS) rc = ble_gattc_init(); SYSINIT_PANIC_ASSERT(rc == 0); +#endif #if MYNEWT_VAL(BLE_GATT_CACHING) rc = ble_gattc_cache_conn_init(); @@ -854,7 +984,9 @@ ble_hs_init(void) ble_hs_stop_init(); +#if NIMBLE_BLE_CONNECT ble_mqueue_init(&ble_hs_rx_q, ble_hs_event_rx_data, NULL); +#endif rc = stats_init_and_reg( STATS_HDR(ble_hs_stats), STATS_SIZE_INIT_PARMS(ble_hs_stats, @@ -887,7 +1019,7 @@ ble_hs_init(void) #endif #endif /* Initialize npl variables related to hs flow control */ - ble_hs_flow_init(); + ble_hs_flow_init(); } /* Transport APIs for HS side */ @@ -898,11 +1030,13 @@ ble_transport_to_hs_evt_impl(void *buf) return ble_hs_hci_rx_evt(buf, NULL); } +#if NIMBLE_BLE_CONNECT int ble_transport_to_hs_acl_impl(struct os_mbuf *om) { return ble_hs_rx_data(om, NULL); } +#endif int ble_transport_to_hs_iso_impl(struct os_mbuf *om) @@ -950,6 +1084,27 @@ ble_hs_deinit(void) ble_npl_event_deinit(&ble_hs_ev_start_stage1); ble_npl_event_deinit(&ble_hs_ev_reset); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + ble_hs_conn_deinit(); + +#if NIMBLE_BLE_CONNECT +#if MYNEWT_VAL(BLE_GATTC) || MYNEWT_VAL(BLE_GATTS) + ble_gattc_deinit(); +#endif + + ble_l2cap_deinit(); + + ble_att_deinit(); +#endif + +#if MYNEWT_VAL(BLE_GATTS) + ble_att_svr_deinit(); +#endif + +#if NIMBLE_BLE_SM + ble_sm_deinit(); +#endif +#endif #if NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_GATTS) ble_npl_event_deinit(&ble_hs_ev_tx_notifications); @@ -962,4 +1117,43 @@ ble_hs_deinit(void) #if (MYNEWT_VAL(BLE_HOST_BASED_PRIVACY)) ble_hs_resolv_deinit(); #endif + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_hs_ctx) { + ble_hs_ctx->parent_task = NULL; + if (ble_hs_ctx->hci_os_event_buf) { + nimble_platform_mem_free(ble_hs_ctx->hci_os_event_buf); + ble_hs_ctx->hci_os_event_buf = NULL; + } + nimble_platform_mem_free(ble_hs_ctx); + ble_hs_ctx = NULL; + } + + if (ble_hs_state_ctx) { + nimble_platform_mem_free(ble_hs_state_ctx); + ble_hs_state_ctx = NULL; + } + +#if MYNEWT_VAL(BLE_PERIODIC_ADV) + ble_hs_periodic_sync_deinit(); +#endif + + ble_store_config_deinit(); + + ble_hs_adv_parse_free(); + +#if MYNEWT_VAL(BLE_HS_PVCY) + ble_hs_pvcy_irk_deinit(); +#endif + + ble_hs_id_ctx_free(); + + ble_hs_hci_ctx_free(); + + ble_uuid_deinit(); + +#if MYNEWT_VAL(BLE_GATTS) && CONFIG_BT_NIMBLE_GAP_SERVICE + ble_svc_gap_deinit(); +#endif +#endif } diff --git a/nimble/host/src/ble_hs_adv.c b/nimble/host/src/ble_hs_adv.c index 0403c479d..ec56d7002 100644 --- a/nimble/host/src/ble_hs_adv.c +++ b/nimble/host/src/ble_hs_adv.c @@ -25,15 +25,35 @@ #if MYNEWT_VAL(ENC_ADV_DATA) #include "host/ble_ead.h" #endif +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#include "esp_nimble_mem.h" +#endif struct find_field_data { uint8_t type; const struct ble_hs_adv_field *field; }; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +static const char *TAG = "ble_hs_adv"; + +typedef struct{ + ble_uuid16_t _ble_hs_adv_uuids16[BLE_HS_ADV_MAX_FIELD_SZ / 2]; + ble_uuid32_t _ble_hs_adv_uuids32[BLE_HS_ADV_MAX_FIELD_SZ / 4]; + ble_uuid128_t _ble_hs_adv_uuids128[BLE_HS_ADV_MAX_FIELD_SZ / 16]; +}ble_hs_adv_uuids_ctx; + +static ble_hs_adv_uuids_ctx *ble_hs_adv_uuids; + +#define ble_hs_adv_uuids16 (ble_hs_adv_uuids->_ble_hs_adv_uuids16) +#define ble_hs_adv_uuids32 (ble_hs_adv_uuids->_ble_hs_adv_uuids32) +#define ble_hs_adv_uuids128 (ble_hs_adv_uuids->_ble_hs_adv_uuids128) + +#else static ble_uuid16_t ble_hs_adv_uuids16[BLE_HS_ADV_MAX_FIELD_SZ / 2]; static ble_uuid32_t ble_hs_adv_uuids32[BLE_HS_ADV_MAX_FIELD_SZ / 4]; static ble_uuid128_t ble_hs_adv_uuids128[BLE_HS_ADV_MAX_FIELD_SZ / 16]; +#endif static int ble_hs_adv_set_hdr(uint8_t type, uint8_t data_len, uint8_t max_len, @@ -239,7 +259,9 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, uint8_t type; int8_t tx_pwr_lvl; uint8_t dst_len_local; +#if MYNEWT_VAL(BLE_EXTRA_ADV_FIELDS) uint8_t dev_addr_ad[7]; +#endif int rc; dst_len_local = 0; @@ -347,6 +369,7 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, } } +#if MYNEWT_VAL(BLE_EXTRA_ADV_FIELDS) /*** 0x10 - Security Manager TK value */ if (adv_fields->sm_tk_value_is_present) { rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_SEC_MGR_TK_VALUE, 16, @@ -368,6 +391,7 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, return rc; } } +#endif /*** 0x12 - Slave connection interval range. */ if (adv_fields->slave_itvl_range != NULL) { @@ -380,6 +404,8 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, } } +#if MYNEWT_VAL(BLE_EXTRA_ADV_FIELDS) + /*** 0x14 - 16 bit service solicitaion */ if (adv_fields->sol_uuids16 != NULL) { rc = ble_hs_adv_set_array_uuid16(BLE_HS_ADV_TYPE_SOL_UUIDS16, adv_fields->sol_num_uuids16, @@ -400,6 +426,8 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, } } +#endif + /*** 0x16 - Service data - 16-bit UUID. */ if (adv_fields->svc_data_uuid16 != NULL && adv_fields->svc_data_uuid16_len) { rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_SVC_DATA_UUID16, @@ -425,6 +453,7 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, } } +#if MYNEWT_VAL(BLE_EXTRA_ADV_FIELDS) /*** 0x18 - Random target address. */ if (adv_fields->random_tgt_addr != NULL && adv_fields->num_random_tgt_addrs != 0) { @@ -438,6 +467,8 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, return rc; } } +#endif + /*** 0x19 - Appearance. */ if (adv_fields->appearance_is_present) { @@ -460,6 +491,7 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, } } +#if MYNEWT_VAL(BLE_EXTRA_ADV_FIELDS) /*** 0x1b - LE Bluetooth Device address. */ if (adv_fields->device_addr != NULL) { for (int i = 0; i < BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN; i++) { @@ -496,6 +528,7 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, return rc; } } +#endif /*** 0x20 - Service data - 32-bit UUID. */ if (adv_fields->svc_data_uuid32 != NULL && adv_fields->svc_data_uuid32_len) { @@ -529,6 +562,7 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, } } +#if MYNEWT_VAL(BLE_EXTRA_ADV_FIELDS) /*** 0x27 - LE Supported Features. */ if (adv_fields->le_supp_feat_is_present) { rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_LE_SUPP_FEAT, @@ -554,6 +588,7 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, adv_fields->enc_adv_data, dst, &dst_len_local, max_len, om); } +#endif #endif /*** 0xff - Manufacturer specific data. */ @@ -666,6 +701,22 @@ ble_hs_adv_parse_uuids128(struct ble_hs_adv_fields *adv_fields, return 0; } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +static int +ble_hs_adv_uuids_alloc(void) +{ + if (ble_hs_adv_uuids) { + nimble_platform_mem_free(ble_hs_adv_uuids); + ble_hs_adv_uuids = NULL; + } + ble_hs_adv_uuids = nimble_platform_mem_calloc(1, sizeof(*ble_hs_adv_uuids)); + if (!ble_hs_adv_uuids) { + return BLE_HS_ENOMEM; + } + return 0; +} +#endif + static int ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields, uint8_t *total_len, const uint8_t *src, @@ -769,6 +820,7 @@ ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields, adv_fields->tx_pwr_lvl_is_present = 1; break; +#if MYNEWT_VAL(BLE_EXTRA_ADV_FIELDS) case BLE_HS_ADV_TYPE_SEC_MGR_TK_VALUE: if (data_len != 16) { return BLE_HS_EBADDATA; @@ -784,6 +836,7 @@ ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields, adv_fields->sm_oob_flag = *data; adv_fields->sm_oob_flag_is_present = 1; break; +#endif case BLE_HS_ADV_TYPE_SLAVE_ITVL_RANGE: if (data_len != BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN) { @@ -792,6 +845,7 @@ ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields, adv_fields->slave_itvl_range = data; break; +#if MYNEWT_VAL(BLE_EXTRA_ADV_FIELDS) case BLE_HS_ADV_TYPE_SOL_UUIDS16: rc = ble_hs_adv_parse_uuids16(adv_fields, data, data_len); if (rc != 0) { @@ -805,6 +859,7 @@ ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields, return rc; } break; +#endif case BLE_HS_ADV_TYPE_SVC_DATA_UUID16: if (data_len < BLE_HS_ADV_SVC_DATA_UUID16_MIN_LEN) { @@ -823,6 +878,7 @@ ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields, data_len / BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN; break; +#if MYNEWT_VAL(BLE_EXTRA_ADV_FIELDS) case BLE_HS_ADV_TYPE_RANDOM_TGT_ADDR: if (data_len % BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN != 0) { return BLE_HS_EBADDATA; @@ -831,6 +887,7 @@ ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields, adv_fields->num_random_tgt_addrs = data_len / BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN; break; +#endif case BLE_HS_ADV_TYPE_APPEARANCE: if (data_len != BLE_HS_ADV_APPEARANCE_LEN) { @@ -840,6 +897,7 @@ ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields, adv_fields->appearance_is_present = 1; break; +#if MYNEWT_VAL(BLE_EXTRA_ADV_FIELDS) case BLE_HS_ADV_TYPE_DEVICE_ADDR: if (data_len != 7) { return BLE_HS_EBADDATA; @@ -855,6 +913,7 @@ ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields, adv_fields->le_role = *data; adv_fields->le_role_is_present = 1; break; +#endif case BLE_HS_ADV_TYPE_ADV_ITVL: if (data_len != BLE_HS_ADV_ADV_ITVL_LEN) { @@ -885,12 +944,14 @@ ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields, adv_fields->uri_len = data_len; break; +#if MYNEWT_VAL(BLE_EXTRA_ADV_FIELDS) case BLE_HS_ADV_TYPE_SOL_UUIDS32: rc = ble_hs_adv_parse_uuids32(adv_fields, data, data_len); if (rc != 0) { return rc; } break; +#endif #if MYNEWT_VAL(ENC_ADV_DATA) case BLE_HS_ADV_TYPE_ENC_ADV_DATA: @@ -898,7 +959,6 @@ ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields, adv_fields->enc_adv_data_len = data_len; break; #endif - case BLE_HS_ADV_TYPE_MFG_DATA: adv_fields->mfg_data = data; adv_fields->mfg_data_len = data_len; @@ -920,6 +980,13 @@ ble_hs_adv_parse_fields(struct ble_hs_adv_fields *adv_fields, memset(adv_fields, 0, sizeof *adv_fields); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_hs_adv_uuids_alloc() != 0) { + ESP_LOGE(TAG, "Failed to allocate BLE adv UUIDs"); + return BLE_HS_ENOMEM; + } +#endif + while (src_len > 0) { rc = ble_hs_adv_parse_one_field(adv_fields, &field_len, src, src_len); if (rc != 0) { @@ -994,3 +1061,14 @@ ble_hs_adv_find_field(uint8_t type, const uint8_t *data, uint8_t length, return 0; } + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void +ble_hs_adv_parse_free(void) +{ + if (ble_hs_adv_uuids) { + nimble_platform_mem_free(ble_hs_adv_uuids); + ble_hs_adv_uuids = NULL; + } +} +#endif diff --git a/nimble/host/src/ble_hs_conn.c b/nimble/host/src/ble_hs_conn.c index a9de269c0..26d08af18 100644 --- a/nimble/host/src/ble_hs_conn.c +++ b/nimble/host/src/ble_hs_conn.c @@ -24,13 +24,21 @@ #include "host/ble_hs_id.h" #include "ble_hs_priv.h" #include "ble_hs_resolv_priv.h" +#include "esp_nimble_mem.h" /** At least three channels required per connection (sig, att, sm). */ #define BLE_HS_CONN_MIN_CHANS 3 static SLIST_HEAD(, ble_hs_conn) ble_hs_conns; -static struct os_mempool ble_hs_conn_pool; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +static struct { + struct os_mempool pool; + os_membuf_t *elem_mem; +} *ble_hs_conn_ctx; +#define ble_hs_conn_pool (ble_hs_conn_ctx->pool) +#define ble_hs_conn_elem_mem (ble_hs_conn_ctx->elem_mem) +#else #if MYNEWT_VAL(MP_RUNTIME_ALLOC) static os_membuf_t *ble_hs_conn_elem_mem = NULL; #else @@ -39,9 +47,28 @@ static os_membuf_t ble_hs_conn_elem_mem[ sizeof (struct ble_hs_conn)) ]; #endif +static struct os_mempool ble_hs_conn_pool; +#endif static const uint8_t ble_hs_conn_null_addr[6]; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +static int +ble_hs_conn_ensure_ctx(void) +{ + if (ble_hs_conn_ctx != NULL) { + return 0; + } + + ble_hs_conn_ctx = nimble_platform_mem_calloc(1, sizeof(*ble_hs_conn_ctx)); + if (ble_hs_conn_ctx == NULL) { + return BLE_HS_ENOMEM; + } + + return 0; +} +#endif + int ble_hs_conn_can_alloc(void) { @@ -53,11 +80,11 @@ ble_hs_conn_can_alloc(void) return ble_hs_conn_pool.mp_num_free >= 1 && ble_l2cap_chan_pool.mp_num_free >= BLE_HS_CONN_MIN_CHANS && ble_gatts_conn_can_alloc(); + #else return ble_hs_conn_pool.mp_num_free >= 1 && ble_l2cap_chan_pool.mp_num_free >= BLE_HS_CONN_MIN_CHANS; #endif - } struct ble_l2cap_chan * @@ -153,12 +180,17 @@ ble_hs_conn_alloc(uint16_t conn_handle) { #if !NIMBLE_BLE_CONNECT return NULL; -#endif - +#else struct ble_l2cap_chan *chan; struct ble_hs_conn *conn; int rc; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_hs_conn_ctx == NULL) { + return NULL; + } +#endif + conn = os_memblock_get(&ble_hs_conn_pool); if (conn == NULL) { goto err; @@ -214,13 +246,19 @@ ble_hs_conn_alloc(uint16_t conn_handle) err: ble_hs_conn_free(conn); return NULL; +#endif } void ble_hs_conn_delete_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan) { +#if MYNEWT_VAL(BT_NIMBLE_MEM_OPTIMIZATION) + if (conn->bhc_rx_scid == chan->scid) { + conn->bhc_rx_scid = 0x0000; +#else if (conn->bhc_rx_chan == chan) { conn->bhc_rx_chan = NULL; +#endif } SLIST_REMOVE(&conn->bhc_channels, chan, ble_l2cap_chan, next); @@ -272,7 +310,14 @@ ble_hs_conn_free(struct ble_hs_conn *conn) #if MYNEWT_VAL(BLE_HS_DEBUG) memset(conn, 0xff, sizeof *conn); #endif + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_hs_conn_ctx == NULL) { + return; + } +#endif rc = os_memblock_put(&ble_hs_conn_pool, conn); + BLE_HS_DBG_ASSERT_EVAL(rc == 0); STATS_INC(ble_hs_stats, conn_delete); @@ -426,7 +471,6 @@ ble_hs_conn_addrs(const struct ble_hs_conn *conn, { const uint8_t *our_id_addr_val; int rc; - /* Determine our address information. */ addrs->our_id_addr.type = ble_hs_misc_own_addr_type_to_id(conn->bhc_our_addr_type); @@ -539,7 +583,11 @@ ble_hs_conn_timer(void) * passes after a partial packet is received, the connection is * terminated. */ +#if MYNEWT_VAL(BT_NIMBLE_MEM_OPTIMIZATION) + if (conn->bhc_rx_scid != 0x0000) { +#else if (conn->bhc_rx_chan != NULL) { +#endif time_diff = conn->bhc_rx_timeout - now; if (time_diff <= 0) { @@ -591,14 +639,67 @@ ble_hs_conn_init(void) { int rc; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + rc = ble_hs_conn_ensure_ctx(); + if (rc != 0) { + return rc; + } + +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + size_t elem_mem_size = OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_CONNECTIONS), sizeof(struct ble_hs_conn)); + + if (!ble_hs_conn_elem_mem) { + ble_hs_conn_elem_mem = (os_membuf_t *)nimble_platform_mem_calloc(1,elem_mem_size * sizeof(os_membuf_t)); + + if (!ble_hs_conn_elem_mem) { + nimble_platform_mem_free(ble_hs_conn_ctx); + ble_hs_conn_ctx = NULL; + return BLE_HS_ENOMEM; + } + } +#endif + memset(&ble_hs_conn_pool, 0, sizeof(ble_hs_conn_pool)); +#endif rc = os_mempool_init(&ble_hs_conn_pool, MYNEWT_VAL(BLE_MAX_CONNECTIONS), sizeof (struct ble_hs_conn), ble_hs_conn_elem_mem, "ble_hs_conn_pool"); + if (rc != 0) { - return BLE_HS_EOS; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + nimble_platform_mem_free(ble_hs_conn_elem_mem); + ble_hs_conn_elem_mem = NULL; +#endif + if (ble_hs_conn_ctx) { + nimble_platform_mem_free(ble_hs_conn_ctx); + ble_hs_conn_ctx = NULL; + } + memset(&ble_hs_conn_pool, 0, sizeof(ble_hs_conn_pool)); +#endif + return BLE_HS_EOS; } SLIST_INIT(&ble_hs_conns); return 0; } + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void +ble_hs_conn_deinit(void) +{ + if (ble_hs_conn_ctx == NULL) { + return; + } + +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + if (ble_hs_conn_elem_mem) { + nimble_platform_mem_free(ble_hs_conn_elem_mem); + ble_hs_conn_elem_mem = NULL; + } +#endif + memset(&ble_hs_conn_pool, 0, sizeof(ble_hs_conn_pool)); + nimble_platform_mem_free(ble_hs_conn_ctx); + ble_hs_conn_ctx = NULL; +} +#endif diff --git a/nimble/host/src/ble_hs_conn_priv.h b/nimble/host/src/ble_hs_conn_priv.h index 82833ad36..1a2e243a3 100644 --- a/nimble/host/src/ble_hs_conn_priv.h +++ b/nimble/host/src/ble_hs_conn_priv.h @@ -49,12 +49,12 @@ typedef uint8_t ble_hs_conn_flags_t; struct ble_hs_conn { SLIST_ENTRY(ble_hs_conn) bhc_next; - uint16_t bhc_handle; uint8_t bhc_our_addr_type; uint8_t slave_conn : 1; #if MYNEWT_VAL(BLE_EXT_ADV) uint8_t bhc_our_rnd_addr[6]; #endif + uint16_t bhc_handle; ble_addr_t bhc_peer_addr; ble_addr_t bhc_our_rpa_addr; ble_addr_t bhc_peer_rpa_addr; @@ -66,6 +66,9 @@ struct ble_hs_conn { uint16_t bhc_max_rx_octets; uint16_t bhc_max_tx_time; uint16_t bhc_max_rx_time; +#if MYNEWT_VAL(BT_NIMBLE_MEM_OPTIMIZATION) + uint16_t bhc_rx_scid; +#endif uint8_t bhc_master_clock_accuracy; uint32_t supported_feat; @@ -73,7 +76,9 @@ struct ble_hs_conn { ble_hs_conn_flags_t bhc_flags; struct ble_l2cap_chan_list bhc_channels; +#if !MYNEWT_VAL(BT_NIMBLE_MEM_OPTIMIZATION) struct ble_l2cap_chan *bhc_rx_chan; /* Channel rxing current packet. */ +#endif ble_npl_time_t bhc_rx_timeout; #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) uint32_t l2cap_coc_cid_mask[BLE_HS_CONN_L2CAP_COC_CID_MASK_LEN]; @@ -105,8 +110,14 @@ struct ble_hs_conn { ble_gap_event_fn *bhc_cb; void *bhc_cb_arg; +#if MYNEWT_VAL(BT_NIMBLE_MEM_OPTIMIZATION) +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) + struct ble_hs_periodic_sync *psync; +#endif +#else #if MYNEWT_VAL(BLE_PERIODIC_ADV) struct ble_hs_periodic_sync *psync; +#endif #endif STAILQ_HEAD(, os_mbuf_pkthdr) att_tx_q; @@ -151,6 +162,9 @@ int32_t ble_hs_conn_timer(void); typedef int ble_hs_conn_foreach_fn(struct ble_hs_conn *conn, void *arg); void ble_hs_conn_foreach(ble_hs_conn_foreach_fn *cb, void *arg); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void ble_hs_conn_deinit(void); +#endif int ble_hs_conn_init(void); #ifdef __cplusplus diff --git a/nimble/host/src/ble_hs_flow.c b/nimble/host/src/ble_hs_flow.c index 0d47b15a4..ea902a1cf 100644 --- a/nimble/host/src/ble_hs_flow.c +++ b/nimble/host/src/ble_hs_flow.c @@ -19,12 +19,37 @@ #include "syscfg/syscfg.h" #include "ble_hs_priv.h" +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#include "esp_nimble_mem.h" +#endif #if MYNEWT_VAL(BLE_HS_FLOW_CTRL) #define BLE_HS_FLOW_ITVL_TICKS \ ble_npl_time_ms_to_ticks32(MYNEWT_VAL(BLE_HS_FLOW_CTRL_ITVL)) +static ble_npl_event_fn ble_hs_flow_event_cb; + +/* Connection handle associated with each mbuf in ACL pool */ +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +typedef struct { + uint16_t num_completed_pkts; /* Tracks number of completed packets */ + struct ble_npl_callout flow_timer; /* Periodic flow timer */ + struct ble_npl_event flow_ev; /* Event for flow handling */ +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + uint16_t mbuf_conn_handle[MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_LL_COUNT)]; +#endif +} ble_hs_flow_ctx_t; + +static ble_hs_flow_ctx_t *ble_hs_flow_ctx; + +#define ble_hs_flow_num_completed_pkts (ble_hs_flow_ctx->num_completed_pkts) +#define ble_hs_flow_timer (ble_hs_flow_ctx->flow_timer) +#define ble_hs_flow_ev (ble_hs_flow_ctx->flow_ev) +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) +#define ble_hs_flow_mbuf_conn_handle (ble_hs_flow_ctx->mbuf_conn_handle) +#endif +#else /** * The number of freed buffers since the most-recent * number-of-completed-packets event was sent. This is used to determine if an @@ -34,15 +59,15 @@ static uint16_t ble_hs_flow_num_completed_pkts; /** Periodically sends number-of-completed-packets events. */ static struct ble_npl_callout ble_hs_flow_timer; - -static ble_npl_event_fn ble_hs_flow_event_cb; - static struct ble_npl_event ble_hs_flow_ev; #if !MYNEWT_VAL(MP_RUNTIME_ALLOC) /* Connection handle associated with each mbuf in ACL pool */ static uint16_t ble_hs_flow_mbuf_conn_handle[ MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_LL_COUNT) ]; +#endif +#endif +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) static inline int ble_hs_flow_mbuf_index(const struct os_mbuf *om) { @@ -244,7 +269,7 @@ ble_hs_flow_startup(void) /* Remove previous event from queue, if any*/ ble_npl_eventq_remove(ble_hs_evq_get(), &ble_hs_flow_ev); - + #if MYNEWT_VAL(SELFTEST) ble_npl_callout_stop(&ble_hs_flow_timer); @@ -296,6 +321,15 @@ void ble_hs_flow_init(void) { #if MYNEWT_VAL(BLE_HS_FLOW_CTRL) +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (!ble_hs_flow_ctx) { + ble_hs_flow_ctx = nimble_platform_mem_calloc(1, sizeof(*ble_hs_flow_ctx)); + if (!ble_hs_flow_ctx) { + return; + } + } +#endif + ble_npl_event_init(&ble_hs_flow_ev, ble_hs_flow_event_cb, NULL); ble_npl_callout_init(&ble_hs_flow_timer, ble_hs_evq_get(), ble_hs_flow_event_cb, NULL); @@ -308,5 +342,12 @@ ble_hs_flow_deinit(void) #if MYNEWT_VAL(BLE_HS_FLOW_CTRL) ble_npl_event_deinit(&ble_hs_flow_ev); ble_npl_callout_deinit(&ble_hs_flow_timer); + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_hs_flow_ctx) { + nimble_platform_mem_free(ble_hs_flow_ctx); + ble_hs_flow_ctx = NULL; + } +#endif /* MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) */ #endif //MYNEWT_VAL(BLE_HS_FLOW_CTRL) } diff --git a/nimble/host/src/ble_hs_hci.c b/nimble/host/src/ble_hs_hci.c index fef7131c8..8aff43310 100644 --- a/nimble/host/src/ble_hs_hci.c +++ b/nimble/host/src/ble_hs_hci.c @@ -23,6 +23,7 @@ #include "os/os.h" #include "mem/mem.h" #include "ble_hs_priv.h" +#include "esp_nimble_mem.h" #include "nimble/transport.h" #include "bt_common.h" @@ -30,10 +31,12 @@ #include "hci_log/bt_hci_log.h" #include "host/ble_hs.h" #endif // (BT_HCI_LOG_INCLUDED == TRUE) - +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#include "esp_nimble_mem.h" +#endif #define BLE_HCI_CMD_TIMEOUT_MS 2000 -#if MYNEWT_VAL(BLE_ERR_CHECK) +#if MYNEWT_VAL(BLE_ERR_NAME) /* HCI ERROR */ #define BLE_ERR_UNKNOWN_HCI_CMD 0x01 #define BLE_ERR_UNK_CONN_ID 0x02 @@ -256,12 +259,47 @@ static void esp_hci_err_to_name(int error_code, uint16_t *opcode) } return; } - #endif + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +typedef struct { + struct ble_npl_mutex hci_mutex; + struct ble_npl_sem hci_sem; + struct os_mbuf_pool hci_frag_mbuf_pool; + uint16_t hci_buf_sz; + uint8_t hci_max_pkts; + uint32_t hci_sup_feat; + uint8_t hci_version; + uint16_t hci_avial_pkts; + + struct os_mempool hci_frag_mempool; /* Memory pool for HCI fragments */ + os_membuf_t *hci_frag_data; /* Memory buffer backing HCI pool */ + struct ble_hs_hci_sup_cmd sup_cmd; /* Supported command table */ + + struct ble_hci_ev *hci_ack; +} ble_hs_hci_ctx_t; + +/* Pointer to dynamically allocated HCI context */ +static ble_hs_hci_ctx_t *ble_hs_hci_ctx = NULL; +#define ble_hs_hci_mutex (ble_hs_hci_ctx->hci_mutex) +#define ble_hs_hci_sem (ble_hs_hci_ctx->hci_sem) +#define ble_hs_hci_frag_mbuf_pool (ble_hs_hci_ctx->hci_frag_mbuf_pool) +#define ble_hs_hci_buf_sz (ble_hs_hci_ctx->hci_buf_sz) +#define ble_hs_hci_max_pkts (ble_hs_hci_ctx->hci_max_pkts) +#define ble_hs_hci_sup_feat (ble_hs_hci_ctx->hci_sup_feat) +#define ble_hs_hci_version (ble_hs_hci_ctx->hci_version) +#define ble_hs_hci_avail_pkts (ble_hs_hci_ctx->hci_avial_pkts) + +#define ble_hs_hci_frag_mempool (ble_hs_hci_ctx->hci_frag_mempool) +#define ble_hs_hci_frag_data (ble_hs_hci_ctx->hci_frag_data) +#define l_ble_hs_hci_sup_cmd (ble_hs_hci_ctx->sup_cmd) + +#define l_ble_hs_hci_ack (ble_hs_hci_ctx->hci_ack) +#else static struct ble_npl_mutex ble_hs_hci_mutex; static struct ble_npl_sem ble_hs_hci_sem; +static struct os_mbuf_pool ble_hs_hci_frag_mbuf_pool; -static struct ble_hci_ev *ble_hs_hci_ack; static uint16_t ble_hs_hci_buf_sz; static uint8_t ble_hs_hci_max_pkts; @@ -269,8 +307,13 @@ static uint8_t ble_hs_hci_max_pkts; static uint32_t ble_hs_hci_sup_feat; static uint8_t ble_hs_hci_version; - -static struct ble_hs_hci_sup_cmd ble_hs_hci_sup_cmd; +/** + * The number of available ACL transmit buffers on the controller. This + * variable must only be accessed while the host mutex is locked. + */ +uint16_t ble_hs_hci_avail_pkts; +static struct ble_hci_ev *l_ble_hs_hci_ack; +#endif //BLE_STATIC_TO_DYNAMIC #if CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE #define BLE_HS_HCI_FRAG_DATABUF_SIZE \ @@ -302,6 +345,7 @@ static struct ble_hs_hci_sup_cmd ble_hs_hci_sup_cmd; * from fragmenting outgoing packets and sending them (and ultimately freeing * them). */ +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) #if MYNEWT_VAL(MP_RUNTIME_ALLOC) static os_membuf_t *ble_hs_hci_frag_data = NULL; #else @@ -309,12 +353,8 @@ static os_membuf_t ble_hs_hci_frag_data[BLE_HS_HCI_FRAG_MEMPOOL_SIZE]; #endif static struct os_mbuf_pool ble_hs_hci_frag_mbuf_pool; static struct os_mempool ble_hs_hci_frag_mempool; - -/** - * The number of available ACL transmit buffers on the controller. This - * variable must only be accessed while the host mutex is locked. - */ -uint16_t ble_hs_hci_avail_pkts; +static struct ble_hs_hci_sup_cmd l_ble_hs_hci_sup_cmd; +#endif #if MYNEWT_VAL(BLE_HS_PHONY_HCI_ACKS) static ble_hs_hci_phony_ack_fn *ble_hs_hci_phony_ack_cb; @@ -447,7 +487,7 @@ ble_hs_hci_process_ack(uint16_t expected_opcode, { int rc; - BLE_HS_DBG_ASSERT(ble_hs_hci_ack != NULL); + BLE_HS_DBG_ASSERT(l_ble_hs_hci_ack != NULL); /* Count events received */ STATS_INC(ble_hs_stats, hci_event); @@ -456,15 +496,15 @@ ble_hs_hci_process_ack(uint16_t expected_opcode, /* Clear ack fields up front to silence spurious gcc warnings. */ memset(out_ack, 0, sizeof *out_ack); - switch (ble_hs_hci_ack->opcode) { + switch (l_ble_hs_hci_ack->opcode) { case BLE_HCI_EVCODE_COMMAND_COMPLETE: - rc = ble_hs_hci_rx_cmd_complete(ble_hs_hci_ack->data, - ble_hs_hci_ack->length, out_ack); + rc = ble_hs_hci_rx_cmd_complete(l_ble_hs_hci_ack->data, + l_ble_hs_hci_ack->length, out_ack); break; case BLE_HCI_EVCODE_COMMAND_STATUS: - rc = ble_hs_hci_rx_cmd_status(ble_hs_hci_ack->data, - ble_hs_hci_ack->length, out_ack); + rc = ble_hs_hci_rx_cmd_status(l_ble_hs_hci_ack->data, + l_ble_hs_hci_ack->length, out_ack); break; default: @@ -506,16 +546,16 @@ ble_hs_hci_wait_for_ack(void) if (ble_hs_hci_phony_ack_cb == NULL) { rc = BLE_HS_ETIMEOUT_HCI; } else { - ble_hs_hci_ack = ble_transport_alloc_cmd(); - BLE_HS_DBG_ASSERT(ble_hs_hci_ack != NULL); - rc = ble_hs_hci_phony_ack_cb((void *)ble_hs_hci_ack, 260); + l_ble_hs_hci_ack = ble_transport_alloc_cmd(); + BLE_HS_DBG_ASSERT(l_ble_hs_hci_ack != NULL); + rc = ble_hs_hci_phony_ack_cb((void *)l_ble_hs_hci_ack, 260); } #else rc = ble_npl_sem_pend(&ble_hs_hci_sem, ble_npl_time_ms_to_ticks32(BLE_HCI_CMD_TIMEOUT_MS)); switch (rc) { case 0: - BLE_HS_DBG_ASSERT(ble_hs_hci_ack != NULL); + BLE_HS_DBG_ASSERT(l_ble_hs_hci_ack != NULL); break; case OS_TIMEOUT: rc = BLE_HS_ETIMEOUT_HCI; @@ -550,7 +590,7 @@ ble_hs_hci_cmd_tx(uint16_t opcode, const void *cmd, uint8_t cmd_len, struct ble_hs_hci_ack ack; int rc; - BLE_HS_DBG_ASSERT(ble_hs_hci_ack == NULL); + BLE_HS_DBG_ASSERT(l_ble_hs_hci_ack == NULL); ble_hs_hci_lock(); rc = ble_hs_hci_cmd_send_buf(opcode, cmd, cmd_len); @@ -581,17 +621,17 @@ ble_hs_hci_cmd_tx(uint16_t opcode, const void *cmd, uint8_t cmd_len, goto done; } done: - if (ble_hs_hci_ack != NULL) { + if (l_ble_hs_hci_ack != NULL) { #if MYNEWT_VAL(MP_RUNTIME_ALLOC) - ble_transport_free(BLE_HCI_EVT, (uint8_t *) ble_hs_hci_ack); + ble_transport_free(BLE_HCI_EVT, (uint8_t *) l_ble_hs_hci_ack); #else - ble_transport_free((uint8_t *) ble_hs_hci_ack); + ble_transport_free((uint8_t *) l_ble_hs_hci_ack); #endif - ble_hs_hci_ack = NULL; + l_ble_hs_hci_ack = NULL; } ble_hs_hci_unlock(); -#if MYNEWT_VAL(BLE_ERR_CHECK) +#if MYNEWT_VAL(BLE_ERR_NAME) esp_hci_err_to_name(rc, &opcode); #endif return rc; @@ -623,12 +663,12 @@ ble_hs_hci_rx_ack(uint8_t *ack_ev) #endif return; } - BLE_HS_DBG_ASSERT(ble_hs_hci_ack == NULL); + BLE_HS_DBG_ASSERT(l_ble_hs_hci_ack == NULL); /* Unblock the application now that the HCI command buffer is populated * with the acknowledgement. */ - ble_hs_hci_ack = (struct ble_hci_ev *) ack_ev; + l_ble_hs_hci_ack = (struct ble_hci_ev *) ack_ev; ble_npl_sem_release(&ble_hs_hci_sem); } @@ -701,6 +741,7 @@ ble_hs_hci_rx_evt(uint8_t *hci_ev, void *arg) return 0; } +#if NIMBLE_BLE_CONNECT #if !(SOC_ESP_NIMBLE_CONTROLLER) || !(CONFIG_BT_CONTROLLER_ENABLED) /** * Calculates the largest ACL payload that the controller can accept. @@ -748,6 +789,7 @@ ble_hs_hci_frag_alloc(uint16_t frag_size, void *arg) return NULL; } +#endif /** * Retrieves the total capacity of the ACL fragment pool (always 1). @@ -767,6 +809,7 @@ ble_hs_hci_frag_num_mbufs_free(void) return ble_hs_hci_frag_mempool.mp_num_free; } +#if NIMBLE_BLE_CONNECT static struct os_mbuf * ble_hs_hci_acl_hdr_prepend(struct os_mbuf *om, uint16_t handle, uint8_t pb_flag) @@ -908,6 +951,7 @@ ble_hs_hci_acl_tx(struct ble_hs_conn *conn, struct os_mbuf **om) return ble_hs_hci_acl_tx_now(conn, om); } +#endif void ble_hs_hci_set_le_supported_feat(uint32_t feat) @@ -936,13 +980,13 @@ ble_hs_hci_get_hci_version(void) void ble_hs_hci_set_hci_supported_cmd(struct ble_hs_hci_sup_cmd sup_cmd) { - ble_hs_hci_sup_cmd = sup_cmd; + l_ble_hs_hci_sup_cmd = sup_cmd; } struct ble_hs_hci_sup_cmd ble_hs_hci_get_hci_supported_cmd(void) { - return ble_hs_hci_sup_cmd; + return l_ble_hs_hci_sup_cmd; } void @@ -950,6 +994,28 @@ ble_hs_hci_init(void) { int rc; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + /* Allocate HCI context structure dynamically */ + if (!ble_hs_hci_ctx) { + ble_hs_hci_ctx = nimble_platform_mem_calloc(1, sizeof(*ble_hs_hci_ctx)); + if (!ble_hs_hci_ctx) { + BLE_HS_DBG_ASSERT_EVAL(0); + } + } + +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + size_t frag_data_size = BLE_HS_HCI_FRAG_MEMPOOL_SIZE * sizeof(os_membuf_t); + + if (!ble_hs_hci_frag_data) { + ble_hs_hci_frag_data = nimble_platform_mem_calloc(1, frag_data_size); + if (!ble_hs_hci_frag_data) { + nimble_platform_mem_free(ble_hs_hci_ctx); + BLE_HS_DBG_ASSERT_EVAL(0); + } + } +#endif +#endif + rc = ble_npl_sem_init(&ble_hs_hci_sem, 0); BLE_HS_DBG_ASSERT_EVAL(rc == 0); @@ -962,16 +1028,29 @@ ble_hs_hci_init(void) 1, BLE_HS_HCI_FRAG_MEMBLOCK_SIZE, "ble_hs_hci_frag"); + BLE_HS_DBG_ASSERT_EVAL(rc == 0); } void ble_hs_hci_deinit(void) { int rc; - rc = ble_npl_mutex_deinit(&ble_hs_hci_mutex); BLE_HS_DBG_ASSERT_EVAL(rc == 0); rc = ble_npl_sem_deinit(&ble_hs_hci_sem); BLE_HS_DBG_ASSERT_EVAL(rc == 0); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_hs_hci_ctx) { +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + if (ble_hs_hci_frag_data) { + nimble_platform_mem_free(ble_hs_hci_frag_data); + ble_hs_hci_frag_data = NULL; + } +#endif + nimble_platform_mem_free(ble_hs_hci_ctx); + ble_hs_hci_ctx = NULL; + } + +#endif } diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index 703933a7a..8c7632c16 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -31,18 +31,81 @@ #endif /* MYNEWT_VAL(BLE_ISO) */ #if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) + +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) struct ble_gap_reattempt_ctxt { ble_addr_t peer_addr; uint8_t count; }reattempt_conn; +#endif +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_OBSERVER) extern int ble_gap_master_connect_reattempt(uint16_t conn_handle); +#endif +#if MYNEWT_VAL(BLE_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_ROLE_BROADCASTER) extern int ble_gap_slave_adv_reattempt(void); #endif +#if !MYNEWT_VAL(BT_NIMBLE_MEM_OPTIMIZATION) +extern int slave_conn[MYNEWT_VAL(BLE_MAX_CONNECTIONS) + 1]; +#endif +#endif + + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + +#if (NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT)) || \ + (NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_EXT_ADV) && !MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES)) || \ + (NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_EXT_ADV)) || \ + MYNEWT_VAL(BLE_QUEUE_CONG_CHECK) || \ + (MYNEWT_VAL(BLE_EXT_ADV) && ((NIMBLE_BLE_CONNECT && (MYNEWT_VAL(BLE_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_ROLE_BROADCASTER))) || \ + (MYNEWT_VAL(BLE_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_ROLE_BROADCASTER)))) + +typedef struct { + +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) + struct ble_gap_reattempt_ctxt { + ble_addr_t peer_addr; + uint8_t count; + } reattempt_ctx; +#endif + +#if MYNEWT_VAL(BLE_QUEUE_CONG_CHECK) + struct ble_npl_mutex list_lock; + uint16_t adv_list_count; +#endif + +#if ((NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_EXT_ADV)) || \ + (MYNEWT_VAL(BLE_EXT_ADV) && (MYNEWT_VAL(BLE_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_ROLE_BROADCASTER)) && \ + (NIMBLE_BLE_CONNECT || (MYNEWT_VAL(BLE_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_ROLE_BROADCASTER))))) + struct ble_gap_conn_complete conn_complete; +#endif +}ble_hci_ctx_t; + +static ble_hci_ctx_t *ble_hci_ctx; + +#define reattempt_conn (ble_hci_ctx->reattempt_ctx) +#if MYNEWT_VAL(BLE_QUEUE_CONG_CHECK) +#define adv_list_lock (ble_hci_ctx->list_lock) +#define ble_adv_list_count (ble_hci_ctx->adv_list_count) +#endif + +#if ((NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_EXT_ADV)) || \ + (MYNEWT_VAL(BLE_EXT_ADV) && (MYNEWT_VAL(BLE_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_ROLE_BROADCASTER)) && \ + (NIMBLE_BLE_CONNECT || (MYNEWT_VAL(BLE_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_ROLE_BROADCASTER))))) +#define pend_conn_complete (ble_hci_ctx->conn_complete) +#endif + +#endif +#else #if MYNEWT_VAL(BLE_QUEUE_CONG_CHECK) static struct ble_npl_mutex adv_list_lock; static uint16_t ble_adv_list_count; +#endif +#endif + + +#if MYNEWT_VAL(BLE_QUEUE_CONG_CHECK) #define BLE_ADV_LIST_MAX_LENGTH 50 #define BLE_ADV_LIST_MAX_COUNT 200 #endif @@ -58,24 +121,32 @@ typedef int ble_hs_hci_evt_fn(uint8_t event_code, const void *data, unsigned int len); static ble_hs_hci_evt_fn ble_hs_hci_evt_hw_error; static ble_hs_hci_evt_fn ble_hs_hci_evt_num_completed_pkts; -static ble_hs_hci_evt_fn ble_hs_hci_evt_rd_rem_ver_complete; #if NIMBLE_BLE_CONNECT static ble_hs_hci_evt_fn ble_hs_hci_evt_disconn_complete; +#if MYNEWT_VAL(BLE_SM_SC) static ble_hs_hci_evt_fn ble_hs_hci_evt_encrypt_change; static ble_hs_hci_evt_fn ble_hs_hci_evt_enc_key_refresh; #endif +static ble_hs_hci_evt_fn ble_hs_hci_evt_rd_rem_ver_complete; +#endif static ble_hs_hci_evt_fn ble_hs_hci_evt_le_meta; #if MYNEWT_VAL(BLE_HCI_VS) static ble_hs_hci_evt_fn ble_hs_hci_evt_vs; #endif +#if MYNEWT_VAL(BLE_DTM_MODE_TEST) static ble_hs_hci_evt_fn ble_hs_hci_evt_rx_test; static ble_hs_hci_evt_fn ble_hs_hci_evt_tx_test; static ble_hs_hci_evt_fn ble_hs_hci_evt_end_test; +#endif typedef int ble_hs_hci_evt_le_fn(uint8_t subevent, const void *data, unsigned int len); + +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_OBSERVER) static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_adv_rpt; +#endif + #if NIMBLE_BLE_CONNECT static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_conn_complete; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_conn_upd_complete; @@ -84,17 +155,29 @@ static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_conn_parm_req; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_data_len_change; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_phy_update_complete; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_enh_conn_complete; -#endif -static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_dir_adv_rpt; -static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_ext_adv_rpt; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_rd_rem_used_feat_complete; +#endif +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_OBSERVER) +static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_dir_adv_rpt; +#endif +#if MYNEWT_VAL(BLE_EXT_ADV) +static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_ext_adv_rpt; +#endif +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_OBSERVER) static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_scan_timeout; +#endif +#if MYNEWT_VAL(BLE_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_ROLE_BROADCASTER) static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_adv_set_terminated; +static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_scan_req_rcvd; +#endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV) static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_estab; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_rpt; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_lost; -static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_scan_req_rcvd; +#endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV) static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_transfer; +#endif #if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS) && !MYNEWT_VAL(BLE_ISO) static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_biginfo_adv_report; #endif @@ -144,6 +227,15 @@ struct host_hci_stats { #define BLE_HS_HCI_EVT_TIMEOUT 50 /* Milliseconds. */ +#if MYNEWT_VAL(BLE_EXT_ADV) +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#if NIMBLE_BLE_CONNECT || \ + (MYNEWT_VAL(BLE_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_ROLE_BROADCASTER)) +static struct ble_gap_conn_complete pend_conn_complete; +#endif +#endif +#endif + /** Dispatch table for incoming HCI events. Sorted by event code field. */ struct ble_hs_hci_evt_dispatch_entry { uint8_t event_code; @@ -152,22 +244,26 @@ struct ble_hs_hci_evt_dispatch_entry { static const struct ble_hs_hci_evt_dispatch_entry ble_hs_hci_evt_dispatch[] = { { BLE_HCI_EVCODE_LE_META, ble_hs_hci_evt_le_meta }, - { BLE_HCI_EVCODE_RD_REM_VER_INFO_CMP, ble_hs_hci_evt_rd_rem_ver_complete }, { BLE_HCI_EVCODE_NUM_COMP_PKTS, ble_hs_hci_evt_num_completed_pkts }, #if NIMBLE_BLE_CONNECT + { BLE_HCI_EVCODE_RD_REM_VER_INFO_CMP, ble_hs_hci_evt_rd_rem_ver_complete }, { BLE_HCI_EVCODE_DISCONN_CMP, ble_hs_hci_evt_disconn_complete }, +#if MYNEWT_VAL(BLE_SM_SC) { BLE_HCI_EVCODE_ENCRYPT_CHG, ble_hs_hci_evt_encrypt_change }, { BLE_HCI_EVCODE_ENC_KEY_REFRESH, ble_hs_hci_evt_enc_key_refresh }, +#endif #endif { BLE_HCI_EVCODE_HW_ERROR, ble_hs_hci_evt_hw_error }, #if MYNEWT_VAL(BLE_HCI_VS) { BLE_HCI_EVCODE_VS, ble_hs_hci_evt_vs }, #endif +#if MYNEWT_VAL(BLE_DTM_MODE_TEST) { BLE_HCI_OCF_LE_RX_TEST, ble_hs_hci_evt_rx_test }, { BLE_HCI_OCF_LE_TX_TEST, ble_hs_hci_evt_tx_test }, { BLE_HCI_OCF_LE_TEST_END, ble_hs_hci_evt_end_test }, { BLE_HCI_OCF_LE_RX_TEST_V2, ble_hs_hci_evt_rx_test }, { BLE_HCI_OCF_LE_TX_TEST_V2, ble_hs_hci_evt_tx_test }, +#endif }; #define BLE_HS_HCI_EVT_DISPATCH_SZ \ @@ -177,7 +273,9 @@ static ble_hs_hci_evt_le_fn * const ble_hs_hci_evt_le_dispatch[] = { #if NIMBLE_BLE_CONNECT [BLE_HCI_LE_SUBEV_CONN_COMPLETE] = ble_hs_hci_evt_le_conn_complete, #endif +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_OBSERVER) [BLE_HCI_LE_SUBEV_ADV_RPT] = ble_hs_hci_evt_le_adv_rpt, +#endif #if NIMBLE_BLE_CONNECT [BLE_HCI_LE_SUBEV_CONN_UPD_COMPLETE] = ble_hs_hci_evt_le_conn_upd_complete, [BLE_HCI_LE_SUBEV_LT_KEY_REQ] = ble_hs_hci_evt_le_lt_key_req, @@ -185,19 +283,33 @@ static ble_hs_hci_evt_le_fn * const ble_hs_hci_evt_le_dispatch[] = { [BLE_HCI_LE_SUBEV_DATA_LEN_CHG] = ble_hs_hci_evt_le_data_len_change, [BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE] = ble_hs_hci_evt_le_enh_conn_complete, #endif +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_OBSERVER) [BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT] = ble_hs_hci_evt_le_dir_adv_rpt, +#endif #if NIMBLE_BLE_CONNECT [BLE_HCI_LE_SUBEV_PHY_UPDATE_COMPLETE] = ble_hs_hci_evt_le_phy_update_complete, #endif +#if MYNEWT_VAL(BLE_EXT_ADV) [BLE_HCI_LE_SUBEV_EXT_ADV_RPT] = ble_hs_hci_evt_le_ext_adv_rpt, +#endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV) [BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_ESTAB] = ble_hs_hci_evt_le_periodic_adv_sync_estab, [BLE_HCI_LE_SUBEV_PERIODIC_ADV_RPT] = ble_hs_hci_evt_le_periodic_adv_rpt, [BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_LOST] = ble_hs_hci_evt_le_periodic_adv_sync_lost, +#endif +#if NIMBLE_BLE_CONNECT [BLE_HCI_LE_SUBEV_RD_REM_USED_FEAT] = ble_hs_hci_evt_le_rd_rem_used_feat_complete, +#endif +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_OBSERVER) [BLE_HCI_LE_SUBEV_SCAN_TIMEOUT] = ble_hs_hci_evt_le_scan_timeout, +#endif +#if MYNEWT_VAL(BLE_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_ROLE_BROADCASTER) [BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED] = ble_hs_hci_evt_le_adv_set_terminated, [BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD] = ble_hs_hci_evt_le_scan_req_rcvd, +#endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV) [BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_TRANSFER] = ble_hs_hci_evt_le_periodic_adv_sync_transfer, +#endif #if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS) && !MYNEWT_VAL(BLE_ISO) [BLE_HCI_LE_SUBEV_BIGINFO_ADV_REPORT] = ble_hs_hci_evt_le_biginfo_adv_report, #endif @@ -251,6 +363,44 @@ static ble_hs_hci_evt_le_fn * const ble_hs_hci_evt_le_dispatch[] = { #endif }; + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + +#if (NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT)) || \ + (NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_EXT_ADV) && !MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES)) || \ + (NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_EXT_ADV)) || \ + MYNEWT_VAL(BLE_QUEUE_CONG_CHECK) || \ + (MYNEWT_VAL(BLE_EXT_ADV) && (MYNEWT_VAL(BLE_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_ROLE_BROADCASTER))) +static int ble_hs_hci_ensure_ctx(void) +{ + if (ble_hci_ctx) { + return 0; + } + + ble_hci_ctx = nimble_platform_mem_calloc (1, sizeof(* ble_hci_ctx)); + + if (!ble_hci_ctx) { + return BLE_HS_ENOMEM; + } + + return 0; +} + +void ble_hs_hci_ctx_free(void) +{ + if (ble_hci_ctx) { + nimble_platform_mem_free(ble_hci_ctx); + ble_hci_ctx = NULL; + } +} +#else +void ble_hs_hci_ctx_free(void) +{ + /* Empty function */ +} +#endif +#endif + #define BLE_HS_HCI_EVT_LE_DISPATCH_SZ \ (sizeof ble_hs_hci_evt_le_dispatch / sizeof ble_hs_hci_evt_le_dispatch[0]) @@ -293,6 +443,10 @@ ble_hs_hci_evt_disconn_complete(uint8_t event_code, const void *data, const struct ble_hci_ev_disconn_cmp *ev = data; const struct ble_hs_conn *conn; +#if MYNEWT_VAL(BLE_ENABLE_CONN_REATTEMPT) && MYNEWT_VAL(BT_NIMBLE_MEM_OPTIMIZATION) + bool should_reattempt = false; +#endif + if (len != sizeof(*ev)) { return BLE_HS_ECONTROLLER; } @@ -309,12 +463,20 @@ ble_hs_hci_evt_disconn_complete(uint8_t event_code, const void *data, uint16_t handle; int rc; +#if MYNEWT_VAL(BT_NIMBLE_MEM_OPTIMIZATION) + should_reattempt = (!conn->slave_conn && ev->reason == BLE_ERR_CONN_SPVN_TMO); +#endif /* For master role, check if failure reason is 0x3E, to restart connect attempt * For slave role, check whether * a. Failure reason is 0x3E * b. Connect event was not posted and 0x8 was received * Restart advertising in above reasons for slave. */ +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_hs_hci_ensure_ctx()) { + return BLE_HS_ENOMEM; + } +#endif if ((conn->bhc_flags & BLE_HS_CONN_F_MASTER) && \ (ev->reason == BLE_ERR_CONN_ESTABLISHMENT)) { // master @@ -328,20 +490,25 @@ ble_hs_hci_evt_disconn_complete(uint8_t event_code, const void *data, handle = le16toh(ev->conn_handle); /* Post event to interested application */ ble_gap_reattempt_count(handle, reattempt_conn.count); - +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_OBSERVER) rc = ble_gap_master_connect_reattempt(ev->conn_handle); if (rc != 0) { BLE_HS_LOG(INFO, "Master reconnect attempt failed; rc = %d", rc); } +#endif } else { /* Exhausted attempts */ memset(&reattempt_conn, 0x0, sizeof (struct ble_gap_reattempt_ctxt)); } } +#if MYNEWT_VAL(BT_NIMBLE_MEM_OPTIMIZATION) + else if (!(conn->bhc_flags & BLE_HS_CONN_F_MASTER) && \ + ((ev->reason == BLE_ERR_CONN_ESTABLISHMENT) || should_reattempt)) { +#else else if (!(conn->bhc_flags & BLE_HS_CONN_F_MASTER) && \ ((ev->reason == BLE_ERR_CONN_ESTABLISHMENT) || \ (!conn->slave_conn && ev->reason == BLE_ERR_CONN_SPVN_TMO))) { //slave - +#endif BLE_HS_LOG(INFO, "Reattempt advertising; reason: 0x%x, status = %x", ev->reason, ev->status); ble_l2cap_sig_conn_broken(ev->conn_handle, BLE_ERR_CONN_ESTABLISHMENT); @@ -361,12 +528,14 @@ ble_hs_hci_evt_disconn_complete(uint8_t event_code, const void *data, return rc; } +#if MYNEWT_VAL(BLE_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_ROLE_BROADCASTER) rc = ble_gap_slave_adv_reattempt(); if (rc != 0) { BLE_HS_LOG(INFO, "Adv reattempt failed; rc= %d ", rc); } return 0; // Restart advertising, so don't post disconnect event +#endif } else { /* Normal disconnect. Reset the structure */ memset(&reattempt_conn, 0x0, sizeof (struct ble_gap_reattempt_ctxt)); @@ -388,11 +557,14 @@ ble_hs_hci_evt_disconn_complete(uint8_t event_code, const void *data, * controller for additional ACL data packets. Wake up any stalled * connections. */ +#if NIMBLE_BLE_CONNECT ble_hs_wakeup_tx(); +#endif return 0; } +#if MYNEWT_VAL(BLE_SM_SC) static int ble_hs_hci_evt_encrypt_change(uint8_t event_code, const void *data, unsigned int len) @@ -408,6 +580,7 @@ ble_hs_hci_evt_encrypt_change(uint8_t event_code, const void *data, return 0; } #endif +#endif static int ble_hs_hci_evt_hw_error(uint8_t event_code, const void *data, unsigned int len) { @@ -422,7 +595,7 @@ ble_hs_hci_evt_hw_error(uint8_t event_code, const void *data, unsigned int len) return 0; } -#if NIMBLE_BLE_CONNECT +#if NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_SM_SC) static int ble_hs_hci_evt_enc_key_refresh(uint8_t event_code, const void *data, unsigned int len) @@ -479,8 +652,10 @@ ble_hs_hci_evt_num_completed_pkts(uint8_t event_code, const void *data, } } +#if NIMBLE_BLE_CONNECT /* If any transmissions have stalled, wake them up now. */ ble_hs_wakeup_tx(); +#endif return 0; } @@ -501,6 +676,7 @@ ble_hs_hci_evt_vs(uint8_t event_code, const void *data, unsigned int len) } #endif +#if MYNEWT_VAL(BLE_DTM_MODE_TEST) static int ble_hs_hci_evt_rx_test(uint8_t event_code, const void *data, unsigned int len) { @@ -524,6 +700,7 @@ ble_hs_hci_evt_end_test(uint8_t event_code, const void *data, unsigned int len) return 0; } +#endif static int ble_hs_hci_evt_le_meta(uint8_t event_code, const void *data, unsigned int len) @@ -543,9 +720,6 @@ ble_hs_hci_evt_le_meta(uint8_t event_code, const void *data, unsigned int len) return 0; } -#if MYNEWT_VAL(BLE_EXT_ADV) -static struct ble_gap_conn_complete pend_conn_complete; -#endif #if NIMBLE_BLE_CONNECT static int @@ -595,6 +769,13 @@ ble_hs_hci_evt_le_enh_conn_complete(uint8_t subevent, const void *data, #if MYNEWT_VAL(BLE_EXT_ADV) && !MYNEWT_VAL(BLE_PERIODIC_ADV_WITH_RESPONSES) if (evt.status == BLE_ERR_DIR_ADV_TMO || evt.role == BLE_HCI_LE_CONN_COMPLETE_ROLE_SLAVE) { + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_hs_hci_ensure_ctx()) { + return BLE_HS_ENOMEM; + } +#endif + /* store this until we get set terminated event with adv handle */ memcpy(&pend_conn_complete, &evt, sizeof(evt)); return 0; @@ -660,7 +841,14 @@ ble_hs_hci_evt_le_conn_complete(uint8_t subevent, const void *data, #if MYNEWT_VAL(BLE_EXT_ADV) if (evt.status == BLE_ERR_DIR_ADV_TMO || evt.role == BLE_HCI_LE_CONN_COMPLETE_ROLE_SLAVE) { - /* store this until we get set terminated event with adv handle */ + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_hs_hci_ensure_ctx()) { + return BLE_HS_ENOMEM; + } +#endif + + /* store this until we get set terminated event with adv handle */ memcpy(&pend_conn_complete, &evt, sizeof(evt)); return 0; } @@ -669,6 +857,7 @@ ble_hs_hci_evt_le_conn_complete(uint8_t subevent, const void *data, } #endif +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_OBSERVER) static int ble_hs_hci_evt_le_adv_rpt_first_pass(const void *data, unsigned int len) { @@ -807,7 +996,9 @@ ble_hs_hci_evt_le_dir_adv_rpt(uint8_t subevent, const void *data, unsigned int l return 0; } +#endif +#if NIMBLE_BLE_CONNECT static int ble_hs_hci_evt_le_rd_rem_used_feat_complete(uint8_t subevent, const void *data, unsigned int len) @@ -837,7 +1028,7 @@ ble_hs_hci_evt_rd_rem_ver_complete(uint8_t subevent, const void *data, return 0; } - +#endif #if MYNEWT_VAL(BLE_EXT_ADV) && NIMBLE_BLE_SCAN static int @@ -1086,11 +1277,12 @@ ble_hs_hci_evt_le_ext_adv_rpt_first_pass(const void *data, unsigned int len) } #endif +#if MYNEWT_VAL(BLE_EXT_ADV) static int ble_hs_hci_evt_le_ext_adv_rpt(uint8_t subevent, const void *data, unsigned int len) { -#if MYNEWT_VAL(BLE_EXT_ADV) && NIMBLE_BLE_SCAN +#if NIMBLE_BLE_SCAN const struct ble_hci_ev_le_subev_ext_adv_rpt *ev = data; const struct ext_adv_report *report; struct ble_gap_ext_disc_desc desc; @@ -1151,12 +1343,13 @@ ble_hs_hci_evt_le_ext_adv_rpt(uint8_t subevent, const void *data, #endif return 0; } +#endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV) static int ble_hs_hci_evt_le_periodic_adv_sync_estab(uint8_t subevent, const void *data, unsigned int len) { -#if MYNEWT_VAL(BLE_PERIODIC_ADV) const struct ble_hci_ev_le_subev_periodic_adv_sync_estab *ev = data; if (len != sizeof(*ev)) { @@ -1164,16 +1357,16 @@ ble_hs_hci_evt_le_periodic_adv_sync_estab(uint8_t subevent, const void *data, } ble_gap_rx_peroidic_adv_sync_estab(ev); -#endif return 0; } +#endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV) static int ble_hs_hci_evt_le_periodic_adv_rpt(uint8_t subevent, const void *data, unsigned int len) { -#if MYNEWT_VAL(BLE_PERIODIC_ADV) const struct ble_hci_ev_le_subev_periodic_adv_rpt *ev = data; if (len < sizeof(*ev) || len != (sizeof(*ev) + ev->data_len)) { @@ -1181,16 +1374,16 @@ ble_hs_hci_evt_le_periodic_adv_rpt(uint8_t subevent, const void *data, } ble_gap_rx_periodic_adv_rpt(ev); -#endif return 0; } +#endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV) static int ble_hs_hci_evt_le_periodic_adv_sync_lost(uint8_t subevent, const void *data, unsigned int len) { -#if MYNEWT_VAL(BLE_PERIODIC_ADV) const struct ble_hci_ev_le_subev_periodic_adv_sync_lost *ev = data; if (len != sizeof(*ev)) { @@ -1199,9 +1392,9 @@ ble_hs_hci_evt_le_periodic_adv_sync_lost(uint8_t subevent, const void *data, ble_gap_rx_periodic_adv_sync_lost(ev); -#endif return 0; } +#endif #if MYNEWT_VAL(BLE_POWER_CONTROL) static int @@ -1233,6 +1426,7 @@ ble_hs_hci_evt_le_transmit_power_report(uint8_t subevent, const void *data, } #endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV) static int ble_hs_hci_evt_le_periodic_adv_sync_transfer(uint8_t subevent, const void *data, unsigned int len) @@ -1249,6 +1443,7 @@ ble_hs_hci_evt_le_periodic_adv_sync_transfer(uint8_t subevent, const void *data, #endif return 0; } +#endif #if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS) && !MYNEWT_VAL(BLE_ISO) static int @@ -1267,6 +1462,7 @@ ble_hs_hci_evt_le_biginfo_adv_report(uint8_t subevent, const void *data, } #endif +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_OBSERVER) static int ble_hs_hci_evt_le_scan_timeout(uint8_t subevent, const void *data, unsigned int len) @@ -1282,7 +1478,9 @@ ble_hs_hci_evt_le_scan_timeout(uint8_t subevent, const void *data, #endif return 0; } +#endif +#if MYNEWT_VAL(BLE_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_ROLE_BROADCASTER) static int ble_hs_hci_evt_le_adv_set_terminated(uint8_t subevent, const void *data, unsigned int len) @@ -1302,7 +1500,13 @@ ble_hs_hci_evt_le_adv_set_terminated(uint8_t subevent, const void *data, } if (ev->status == 0) { - /* ignore return code as we need to terminate advertising set anyway */ + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_hs_hci_ensure_ctx()) { + return BLE_HS_ENOMEM; + } +#endif + /* ignore return code as we need to terminate advertising set anyway */ ble_gap_rx_conn_complete(&pend_conn_complete, ev->adv_handle); } ble_gap_rx_adv_set_terminated(ev); @@ -1334,6 +1538,7 @@ ble_hs_hci_evt_le_scan_req_rcvd(uint8_t subevent, const void *data, return 0; } +#endif #if MYNEWT_VAL(BLE_CONN_SUBRATING) static int @@ -1639,6 +1844,7 @@ ble_hs_hci_evt_process(struct ble_hci_ev *ev) return rc; } +#if NIMBLE_BLE_CONNECT /** * Called when a data packet is received from the controller. This function * consumes the supplied mbuf, regardless of the outcome. @@ -1651,10 +1857,12 @@ ble_hs_hci_evt_process(struct ble_hci_ev *ev) int ble_hs_hci_evt_acl_process(struct os_mbuf *om) { -#if NIMBLE_BLE_CONNECT struct hci_data_hdr hci_hdr; struct ble_hs_conn *conn; ble_l2cap_rx_fn *rx_cb; +#if MYNEWT_VAL(BT_NIMBLE_MEM_OPTIMIZATION) + struct ble_l2cap_chan *chan; +#endif uint16_t conn_handle; int reject_cid; int rc; @@ -1702,8 +1910,14 @@ ble_hs_hci_evt_acl_process(struct os_mbuf *om) case 0: /* Final fragment received. */ BLE_HS_DBG_ASSERT(rx_cb != NULL); +#if MYNEWT_VAL(BT_NIMBLE_MEM_OPTIMIZATION) + chan = ble_hs_conn_chan_find_by_scid(conn,conn->bhc_rx_scid); + rc = rx_cb(chan); + ble_l2cap_remove_rx(conn, chan); +#else rc = rx_cb(conn->bhc_rx_chan); - ble_l2cap_remove_rx(conn, conn->bhc_rx_chan); + ble_l2cap_remove_rx(conn, conn->bhc_rx_chan); +#endif break; case BLE_HS_EAGAIN: @@ -1722,10 +1936,8 @@ ble_hs_hci_evt_acl_process(struct os_mbuf *om) err: os_mbuf_free_chain(om); return rc; -#else - return BLE_HS_ENOTSUP; -#endif } +#endif #if MYNEWT_VAL(BLE_QUEUE_CONG_CHECK) struct ble_addr_list_entry @@ -1738,6 +1950,12 @@ SLIST_HEAD(ble_device_list, ble_addr_list_entry) ble_adv_list; void ble_adv_list_init(void) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_hs_hci_ensure_ctx()) { + return; + } +#endif + ble_npl_mutex_init(&adv_list_lock); SLIST_INIT(&ble_adv_list); @@ -1796,6 +2014,12 @@ void ble_adv_list_refresh(void) struct ble_addr_list_entry *temp; ble_adv_list_count = 0; + if (SLIST_EMPTY(&ble_adv_list)) { + BLE_HS_LOG(ERROR, "%s: ble_adv_list empty — reinitializing", __func__); + SLIST_INIT(&ble_adv_list); + ble_adv_list_count = 0; + return; + } if (SLIST_EMPTY(&ble_adv_list)) { BLE_HS_LOG(ERROR, "%s ble_adv_list is empty", __func__); return; @@ -1834,7 +2058,7 @@ bool ble_check_adv_list(const uint8_t *addr, uint8_t addr_type) ble_npl_mutex_release(&adv_list_lock); if (!found) { - adv_packet = nimble_platform_mem_malloc(sizeof(struct ble_addr_list_entry)); + adv_packet = nimble_platform_mem_calloc(1,sizeof(struct ble_addr_list_entry)); if (adv_packet) { adv_packet->addr.type = addr_type; memcpy(adv_packet->addr.val, addr, BLE_DEV_ADDR_LEN); diff --git a/nimble/host/src/ble_hs_hci_priv.h b/nimble/host/src/ble_hs_hci_priv.h index 2f8ec4ca4..51ece2e3d 100644 --- a/nimble/host/src/ble_hs_hci_priv.h +++ b/nimble/host/src/ble_hs_hci_priv.h @@ -153,6 +153,10 @@ int ble_hs_hci_read_monitor_adv_list_size(uint8_t *out_number); int ble_hs_hci_enable_monitor_adv(uint8_t enable); #endif +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void ble_hs_hci_ctx_free(void); +#endif + #ifdef __cplusplus } #endif diff --git a/nimble/host/src/ble_hs_hci_util.c b/nimble/host/src/ble_hs_hci_util.c index b9b782517..ef537ac7a 100644 --- a/nimble/host/src/ble_hs_hci_util.c +++ b/nimble/host/src/ble_hs_hci_util.c @@ -278,6 +278,7 @@ ble_hs_hci_set_chan_class(const uint8_t *chan_map) &cmd, sizeof(cmd), NULL, 0); } +#if MYNEWT_VAL(BLE_UTIL_API) int ble_hs_hci_util_set_data_addr_change(uint8_t adv_handle, uint8_t change_reason) { @@ -291,7 +292,9 @@ ble_hs_hci_util_set_data_addr_change(uint8_t adv_handle, uint8_t change_reason) return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); } +#endif +#if MYNEWT_VAL(BLE_DTM_MODE_TEST) int ble_hs_hci_dtm_tx_start(const uint8_t tx_chan, const uint8_t test_data_len, const uint8_t payload) @@ -360,7 +363,9 @@ ble_hs_hci_dtm_enh_rx_start(const uint8_t rx_chan, const uint8_t index, return ble_hs_hci_cmd_tx_no_rsp(opcode, &cmd, sizeof(cmd)); } +#endif +#if MYNEWT_VAL(BLE_UTIL_API) int ble_hs_hci_set_host_feature(uint8_t bit_num, uint8_t bit_val) { @@ -377,6 +382,7 @@ ble_hs_hci_set_host_feature(uint8_t bit_num, uint8_t bit_val) BLE_HCI_OCF_LE_SET_HOST_FEATURE), &cmd, sizeof(cmd), NULL, 0); } +#endif int ble_hs_hci_rd_all_local_supp_features(uint8_t* status, uint8_t* max_page, diff --git a/nimble/host/src/ble_hs_id.c b/nimble/host/src/ble_hs_id.c index 2d05bd8a4..81823d656 100644 --- a/nimble/host/src/ble_hs_id.c +++ b/nimble/host/src/ble_hs_id.c @@ -20,13 +20,56 @@ #include #include "host/ble_hs_id.h" #include "ble_hs_priv.h" +#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) #include "ble_hs_resolv_priv.h" +#endif + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#include "esp_nimble_mem.h" +typedef struct { + uint8_t ble_hs_id_pub[6]; + uint8_t ble_hs_id_rnd[6]; +}ble_hs_id_ctx_t; + +static ble_hs_id_ctx_t *ble_hs_id_ctx; + +#define ble_hs_id_pub (ble_hs_id_ctx->ble_hs_id_pub) +#define ble_hs_id_rnd (ble_hs_id_ctx->ble_hs_id_rnd) +#else static uint8_t ble_hs_id_pub[6]; static uint8_t ble_hs_id_rnd[6]; +#endif + static const uint8_t ble_hs_misc_null_addr[6]; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +int +ble_hs_id_ensure_ctx(void) +{ + if (ble_hs_id_ctx) { + return 0; + } + ble_hs_id_ctx = nimble_platform_mem_calloc(1, sizeof(* ble_hs_id_ctx)); + + if (!ble_hs_id_ctx) { + return BLE_HS_ENOMEM; + } + + return 0; +} + +void ble_hs_id_ctx_free(void) +{ + if (ble_hs_id_ctx) { + nimble_platform_mem_free(ble_hs_id_ctx); + ble_hs_id_ctx = NULL; + } +} +#endif + +#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) bool ble_hs_is_rpa(uint8_t *addr, uint8_t addr_type) { @@ -38,10 +81,16 @@ ble_hs_is_rpa(uint8_t *addr, uint8_t addr_type) } return rc; } +#endif void ble_hs_id_set_pub(const uint8_t *pub_addr) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_hs_id_ensure_ctx()) { + return; + } +#endif ble_hs_lock(); memcpy(ble_hs_id_pub, pub_addr, 6); ble_hs_unlock(); @@ -157,6 +206,12 @@ ble_hs_id_set_rnd(const uint8_t *rnd_addr) int rc; int ones; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_hs_id_ensure_ctx()) { + return BLE_HS_EINVAL; + } +#endif + ble_hs_lock(); /* Make sure random part of rnd_addr is not all ones or zeros. Reference: @@ -320,11 +375,14 @@ ble_hs_id_use_addr(uint8_t own_addr_type) /* If privacy is being used, make sure RPA rotation is in effect. */ if (own_addr_type == BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT || own_addr_type == BLE_OWN_ADDR_RPA_RANDOM_DEFAULT) { - +#if MYNEWT_VAL(BLE_HS_PVCY) rc = ble_hs_pvcy_ensure_started(); if (rc != 0) { return rc; } +#else + return BLE_HS_ENOTSUP; +#endif } return 0; @@ -388,6 +446,11 @@ done: void ble_hs_id_reset(void) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_hs_id_ensure_ctx()) { + return; + } +#endif memset(ble_hs_id_pub, 0, sizeof ble_hs_id_pub); memset(ble_hs_id_rnd, 0, sizeof ble_hs_id_rnd); } @@ -396,8 +459,15 @@ ble_hs_id_reset(void) * Clears random address. This function is necessary when the host wants to * clear random address. */ - void - ble_hs_id_rnd_reset(void) - { +void +ble_hs_id_rnd_reset(void) +{ + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_hs_id_ensure_ctx()) { + return; + } +#endif + memset(ble_hs_id_rnd, 0, sizeof ble_hs_id_rnd); - } +} diff --git a/nimble/host/src/ble_hs_id_priv.h b/nimble/host/src/ble_hs_id_priv.h index 85260ec48..2657a9203 100644 --- a/nimble/host/src/ble_hs_id_priv.h +++ b/nimble/host/src/ble_hs_id_priv.h @@ -32,6 +32,7 @@ int ble_hs_id_addr(uint8_t id_addr_type, const uint8_t **out_id_addr, int ble_hs_id_use_addr(uint8_t addr_type); void ble_hs_id_reset(void); void ble_hs_id_rnd_reset(void); +void ble_hs_id_ctx_free(void); #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) bool ble_hs_is_rpa(uint8_t *addr, uint8_t addr_type); diff --git a/nimble/host/src/ble_hs_iso.c b/nimble/host/src/ble_hs_iso.c index 8461f35e5..456eaffa1 100644 --- a/nimble/host/src/ble_hs_iso.c +++ b/nimble/host/src/ble_hs_iso.c @@ -181,7 +181,7 @@ ble_hs_hci_iso_tx_now(uint16_t conn_handle, const uint8_t *sdu, uint16_t sdu_len dlh_len = (ts_flag ? BLE_HCI_ISO_DATA_LOAD_TS_SZ : 0) + BLE_HCI_ISO_DATA_LOAD_HDR_SZ; - frag = nimble_platform_mem_malloc(BLE_HCI_ISO_DATA_HDR_SZ + dlh_len + sdu_len); + frag = nimble_platform_mem_calloc(1,BLE_HCI_ISO_DATA_HDR_SZ + dlh_len + sdu_len); if (frag == NULL) { return BLE_HS_ENOMEM; } diff --git a/nimble/host/src/ble_hs_misc.c b/nimble/host/src/ble_hs_misc.c index c016ce75e..33050ffe8 100644 --- a/nimble/host/src/ble_hs_misc.c +++ b/nimble/host/src/ble_hs_misc.c @@ -114,19 +114,22 @@ ble_hs_misc_peer_addr_type_to_id(uint8_t peer_addr_type) } } +#if NIMBLE_BLE_CONNECT static int ble_hs_misc_restore_one_irk(int obj_type, union ble_store_value *val, void *cookie) { const struct ble_store_value_sec *sec; - int rc; + int rc = -1; BLE_HS_DBG_ASSERT(obj_type == BLE_STORE_OBJ_TYPE_PEER_SEC); sec = &val->sec; if (sec->irk_present) { +#if MYNEWT_VAL(BLE_HS_PVCY) rc = ble_hs_pvcy_add_entry(sec->peer_addr.val, sec->peer_addr.type, sec->irk); +#endif if (rc != 0) { BLE_HS_LOG(ERROR, "failed to configure restored IRK\n"); } @@ -145,3 +148,4 @@ ble_hs_misc_restore_irks(void) NULL); return rc; } +#endif diff --git a/nimble/host/src/ble_hs_periodic_sync.c b/nimble/host/src/ble_hs_periodic_sync.c index 71d5ca907..d18ae3dc9 100644 --- a/nimble/host/src/ble_hs_periodic_sync.c +++ b/nimble/host/src/ble_hs_periodic_sync.c @@ -26,8 +26,21 @@ #if MYNEWT_VAL(BLE_PERIODIC_ADV) static SLIST_HEAD(, ble_hs_periodic_sync) g_ble_hs_periodic_sync_handles; -static struct os_mempool ble_hs_periodic_sync_pool; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#include "esp_nimble_mem.h" +static struct +{ + struct os_mempool pool; + os_membuf_t *elem_mem; +} *ble_hs_periodic_ctx; +#define ble_hs_periodic_sync_pool (ble_hs_periodic_ctx->pool) +#define ble_hs_psync_elem_mem (ble_hs_periodic_ctx->elem_mem) +#else +static struct os_mempool ble_hs_periodic_sync_pool; +#endif + +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) #if MYNEWT_VAL(MP_RUNTIME_ALLOC) static os_membuf_t *ble_hs_psync_elem_mem = NULL; #else @@ -36,6 +49,21 @@ static os_membuf_t ble_hs_psync_elem_mem[ sizeof (struct ble_hs_periodic_sync)) ]; #endif +#endif + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +static int +ble_hs_periodic_sync_ensure_ctx(void) +{ + if (ble_hs_periodic_ctx != NULL) + { + return 0; + } + + ble_hs_periodic_ctx = nimble_platform_mem_calloc(1, sizeof(*ble_hs_periodic_ctx)); + return ble_hs_periodic_ctx ? 0 : BLE_HS_ENOMEM; +} +#endif struct ble_hs_periodic_sync * ble_hs_periodic_sync_alloc(void) @@ -59,7 +87,7 @@ ble_hs_periodic_sync_free(struct ble_hs_periodic_sync *psync) return; } - if((psync->lost_ev).event != NULL) + if ((psync->lost_ev).event != NULL) ble_npl_event_deinit(&psync->lost_ev); #if MYNEWT_VAL(BLE_HS_DEBUG) @@ -75,7 +103,7 @@ ble_hs_periodic_sync_insert(struct ble_hs_periodic_sync *psync) BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task()); BLE_HS_DBG_ASSERT_EVAL( - ble_hs_periodic_sync_find_by_handle(psync->sync_handle) == NULL); + ble_hs_periodic_sync_find_by_handle(psync->sync_handle) == NULL); SLIST_INSERT_HEAD(&g_ble_hs_periodic_sync_handles, psync, next); } @@ -118,7 +146,8 @@ ble_hs_periodic_sync_find(const ble_addr_t *addr, uint8_t sid) SLIST_FOREACH(psync, &g_ble_hs_periodic_sync_handles, next) { if ((ble_addr_cmp(&psync->advertiser_addr, addr) == 0) && - (psync->adv_sid == sid)) { + (psync->adv_sid == sid)) + { return psync; } } @@ -141,16 +170,81 @@ ble_hs_periodic_sync_first(void) return psync; } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void +ble_hs_periodic_sync_deinit(void) +{ + if (ble_hs_periodic_ctx == NULL) + { + return; + } +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + if (ble_hs_psync_elem_mem) + { + nimble_platform_mem_free(ble_hs_psync_elem_mem); + } +#endif + memset(&ble_hs_periodic_sync_pool, 0, sizeof(ble_hs_periodic_sync_pool)); + nimble_platform_mem_free(ble_hs_periodic_ctx); + ble_hs_periodic_ctx = NULL; +} +#endif + int ble_hs_periodic_sync_init(void) { int rc; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + rc = ble_hs_periodic_sync_ensure_ctx(); + if (rc != 0) + { + return rc; + } + +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + if (!ble_hs_psync_elem_mem) + { + ble_hs_psync_elem_mem = nimble_platform_mem_calloc(1, + OS_MEMPOOL_SIZE( + MYNEWT_VAL(BLE_MAX_PERIODIC_SYNCS), + sizeof(struct ble_hs_periodic_sync)) * + sizeof(os_membuf_t)); + } + + if (ble_hs_psync_elem_mem == NULL) + { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_hs_periodic_ctx) { + nimble_platform_mem_free(ble_hs_periodic_ctx); + ble_hs_periodic_ctx = NULL; + } +#endif + return BLE_HS_ENOMEM; + } + + memset(&ble_hs_periodic_sync_pool, 0, sizeof(ble_hs_periodic_sync_pool)); +#endif +#endif + rc = os_mempool_init(&ble_hs_periodic_sync_pool, MYNEWT_VAL(BLE_MAX_PERIODIC_SYNCS), - sizeof (struct ble_hs_periodic_sync), + sizeof(struct ble_hs_periodic_sync), ble_hs_psync_elem_mem, "ble_hs_periodic_disc_pool"); if (rc != 0) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + if (ble_hs_psync_elem_mem) + { + nimble_platform_mem_free(ble_hs_psync_elem_mem); + } +#endif + if (ble_hs_periodic_ctx) + { + nimble_platform_mem_free(ble_hs_periodic_ctx); + ble_hs_periodic_ctx = NULL; + } +#endif return BLE_HS_EOS; } diff --git a/nimble/host/src/ble_hs_periodic_sync_priv.h b/nimble/host/src/ble_hs_periodic_sync_priv.h index c82ea7904..1f0a02526 100644 --- a/nimble/host/src/ble_hs_periodic_sync_priv.h +++ b/nimble/host/src/ble_hs_periodic_sync_priv.h @@ -47,7 +47,7 @@ struct ble_hs_periodic_sync *ble_hs_periodic_sync_find(const ble_addr_t *addr, uint8_t sid); struct ble_hs_periodic_sync *ble_hs_periodic_sync_first(void); int ble_hs_periodic_sync_init(void); - +void ble_hs_periodic_sync_deinit(void); #ifdef __cplusplus } #endif diff --git a/nimble/host/src/ble_hs_priv.h b/nimble/host/src/ble_hs_priv.h index cb97e5374..62bf02114 100644 --- a/nimble/host/src/ble_hs_priv.h +++ b/nimble/host/src/ble_hs_priv.h @@ -95,12 +95,29 @@ STATS_SECT_END extern STATS_SECT_DECL(ble_hs_stats) ble_hs_stats; extern struct os_mbuf_pool ble_hs_mbuf_pool; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +typedef struct { + uint8_t sync_state; + uint8_t enabled_state; + uint16_t max_attrs; + uint16_t max_services; + uint16_t max_client_configs; +} ble_hs_state_ctx_t; + +#define ble_hs_sync_state (ble_hs_state_ctx->sync_state) +#define ble_hs_enabled_state (ble_hs_state_ctx->enabled_state) +#define ble_hs_max_attrs (ble_hs_state_ctx->max_attrs) +#define ble_hs_max_services (ble_hs_state_ctx->max_services) +#define ble_hs_max_client_configs (ble_hs_state_ctx->max_client_configs) +extern ble_hs_state_ctx_t *ble_hs_state_ctx; +#else extern uint8_t ble_hs_sync_state; extern uint8_t ble_hs_enabled_state; extern uint16_t ble_hs_max_attrs; extern uint16_t ble_hs_max_services; extern uint16_t ble_hs_max_client_configs; +#endif // BT_NIMBLE_MEM_OPTIMIZATION void ble_hs_process_rx_data_queue(void); int ble_hs_tx_data(struct os_mbuf *om); @@ -143,7 +160,9 @@ int ble_mqueue_init(struct ble_mqueue *mq, ble_npl_event_fn *ev_fn, void *ev_arg struct os_mbuf *ble_mqueue_get(struct ble_mqueue *mq); int ble_mqueue_put(struct ble_mqueue *mq, struct ble_npl_eventq *evq, struct os_mbuf *om); +#if MYNEWT_VAL(BLE_PERIODIC_ADV) void ble_gap_npl_sync_lost(struct ble_npl_event *ev); +#endif #if MYNEWT_VAL(BLE_HS_DEBUG) #define BLE_HS_DBG_ASSERT(x) assert(x) diff --git a/nimble/host/src/ble_hs_pvcy.c b/nimble/host/src/ble_hs_pvcy.c index a0cb261ac..fabd7aa1c 100644 --- a/nimble/host/src/ble_hs_pvcy.c +++ b/nimble/host/src/ble_hs_pvcy.c @@ -24,12 +24,32 @@ #include "ble_hs_resolv_priv.h" #include "host/ble_hs_pvcy.h" +#if MYNEWT_VAL(BLE_HS_PVCY) +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#include "esp_nimble_mem.h" + +typedef struct { + uint8_t pvcy_started; /* Indicates if privacy is started */ + uint8_t pvcy_irk[16]; /* Static IRK */ + uint8_t pvcy_default_irk[16]; /* Static default IRK */ + uint16_t rpa_timeout; /* Timeout for RPA rotation */ +} ble_hs_pvcy_ctx_t; + +static ble_hs_pvcy_ctx_t *ble_hs_pvcy_ctx; + +#define ble_hs_pvcy_started (ble_hs_pvcy_ctx->pvcy_started) +#define ble_hs_pvcy_irk (ble_hs_pvcy_ctx->pvcy_irk) +#define ble_hs_pvcy_default_irk (ble_hs_pvcy_ctx->pvcy_default_irk) +#define l_rpa_timeout (ble_hs_pvcy_ctx->rpa_timeout) + +#else static uint8_t ble_hs_pvcy_started; static uint8_t ble_hs_pvcy_irk[16]; /** Use this as a default IRK if none gets set. */ uint8_t ble_hs_pvcy_default_irk[16]; -uint16_t rpa_timeout; +uint16_t l_rpa_timeout; +#endif static int ble_hs_pvcy_set_addr_timeout(uint16_t timeout) @@ -53,19 +73,19 @@ ble_hs_pvcy_set_addr_timeout(uint16_t timeout) int ble_hs_set_rpa_timeout (uint16_t timeout) { - rpa_timeout = timeout; + l_rpa_timeout = timeout; - return ble_hs_pvcy_set_addr_timeout(rpa_timeout); + return ble_hs_pvcy_set_addr_timeout(l_rpa_timeout); } uint16_t ble_hs_get_rpa_timeout(void) { - return rpa_timeout; + return l_rpa_timeout; } void ble_hs_reset_rpa_timeout(void) { - rpa_timeout = 0 ; + l_rpa_timeout = 0 ; } #if (!MYNEWT_VAL(BLE_HOST_BASED_PRIVACY)) @@ -250,12 +270,28 @@ void ble_hs_pvcy_set_default_irk(void) /* Read NVS for local IRK */ +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (!ble_hs_pvcy_ctx) { + ble_hs_pvcy_ctx = nimble_platform_mem_calloc(1, sizeof(*ble_hs_pvcy_ctx)); + if (!ble_hs_pvcy_ctx) { + BLE_HS_LOG(ERROR," Failed to allocate memory for ble_hs_pvcy_ctx"); + return; + } + } + + void ble_store_config_init(void); + ble_store_config_init(); +#endif + rc = ble_store_read_local_irk(&key_local_irk, &value_local_irk); if (!rc) { memcpy(ble_hs_pvcy_default_irk, value_local_irk.irk, 16); } else { + +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) /* No entry for local IRK found . Generate one and load in NVS */ memset(ble_hs_pvcy_default_irk, 0x0, 16); +#endif rc = ble_hs_hci_util_rand(ble_hs_pvcy_default_irk, 16); if (rc != 0) { @@ -277,6 +313,17 @@ void ble_hs_pvcy_set_default_irk(void) } } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void +ble_hs_pvcy_irk_deinit(void) +{ + if (ble_hs_pvcy_ctx) { + nimble_platform_mem_free(ble_hs_pvcy_ctx); + ble_hs_pvcy_ctx = NULL; + } +} +#endif + int ble_hs_pvcy_set_our_irk(const uint8_t *irk) { @@ -323,6 +370,8 @@ ble_hs_pvcy_set_our_irk(const uint8_t *irk) } #endif + +#if MYNEWT_VAL(BLE_HS_PVCY) /* * Add local IRK entry with 00:00:00:00:00:00 address. This entry will * be used to generate RPA for non-directed advertising if own_addr_type @@ -336,6 +385,7 @@ ble_hs_pvcy_set_our_irk(const uint8_t *irk) if (rc != 0) { return rc; } +#endif return 0; } @@ -367,13 +417,13 @@ ble_hs_pvcy_set_mode(const ble_addr_t *addr, uint8_t priv_mode) &cmd, sizeof(cmd), NULL, 0); } +#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) bool ble_hs_pvcy_enabled(void) { return ble_hs_pvcy_started; } -#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) int ble_hs_pvcy_rpa_config(uint8_t enable) { @@ -403,3 +453,4 @@ ble_hs_pvcy_rpa_config(uint8_t enable) return rc; } #endif +#endif diff --git a/nimble/host/src/ble_hs_pvcy_priv.h b/nimble/host/src/ble_hs_pvcy_priv.h index 2b0f07b12..b556860f4 100644 --- a/nimble/host/src/ble_hs_pvcy_priv.h +++ b/nimble/host/src/ble_hs_pvcy_priv.h @@ -26,7 +26,11 @@ extern "C" { #endif +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +extern uint8_t *ble_hs_pvcy_default_irk; +#else extern uint8_t ble_hs_pvcy_default_irk[16]; +#endif void ble_hs_pvcy_set_default_irk(void); int ble_hs_pvcy_set_our_irk(const uint8_t *irk); @@ -40,6 +44,7 @@ int ble_hs_pvcy_set_mode(const ble_addr_t *addr, uint8_t priv_mode); bool ble_hs_pvcy_enabled(void); #endif +void ble_hs_pvcy_irk_deinit(void); #ifdef __cplusplus } #endif diff --git a/nimble/host/src/ble_hs_resolv.c b/nimble/host/src/ble_hs_resolv.c index 217cef198..0222fa6e1 100644 --- a/nimble/host/src/ble_hs_resolv.c +++ b/nimble/host/src/ble_hs_resolv.c @@ -117,11 +117,19 @@ ble_rpa_peer_dev_rec_clear_all(void) * peer_records */ for (i = 0; i < num_peer_dev_rec; i++) { ble_store_num_peer_dev_rec--; - memmove(&peer_dev_rec[0], &peer_dev_rec[1], - ble_store_num_peer_dev_rec * sizeof(struct ble_hs_dev_records)); - memset(&peer_dev_rec[ble_store_num_peer_dev_rec], 0, + + if (ble_store_num_peer_dev_rec > 1) { + /* Copy (n-1) valid elements, only if the array can hold at least 2 */ +#if BLE_RESOLV_LIST_SIZE > 1 + size_t move_count = (ble_store_num_peer_dev_rec - 1) * sizeof(peer_dev_rec[0]); + __builtin_memmove(&peer_dev_rec[0], &peer_dev_rec[1], move_count); +#endif + } + + memset(&peer_dev_rec[ble_store_num_peer_dev_rec], 0, sizeof(struct ble_hs_dev_records)); - ble_store_persist_peer_records(); + + ble_store_persist_peer_records(); } return; } diff --git a/nimble/host/src/ble_hs_startup.c b/nimble/host/src/ble_hs_startup.c index 3c5badf23..2190b9fc3 100644 --- a/nimble/host/src/ble_hs_startup.c +++ b/nimble/host/src/ble_hs_startup.c @@ -568,18 +568,22 @@ ble_hs_startup_go(void) memset(&gen_key, 0, sizeof(gen_key)); rc = ble_hs_cfg.store_gen_key_cb(BLE_STORE_GEN_KEY_IRK, &gen_key, BLE_HS_CONN_HANDLE_NONE); - if (rc == 0) { +#if MYNEWT_VAL(BLE_HS_PVCY) + if (rc == 0) { ble_hs_pvcy_set_our_irk(gen_key.irk); } +#endif } else { rc = -1; } +#if MYNEWT_VAL(BLE_HS_PVCY) if (rc != 0) { ble_hs_pvcy_set_default_irk(); ble_hs_pvcy_set_our_irk(NULL); } +#endif /* If flow control is enabled, configure the controller to use it. */ ble_hs_flow_startup(); diff --git a/nimble/host/src/ble_hs_stop.c b/nimble/host/src/ble_hs_stop.c index 06ee06b1a..fbb7b2ffb 100644 --- a/nimble/host/src/ble_hs_stop.c +++ b/nimble/host/src/ble_hs_stop.c @@ -29,19 +29,43 @@ #define BLE_HOST_STOP_TIMEOUT_MS MYNEWT_VAL(BLE_HS_STOP_ON_SHUTDOWN_TIMEOUT) +SLIST_HEAD(ble_hs_stop_listener_slist, ble_hs_stop_listener); + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#include "esp_nimble_mem.h" + +/** + * Global context for Host stop procedure. + * Holds listener list, GAP listener, connection count, and timeout callout. + */ +struct ble_hs_stop_ctx { + struct ble_gap_event_listener gap_listener; /* GAP stop listener */ + struct ble_hs_stop_listener_slist listeners; /* Registered stop listeners */ + uint8_t conn_cnt; /* Number of active connections */ + struct ble_npl_callout terminate_tmo; /* Stop termination timeout */ +}; + +static struct ble_hs_stop_ctx *ble_hs_stop_ctx; + +/* Macros for cleaner access */ +#define ble_hs_stop_gap_listener (ble_hs_stop_ctx->gap_listener) +#define ble_hs_stop_listeners (ble_hs_stop_ctx->listeners) +#define ble_hs_stop_conn_cnt (ble_hs_stop_ctx->conn_cnt) +#define ble_hs_stop_terminate_tmo (ble_hs_stop_ctx->terminate_tmo) +#else static struct ble_gap_event_listener ble_hs_stop_gap_listener; /** * List of stop listeners. These are notified when a stop procedure completes. */ -SLIST_HEAD(ble_hs_stop_listener_slist, ble_hs_stop_listener); +//SLIST_HEAD(ble_hs_stop_listener_slist, ble_hs_stop_listener); static struct ble_hs_stop_listener_slist ble_hs_stop_listeners; /* Track number of connections */ static uint8_t ble_hs_stop_conn_cnt; static struct ble_npl_callout ble_hs_stop_terminate_tmo; - +#endif /** * Called when a stop procedure has completed. */ @@ -274,6 +298,16 @@ ble_hs_stop(struct ble_hs_stop_listener *listener, void ble_hs_stop_init(void) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (!ble_hs_stop_ctx) { + ble_hs_stop_ctx = nimble_platform_mem_calloc(1, sizeof(*ble_hs_stop_ctx)); + if (!ble_hs_stop_ctx) { + MODLOG_DFLT(ERROR, "Failed to allocate memory for ble_hs_stop_ctx\n"); + return; + } + } +#endif + #ifdef MYNEWT ble_npl_callout_init(&ble_hs_stop_terminate_tmo, ble_npl_eventq_dflt_get(), ble_hs_stop_terminate_timeout_cb, NULL); @@ -287,4 +321,11 @@ void ble_hs_stop_deinit(void) { ble_npl_callout_deinit(&ble_hs_stop_terminate_tmo); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_hs_stop_ctx) { + nimble_platform_mem_free(ble_hs_stop_ctx); + ble_hs_stop_ctx = NULL; + } +#endif + } diff --git a/nimble/host/src/ble_l2cap.c b/nimble/host/src/ble_l2cap.c index de3d674d3..9a32edfba 100644 --- a/nimble/host/src/ble_l2cap.c +++ b/nimble/host/src/ble_l2cap.c @@ -26,13 +26,17 @@ #include "nimble/hci_common.h" #include "ble_hs_priv.h" #include "ble_l2cap_coc_priv.h" +#include "esp_nimble_mem.h" #if NIMBLE_BLE_CONNECT _Static_assert(sizeof (struct ble_l2cap_hdr) == BLE_L2CAP_HDR_SZ, "struct ble_l2cap_hdr must be 4 bytes"); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +ble_l2cap_ctx_t *ble_l2cap_ctx; +#define ble_l2cap_chan_mem (ble_l2cap_ctx->chan_mem) +#else struct os_mempool ble_l2cap_chan_pool; - #if MYNEWT_VAL(MP_RUNTIME_ALLOC) static os_membuf_t *ble_l2cap_chan_mem = NULL; #else @@ -41,6 +45,25 @@ static os_membuf_t ble_l2cap_chan_mem[ MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM), sizeof (struct ble_l2cap_chan)) ]; +#endif // MP_RUNTIME_ALLOC +#endif + + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +static int +ble_l2cap_ensure_ctx(void) +{ + if (ble_l2cap_ctx != NULL) { + return 0; + } + + ble_l2cap_ctx = nimble_platform_mem_calloc(1, sizeof(*ble_l2cap_ctx)); + if (ble_l2cap_ctx == NULL) { + return BLE_HS_ENOMEM; + } + + return 0; +} #endif STATS_SECT_DECL(ble_l2cap_stats) ble_l2cap_stats; @@ -62,7 +85,13 @@ ble_l2cap_chan_alloc(uint16_t conn_handle) { struct ble_l2cap_chan *chan; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_l2cap_ctx == NULL) { + return NULL; + } +#endif chan = os_memblock_get(&ble_l2cap_chan_pool); + if (chan == NULL) { return NULL; } @@ -90,7 +119,14 @@ ble_l2cap_chan_free(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan) #if MYNEWT_VAL(BLE_HS_DEBUG) memset(chan, 0xff, sizeof *chan); #endif + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_l2cap_ctx == NULL) { + return; + } +#endif rc = os_memblock_put(&ble_l2cap_chan_pool, chan); + BLE_HS_DBG_ASSERT_EVAL(rc == 0); STATS_INC(ble_l2cap_stats, chan_delete); @@ -214,7 +250,7 @@ ble_l2cap_reconfig(struct ble_l2cap_chan *chans[], uint8_t num, uint16_t new_mtu return ble_l2cap_sig_coc_reconfig(conn_handle, chans, num, new_mtu, MYNEWT_VAL(BLE_L2CAP_COC_MPS)); } - +#if MYNEWT_VAL(BLE_RECONFIG_MTU) int ble_l2cap_reconfig_mtu_mps(struct ble_l2cap_chan *chans[], uint8_t num, uint16_t new_mtu, uint16_t new_mps) { @@ -236,6 +272,7 @@ ble_l2cap_reconfig_mtu_mps(struct ble_l2cap_chan *chans[], uint8_t num, uint16_t return ble_l2cap_sig_coc_reconfig(conn_handle, chans, num, new_mtu, new_mps); } +#endif int ble_l2cap_disconnect(struct ble_l2cap_chan *chan) @@ -262,7 +299,11 @@ ble_l2cap_recv_ready(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_rx) void ble_l2cap_remove_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan) { +#if MYNEWT_VAL(BT_NIMBLE_MEM_OPTIMIZATION) + conn->bhc_rx_scid = 0x0000; +#else conn->bhc_rx_chan = NULL; +#endif os_mbuf_free_chain(chan->rx_buf); chan->rx_buf = NULL; chan->rx_len = 0; @@ -435,12 +476,20 @@ ble_l2cap_rx(struct ble_hs_conn *conn, } /* Remember channel and length of L2CAP data for reassembly. */ +#if MYNEWT_VAL(BT_NIMBLE_MEM_OPTIMIZATION) + conn->bhc_rx_scid = chan->scid; +#else conn->bhc_rx_chan = chan; - chan->rx_len = l2cap_hdr.len; - break; +#endif + chan->rx_len = l2cap_hdr.len; + break; case BLE_HCI_PB_MIDDLE: +#if MYNEWT_VAL(BT_NIMBLE_MEM_OPTIMIZATION) + chan = ble_hs_conn_chan_find_by_scid(conn,conn->bhc_rx_scid); +#else chan = conn->bhc_rx_chan; +#endif if (chan == NULL || chan->rx_buf == NULL) { /* Middle fragment without the start. Discard new packet. */ rc = BLE_HS_EBADDATA; @@ -508,28 +557,61 @@ ble_l2cap_init(void) { int rc; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + rc = ble_l2cap_ensure_ctx(); + if (rc != 0) { + return rc; + } + +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + size_t chan_mem_bytes = OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_L2CAP_MAX_CHANS) + + MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM), + sizeof (struct ble_l2cap_chan)) * sizeof(os_membuf_t); + if (ble_l2cap_chan_mem == NULL) { + ble_l2cap_chan_mem = (os_membuf_t *)nimble_platform_mem_calloc(1, chan_mem_bytes); + if (ble_l2cap_chan_mem == NULL) { + nimble_platform_mem_free(ble_l2cap_ctx); + ble_l2cap_ctx = NULL; + return BLE_HS_ENOMEM; + } + } +#endif +#endif + rc = os_mempool_init(&ble_l2cap_chan_pool, MYNEWT_VAL(BLE_L2CAP_MAX_CHANS) + MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM), sizeof (struct ble_l2cap_chan), ble_l2cap_chan_mem, "ble_l2cap_chan_pool"); + + if (rc != 0) { - return BLE_HS_EOS; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + nimble_platform_mem_free(ble_l2cap_chan_mem); + ble_l2cap_chan_mem = NULL; +#endif + memset(&ble_l2cap_chan_pool, 0, sizeof(ble_l2cap_chan_pool)); + + nimble_platform_mem_free(ble_l2cap_ctx); + ble_l2cap_ctx = NULL; +#endif + return BLE_HS_EOS; } rc = ble_l2cap_sig_init(); if (rc != 0) { - return rc; + goto done; } rc = ble_l2cap_coc_init(); if (rc != 0) { - return rc; + goto done; } rc = ble_sm_init(); if (rc != 0) { - return rc; + goto done; } rc = stats_init_and_reg( @@ -540,6 +622,38 @@ ble_l2cap_init(void) } return 0; +done: +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + nimble_platform_mem_free(ble_l2cap_chan_mem); + ble_l2cap_chan_mem = NULL; +#endif + nimble_platform_mem_free(ble_l2cap_ctx); + ble_l2cap_ctx = NULL; +#endif + return rc; } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void +ble_l2cap_deinit(void) +{ + if (ble_l2cap_ctx != NULL) { +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + if (ble_l2cap_chan_mem != NULL) { + nimble_platform_mem_free(ble_l2cap_chan_mem); + ble_l2cap_chan_mem = NULL; + } +#endif + memset(&ble_l2cap_chan_pool, 0, sizeof(ble_l2cap_chan_pool)); + } + ble_l2cap_sig_deinit(); + ble_l2cap_coc_deinit(); + ble_sm_deinit(); + + nimble_platform_mem_free(ble_l2cap_ctx); + ble_l2cap_ctx = NULL; +} +#endif + #endif diff --git a/nimble/host/src/ble_l2cap_coc.c b/nimble/host/src/ble_l2cap_coc.c index 73de555f3..48b7de76b 100644 --- a/nimble/host/src/ble_l2cap_coc.c +++ b/nimble/host/src/ble_l2cap_coc.c @@ -31,8 +31,20 @@ STAILQ_HEAD(ble_l2cap_coc_srv_list, ble_l2cap_coc_srv); -static struct ble_l2cap_coc_srv_list ble_l2cap_coc_srvs; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#include "esp_nimble_mem.h" +typedef struct { + os_membuf_t *srv_mem; + struct os_mempool srv_pool; + struct ble_l2cap_coc_srv_list l2cap_coc_srvs; +} ble_l2cap_coc_ctx_t; +static ble_l2cap_coc_ctx_t *ble_l2cap_coc_ctx; + +#define ble_l2cap_coc_srv_mem (ble_l2cap_coc_ctx->srv_mem) +#define ble_l2cap_coc_srv_pool (ble_l2cap_coc_ctx->srv_pool) +#define ble_l2cap_coc_srvs (ble_l2cap_coc_ctx->l2cap_coc_srvs) +#else #if MYNEWT_VAL(MP_RUNTIME_ALLOC) static os_membuf_t *ble_l2cap_coc_srv_mem = NULL; #else @@ -41,8 +53,10 @@ static os_membuf_t ble_l2cap_coc_srv_mem[ sizeof(struct ble_l2cap_coc_srv)) ]; #endif - static struct os_mempool ble_l2cap_coc_srv_pool; +static struct ble_l2cap_coc_srv_list ble_l2cap_coc_srvs; +#endif + #ifndef min #define min(a, b) ((a) < (b) ? (a) : (b)) @@ -69,6 +83,11 @@ ble_l2cap_coc_srv_alloc(void) { struct ble_l2cap_coc_srv *srv; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_l2cap_coc_ctx == NULL) { + return NULL; + } +#endif srv = os_memblock_get(&ble_l2cap_coc_srv_pool); if (srv != NULL) { memset(srv, 0, sizeof(*srv)); @@ -685,13 +704,65 @@ ble_l2cap_coc_send(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_tx) int ble_l2cap_coc_init(void) { + int rc; + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_l2cap_coc_ctx == NULL) { + ble_l2cap_coc_ctx = nimble_platform_mem_calloc(1, sizeof(*ble_l2cap_coc_ctx)); + if (ble_l2cap_coc_ctx == NULL) { + return BLE_HS_ENOMEM; + } + } +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) // Doubt + size_t srv_mem_bytes = OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM), + sizeof (struct ble_l2cap_coc_srv)) * sizeof(os_membuf_t); + + if (!ble_l2cap_coc_srv_mem) { + ble_l2cap_coc_srv_mem = nimble_platform_mem_calloc(1, srv_mem_bytes); + if (!ble_l2cap_coc_srv_mem) { + nimble_platform_mem_free(ble_l2cap_coc_ctx); + ble_l2cap_coc_ctx = NULL; + return BLE_HS_ENOMEM; + } + } +#endif + memset(&ble_l2cap_coc_srv_pool, 0, sizeof(ble_l2cap_coc_srv_pool)); +#endif + STAILQ_INIT(&ble_l2cap_coc_srvs); - return os_mempool_init(&ble_l2cap_coc_srv_pool, + rc = os_mempool_init(&ble_l2cap_coc_srv_pool, MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM), sizeof(struct ble_l2cap_coc_srv), ble_l2cap_coc_srv_mem, "ble_l2cap_coc_srv_pool"); + if (rc != 0) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) // Doubt + nimble_platform_mem_free(ble_l2cap_coc_srv_mem); +#endif + memset(&ble_l2cap_coc_srv_pool, 0, sizeof(ble_l2cap_coc_srv_pool)); +#endif + } + + return rc; } +void ble_l2cap_coc_deinit(void) +{ +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_l2cap_coc_ctx) { +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) // Doubt + if (ble_l2cap_coc_srv_mem) { + nimble_platform_mem_free(ble_l2cap_coc_srv_mem); + ble_l2cap_coc_srv_mem = NULL; + } +#endif + memset(&ble_l2cap_coc_srv_pool, 0, sizeof(ble_l2cap_coc_srv_pool)); + nimble_platform_mem_free(ble_l2cap_coc_ctx); + ble_l2cap_coc_ctx = NULL; + + } +#endif +} #endif diff --git a/nimble/host/src/ble_l2cap_coc_priv.h b/nimble/host/src/ble_l2cap_coc_priv.h index 37a95b31e..7bcd615ad 100644 --- a/nimble/host/src/ble_l2cap_coc_priv.h +++ b/nimble/host/src/ble_l2cap_coc_priv.h @@ -61,6 +61,7 @@ struct ble_l2cap_coc_srv { #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0 int ble_l2cap_coc_init(void); +void ble_l2cap_coc_deinit(void); int ble_l2cap_coc_create_server(uint16_t psm, uint16_t mtu, ble_l2cap_event_fn *cb, void *cb_arg); int ble_l2cap_coc_create_srv_chan(struct ble_hs_conn *conn, uint16_t psm, @@ -83,6 +84,9 @@ ble_l2cap_coc_init(void) { return 0; } +inline void ble_l2cap_coc_deinit (void){ + +} static inline int ble_l2cap_coc_create_server(uint16_t psm, uint16_t mtu, ble_l2cap_event_fn *cb, void *cb_arg) { diff --git a/nimble/host/src/ble_l2cap_priv.h b/nimble/host/src/ble_l2cap_priv.h index 08ad3b3e8..7fcc77401 100644 --- a/nimble/host/src/ble_l2cap_priv.h +++ b/nimble/host/src/ble_l2cap_priv.h @@ -47,7 +47,17 @@ STATS_SECT_START(ble_l2cap_stats) STATS_SECT_END extern STATS_SECT_DECL(ble_l2cap_stats) ble_l2cap_stats; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +typedef struct { + os_membuf_t *chan_mem; + struct os_mempool chan_pool; +} ble_l2cap_ctx_t; + +extern ble_l2cap_ctx_t *ble_l2cap_ctx; +#define ble_l2cap_chan_pool (ble_l2cap_ctx->chan_pool) +#else extern struct os_mempool ble_l2cap_chan_pool; +#endif /* This is nimble specific; packets sent to the black hole CID do not elicit * an "invalid CID" response. @@ -144,6 +154,9 @@ int ble_l2cap_tx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, void ble_l2cap_remove_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan); int ble_l2cap_init(void); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void ble_l2cap_deinit(void); +#endif /* Below experimental API is available when BLE_VERSION >= 52 */ int ble_l2cap_enhanced_connect(uint16_t conn_handle, diff --git a/nimble/host/src/ble_l2cap_sig.c b/nimble/host/src/ble_l2cap_sig.c index d506468d1..d5f91d674 100644 --- a/nimble/host/src/ble_l2cap_sig.c +++ b/nimble/host/src/ble_l2cap_sig.c @@ -46,6 +46,7 @@ #include #include "nimble/ble.h" #include "ble_hs_priv.h" +#include "esp_nimble_mem.h" #if NIMBLE_BLE_CONNECT /***************************************************************************** @@ -67,6 +68,9 @@ #else #define BLE_L2CAP_MAX_COC_CONN_REQ (1) #endif +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#include "esp_nimble_mem.h" +#endif struct ble_l2cap_sig_proc { STAILQ_ENTRY(ble_l2cap_sig_proc) next; @@ -101,8 +105,6 @@ struct ble_l2cap_sig_proc { STAILQ_HEAD(ble_l2cap_sig_proc_list, ble_l2cap_sig_proc); -static struct ble_l2cap_sig_proc_list ble_l2cap_sig_procs; - typedef int ble_l2cap_sig_rx_fn(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, struct os_mbuf **om); @@ -160,8 +162,9 @@ static ble_l2cap_sig_rx_fn * const ble_l2cap_sig_dispatch[] = { [BLE_L2CAP_SIG_OP_CREDIT_RECONFIG_RSP] = ble_l2cap_sig_credit_base_reconfig_rsp_rx, }; +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +static struct ble_l2cap_sig_proc_list ble_l2cap_sig_procs; static uint8_t ble_l2cap_sig_cur_id; - #if MYNEWT_VAL(MP_RUNTIME_ALLOC) static os_membuf_t *ble_l2cap_sig_proc_mem = NULL; #else @@ -172,6 +175,30 @@ static os_membuf_t ble_l2cap_sig_proc_mem[ #endif static struct os_mempool ble_l2cap_sig_proc_pool; +#else + +typedef struct { + os_membuf_t *sig_proc_mem; + + struct os_mempool sig_proc_pool; + + /* active signal process list */ + struct ble_l2cap_sig_proc_list sig_procs; + + /* current signal identifier */ + uint8_t sig_cur_id; +} ble_l2cap_sig_ctx_t; + +static ble_l2cap_sig_ctx_t *ble_l2cap_sig_ctx; + +/* macros for access */ +#define ble_l2cap_sig_proc_mem (ble_l2cap_sig_ctx->sig_proc_mem) +#define ble_l2cap_sig_proc_pool (ble_l2cap_sig_ctx->sig_proc_pool) +#define ble_l2cap_sig_procs (ble_l2cap_sig_ctx->sig_procs) +#define ble_l2cap_sig_cur_id (ble_l2cap_sig_ctx->sig_cur_id) + +#endif // BLE_STATIC_TO_DYNAMIC + /***************************************************************************** * $debug * @@ -226,6 +253,7 @@ ble_l2cap_sig_proc_alloc(void) struct ble_l2cap_sig_proc *proc; proc = os_memblock_get(&ble_l2cap_sig_proc_pool); + if (proc != NULL) { memset(proc, 0, sizeof *proc); } @@ -2049,6 +2077,28 @@ ble_l2cap_sig_init(void) { int rc; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (!ble_l2cap_sig_ctx) { + ble_l2cap_sig_ctx = nimble_platform_mem_calloc(1, sizeof(*ble_l2cap_sig_ctx)); + if (!ble_l2cap_sig_ctx) { + return BLE_HS_ENOMEM; + } + } + +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + size_t proc_bytes = OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_L2CAP_SIG_MAX_PROCS), + sizeof (struct ble_l2cap_sig_proc)) * sizeof(os_membuf_t); + + if (!ble_l2cap_sig_proc_mem) { + ble_l2cap_sig_proc_mem = nimble_platform_mem_calloc(1, proc_bytes); + if (!ble_l2cap_sig_proc_mem) { + // free the allocated memory + nimble_platform_mem_free(ble_l2cap_sig_ctx); + return BLE_HS_ENOMEM; + } + } +#endif +#endif STAILQ_INIT(&ble_l2cap_sig_procs); rc = os_mempool_init(&ble_l2cap_sig_proc_pool, @@ -2056,11 +2106,39 @@ ble_l2cap_sig_init(void) sizeof (struct ble_l2cap_sig_proc), ble_l2cap_sig_proc_mem, "ble_l2cap_sig_proc_pool"); + if (rc != 0) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + nimble_platform_mem_free(ble_l2cap_sig_proc_mem); + ble_l2cap_sig_proc_mem = NULL; +#endif + nimble_platform_mem_free(ble_l2cap_sig_ctx); + ble_l2cap_sig_ctx = NULL; +#endif return rc; } return 0; } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void +ble_l2cap_sig_deinit(void) +{ +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + if (ble_l2cap_sig_proc_mem) { + nimble_platform_mem_free(ble_l2cap_sig_proc_mem); + ble_l2cap_sig_proc_mem = NULL; + } +#endif + if (ble_l2cap_sig_ctx) { + nimble_platform_mem_free(ble_l2cap_sig_ctx); + ble_l2cap_sig_ctx = NULL; + } + + return ; +} +#endif + #endif diff --git a/nimble/host/src/ble_l2cap_sig_priv.h b/nimble/host/src/ble_l2cap_sig_priv.h index b997ce35e..0c89b95a5 100644 --- a/nimble/host/src/ble_l2cap_sig_priv.h +++ b/nimble/host/src/ble_l2cap_sig_priv.h @@ -176,6 +176,9 @@ void ble_l2cap_sig_conn_broken(uint16_t conn_handle, int reason); int32_t ble_l2cap_sig_timer(void); struct ble_l2cap_chan *ble_l2cap_sig_create_chan(uint16_t conn_handle); int ble_l2cap_sig_init(void); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void ble_l2cap_sig_deinit(void); +#endif #ifdef __cplusplus } diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index 20ad8bbb3..15ab72e57 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -49,6 +49,7 @@ #include "ble_hs_priv.h" #include "ble_hs_resolv_priv.h" #include "../store/config/src/ble_store_config_priv.h" +#include "esp_nimble_mem.h" #if NIMBLE_BLE_CONNECT @@ -65,6 +66,10 @@ /** Procedure timeout; 30 seconds. */ #define BLE_SM_TIMEOUT_MS (30000) +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#include "esp_nimble_mem.h" +#endif + STAILQ_HEAD(ble_sm_proc_list, ble_sm_proc); typedef void ble_sm_rx_fn(uint16_t conn_handle, struct os_mbuf **om, @@ -126,6 +131,9 @@ static ble_sm_state_fn ble_sm_enc_restore_exec; static ble_sm_state_fn ble_sm_key_exch_exec; static ble_sm_state_fn ble_sm_sec_req_exec; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +static ble_sm_state_fn **ble_sm_state_dispatch = NULL; +#else static ble_sm_state_fn * const ble_sm_state_dispatch[BLE_SM_PROC_STATE_CNT] = { [BLE_SM_PROC_STATE_PAIR] = ble_sm_pair_exec, @@ -145,7 +153,9 @@ ble_sm_state_dispatch[BLE_SM_PROC_STATE_CNT] = { [BLE_SM_PROC_STATE_DHKEY_CHECK] = NULL, #endif }; +#endif +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) #if MYNEWT_VAL(MP_RUNTIME_ALLOC) static os_membuf_t *ble_sm_proc_mem = NULL; #else @@ -159,6 +169,7 @@ static struct os_mempool ble_sm_proc_pool; /* Maintains the list of active security manager procedures. */ static struct ble_sm_proc_list ble_sm_procs; +#endif // BLE_STATIC_TO_DYNAMIC static void ble_sm_pair_cfg(struct ble_sm_proc *proc); @@ -167,8 +178,58 @@ static void ble_sm_pair_cfg(struct ble_sm_proc *proc); * $debug * *****************************************************************************/ +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +/** + * Security Manager context. + * + * Contains all state for Security Manager (SM): + * - Memory pool and buffer for SM procedures. + * - Active procedure list. + * - Key generation and pairing variables. + * + * Memory is allocated dynamically at runtime during ble_sm_init(). + */ +typedef struct { + /* sm procedure memory pool */ + struct os_membuf_t *proc_mem; + struct os_mempool proc_pool; + struct ble_sm_proc_list proc_list; #if MYNEWT_VAL(BLE_HS_DEBUG) + /* sm pairing and key variables */ + uint8_t next_pair_rand[16]; + uint8_t next_pair_rand_set; + uint16_t next_ediv; + uint8_t next_ediv_set; + uint64_t next_master_id_rand; + uint8_t next_master_id_rand_set; + uint8_t next_ltk[16]; + uint8_t next_ltk_set; + uint8_t next_csrk[16]; + uint8_t next_csrk_set; +#endif +} ble_sm_ctx_t; +static ble_sm_ctx_t *ble_sm_ctx; + +/* convenient macros for access */ +#define ble_sm_proc_mem (ble_sm_ctx->proc_mem) +#define ble_sm_proc_pool (ble_sm_ctx->proc_pool) +#define ble_sm_procs (ble_sm_ctx->proc_list) + +#if MYNEWT_VAL(BLE_HS_DEBUG) +#define ble_sm_dbg_next_pair_rand (ble_sm_ctx->next_pair_rand) +#define ble_sm_dbg_next_pair_rand_set (ble_sm_ctx->next_pair_rand_set) +#define ble_sm_dbg_next_ediv (ble_sm_ctx->next_ediv) +#define ble_sm_dbg_next_ediv_set (ble_sm_ctx->next_ediv_set) +#define ble_sm_dbg_next_master_id_rand (ble_sm_ctx->next_master_id_rand) +#define ble_sm_dbg_next_master_id_rand_set (ble_sm_ctx->next_master_id_rand_set) +#define ble_sm_dbg_next_ltk (ble_sm_ctx->next_ltk) +#define ble_sm_dbg_next_ltk_set (ble_sm_ctx->next_ltk_set) +#define ble_sm_dbg_next_csrk (ble_sm_ctx->next_csrk) +#define ble_sm_dbg_next_csrk_set (ble_sm_ctx->next_csrk_set) +#endif // BLE_HS_DEBUG +#else +#if MYNEWT_VAL(BLE_HS_DEBUG) static uint8_t ble_sm_dbg_next_pair_rand[16]; static uint8_t ble_sm_dbg_next_pair_rand_set; static uint16_t ble_sm_dbg_next_ediv; @@ -217,8 +278,8 @@ ble_sm_dbg_set_next_csrk(uint8_t *next_csrk) sizeof ble_sm_dbg_next_csrk); ble_sm_dbg_next_csrk_set = 1; } - -#endif +#endif // BLE_HS_DEBUG +#endif // BLE_STATIC_TO_DYNAMIC static void ble_sm_dbg_assert_no_cycles(void) @@ -402,6 +463,7 @@ ble_sm_proc_alloc(void) struct ble_sm_proc *proc; proc = os_memblock_get(&ble_sm_proc_pool); + if (proc != NULL) { memset(proc, 0, sizeof *proc); } @@ -422,7 +484,9 @@ ble_sm_proc_free(struct ble_sm_proc *proc) #if MYNEWT_VAL(BLE_HS_DEBUG) memset(proc, 0xff, sizeof *proc); #endif + rc = os_memblock_put(&ble_sm_proc_pool, proc); + BLE_HS_DBG_ASSERT_EVAL(rc == 0); } } @@ -962,9 +1026,10 @@ ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res, struct ble_sm_proc *prev; struct ble_sm_proc *proc; int rm; +#if MYNEWT_VAL(BLE_RESTART_PAIR) ble_hs_conn_flags_t conn_flags; struct ble_hs_conn *conn; - +#endif rm = 0; if (res && res->out_of_order) { @@ -1013,6 +1078,7 @@ ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res, break; } +#if MYNEWT_VAL(BLE_RESTART_PAIR) if (res->app_status == 518 ) { conn = ble_hs_conn_find(conn_handle); @@ -1027,7 +1093,7 @@ ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res, } break; } - +#endif if (res->enc_cb && res->app_status != BLE_HS_ENOTCONN) { /* Do not send this event on broken connection */ @@ -2191,18 +2257,20 @@ static void ble_sm_key_exch_exec(struct ble_sm_proc *proc, struct ble_sm_result *res, void *arg) { - struct ble_sm_id_addr_info *addr_info; - struct ble_hs_conn_addrs addrs; struct ble_sm_sign_info *sign_info; struct ble_sm_master_id *master_id; struct ble_sm_enc_info *enc_info; - struct ble_sm_id_info *id_info; - struct ble_hs_conn *conn; uint8_t init_key_dist; uint8_t resp_key_dist; uint8_t our_key_dist; struct os_mbuf *txom; +#if MYNEWT_VAL(BLE_HS_PVCY) + struct ble_hs_conn *conn; const uint8_t *irk; + struct ble_hs_conn_addrs addrs; + struct ble_sm_id_info *id_info; + struct ble_sm_id_addr_info *addr_info; +#endif struct ble_store_gen_key gen_key; int ltk_gen = 0; int rc; @@ -2294,6 +2362,7 @@ ble_sm_key_exch_exec(struct ble_sm_proc *proc, struct ble_sm_result *res, } } +#if MYNEWT_VAL(BLE_HS_PVCY) if (our_key_dist & BLE_SM_PAIR_KEY_DIST_ID) { /* Send identity information. */ id_info = ble_sm_cmd_get(BLE_SM_OP_IDENTITY_INFO, sizeof(*id_info), @@ -2354,6 +2423,7 @@ ble_sm_key_exch_exec(struct ble_sm_proc *proc, struct ble_sm_result *res, goto err; } } +#endif if (our_key_dist & BLE_SM_PAIR_KEY_DIST_SIGN) { /* Send signing information. */ @@ -2648,6 +2718,7 @@ ble_sm_fail_rx(uint16_t conn_handle, struct os_mbuf **om, * $api * *****************************************************************************/ +#if MYNEWT_VAL(BLE_SM_SIGN_CNT) /** * API to be used to increment the sign-counter whenever the CSRK is used * to sign a message. @@ -2739,11 +2810,13 @@ ble_sm_incr_peer_sign_counter(uint16_t conn_handle) return rc; } +#if MYNEWT_VAL(BLE_HS_PVCY) if (value_sec.irk_present == 1) { ble_hs_pvcy_remove_entry(value_sec.peer_addr.type, value_sec.peer_addr.val); // No need to check if the above command fails or passes // Proceed with trying to write the new sign counter } +#endif value_sec.sign_counter += 1; rc = ble_store_write_peer_sec(&value_sec); @@ -2753,6 +2826,7 @@ ble_sm_incr_peer_sign_counter(uint16_t conn_handle) return 0; } +#endif /** * Times out expired SM procedures. @@ -3113,26 +3187,124 @@ ble_sm_connection_broken(uint16_t conn_handle) ble_sm_process_result(conn_handle, &res, true); } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +static int +ble_sm_state_dispatch_init(void) +{ + ble_sm_state_dispatch = nimble_platform_mem_calloc(1, BLE_SM_PROC_STATE_CNT * sizeof(ble_sm_state_fn *)); + + if (!ble_sm_state_dispatch) { + return BLE_HS_ENOMEM; + } + + ble_sm_state_dispatch[BLE_SM_PROC_STATE_PAIR] = ble_sm_pair_exec; + ble_sm_state_dispatch[BLE_SM_PROC_STATE_CONFIRM] = ble_sm_confirm_exec; + ble_sm_state_dispatch[BLE_SM_PROC_STATE_RANDOM] = ble_sm_random_exec; + ble_sm_state_dispatch[BLE_SM_PROC_STATE_LTK_START] = ble_sm_ltk_start_exec; + ble_sm_state_dispatch[BLE_SM_PROC_STATE_LTK_RESTORE] = ble_sm_ltk_restore_exec; + ble_sm_state_dispatch[BLE_SM_PROC_STATE_ENC_START] = ble_sm_enc_start_exec; + ble_sm_state_dispatch[BLE_SM_PROC_STATE_ENC_RESTORE] = ble_sm_enc_restore_exec; + ble_sm_state_dispatch[BLE_SM_PROC_STATE_KEY_EXCH] = ble_sm_key_exch_exec; + ble_sm_state_dispatch[BLE_SM_PROC_STATE_SEC_REQ] = ble_sm_sec_req_exec; +#if MYNEWT_VAL(BLE_SM_SC) + ble_sm_state_dispatch[BLE_SM_PROC_STATE_PUBLIC_KEY] = ble_sm_sc_public_key_exec; + ble_sm_state_dispatch[BLE_SM_PROC_STATE_DHKEY_CHECK] = ble_sm_sc_dhkey_check_exec; +#else + ble_sm_state_dispatch[BLE_SM_PROC_STATE_PUBLIC_KEY] = NULL; + ble_sm_state_dispatch[BLE_SM_PROC_STATE_DHKEY_CHECK] = NULL; +#endif + + return 0; +} + +static void ble_sm_state_dispatch_deinit(void) +{ + if (ble_sm_state_dispatch) { + nimble_platform_mem_free(ble_sm_state_dispatch); + ble_sm_state_dispatch = NULL; + } +} +#endif + int ble_sm_init(void) { int rc; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (!ble_sm_ctx) { + ble_sm_ctx = nimble_platform_mem_calloc(1, sizeof(*ble_sm_ctx)); + if (!ble_sm_ctx) { + return BLE_HS_ENOMEM; + } + } + +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + size_t proc_mem_size = OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_SM_MAX_PROCS), sizeof(struct ble_sm_proc)); + + if (!ble_sm_proc_mem) { + ble_sm_proc_mem = nimble_platform_mem_calloc(1,proc_mem_size * sizeof(os_membuf_t)); + if (!ble_sm_proc_mem) { + // free the allocated memory + nimble_platform_mem_free(ble_sm_ctx); + ble_sm_ctx = NULL; + return BLE_HS_ENOMEM; + } + } +#endif +#endif + STAILQ_INIT(&ble_sm_procs); rc = os_mempool_init(&ble_sm_proc_pool, - MYNEWT_VAL(BLE_SM_MAX_PROCS), - sizeof (struct ble_sm_proc), - ble_sm_proc_mem, - "ble_sm_proc_pool"); + MYNEWT_VAL(BLE_SM_MAX_PROCS), + sizeof (struct ble_sm_proc), + ble_sm_proc_mem, + "ble_sm_proc_pool"); + if (rc != 0) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + ble_sm_deinit(); +#endif return rc; } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + rc = ble_sm_state_dispatch_init(); + + if (rc != 0) { + ble_sm_deinit(); + return rc; + } + +#endif + ble_sm_sc_init(); return 0; } + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void +ble_sm_deinit(void) +{ + if (ble_sm_ctx != NULL) { +#if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + if (ble_sm_proc_mem) { + nimble_platform_mem_free(ble_sm_proc_mem); + ble_sm_proc_mem = NULL; + } +#endif + nimble_platform_mem_free(ble_sm_ctx); + ble_sm_ctx = NULL; + } + + ble_sm_sc_deinit(); + + ble_sm_state_dispatch_deinit(); +} +#endif + #else /* if pairing is not supported it is only needed to reply with Pairing * Failed with 'Pairing not Supported' reason so this function can be very diff --git a/nimble/host/src/ble_sm_alg.c b/nimble/host/src/ble_sm_alg.c index 306c240f0..aacbde4f7 100644 --- a/nimble/host/src/ble_sm_alg.c +++ b/nimble/host/src/ble_sm_alg.c @@ -57,10 +57,14 @@ #if MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS) #if MYNEWT_VAL(BLE_SM_SC) -#ifndef CONFIG_MBEDTLS_VER_4_X_SUPPORT +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#include "esp_nimble_mem.h" +static mbedtls_ecp_keypair * keypair_ptr = NULL; +#define keypair (*keypair_ptr) +#else static mbedtls_ecp_keypair keypair; -#endif // CONFIG_MBEDTLS_VER_4_X_SUPPORT -#endif // MYNEWT_VAL(BLE_SM_SC) +#endif /* MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) */ +#endif #else #if MYNEWT_VAL(BLE_SM_SC) && MYNEWT_VAL(TRNG) static struct trng_dev *g_trng; @@ -646,6 +650,12 @@ exit: swap_buf(pk, peer_pub_key_x, 32); swap_buf(&pk[32], peer_pub_key_y, 32); +#if MYNEWT_VAL(BLE_SM_SC) && MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (!keypair_ptr) { + keypair_ptr = nimble_platform_mem_calloc(1, sizeof(mbedtls_ecp_keypair)); + } +#endif + struct mbedtls_ecp_point pt = {0}, Q = {0}; mbedtls_mpi z = {0}, d = {0}; mbedtls_ctr_drbg_context ctr_drbg = {0}; @@ -712,6 +722,12 @@ exit: mbedtls_ctr_drbg_free(&ctr_drbg); #endif // CONFIG_MBEDTLS_VER_4_X_SUPPORT if (rc != 0) { +#if MYNEWT_VAL(BLE_SM_SC) && MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (keypair_ptr) { + nimble_platform_mem_free(keypair_ptr); + keypair_ptr = NULL; + } +#endif return BLE_HS_EUNKNOWN; } #else @@ -803,6 +819,12 @@ exit: mbedtls_entropy_context entropy = {0}; mbedtls_ctr_drbg_context ctr_drbg = {0}; +#if MYNEWT_VAL(BLE_SM_SC) && MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (!keypair_ptr) { + keypair_ptr = nimble_platform_mem_calloc(1, sizeof(mbedtls_ecp_keypair)); + } +#endif + mbedtls_entropy_init(&entropy); mbedtls_ctr_drbg_init(&ctr_drbg); @@ -840,7 +862,14 @@ exit: mbedtls_entropy_free( &entropy ); if (rc != 0) { mbedtls_ecp_keypair_free(&keypair); - return BLE_HS_EUNKNOWN; + +#if MYNEWT_VAL(BLE_SM_SC) && MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (keypair_ptr) { + nimble_platform_mem_free(keypair_ptr); + keypair_ptr = NULL; + } +#endif + rc = BLE_HS_EUNKNOWN; } #endif // CONFIG_MBEDTLS_VER_4_X_SUPPORT return 0; @@ -861,6 +890,7 @@ void mbedtls_free_keypair(void) int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) { + #if MYNEWT_VAL(BLE_SM_SC_DEBUG_KEYS) swap_buf(pub, ble_sm_alg_dbg_pub_key, 32); swap_buf(&pub[32], &ble_sm_alg_dbg_pub_key[32], 32); diff --git a/nimble/host/src/ble_sm_cmd.c b/nimble/host/src/ble_sm_cmd.c index a740dc3ac..9f2099273 100644 --- a/nimble/host/src/ble_sm_cmd.c +++ b/nimble/host/src/ble_sm_cmd.c @@ -28,6 +28,7 @@ void * ble_sm_cmd_get(uint8_t opcode, size_t len, struct os_mbuf **txom) { +#if NIMBLE_BLE_SM struct ble_sm_hdr *hdr; void *data; @@ -47,12 +48,15 @@ ble_sm_cmd_get(uint8_t opcode, size_t len, struct os_mbuf **txom) hdr->opcode = opcode; return hdr->data; +#endif + return NULL; } /* this function consumes tx os_mbuf */ int ble_sm_tx(uint16_t conn_handle, struct os_mbuf *txom) { +#if NIMBLE_BLE_SM struct ble_l2cap_chan *chan; struct ble_hs_conn *conn; int rc; @@ -70,6 +74,8 @@ ble_sm_tx(uint16_t conn_handle, struct os_mbuf *txom) } return rc; +#endif + return BLE_HS_ENOTSUP; } #endif diff --git a/nimble/host/src/ble_sm_priv.h b/nimble/host/src/ble_sm_priv.h index 94b57be5d..c6a542647 100644 --- a/nimble/host/src/ble_sm_priv.h +++ b/nimble/host/src/ble_sm_priv.h @@ -365,6 +365,9 @@ bool ble_sm_sc_oob_data_check(struct ble_sm_proc *proc, bool oob_data_remote_present); void ble_sm_sc_oob_confirm(struct ble_sm_proc *proc, struct ble_sm_result *res); void ble_sm_sc_init(void); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void ble_sm_sc_deinit(void); +#endif #else #define ble_sm_sc_io_action(proc, action) (BLE_HS_ENOTSUP) #define ble_sm_sc_confirm_exec(proc, res) @@ -407,6 +410,9 @@ int ble_sm_enc_initiate(uint16_t conn_handle, uint8_t key_size, int ble_sm_alg_encrypt(const uint8_t *key, const uint8_t *plaintext, uint8_t *enc_data); int ble_sm_init(void); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void ble_sm_deinit(void); +#endif #else #define ble_sm_incr_our_sign_counter(conn_handle) BLE_HS_ENOTSUP @@ -424,7 +430,7 @@ int ble_sm_init(void); BLE_HS_ENOTSUP #define ble_sm_init() 0 - +#define ble_sm_deinit() #define ble_sm_alg_encrypt(key, plaintext, enc_data) \ BLE_HS_ENOTSUP @@ -434,6 +440,9 @@ struct ble_l2cap_chan *ble_sm_create_chan(uint16_t handle); void *ble_sm_cmd_get(uint8_t opcode, size_t len, struct os_mbuf **txom); int ble_sm_tx(uint16_t conn_handle, struct os_mbuf *txom); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void ble_sm_proc_deinit(void); +#endif #ifdef __cplusplus } diff --git a/nimble/host/src/ble_sm_sc.c b/nimble/host/src/ble_sm_sc.c index faf3191c3..7be961da2 100644 --- a/nimble/host/src/ble_sm_sc.c +++ b/nimble/host/src/ble_sm_sc.c @@ -23,6 +23,7 @@ #include "host/ble_sm.h" #include "ble_hs_priv.h" #include "ble_sm_priv.h" +#include "esp_nimble_mem.h" #if NIMBLE_BLE_CONNECT #if MYNEWT_VAL(BLE_SM_SC) @@ -30,8 +31,30 @@ #define BLE_SM_SC_PASSKEY_BYTES 4 #define BLE_SM_SC_PASSKEY_BITS 20 +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#include "esp_nimble_mem.h" + +typedef struct { + uint8_t pub_key[64]; + uint8_t priv_key[32]; + +#if MYNEWT_VAL(BLE_HS_DEBUG) + uint8_t dbg_pub_key[64]; + uint8_t dbg_priv_key[32]; +#endif +}ble_sm_sc_ctx_t; + +static ble_sm_sc_ctx_t *ble_sm_sc_ctx; + +#define ble_sm_sc_pub_key (ble_sm_sc_ctx->pub_key) +#define ble_sm_sc_priv_key (ble_sm_sc_ctx->priv_key) +#define ble_sm_dbg_sc_pub_key (ble_sm_sc_ctx->dbg_pub_key) +#define ble_sm_dbg_sc_priv_key (ble_sm_sc_ctx->dbg_priv_key) + +#else static uint8_t ble_sm_sc_pub_key[64]; static uint8_t ble_sm_sc_priv_key[32]; +#endif /** * Whether our public-private key pair has been generated. We generate it on @@ -79,19 +102,47 @@ static const uint8_t ble_sm_sc_resp_ioa[5 /*resp*/ ][5 /*init*/ ] = {IOACT_INPUT, IOACT_NUMCMP, IOACT_DISP, IOACT_NONE, IOACT_NUMCMP}, }; -#if MYNEWT_VAL(BLE_HS_DEBUG) +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +int +ble_sm_sc_ensure_ctx (void) +{ + if (ble_sm_sc_ctx) { + return 0; + } + ble_sm_sc_ctx = nimble_platform_mem_calloc(1, sizeof(* ble_sm_sc_ctx)); + + if (!ble_sm_sc_ctx) { + return BLE_HS_ENOMEM; + } + + return 0; +} +#endif + +#if MYNEWT_VAL(BLE_HS_DEBUG) +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) static uint8_t ble_sm_dbg_sc_pub_key[64]; static uint8_t ble_sm_dbg_sc_priv_key[32]; +#endif +#define sizeof_ble_sm_dbg_sc_pub_key sizeof(ble_sm_dbg_sc_pub_key) +#define sizeof_ble_sm_dbg_sc_priv_key sizeof(ble_sm_dbg_sc_priv_key) + static uint8_t ble_sm_dbg_sc_keys_set; void ble_sm_dbg_set_sc_keys(uint8_t *pubkey, uint8_t *privkey) { - memcpy(ble_sm_dbg_sc_pub_key, pubkey, - sizeof ble_sm_dbg_sc_pub_key); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_sm_sc_ensure_ctx()) { + return ; + } +#endif + + memcpy(ble_sm_dbg_sc_pub_key, pubkey, + sizeof_ble_sm_dbg_sc_pub_key); memcpy(ble_sm_dbg_sc_priv_key, privkey, - sizeof ble_sm_dbg_sc_priv_key); + sizeof_ble_sm_dbg_sc_priv_key); ble_sm_dbg_sc_keys_set = 1; } @@ -176,8 +227,8 @@ ble_sm_gen_pub_priv(uint8_t *pub, uint8_t *priv) #if MYNEWT_VAL(BLE_HS_DEBUG) if (ble_sm_dbg_sc_keys_set) { ble_sm_dbg_sc_keys_set = 0; - memcpy(pub, ble_sm_dbg_sc_pub_key, sizeof ble_sm_dbg_sc_pub_key); - memcpy(priv, ble_sm_dbg_sc_priv_key, sizeof ble_sm_dbg_sc_priv_key); + memcpy(pub, ble_sm_dbg_sc_pub_key, sizeof_ble_sm_dbg_sc_pub_key); + memcpy(priv, ble_sm_dbg_sc_priv_key, sizeof_ble_sm_dbg_sc_priv_key); return 0; } #endif @@ -196,6 +247,11 @@ ble_sm_sc_ensure_keys_generated(void) int rc; if (!ble_sm_sc_keys_generated) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_sm_sc_ensure_ctx()) { + return BLE_HS_ENOMEM; + } +#endif rc = ble_sm_gen_pub_priv(ble_sm_sc_pub_key, ble_sm_sc_priv_key); if (rc != 0) { return rc; @@ -205,10 +261,18 @@ ble_sm_sc_ensure_keys_generated(void) } BLE_HS_LOG(DEBUG, "our pubkey="); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + ble_hs_log_flat_buf(ble_sm_sc_pub_key, 64); +#else ble_hs_log_flat_buf(&ble_sm_sc_pub_key, 64); +#endif BLE_HS_LOG(DEBUG, "\n"); BLE_HS_LOG(DEBUG, "our privkey="); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + ble_hs_log_flat_buf(ble_sm_sc_priv_key, 32); +#else ble_hs_log_flat_buf(&ble_sm_sc_priv_key, 32); +#endif BLE_HS_LOG(DEBUG, "\n"); return 0; @@ -942,5 +1006,16 @@ ble_sm_sc_init(void) ble_sm_sc_keys_generated = 0; } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void +ble_sm_sc_deinit(void) +{ + if (ble_sm_sc_ctx) { + nimble_platform_mem_free(ble_sm_sc_ctx); + ble_sm_sc_ctx = NULL; + } +} +#endif + #endif /* MYNEWT_VAL(BLE_SM_SC) */ #endif diff --git a/nimble/host/src/ble_store.c b/nimble/host/src/ble_store.c index a407cd8f7..5983ad815 100644 --- a/nimble/host/src/ble_store.c +++ b/nimble/host/src/ble_store.c @@ -26,6 +26,8 @@ int ble_store_read(int obj_type, const union ble_store_key *key, union ble_store_value *val) { +#if NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_SM_SC) + int rc; ble_hs_lock(); @@ -39,11 +41,15 @@ ble_store_read(int obj_type, const union ble_store_key *key, ble_hs_unlock(); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } int ble_store_write(int obj_type, const union ble_store_value *val) { +#if NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_SM_SC) int rc; if (ble_hs_cfg.store_write_cb == NULL) { @@ -74,11 +80,16 @@ ble_store_write(int obj_type, const union ble_store_value *val) return rc; } } +#else + return BLE_HS_ENOTSUP; +#endif } int ble_store_delete(int obj_type, const union ble_store_key *key) { +#if NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_SM_SC) + int rc; ble_hs_lock(); @@ -92,8 +103,12 @@ ble_store_delete(int obj_type, const union ble_store_key *key) ble_hs_unlock(); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } +#if NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_SM_SC) static int ble_store_status(struct ble_store_status_event *event) { @@ -109,10 +124,13 @@ ble_store_status(struct ble_store_status_event *event) return rc; } +#endif int ble_store_overflow_event(int obj_type, const union ble_store_value *value) { +#if NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_SM_SC) + struct ble_store_status_event event; event.event_code = BLE_STORE_EVENT_OVERFLOW; @@ -120,11 +138,16 @@ ble_store_overflow_event(int obj_type, const union ble_store_value *value) event.overflow.value = value; return ble_store_status(&event); +#else + return BLE_HS_ENOTSUP; +#endif } int ble_store_full_event(int obj_type, uint16_t conn_handle) { +#if NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_SM_SC) + struct ble_store_status_event event; event.event_code = BLE_STORE_EVENT_FULL; @@ -132,12 +155,18 @@ ble_store_full_event(int obj_type, uint16_t conn_handle) event.full.conn_handle = conn_handle; return ble_store_status(&event); + +#else + return BLE_HS_ENOTSUP; +#endif } int ble_store_read_our_sec(const struct ble_store_key_sec *key_sec, struct ble_store_value_sec *value_sec) { +#if NIMBLE_BLE_CONNECT + const union ble_store_key *store_key; union ble_store_value *store_value; int rc; @@ -150,12 +179,18 @@ ble_store_read_our_sec(const struct ble_store_key_sec *key_sec, store_value = (void *)value_sec; rc = ble_store_read(BLE_STORE_OBJ_TYPE_OUR_SEC, store_key, store_value); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } + +#if NIMBLE_BLE_CONNECT static int ble_store_persist_sec(int obj_type, const struct ble_store_value_sec *value_sec) { + union ble_store_value *store_value; int rc; @@ -169,42 +204,60 @@ ble_store_persist_sec(int obj_type, rc = ble_store_write(obj_type, store_value); return rc; } +#endif int ble_store_write_our_sec(const struct ble_store_value_sec *value_sec) { +#if NIMBLE_BLE_CONNECT + int rc; rc = ble_store_persist_sec(BLE_STORE_OBJ_TYPE_OUR_SEC, value_sec); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } int ble_store_delete_our_sec(const struct ble_store_key_sec *key_sec) { +#if NIMBLE_BLE_CONNECT + union ble_store_key *store_key; int rc; store_key = (void *)key_sec; rc = ble_store_delete(BLE_STORE_OBJ_TYPE_OUR_SEC, store_key); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } int ble_store_delete_peer_sec(const struct ble_store_key_sec *key_sec) { +#if NIMBLE_BLE_CONNECT + union ble_store_key *store_key; int rc; store_key = (void *)key_sec; rc = ble_store_delete(BLE_STORE_OBJ_TYPE_PEER_SEC, store_key); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } int ble_store_read_peer_sec(const struct ble_store_key_sec *key_sec, struct ble_store_value_sec *value_sec) { +#if NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_SM_SC) + union ble_store_value *store_value; union ble_store_key *store_key; int rc; @@ -221,11 +274,16 @@ ble_store_read_peer_sec(const struct ble_store_key_sec *key_sec, } return 0; +#else + return BLE_HS_ENOTSUP; +#endif } int ble_store_write_peer_sec(const struct ble_store_value_sec *value_sec) { +#if NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_SM_SC) + int rc; rc = ble_store_persist_sec(BLE_STORE_OBJ_TYPE_PEER_SEC, value_sec); @@ -235,7 +293,7 @@ ble_store_write_peer_sec(const struct ble_store_value_sec *value_sec) if (ble_addr_cmp(&value_sec->peer_addr, BLE_ADDR_ANY) && value_sec->irk_present) { - +#if MYNEWT_VAL(BLE_HS_PVCY) /* Write the peer IRK to the controller keycache * There is not much to do here if it fails */ rc = ble_hs_pvcy_add_entry(value_sec->peer_addr.val, @@ -244,15 +302,21 @@ ble_store_write_peer_sec(const struct ble_store_value_sec *value_sec) if (rc != 0) { return rc; } +#endif } return 0; +#else + return BLE_HS_ENOTSUP; +#endif } int ble_store_read_cccd(const struct ble_store_key_cccd *key, struct ble_store_value_cccd *out_value) { +#if NIMBLE_BLE_CONNECT + union ble_store_value *store_value; union ble_store_key *store_key; int rc; @@ -261,34 +325,49 @@ ble_store_read_cccd(const struct ble_store_key_cccd *key, store_value = (void *)out_value; rc = ble_store_read(BLE_STORE_OBJ_TYPE_CCCD, store_key, store_value); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } int ble_store_write_cccd(const struct ble_store_value_cccd *value) { +#if NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_SM_SC) + union ble_store_value *store_value; int rc; store_value = (void *)value; rc = ble_store_write(BLE_STORE_OBJ_TYPE_CCCD, store_value); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } int ble_store_delete_cccd(const struct ble_store_key_cccd *key) { +#if NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_SM_SC) + union ble_store_key *store_key; int rc; store_key = (void *)key; rc = ble_store_delete(BLE_STORE_OBJ_TYPE_CCCD, store_key); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } int ble_store_read_csfc(const struct ble_store_key_csfc *key, struct ble_store_value_csfc *out_value) { +#if NIMBLE_BLE_CONNECT + union ble_store_value *store_value; union ble_store_key *store_key; int rc; @@ -297,45 +376,66 @@ ble_store_read_csfc(const struct ble_store_key_csfc *key, store_value = (void *)out_value; rc = ble_store_read(BLE_STORE_OBJ_TYPE_CSFC, store_key, store_value); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } int ble_store_write_csfc(const struct ble_store_value_csfc *value) { +#if NIMBLE_BLE_CONNECT + union ble_store_value *store_value; int rc; store_value = (void *)value; rc = ble_store_write(BLE_STORE_OBJ_TYPE_CSFC, store_value); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } int ble_store_delete_csfc(const struct ble_store_key_csfc *key) { +#if NIMBLE_BLE_CONNECT + union ble_store_key *store_key; int rc; store_key = (void *)key; rc = ble_store_delete(BLE_STORE_OBJ_TYPE_CSFC, store_key); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } void ble_store_key_from_value_cccd(struct ble_store_key_cccd *out_key, const struct ble_store_value_cccd *value) { +#if NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_SM_SC) + out_key->peer_addr = value->peer_addr; out_key->chr_val_handle = value->chr_val_handle; out_key->idx = 0; + +#endif } void ble_store_key_from_value_sec(struct ble_store_key_sec *out_key, const struct ble_store_value_sec *value) { +#if NIMBLE_BLE_CONNECT + out_key->peer_addr = value->peer_addr; out_key->idx = 0; + +#endif } #if MYNEWT_VAL(ENC_ADV_DATA) @@ -343,6 +443,8 @@ int ble_store_read_ead(const struct ble_store_key_ead *key, struct ble_store_value_ead *out_value) { +#if NIMBLE_BLE_CONNECT + union ble_store_value *store_value; union ble_store_key *store_key; int rc; @@ -351,43 +453,65 @@ ble_store_read_ead(const struct ble_store_key_ead *key, store_value = (void *)out_value; rc = ble_store_read(BLE_STORE_OBJ_TYPE_ENC_ADV_DATA, store_key, store_value); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } int ble_store_write_ead(const struct ble_store_value_ead *value) { +#if NIMBLE_BLE_CONNECT + union ble_store_value *store_value; int rc; store_value = (void *)value; rc = ble_store_write(BLE_STORE_OBJ_TYPE_ENC_ADV_DATA, store_value); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } int ble_store_delete_ead(const struct ble_store_key_ead *key) { +#if NIMBLE_BLE_CONNECT + union ble_store_key *store_key; int rc; store_key = (void *)key; rc = ble_store_delete(BLE_STORE_OBJ_TYPE_ENC_ADV_DATA, store_key); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } void ble_store_key_from_value_ead(struct ble_store_key_ead *out_key, const struct ble_store_value_ead *value) { +#if NIMBLE_BLE_CONNECT + out_key->peer_addr = value->peer_addr; out_key->idx = 0; +#else + return BLE_HS_ENOTSUP; +#endif } #endif // local irk + +#if MYNEWT_VAL(BLE_HS_PVCY) int ble_store_read_local_irk(const struct ble_store_key_local_irk *key, struct ble_store_value_local_irk *out_value) { +#if NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_SM_SC) + union ble_store_value *store_value; union ble_store_key *store_key; int rc; @@ -396,36 +520,55 @@ ble_store_read_local_irk(const struct ble_store_key_local_irk *key, store_value = (void *)out_value; rc = ble_store_read(BLE_STORE_OBJ_TYPE_LOCAL_IRK, store_key, store_value); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } +#endif +#if MYNEWT_VAL(BLE_HS_PVCY) int ble_store_write_local_irk(const struct ble_store_value_local_irk *value) { +#if NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_SM_SC) + union ble_store_value *store_value; int rc; store_value = (void *)value; rc = ble_store_write(BLE_STORE_OBJ_TYPE_LOCAL_IRK, store_value); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } +#endif int ble_store_delete_local_irk(const struct ble_store_key_local_irk *key) { +#if NIMBLE_BLE_CONNECT + union ble_store_key *store_key; int rc; store_key = (void *)key; rc = ble_store_delete(BLE_STORE_OBJ_TYPE_LOCAL_IRK, store_key); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } void ble_store_key_from_value_local_irk(struct ble_store_key_local_irk *out_key, const struct ble_store_value_local_irk *value) { +#if NIMBLE_BLE_CONNECT + out_key->addr = value->addr; out_key->idx = 0; +#endif } // @@ -433,6 +576,8 @@ int ble_store_read_rpa_rec(const struct ble_store_key_rpa_rec *key, struct ble_store_value_rpa_rec *out_value) { +#if NIMBLE_BLE_CONNECT + union ble_store_value *store_value; union ble_store_key *store_key; int rc; @@ -441,43 +586,62 @@ ble_store_read_rpa_rec(const struct ble_store_key_rpa_rec *key, store_value = (void *)out_value; rc = ble_store_read(BLE_STORE_OBJ_TYPE_PEER_ADDR, store_key, store_value); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } int ble_store_write_rpa_rec(const struct ble_store_value_rpa_rec *value) { +#if NIMBLE_BLE_CONNECT + union ble_store_value *store_value; int rc; store_value = (void *)value; rc = ble_store_write(BLE_STORE_OBJ_TYPE_PEER_ADDR, store_value); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } int ble_store_delete_rpa_rec(const struct ble_store_key_rpa_rec *key) { +#if NIMBLE_BLE_CONNECT + union ble_store_key *store_key; int rc; store_key = (void *)key; rc = ble_store_delete(BLE_STORE_OBJ_TYPE_PEER_ADDR, store_key); return rc; +#else + return BLE_HS_ENOTSUP; +#endif } void ble_store_key_from_value_rpa_rec(struct ble_store_key_rpa_rec *out_key, const struct ble_store_value_rpa_rec *value) { +#if NIMBLE_BLE_CONNECT out_key->peer_rpa_addr = value->peer_rpa_addr; out_key->idx = 0; +#endif } void ble_store_key_from_value_csfc(struct ble_store_key_csfc *out_key, const struct ble_store_value_csfc *value) { +#if NIMBLE_BLE_CONNECT + out_key->peer_addr = value->peer_addr; out_key->idx = 0; + +#endif } void @@ -485,6 +649,8 @@ ble_store_key_from_value(int obj_type, union ble_store_key *out_key, const union ble_store_value *value) { +#if NIMBLE_BLE_CONNECT + switch (obj_type) { case BLE_STORE_OBJ_TYPE_OUR_SEC: case BLE_STORE_OBJ_TYPE_PEER_SEC: @@ -516,6 +682,8 @@ ble_store_key_from_value(int obj_type, BLE_HS_DBG_ASSERT(0); break; } + +#endif } int @@ -523,6 +691,8 @@ ble_store_iterate(int obj_type, ble_store_iterator_fn *callback, void *cookie) { +#if NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_SM_SC) + union ble_store_key key; union ble_store_value value; int idx = 0; @@ -589,6 +759,9 @@ ble_store_iterate(int obj_type, idx++; } +#else + return BLE_HS_ENOTSUP; +#endif } /** @@ -599,6 +772,8 @@ ble_store_iterate(int obj_type, int ble_store_clear(void) { +#if NIMBLE_BLE_CONNECT + const uint8_t obj_types[] = { BLE_STORE_OBJ_TYPE_OUR_SEC, BLE_STORE_OBJ_TYPE_PEER_SEC, @@ -632,4 +807,7 @@ ble_store_clear(void) } return 0; +#else + return BLE_HS_ENOTSUP; +#endif } diff --git a/nimble/host/src/ble_store_util.c b/nimble/host/src/ble_store_util.c index 837b8c8cf..57c239285 100644 --- a/nimble/host/src/ble_store_util.c +++ b/nimble/host/src/ble_store_util.c @@ -28,6 +28,7 @@ struct ble_store_util_peer_set { int status; }; +#if NIMBLE_BLE_CONNECT static int ble_store_util_iter_unique_peer(int obj_type, union ble_store_value *val, @@ -62,6 +63,7 @@ ble_store_util_iter_unique_peer(int obj_type, return 0; } +#endif /** * Retrieves the set of peer addresses for which a bond has been established. @@ -81,6 +83,8 @@ int ble_store_util_bonded_peers(ble_addr_t *out_peer_id_addrs, int *out_num_peers, int max_peers) { +#if NIMBLE_BLE_CONNECT + struct ble_store_util_peer_set set = { .peer_id_addrs = out_peer_id_addrs, .num_peers = 0, @@ -98,6 +102,9 @@ ble_store_util_bonded_peers(ble_addr_t *out_peer_id_addrs, int *out_num_peers, *out_num_peers = set.num_peers; return 0; +#else + return BLE_HS_ENOTSUP; +#endif } /** @@ -112,6 +119,8 @@ ble_store_util_bonded_peers(ble_addr_t *out_peer_id_addrs, int *out_num_peers, int ble_store_util_delete_peer(const ble_addr_t *peer_id_addr) { +#if NIMBLE_BLE_CONNECT + union ble_store_key key; int rc; @@ -182,6 +191,9 @@ ble_store_util_delete_peer(const ble_addr_t *peer_id_addr) #endif return 0; +#else + return BLE_HS_ENOTSUP; +#endif } /** @@ -196,6 +208,8 @@ ble_store_util_delete_peer(const ble_addr_t *peer_id_addr) int ble_store_util_delete_all(int type, const union ble_store_key *key) { +#if NIMBLE_BLE_CONNECT + int rc; do { @@ -207,8 +221,12 @@ ble_store_util_delete_all(int type, const union ble_store_key *key) } return 0; +#else + return BLE_HS_ENOTSUP; +#endif } +#if NIMBLE_BLE_CONNECT static int ble_store_util_iter_count(int obj_type, union ble_store_value *val, @@ -221,10 +239,13 @@ ble_store_util_iter_count(int obj_type, return 0; } +#endif int ble_store_util_count(int type, int *out_count) { +#if NIMBLE_BLE_CONNECT + int rc; *out_count = 0; @@ -236,11 +257,15 @@ ble_store_util_count(int type, int *out_count) } return 0; +#else + return BLE_HS_ENOTSUP; +#endif } int ble_store_util_delete_oldest_peer(void) { +#if NIMBLE_BLE_CONNECT #if MYNEWT_VAL(BLE_STORE_MAX_BONDS) ble_addr_t peer_id_addrs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; int num_peers; @@ -263,6 +288,9 @@ ble_store_util_delete_oldest_peer(void) } #endif return 0; +#else + return BLE_HS_ENOTSUP; +#endif } #if MYNEWT_VAL(ENC_ADV_DATA) @@ -284,6 +312,8 @@ int ble_store_util_ead_peers(ble_addr_t *out_peer_id_addrs, int *out_num_peers, int max_peers) { +#if NIMBLE_BLE_CONNECT + struct ble_store_util_peer_set set = { .peer_id_addrs = out_peer_id_addrs, .num_peers = 0, @@ -301,12 +331,17 @@ ble_store_util_ead_peers(ble_addr_t *out_peer_id_addrs, int *out_num_peers, *out_num_peers = set.num_peers; return 0; +#else + return BLE_HS_ENOTSUP; +#endif } int ble_store_util_delete_ead_oldest_peer(void) { +#if NIMBLE_BLE_CONNECT + ble_addr_t peer_id_addrs[MYNEWT_VAL(BLE_STORE_MAX_EADS)]; int num_peers; int rc; @@ -331,6 +366,9 @@ ble_store_util_delete_ead_oldest_peer(void) } return 0; +#else + return BLE_HS_ENOTSUP; +#endif } #endif diff --git a/nimble/host/src/ble_uuid.c b/nimble/host/src/ble_uuid.c index 15f663748..0f99f7f64 100644 --- a/nimble/host/src/ble_uuid.c +++ b/nimble/host/src/ble_uuid.c @@ -25,15 +25,22 @@ #include "nimble/ble.h" #include "ble_hs_priv.h" #include "host/ble_uuid.h" +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#include "esp_nimble_mem.h" +#endif #define BLE_UUID16_STR_MAX_LEN 6 #define BLE_UUID32_STR_MAX_LEN 10 #define BLE_UUID128_STR_MAX_LEN 36 +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +static uint8_t * ble_uuid_base = NULL; +#else static uint8_t ble_uuid_base[16] = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +#endif #if MYNEWT_VAL(BLE_HS_DEBUG) #define VERIFY_UUID(uuid) \ @@ -186,6 +193,30 @@ ble_uuid_to_str(const ble_uuid_t *uuid, char *dst) return dst; } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +static int +ble_uuid_base_init(void) +{ + if (ble_uuid_base == NULL) { + ble_uuid_base = nimble_platform_mem_calloc(1, sizeof(uint8_t) * 16); + if (ble_uuid_base == NULL) { + return BLE_HS_ENOMEM; + } + } + + ble_uuid_base[0] = 0xfb; + ble_uuid_base[1] = 0x34; + ble_uuid_base[2] = 0x9b; + ble_uuid_base[3] = 0x5f; + ble_uuid_base[4] = 0x80; + ble_uuid_base[7] = 0x80; + ble_uuid_base[9] = 0x10; + + return 0; +} +#endif + + int ble_uuid_from_str(ble_uuid_any_t *uuid, const char *str) { @@ -196,6 +227,13 @@ ble_uuid_from_str(ble_uuid_any_t *uuid, const char *str) uint32_t u32 = 0; int len = (int) strlen(str); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + int rc = ble_uuid_base_init(); + if (rc != 0) { + return rc; + } +#endif + if ((len < 4) || (len % 2 != 0)) { return BLE_HS_EINVAL; } @@ -382,6 +420,13 @@ ble_uuid_flat(const ble_uuid_t *uuid, void *dst) { VERIFY_UUID(uuid); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + int rc = ble_uuid_base_init(); + if (rc != 0) { + return rc; + } +#endif + switch (uuid->type) { case BLE_UUID_TYPE_16: put_le16(dst, BLE_UUID16(uuid)->value); @@ -407,3 +452,15 @@ ble_uuid_length(const ble_uuid_t *uuid) return uuid->type >> 3; } + + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void +ble_uuid_deinit(void) +{ + if (ble_uuid_base) { + nimble_platform_mem_free(ble_uuid_base); + ble_uuid_base = NULL; + } +} +#endif diff --git a/nimble/host/src/ble_uuid_priv.h b/nimble/host/src/ble_uuid_priv.h index 3dbcc6b8e..2f51e0532 100644 --- a/nimble/host/src/ble_uuid_priv.h +++ b/nimble/host/src/ble_uuid_priv.h @@ -37,6 +37,7 @@ int ble_uuid_to_any(const ble_uuid_t *uuid, ble_uuid_any_t *uuid_any); int ble_uuid_to_mbuf(const ble_uuid_t *uuid, struct os_mbuf *om); int ble_uuid_flat(const ble_uuid_t *uuid, void *dst); int ble_uuid_length(const ble_uuid_t *uuid); +void ble_uuid_deinit(void); #ifdef __cplusplus } diff --git a/nimble/host/store/config/src/ble_store_config.c b/nimble/host/store/config/src/ble_store_config.c index cab636340..8a8decfd6 100644 --- a/nimble/host/store/config/src/ble_store_config.c +++ b/nimble/host/store/config/src/ble_store_config.c @@ -25,7 +25,13 @@ #include "host/ble_hs.h" #include "store/config/ble_store_config.h" #include "ble_store_config_priv.h" +#include "esp_nimble_mem.h" +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +ble_store_config_vars_t * ble_store_config_vars = NULL; +#endif + +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) #if MYNEWT_VAL(BLE_STORE_MAX_BONDS) struct ble_store_value_sec ble_store_config_our_secs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; @@ -70,11 +76,13 @@ int ble_store_config_num_rpa_recs; struct ble_store_value_local_irk ble_store_config_local_irks[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; int ble_store_config_num_local_irks; +#endif /* !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) */ /***************************************************************************** * $sec * *****************************************************************************/ +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) int ble_store_config_compare_bond_count(const void *a, const void *b) { const struct ble_store_value_sec *sec_a = (const struct ble_store_value_sec *)a; const struct ble_store_value_sec *sec_b = (const struct ble_store_value_sec *)b; @@ -85,11 +93,9 @@ int ble_store_config_compare_bond_count(const void *a, const void *b) { /* This function gets the stored device records of OUR_SEC object type, arranges them in order of their bond count, * and then updates them with new counts so they're in sequence. */ -#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) int ble_restore_our_sec_nvs(void) { esp_err_t err; - extern uint16_t ble_store_config_our_bond_count; struct ble_store_value_sec temp_our_secs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; int temp_count = 0; @@ -135,7 +141,6 @@ int ble_restore_our_sec_nvs(void) int ble_restore_peer_sec_nvs(void) { esp_err_t err; - extern uint16_t ble_store_config_peer_bond_count; struct ble_store_value_sec temp_peer_secs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; int temp_count = 0; @@ -353,10 +358,10 @@ ble_store_config_delete_sec(const struct ble_store_key_sec *key_sec, } #endif +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) static int ble_store_config_delete_our_sec(const struct ble_store_key_sec *key_sec) { -#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) int rc; rc = ble_store_config_delete_sec(key_sec, ble_store_config_our_secs, @@ -371,15 +376,11 @@ ble_store_config_delete_our_sec(const struct ble_store_key_sec *key_sec) } return 0; -#else - return BLE_HS_ENOENT; -#endif } static int ble_store_config_delete_peer_sec(const struct ble_store_key_sec *key_sec) { -#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) int rc; rc = ble_store_config_delete_sec(key_sec, ble_store_config_peer_secs, @@ -393,10 +394,8 @@ ble_store_config_delete_peer_sec(const struct ble_store_key_sec *key_sec) return rc; } return 0; -#else - return BLE_HS_ENOENT; -#endif } +#endif static int ble_store_config_read_peer_sec(const struct ble_store_key_sec *key_sec, @@ -1144,6 +1143,7 @@ ble_store_config_delete(int obj_type, const union ble_store_key *key) int rc; switch (obj_type) { +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) case BLE_STORE_OBJ_TYPE_PEER_SEC: rc = ble_store_config_delete_peer_sec(&key->sec); return rc; @@ -1151,6 +1151,7 @@ ble_store_config_delete(int obj_type, const union ble_store_key *key) case BLE_STORE_OBJ_TYPE_OUR_SEC: rc = ble_store_config_delete_our_sec(&key->sec); return rc; +#endif case BLE_STORE_OBJ_TYPE_CCCD: rc = ble_store_config_delete_cccd(&key->cccd); @@ -1181,6 +1182,15 @@ ble_store_config_delete(int obj_type, const union ble_store_key *key) void ble_store_config_init(void) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_store_config_vars == NULL) { + ble_store_config_vars = nimble_platform_mem_calloc(1, sizeof(ble_store_config_vars_t)); + if (ble_store_config_vars == NULL) { + return; + } + } +#endif + /* Ensure this function only gets called by sysinit. */ SYSINIT_ASSERT_ACTIVE(); @@ -1200,3 +1210,14 @@ ble_store_config_init(void) ble_store_config_num_local_irks=0; ble_store_config_conf_init(); } + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void +ble_store_config_deinit(void) +{ + if (ble_store_config_vars != NULL) { + nimble_platform_mem_free(ble_store_config_vars); + ble_store_config_vars = NULL; + } +} +#endif diff --git a/nimble/host/store/config/src/ble_store_config_conf.c b/nimble/host/store/config/src/ble_store_config_conf.c index 8d2d90516..181ee04d1 100644 --- a/nimble/host/store/config/src/ble_store_config_conf.c +++ b/nimble/host/store/config/src/ble_store_config_conf.c @@ -51,17 +51,21 @@ static struct conf_handler ble_store_config_conf_handler = { #define BLE_STORE_CONFIG_SEC_SET_ENCODE_SZ \ (MYNEWT_VAL(BLE_STORE_MAX_BONDS) * BLE_STORE_CONFIG_SEC_ENCODE_SZ + 1) +#if MYNEWT_VAL(BLE_STORE_MAX_CCCDS) #define BLE_STORE_CONFIG_CCCD_ENCODE_SZ \ BASE64_ENCODE_SIZE(sizeof (struct ble_store_value_cccd)) #define BLE_STORE_CONFIG_CCCD_SET_ENCODE_SZ \ (MYNEWT_VAL(BLE_STORE_MAX_CCCDS) * BLE_STORE_CONFIG_CCCD_ENCODE_SZ + 1) +#endif +#if MYNEWT_VAL(BLE_STORE_MAX_CSFCS) #define BLE_STORE_CONFIG_CSFC_ENCODE_SZ \ BASE64_ENCODE_SIZE(sizeof (struct ble_store_value_csfc)) #define BLE_STORE_CONFIG_CSFC_SET_ENCODE_SZ \ (MYNEWT_VAL(BLE_STORE_MAX_CSFCS) * BLE_STORE_CONFIG_CSFC_ENCODE_SZ + 1) +#endif #if MYNEWT_VAL(ENC_ADV_DATA) #define BLE_STORE_CONFIG_EAD_ENCODE_SZ \ @@ -133,7 +137,9 @@ ble_store_config_conf_set(int argc, char **argv, char *val) sizeof *ble_store_config_cccds, &ble_store_config_num_cccds); return rc; - } else if (strcmp(argv[0], "csfc") == 0) { + } +#if MYNEWT_VAL(BLE_STORE_MAX_CSFCS) + else if (strcmp(argv[0], "csfc") == 0) { rc = ble_store_config_deserialize_arr( val, ble_store_config_csfcs, @@ -141,6 +147,7 @@ ble_store_config_conf_set(int argc, char **argv, char *val) &&ble_store_config_num_csfcs); return rc; } +#endif #if MYNEWT_VAL(ENC_ADV_DATA) else if (strcmp(argv[0], "ead") == 0) { rc = ble_store_config_deserialize_arr( @@ -151,7 +158,8 @@ ble_store_config_conf_set(int argc, char **argv, char *val) return rc; } #endif - else if (strcmp(argv[0],"rpa_rec") == 0){ +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) + else if (strcmp(argv[0],"rpa_rec") == 0) { rc = ble_store_config_deserialize_arr( val, ble_store_config_rpa_recs, @@ -159,6 +167,7 @@ ble_store_config_conf_set(int argc, char **argv, char *val) &ble_store_config_num_rpa_recs); return rc; } +#endif } return OS_ENOENT; } @@ -193,14 +202,14 @@ ble_store_config_conf_export(void (*func)(char *name, char *val), buf.cccd, sizeof buf.cccd); func("ble_hs/cccd", buf.cccd); - +#if MYNEWT_VAL(BLE_STORE_MAX_CSFCS) ble_store_config_serialize_arr(ble_store_config_csfcs, sizeof *ble_store_config_csfcs, ble_store_config_num_csfcs, buf.csfc, sizeof buf.csfc); func("ble_hs/csfc", buf.csfc); - +#endif #if MYNEWT_VAL(ENC_ADV_DATA) ble_store_config_serialize_arr(ble_store_config_eads, sizeof *ble_store_config_eads, @@ -209,11 +218,13 @@ ble_store_config_conf_export(void (*func)(char *name, char *val), sizeof buf.ead); func("ble_hs/ead", buf.ead); #endif +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) ble_store_config_serialize_arr(ble_store_config_rpa_recs, sizeof *ble_store_config_rpa_recs, ble_store_config_num_rpa_recs, buf.rpa_rec, sizeof buf.rpa_rec); +#endif return 0; } @@ -283,7 +294,7 @@ ble_store_config_persist_cccds(void) return 0; } - +#if MYNEWT_VAL(BLE_STORE_MAX_CSFCS) int ble_store_config_persist_csfcs(void) { @@ -302,6 +313,7 @@ ble_store_config_persist_csfcs(void) return 0; } +#endif #if MYNEWT_VAL(ENC_ADV_DATA) int @@ -321,6 +333,8 @@ ble_store_config_persist_eads(void) return 0; } #endif + +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) int ble_store_config_persist_rpa_recs(void) { @@ -337,6 +351,8 @@ ble_store_config_persist_rpa_recs(void) } return 0; } +#endif + void ble_store_config_conf_init(void) { diff --git a/nimble/host/store/config/src/ble_store_config_priv.h b/nimble/host/store/config/src/ble_store_config_priv.h index a3dcc6aa4..941bdb937 100644 --- a/nimble/host/store/config/src/ble_store_config_priv.h +++ b/nimble/host/store/config/src/ble_store_config_priv.h @@ -24,28 +24,119 @@ extern "C" { #endif +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +typedef struct { +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) + struct ble_store_value_sec + _ble_store_config_our_secs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; +#endif + int _ble_store_config_num_our_secs; + + uint16_t _ble_store_config_our_bond_count; + uint16_t _ble_store_config_peer_bond_count; + +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) + struct ble_store_value_sec + _ble_store_config_peer_secs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; +#endif + int _ble_store_config_num_peer_secs; + +#if MYNEWT_VAL(BLE_STORE_MAX_CCCDS) + struct ble_store_value_cccd + _ble_store_config_cccds[MYNEWT_VAL(BLE_STORE_MAX_CCCDS)]; +#endif + + int _ble_store_config_num_cccds; + +#if MYNEWT_VAL(BLE_STORE_MAX_CSFCS) + struct ble_store_value_csfc + _ble_store_config_csfcs[MYNEWT_VAL(BLE_STORE_MAX_CSFCS)]; +#endif + int _ble_store_config_num_csfcs; + +#if MYNEWT_VAL(ENC_ADV_DATA) + struct ble_store_value_ead + _ble_store_config_eads[MYNEWT_VAL(BLE_STORE_MAX_EADS)]; + int _ble_store_config_num_eads; +#endif + +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) + struct ble_store_value_rpa_rec + _ble_store_config_rpa_recs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; +#endif + int _ble_store_config_num_rpa_recs; + + struct ble_store_value_local_irk + _ble_store_config_local_irks[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; + int _ble_store_config_num_local_irks; +} ble_store_config_vars_t; + +extern ble_store_config_vars_t * ble_store_config_vars; +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) + #define ble_store_config_our_secs (ble_store_config_vars->_ble_store_config_our_secs) + #define ble_store_config_peer_secs (ble_store_config_vars->_ble_store_config_peer_secs) + #define ble_store_config_rpa_recs (ble_store_config_vars->_ble_store_config_rpa_recs) +#endif + +#define ble_store_config_local_irks (ble_store_config_vars->_ble_store_config_local_irks) +#define ble_store_config_num_our_secs (ble_store_config_vars->_ble_store_config_num_our_secs) +#define ble_store_config_our_bond_count (ble_store_config_vars->_ble_store_config_our_bond_count) +#define ble_store_config_peer_bond_count (ble_store_config_vars->_ble_store_config_peer_bond_count) +#define ble_store_config_num_peer_secs (ble_store_config_vars->_ble_store_config_num_peer_secs) +#define ble_store_config_num_rpa_recs (ble_store_config_vars->_ble_store_config_num_rpa_recs) +#define ble_store_config_num_local_irks (ble_store_config_vars->_ble_store_config_num_local_irks) + +#if MYNEWT_VAL(BLE_STORE_MAX_CCCDS) + #define ble_store_config_cccds (ble_store_config_vars->_ble_store_config_cccds) +#endif +#define ble_store_config_num_cccds (ble_store_config_vars->_ble_store_config_num_cccds) + +#if MYNEWT_VAL(BLE_STORE_MAX_CSFCS) + #define ble_store_config_csfcs (ble_store_config_vars->_ble_store_config_csfcs) +#endif +#define ble_store_config_num_csfcs (ble_store_config_vars->_ble_store_config_num_csfcs) + +#if MYNEWT_VAL(ENC_ADV_DATA) + #define ble_store_config_eads (ble_store_config_vars->_ble_store_config_eads) + #define ble_store_config_num_eads (ble_store_config_vars->_ble_store_config_num_eads) +#endif +#endif /* MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) */ + +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) extern struct ble_store_value_sec ble_store_config_our_secs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; + extern int ble_store_config_num_our_secs; +extern uint16_t ble_store_config_our_bond_count; +extern uint16_t ble_store_config_peer_bond_count; + extern struct ble_store_value_sec ble_store_config_peer_secs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; -extern int ble_store_config_num_peer_secs; +extern int ble_store_config_num_peer_secs; +#endif + +#if MYNEWT_VAL(BLE_STORE_MAX_CCCDS) extern struct ble_store_value_cccd ble_store_config_cccds[MYNEWT_VAL(BLE_STORE_MAX_CCCDS)]; extern int ble_store_config_num_cccds; +#endif +#if MYNEWT_VAL(BLE_STORE_MAX_CSFCS) extern struct ble_store_value_csfc - ble_store_config_csfcs[MYNEWT_VAL(BLE_STORE_MAX_CSFCS)]; + ble_store_config_csfcs[MYNEWT_VAL(BLE_STORE_MAX_CSFCS)]; extern int ble_store_config_num_csfcs; +#endif #if MYNEWT_VAL(ENC_ADV_DATA) extern struct ble_store_value_ead - ble_store_config_eads[MYNEWT_VAL(BLE_STORE_MAX_EADS)]; + ble_store_config_eads[MYNEWT_VAL(BLE_STORE_MAX_EADS)]; extern int ble_store_config_num_eads; #endif +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) extern struct ble_store_value_rpa_rec ble_store_config_rpa_recs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; extern int ble_store_config_num_rpa_recs; @@ -53,14 +144,20 @@ extern int ble_store_config_num_rpa_recs; extern struct ble_store_value_local_irk ble_store_config_local_irks[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; extern int ble_store_config_num_local_irks; - +#endif +#endif /* !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) */ #if MYNEWT_VAL(BLE_STORE_CONFIG_PERSIST) - +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) int ble_store_config_persist_our_secs(void); int ble_store_config_persist_peer_secs(void); +#endif +#if MYNEWT_VAL(BLE_STORE_MAX_CCCDS) int ble_store_config_persist_cccds(void); +#endif +#if MYNEWT_VAL(BLE_STORE_MAX_CSFCS) int ble_store_config_persist_csfcs(void); +#endif #if MYNEWT_VAL(BLE_STORE_MAX_BONDS) int ble_restore_our_sec_nvs(void); int ble_restore_peer_sec_nvs(void); @@ -71,7 +168,9 @@ int ble_store_config_persist_eads(void); int ble_store_config_persist_rpa_recs(void); int ble_store_config_persist_local_irk(void); void ble_store_config_conf_init(void); - +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +void ble_store_config_deinit(void); +#endif #else static inline int ble_store_config_persist_our_secs(void) { return 0; } @@ -84,7 +183,7 @@ static inline int ble_store_config_persist_eads(void) { return 0; } static inline int ble_store_config_persist_rpa_recs(void) { return 0; } static inline int ble_store_config_persist_local_irk(void) { return 0; } static inline void ble_store_config_conf_init(void) { } - +//static inline void ble_store_config_deinit(void) { } #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) static inline int ble_store_persist_peer_records(void) { return 0; } #endif diff --git a/nimble/host/store/config/src/ble_store_nvs.c b/nimble/host/store/config/src/ble_store_nvs.c index 4b0ade857..7b076b994 100644 --- a/nimble/host/store/config/src/ble_store_nvs.c +++ b/nimble/host/store/config/src/ble_store_nvs.c @@ -545,8 +545,6 @@ ble_nvs_restore_sec_keys(void) { esp_err_t err; int flag = 0; - extern uint16_t ble_store_config_our_bond_count; - extern uint16_t ble_store_config_peer_bond_count; extern int ble_store_config_compare_bond_count(const void *a, const void *b); #if MYNEWT_VAL(BLE_STORE_MAX_BONDS) diff --git a/nimble/transport/esp_ipc/src/hci_esp_ipc.c b/nimble/transport/esp_ipc/src/hci_esp_ipc.c index e7c34003f..4e999c54d 100644 --- a/nimble/transport/esp_ipc/src/hci_esp_ipc.c +++ b/nimble/transport/esp_ipc/src/hci_esp_ipc.c @@ -24,10 +24,11 @@ ble_transport_dummy_host_recv_cb(hci_trans_pkt_ind_t type, uint8_t *data, uint16 static int ble_transport_host_recv_cb(hci_trans_pkt_ind_t type, uint8_t *data, uint16_t len) { - int rc; - + int rc = 0; if (type == HCI_ACL_IND) { +#if CONFIG_BT_NIMBLE_ROLE_CENTRAL || CONFIG_BT_NIMBLE_ROLE_PERIPHERAL rc = ble_transport_to_hs_acl((struct os_mbuf *)data); +#endif } #if MYNEWT_VAL(BLE_ISO) else if (type == HCI_ISO_IND) { diff --git a/nimble/transport/socket/src/ble_hci_socket.c b/nimble/transport/socket/src/ble_hci_socket.c index 14b2d4aed..15c47534f 100644 --- a/nimble/transport/socket/src/ble_hci_socket.c +++ b/nimble/transport/socket/src/ble_hci_socket.c @@ -237,7 +237,7 @@ ble_hci_sock_acl_tx(struct os_mbuf *om) len += m->om_len; } - buf = (uint8_t *)nimble_platform_mem_malloc(len); + buf = (uint8_t *)nimble_platform_mem_calloc(1,len); buf[0] = BLE_HCI_UART_H4_ACL; @@ -348,7 +348,7 @@ ble_hci_sock_cmdevt_tx(uint8_t *hci_ev, uint8_t h4_type) STATS_INC(hci_sock_stats, omsg); STATS_INCN(hci_sock_stats, obytes, len + 1); - buf = (uint8_t *)nimble_platform_mem_malloc(len + 1); + buf = (uint8_t *)nimble_platform_mem_calloc(1,len + 1); buf[0] = h4_type; memcpy(&buf[1], hci_ev, len); @@ -783,7 +783,7 @@ ble_hci_sock_init_task(void) { os_stack_t *pstack; - pstack = nimble_platform_mem_malloc(sizeof(os_stack_t)*BLE_SOCK_STACK_SIZE); + pstack = nimble_platform_mem_calloc(1,sizeof(os_stack_t)*BLE_SOCK_STACK_SIZE); assert(pstack); os_task_init(&ble_sock_task, "hci_sock", ble_hci_sock_ack_handler, NULL, MYNEWT_VAL(BLE_SOCK_TASK_PRIO), BLE_NPL_TIME_FOREVER, pstack, diff --git a/nimble/transport/src/transport.c b/nimble/transport/src/transport.c index 074e419c8..b98ba9f75 100644 --- a/nimble/transport/src/transport.c +++ b/nimble/transport/src/transport.c @@ -75,29 +75,113 @@ void os_msys_buf_free(void); BLE_HCI_DATA_HDR_SZ, OS_ALIGNMENT)) #if !SOC_ESP_NIMBLE_CONTROLLER || !CONFIG_BT_CONTROLLER_ENABLED + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +typedef struct { + os_membuf_t *_pool_cmd_buf; + os_membuf_t *_pool_evt_buf; + os_membuf_t *_pool_evt_lo_buf; + +#if POOL_ACL_COUNT > 0 + os_membuf_t *_pool_acl_buf; +#endif + +#if POOL_ISO_COUNT > 0 + os_membuf_t *_pool_iso_buf; +#endif + + struct os_mempool _pool_cmd; + struct os_mempool _pool_evt; + struct os_mempool _pool_evt_lo; + +#if POOL_ACL_COUNT > 0 + struct os_mempool_ext _pool_acl; + struct os_mbuf_pool _mpool_acl; +#endif + +#if POOL_ISO_COUNT > 0 + struct os_mempool_ext _pool_iso; + struct os_mbuf_pool _mpool_iso; +#endif +}ble_trans_ctx_t; + +static ble_trans_ctx_t *ble_trans_ctx; + +#define pool_cmd_buf (ble_trans_ctx->_pool_cmd_buf) +#define pool_evt_buf (ble_trans_ctx->_pool_evt_buf) +#define pool_evt_lo_buf (ble_trans_ctx->_pool_evt_lo_buf) + +#if POOL_ACL_COUNT > 0 +#define pool_acl_buf (ble_trans_ctx->_pool_acl_buf) +#endif + +#if POOL_ISO_COUNT > 0 +#define pool_iso_buf (ble_trans_ctx->_pool_iso_buf) +#endif + +#define pool_cmd (ble_trans_ctx->_pool_cmd) +#define pool_evt (ble_trans_ctx->_pool_evt) +#define pool_evt_lo (ble_trans_ctx->_pool_evt_lo) + +#if POOL_ACL_COUNT > 0 +#define pool_acl (ble_trans_ctx->_pool_acl) +#define mpool_acl (ble_trans_ctx->_mpool_acl) +#endif + +#if POOL_ISO_COUNT > 0 +#define pool_iso (ble_trans_ctx->_pool_iso) +#define mpool_iso (ble_trans_ctx->_mpool_iso) +#endif + +#else /* MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) */ + static os_membuf_t *pool_cmd_buf; -static struct os_mempool pool_cmd; - static os_membuf_t *pool_evt_buf; -static struct os_mempool pool_evt; - static os_membuf_t *pool_evt_lo_buf; -static struct os_mempool pool_evt_lo; #if POOL_ACL_COUNT > 0 static os_membuf_t *pool_acl_buf; +#endif + +#if POOL_ISO_COUNT > 0 +static os_membuf_t *pool_iso_buf; +#endif + +static struct os_mempool pool_cmd; +static struct os_mempool pool_evt; +static struct os_mempool pool_evt_lo; + +#if POOL_ACL_COUNT > 0 static struct os_mempool_ext pool_acl; static struct os_mbuf_pool mpool_acl; #endif #if POOL_ISO_COUNT > 0 -static os_membuf_t *pool_iso_buf; static struct os_mempool_ext pool_iso; static struct os_mbuf_pool mpool_iso; #endif +#endif /* MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) */ + static os_mempool_put_fn *transport_put_acl_from_ll_cb; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +static int +ble_transport_ensure_ctx(void) +{ + if (ble_trans_ctx) { + return 0; + } + + ble_trans_ctx = nimble_platform_mem_calloc(1, sizeof(*ble_trans_ctx)); + if (!ble_trans_ctx) { + return -1; + } + + return 0; +} +#endif + void * ble_transport_alloc_cmd(void) { @@ -318,7 +402,7 @@ ble_transport_ipc_free(void *buf) } } -#if POOL_ACL_COUNT > 0 +#if POOL_ACL_COUNT > 0 && NIMBLE_BLE_CONNECT static os_error_t ble_transport_acl_put(struct os_mempool_ext *mpe, void *data, void *arg) { @@ -362,32 +446,65 @@ void ble_buf_free(void) os_msys_buf_free(); - nimble_platform_mem_free(pool_evt_buf); - pool_evt_buf = NULL; - nimble_platform_mem_free(pool_evt_lo_buf); - pool_evt_lo_buf = NULL; - nimble_platform_mem_free(pool_cmd_buf); - pool_cmd_buf = NULL; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_trans_ctx == NULL) { + return; + } +#endif + + if (pool_evt_buf ){ + nimble_platform_mem_free(pool_evt_buf); + pool_evt_buf = NULL; + } + + if (pool_evt_lo_buf) { + nimble_platform_mem_free(pool_evt_lo_buf); + pool_evt_lo_buf = NULL; + } + + if (pool_cmd_buf) { + nimble_platform_mem_free(pool_cmd_buf); + pool_cmd_buf = NULL; + } + #if POOL_ACL_COUNT > 0 - nimble_platform_mem_free(pool_acl_buf); - pool_acl_buf = NULL; + if (pool_acl_buf) { + nimble_platform_mem_free(pool_acl_buf); + pool_acl_buf = NULL; + } #endif #if POOL_ISO_COUNT > 0 - nimble_platform_mem_free(pool_iso_buf); - pool_iso_buf = NULL; + if (pool_iso_buf) { + nimble_platform_mem_free(pool_iso_buf); + pool_iso_buf = NULL; + } +#endif + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_trans_ctx) { + nimble_platform_mem_free(ble_trans_ctx); + ble_trans_ctx = NULL; + } #endif } esp_err_t ble_buf_alloc(void) { -#if MYNEWT_VAL(MP_RUNTIME_ALLOC) - return ESP_OK; -#endif - if (os_msys_buf_alloc()) { return ESP_ERR_NO_MEM; } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_transport_ensure_ctx()) { + os_msys_buf_free(); + return ESP_ERR_NO_MEM; + } +#endif + +#if MYNEWT_VAL(MP_RUNTIME_ALLOC) + return ESP_OK; +#endif + pool_evt_buf = (os_membuf_t *) nimble_platform_mem_calloc(1, (sizeof(os_membuf_t) * OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT), MYNEWT_VAL(BLE_TRANSPORT_EVT_SIZE)))); @@ -431,6 +548,12 @@ ble_transport_init(void) SYSINIT_ASSERT_ACTIVE(); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_transport_ensure_ctx()) { + return; + } +#endif + rc = os_mempool_init(&pool_cmd, POOL_CMD_COUNT, POOL_CMD_SIZE, pool_cmd_buf, "transport_pool_cmd"); SYSINIT_PANIC_ASSERT(rc == 0); @@ -439,6 +562,7 @@ ble_transport_init(void) pool_evt_buf, "transport_pool_evt"); SYSINIT_PANIC_ASSERT(rc == 0); + rc = os_mempool_init(&pool_evt_lo, POOL_EVT_LO_COUNT, POOL_EVT_SIZE, pool_evt_lo_buf, "transport_pool_evt_lo"); SYSINIT_PANIC_ASSERT(rc == 0); @@ -452,8 +576,10 @@ ble_transport_init(void) POOL_ACL_SIZE, POOL_ACL_COUNT); SYSINIT_PANIC_ASSERT(rc == 0); +#if NIMBLE_BLE_CONNECT pool_acl.mpe_put_cb = ble_transport_acl_put; #endif +#endif #if POOL_ISO_COUNT > 0 rc = os_mempool_ext_init(&pool_iso, POOL_ISO_COUNT, POOL_ISO_SIZE, @@ -470,6 +596,7 @@ void ble_transport_deinit(void) { int rc = 0; + rc = os_mempool_ext_clear(&pool_acl); SYSINIT_PANIC_ASSERT(rc == 0); @@ -481,7 +608,12 @@ ble_transport_deinit(void) rc = os_mempool_clear(&pool_cmd); SYSINIT_PANIC_ASSERT(rc == 0); + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + ble_buf_free(); +#endif } + int ble_transport_register_put_acl_from_ll_cb(os_mempool_put_fn (*cb)) { diff --git a/nimble/transport/uart/src/hci_uart.c b/nimble/transport/uart/src/hci_uart.c index ddf3825c5..c50155b42 100644 --- a/nimble/transport/uart/src/hci_uart.c +++ b/nimble/transport/uart/src/hci_uart.c @@ -205,6 +205,7 @@ ble_transport_to_hs_evt_impl(void *buf) return 0; } +#if NIMBLE_BLE_CONNECT int ble_transport_to_hs_acl_impl(struct os_mbuf *om) { @@ -232,6 +233,7 @@ ble_transport_to_hs_acl_impl(struct os_mbuf *om) return 0; } +#endif int ble_transport_to_hs_iso_impl(struct os_mbuf *om) diff --git a/porting/nimble/src/hal_uart.c b/porting/nimble/src/hal_uart.c index 3e9fd5598..ac58952ce 100644 --- a/porting/nimble/src/hal_uart.c +++ b/porting/nimble/src/hal_uart.c @@ -13,6 +13,7 @@ #include "esp_log.h" #include "esp_attr.h" #include "esp_nimble_mem.h" +#include "esp_nimble_cfg.h" static const char *TAG = "hal_uart"; @@ -52,10 +53,13 @@ void hal_uart_deinit_cbs(void) hci_uart.u_func_arg = NULL; } -static void IRAM_ATTR hci_uart_rx_task(void *pvParameters) +#if !MYNEWT_VAL(BLE_LOW_SPEED_MODE) +IRAM_ATTR +#endif +static void hci_uart_rx_task(void *pvParameters) { uart_event_t event; - uint8_t* dtmp = (uint8_t*) nimble_platform_mem_malloc(RD_BUF_SIZE); + uint8_t* dtmp = (uint8_t*) nimble_platform_mem_calloc(1,RD_BUF_SIZE); while(hci_uart.uart_opened) { //Waiting for UART event. if(xQueueReceive(hci_uart.evt_queue, (void * )&event, (TickType_t)portMAX_DELAY)) { @@ -147,7 +151,10 @@ int hal_uart_config(int uart, int32_t speed, uint8_t data_bits, uint8_t stop_bit return 0; } -void IRAM_ATTR hal_uart_start_tx(int uart_no) +#if !MYNEWT_VAL(BLE_LOW_SPEED_MODE) +IRAM_ATTR +#endif +void hal_uart_start_tx(int uart_no) { int data; uint8_t u8_data=0; diff --git a/porting/nimble/src/nimble_port.c b/porting/nimble/src/nimble_port.c index 3510d4648..4dd82f2c3 100644 --- a/porting/nimble/src/nimble_port.c +++ b/porting/nimble/src/nimble_port.c @@ -54,22 +54,64 @@ extern void os_msys_init(void); #if CONFIG_BT_NIMBLE_ENABLED - extern void ble_hs_deinit(void); -static struct ble_hs_stop_listener stop_listener; +#endif -#endif //CONFIG_BT_NIMBLE_ENABLED +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#include "esp_nimble_mem.h" +typedef struct { + struct ble_npl_eventq eventq; + struct ble_npl_sem stop_sem; + struct ble_npl_event ev_stop; +#if CONFIG_BT_NIMBLE_ENABLED + struct ble_hs_stop_listener listener; +#endif +} ble_npl_ctx_t; +static ble_npl_ctx_t *ble_npl_ctx; + +#define g_eventq_dflt (ble_npl_ctx->eventq) +#define ble_hs_stop_sem (ble_npl_ctx->stop_sem) +#define ble_hs_ev_stop (ble_npl_ctx->ev_stop) + +#if CONFIG_BT_NIMBLE_ENABLED +#define stop_listener (ble_npl_ctx->listener) +#endif + +#else static struct ble_npl_eventq g_eventq_dflt; static struct ble_npl_sem ble_hs_stop_sem; static struct ble_npl_event ble_hs_ev_stop; +#if CONFIG_BT_NIMBLE_ENABLED +static struct ble_hs_stop_listener stop_listener; +#endif //CONFIG_BT_NIMBLE_ENABLED + +#endif + extern void os_msys_init(void); extern void os_mempool_module_init(void); #if MYNEWT_VAL(MP_RUNTIME_ALLOC) extern void os_mempool_deinit(void); #endif +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +static int +ble_npl_ensure_ctx(void) +{ + if (ble_npl_ctx != NULL) { + return 0; + } + + ble_npl_ctx = nimble_platform_mem_calloc(1, sizeof(*ble_npl_ctx)); + if (ble_npl_ctx == NULL) { + return BLE_HS_ENOMEM; + } + + return 0; +} +#endif + /** * Called when the host stop procedure has completed. */ @@ -169,6 +211,12 @@ esp_err_t esp_nimble_deinit(void) npl_freertos_mempool_deinit(); #endif +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_npl_ctx) { + nimble_platform_mem_free(ble_npl_ctx); + ble_npl_ctx = NULL; + } +#endif #if MYNEWT_VAL(MP_RUNTIME_ALLOC) os_mempool_deinit(); #endif @@ -210,6 +258,13 @@ nimble_port_init(void) } #endif +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + ret = ble_npl_ensure_ctx(); + if (ret != ESP_OK) { + return ret; + } +#endif + ret = esp_nimble_init(); if (ret != ESP_OK) { @@ -312,8 +367,10 @@ nimble_port_stop(void) return ESP_OK; } -void -IRAM_ATTR nimble_port_run(void) +#if !MYNEWT_VAL(BLE_LOW_SPEED_MODE) +IRAM_ATTR +#endif +void nimble_port_run(void) { struct ble_npl_event *ev; @@ -328,8 +385,17 @@ IRAM_ATTR nimble_port_run(void) } } +#if !MYNEWT_VAL(BLE_LOW_SPEED_MODE) +IRAM_ATTR +#endif struct ble_npl_eventq * -IRAM_ATTR nimble_port_get_dflt_eventq(void) +nimble_port_get_dflt_eventq(void) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_npl_ensure_ctx()) { + return NULL; + } +#endif + return &g_eventq_dflt; } diff --git a/porting/nimble/src/os_mbuf.c b/porting/nimble/src/os_mbuf.c index 4084c265e..3ea113c07 100644 --- a/porting/nimble/src/os_mbuf.c +++ b/porting/nimble/src/os_mbuf.c @@ -58,8 +58,22 @@ * @{ */ +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) STAILQ_HEAD(, os_mbuf_pool) g_msys_pool_list = STAILQ_HEAD_INITIALIZER(g_msys_pool_list); +#else +STAILQ_HEAD(, os_mbuf_pool) g_msys_pool_list; +static bool g_msys_pool_list_inited; + +static void +os_msys_pool_list_ensure_init(void) +{ + if (!g_msys_pool_list_inited) { + STAILQ_INIT(&g_msys_pool_list); + g_msys_pool_list_inited = true; + } +} +#endif static uint8_t log_count; @@ -133,6 +147,10 @@ os_msys_register(struct os_mbuf_pool *new_pool) { struct os_mbuf_pool *pool; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + os_msys_pool_list_ensure_init(); +#endif + pool = NULL; STAILQ_FOREACH(pool, &g_msys_pool_list, omp_next) { if (new_pool->omp_databuf_len > pool->omp_databuf_len) { @@ -153,6 +171,9 @@ void os_msys_reset(void) { STAILQ_INIT(&g_msys_pool_list); +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + g_msys_pool_list_inited = true; +#endif } static struct os_mbuf_pool * @@ -160,6 +181,10 @@ _os_msys_find_pool(uint16_t dsize) { struct os_mbuf_pool *pool; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + os_msys_pool_list_ensure_init(); +#endif + pool = NULL; STAILQ_FOREACH(pool, &g_msys_pool_list, omp_next) { if (dsize <= pool->omp_databuf_len) { @@ -228,6 +253,10 @@ os_msys_count(void) struct os_mbuf_pool *omp; int total; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + os_msys_pool_list_ensure_init(); +#endif + total = 0; STAILQ_FOREACH(omp, &g_msys_pool_list, omp_next) { total += omp->omp_pool->mp_num_blocks; @@ -242,6 +271,10 @@ os_msys_num_free(void) struct os_mbuf_pool *omp; int total; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + os_msys_pool_list_ensure_init(); +#endif + total = 0; STAILQ_FOREACH(omp, &g_msys_pool_list, omp_next) { total += omp->omp_pool->mp_num_free; diff --git a/porting/nimble/src/os_mempool.c b/porting/nimble/src/os_mempool.c index 37813795f..4520e3cf1 100644 --- a/porting/nimble/src/os_mempool.c +++ b/porting/nimble/src/os_mempool.c @@ -40,7 +40,12 @@ #define OS_MEMPOOL_TRUE_BLOCK_SIZE(mp) OS_MEM_TRUE_BLOCK_SIZE(mp->mp_block_size) #endif +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) STAILQ_HEAD(, os_mempool) g_os_mempool_list = STAILQ_HEAD_INITIALIZER(g_os_mempool_list); +#else +STAILQ_HEAD(, os_mempool) g_os_mempool_list; +static bool g_os_mempool_list_inited; +#endif #if MYNEWT_VAL(OS_MEMPOOL_POISON) static uint32_t os_mem_poison = 0xde7ec7ed; @@ -118,6 +123,17 @@ os_mempool_guard_check(const struct os_mempool *mp, void *start) #define os_mempool_guard_check(mp, start) #endif +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +static void +os_mempool_list_ensure_init(void) +{ + if (!g_os_mempool_list_inited) { + STAILQ_INIT(&g_os_mempool_list); + g_os_mempool_list_inited = true; + } +} +#endif + static os_error_t os_mempool_init_internal(struct os_mempool *mp, uint16_t blocks, uint32_t block_size, void *membuf, const char *name, @@ -159,7 +175,7 @@ os_mempool_init_internal(struct os_mempool *mp, uint16_t blocks, mp->name = name; SLIST_FIRST(mp) = membuf; - #if MYNEWT_VAL(MP_RUNTIME_ALLOC) +#if MYNEWT_VAL(MP_RUNTIME_ALLOC) if (membuf == NULL) { /* Runtime allocation mode */ mp->mp_membuf_addr = 0; @@ -173,7 +189,7 @@ os_mempool_init_internal(struct os_mempool *mp, uint16_t blocks, STAILQ_INSERT_TAIL(&g_os_mempool_list, mp, mp_list); return OS_OK; } - #endif +#endif if (blocks > 0) { os_mempool_poison(mp, membuf); @@ -195,6 +211,22 @@ os_mempool_init_internal(struct os_mempool *mp, uint16_t blocks, SLIST_NEXT(block_ptr, mb_next) = NULL; } +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + os_mempool_list_ensure_init(); + + /* Check if mempool is already in the list (reinitialization case) */ + { + struct os_mempool *cur; + STAILQ_FOREACH(cur, &g_os_mempool_list, mp_list) { + if (cur == mp) { + /* Mempool is already in the list, remove it first */ + os_mempool_unregister(mp); + break; + } + } + } +#endif + STAILQ_INSERT_TAIL(&g_os_mempool_list, mp, mp_list); return OS_OK; @@ -236,6 +268,9 @@ os_mempool_unregister(struct os_mempool *mp) * than with `STAILQ_REMOVE` to allow for a graceful failure if the mempool * isn't found. */ +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + os_mempool_list_ensure_init(); +#endif prev = NULL; STAILQ_FOREACH(cur, &g_os_mempool_list, mp_list) { @@ -275,7 +310,7 @@ os_mempool_clear(struct os_mempool *mp) return OS_INVALID_PARM; } - #if MYNEWT_VAL(MP_RUNTIME_ALLOC) +#if MYNEWT_VAL(MP_RUNTIME_ALLOC) /* For runtime allocation mode, check whether all blocks have been freed */ if (mp->mp_flags & OS_MEMPOOL_F_RUNTIME) { assert(mp->mp_num_free == mp->mp_num_blocks); @@ -295,7 +330,7 @@ os_mempool_clear(struct os_mempool *mp) mp->mp_min_free = mp->mp_num_blocks; return OS_OK; } - #endif +#endif true_block_size = OS_MEMPOOL_TRUE_BLOCK_SIZE(mp); @@ -329,11 +364,11 @@ os_mempool_clear(struct os_mempool *mp) os_error_t os_mempool_ext_clear(struct os_mempool_ext *mpe) { - #if MYNEWT_VAL(MP_RUNTIME_ALLOC) +#if MYNEWT_VAL(MP_RUNTIME_ALLOC) mpe->mpe_mp.mp_flags &= ~OS_MEMPOOL_F_EXT; - #else +#else mpe->mpe_mp.mp_flags = 0; - #endif +#endif mpe->mpe_put_cb = NULL; mpe->mpe_put_arg = NULL; @@ -345,12 +380,12 @@ os_mempool_is_sane(const struct os_mempool *mp) { struct os_memblock *block; - #if MYNEWT_VAL(MP_RUNTIME_ALLOC) +#if MYNEWT_VAL(MP_RUNTIME_ALLOC) /* Runtime mode cannot verify sanity */ if (mp->mp_flags & OS_MEMPOOL_F_RUNTIME) { assert(0); } - #endif +#endif /* Verify that each block in the free list belongs to the mempool. */ SLIST_FOREACH(block, mp, mb_next) { @@ -371,12 +406,12 @@ os_memblock_from(const struct os_mempool *mp, const void *block_addr) uintptr_t baddr32; uint32_t end; - #if MYNEWT_VAL(MP_RUNTIME_ALLOC) +#if MYNEWT_VAL(MP_RUNTIME_ALLOC) /* Runtime allocation mode doesn't support from */ if (mp->mp_flags & OS_MEMPOOL_F_RUNTIME) { assert(0); } - #endif +#endif static_assert(sizeof block_addr == sizeof baddr32, "Pointer to void must be 32-bits."); @@ -409,7 +444,7 @@ os_memblock_get(struct os_mempool *mp) /* Check to make sure they passed in a memory pool (or something) */ block = NULL; - #if MYNEWT_VAL(MP_RUNTIME_ALLOC) +#if MYNEWT_VAL(MP_RUNTIME_ALLOC) /* Runtime allocation mode */ if (mp && mp->mp_flags & OS_MEMPOOL_F_RUNTIME) { bool need_alloc = false; @@ -464,7 +499,7 @@ os_memblock_get(struct os_mempool *mp) return block; } - #endif +#endif if (mp) { OS_ENTER_CRITICAL(sr); @@ -504,7 +539,7 @@ os_memblock_put_from_cb(struct os_mempool *mp, void *block_addr) os_trace_api_u32x2(OS_TRACE_ID_MEMBLOCK_PUT_FROM_CB, (uint32_t)(uintptr_t)mp, (uint32_t)(uintptr_t)block_addr); - #if MYNEWT_VAL(MP_RUNTIME_ALLOC) +#if MYNEWT_VAL(MP_RUNTIME_ALLOC) if (mp->mp_flags & OS_MEMPOOL_F_RUNTIME) { bool need_free = true; os_mempool_guard_check(mp, block_addr); @@ -523,13 +558,20 @@ os_memblock_put_from_cb(struct os_mempool *mp, void *block_addr) /* Free outside critical section */ if (need_free) { - free(block_addr); + nimble_platform_mem_free(block_addr); } else { os_mempool_poison(mp, block_addr); } return OS_OK; } - #endif +#endif + + #if !MYNEWT_VAL(MP_RUNTIME_ALLOC) + /* Validate that the block belongs to this mempool */ + if (!os_memblock_from(mp, block_addr)) { + return OS_INVALID_PARM; + } +#endif os_mempool_guard_check(mp, block_addr); os_mempool_poison(mp, block_addr); @@ -537,11 +579,27 @@ os_memblock_put_from_cb(struct os_mempool *mp, void *block_addr) block = (struct os_memblock *)block_addr; OS_ENTER_CRITICAL(sr); + /* Check for duplicate free - verify block is not already in free list */ + { + struct os_memblock *cur; + SLIST_FOREACH(cur, mp, mb_next) { + if (cur == block) { + OS_EXIT_CRITICAL(sr); + return OS_INVALID_PARM; + } + } + } + + /* Check that the number free doesn't exceed number blocks */ + if (mp->mp_num_free >= mp->mp_num_blocks) { + OS_EXIT_CRITICAL(sr); + return OS_INVALID_PARM; + } + /* Chain current free list pointer to this block; make this block head */ SLIST_NEXT(block, mb_next) = SLIST_FIRST(mp); SLIST_FIRST(mp) = block; - /* XXX: Should we check that the number free <= number blocks? */ /* Increment number free */ mp->mp_num_free++; @@ -610,6 +668,10 @@ os_mempool_info_get_next(struct os_mempool *mp, struct os_mempool_info *omi) { struct os_mempool *cur; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + os_mempool_list_ensure_init(); +#endif + if (mp == NULL) { cur = STAILQ_FIRST(&g_os_mempool_list); } else { @@ -633,6 +695,10 @@ os_mempool_info_get_next(struct os_mempool *mp, struct os_mempool_info *omi) void os_mempool_module_init(void) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + os_mempool_list_ensure_init(); +#endif + STAILQ_INIT(&g_os_mempool_list); } diff --git a/porting/nimble/src/os_msys_init.c b/porting/nimble/src/os_msys_init.c index c4200c844..575e0b293 100644 --- a/porting/nimble/src/os_msys_init.c +++ b/porting/nimble/src/os_msys_init.c @@ -47,10 +47,12 @@ static STAILQ_HEAD(, os_mbuf_pool) g_msys_pool_list = #define SYSINIT_MSYS_1_MEMPOOL_SIZE \ OS_MEMPOOL_SIZE(OS_MSYS_1_BLOCK_COUNT, \ SYSINIT_MSYS_1_MEMBLOCK_SIZE) +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) static os_membuf_t *os_msys_init_1_data; static struct os_mbuf_pool os_msys_init_1_mbuf_pool; static struct os_mempool os_msys_init_1_mempool; -#endif +#endif // BLE_STATIC_TO_DYNAMIC +#endif // OS_MSYS_1_BLOCK_COUNT #if OS_MSYS_2_BLOCK_COUNT > 0 #define SYSINIT_MSYS_2_MEMBLOCK_SIZE \ @@ -58,11 +60,61 @@ static struct os_mempool os_msys_init_1_mempool; #define SYSINIT_MSYS_2_MEMPOOL_SIZE \ OS_MEMPOOL_SIZE(OS_MSYS_2_BLOCK_COUNT, \ SYSINIT_MSYS_2_MEMBLOCK_SIZE) +#if !MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) static os_membuf_t *os_msys_init_2_data; static struct os_mbuf_pool os_msys_init_2_mbuf_pool; static struct os_mempool os_msys_init_2_mempool; +#endif // BLE_STATIC_TO_DYNAMIC +#endif // OS_MSYS_2_BLOCK_COUNT + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +/* Context structure holding all MSYS resources */ +typedef struct { +#if OS_MSYS_1_BLOCK_COUNT > 0 + os_membuf_t *init_1_data; + struct os_mbuf_pool init_1_mbuf_pool; + struct os_mempool init_1_mempool; #endif +#if OS_MSYS_2_BLOCK_COUNT > 0 + os_membuf_t *init_2_data; + struct os_mbuf_pool init_2_mbuf_pool; + struct os_mempool init_2_mempool; +#endif +} os_msys_ctx_t; + +static os_msys_ctx_t *os_msys_ctx = NULL; + +/* Macros for easier access */ +#if OS_MSYS_1_BLOCK_COUNT > 0 +#define os_msys_init_1_data (os_msys_ctx->init_1_data) +#define os_msys_init_1_mbuf_pool (os_msys_ctx->init_1_mbuf_pool) +#define os_msys_init_1_mempool (os_msys_ctx->init_1_mempool) +#endif // OS_MSYS_1_BLOCK_COUNT + +#if OS_MSYS_2_BLOCK_COUNT > 0 +#define os_msys_init_2_data (os_msys_ctx->init_2_data) +#define os_msys_init_2_mbuf_pool (os_msys_ctx->init_2_mbuf_pool) +#define os_msys_init_2_mempool (os_msys_ctx->init_2_mempool) +#endif // OS_MSYS_2_BLOCK_COUNT + +static int +ble_os_msys_ensure_ctx(void) +{ + if(os_msys_ctx) { + return 0; + } + + os_msys_ctx = nimble_platform_mem_calloc(1, sizeof(*os_msys_ctx)); + if(!os_msys_ctx) { + return -1; + } + + return 0; +} + +#endif // BLE_STATIC_TO_DYNAMIC + #define OS_MSYS_SANITY_ENABLED \ (MYNEWT_VAL(MSYS_1_SANITY_MIN_COUNT) > 0 || \ MYNEWT_VAL(MSYS_2_SANITY_MIN_COUNT) > 0) @@ -82,8 +134,11 @@ static struct os_sanity_check os_msys_sc; * * @return The msys pool's minimum safe buffer count. */ +#if !MYNEWT_VAL(BLE_LOW_SPEED_MODE) +IRAM_ATTR +#endif static int -IRAM_ATTR os_msys_sanity_min_count(int idx) +os_msys_sanity_min_count(int idx) { switch (idx) { case 0: @@ -98,8 +153,11 @@ IRAM_ATTR os_msys_sanity_min_count(int idx) } } +#if !MYNEWT_VAL(BLE_LOW_SPEED_MODE) +IRAM_ATTR +#endif static int -IRAM_ATTR os_msys_sanity(struct os_sanity_check *sc, void *arg) +os_msys_sanity(struct os_sanity_check *sc, void *arg) { const struct os_mbuf_pool *omp; int min_count; @@ -137,6 +195,44 @@ os_msys_init_once(void *data, struct os_mempool *mempool, int os_msys_buf_alloc(void) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_os_msys_ensure_ctx()){ + return ESP_FAIL; + } +#endif + +#if MYNEWT_VAL(MP_RUNTIME_ALLOC) + return ESP_OK; +#endif + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +#if OS_MSYS_1_BLOCK_COUNT > 0 + if (!os_msys_ctx->init_1_data) { + os_msys_ctx->init_1_data = nimble_platform_mem_calloc(1, (sizeof(os_membuf_t) * SYSINIT_MSYS_1_MEMPOOL_SIZE)); + if(!os_msys_ctx->init_1_data){ + nimble_platform_mem_free(os_msys_ctx); + os_msys_ctx = NULL; + return ESP_FAIL; + } + } +#endif + +#if OS_MSYS_2_BLOCK_COUNT > 0 + if (!os_msys_ctx->init_2_data) { + os_msys_ctx->init_2_data = nimble_platform_mem_calloc(1, (sizeof(os_membuf_t) * SYSINIT_MSYS_2_MEMPOOL_SIZE)); + if(!os_msys_ctx->init_2_data) { +#if OS_MSYS_1_BLOCK_COUNT > 0 + nimble_platform_mem_free(os_msys_ctx->init_1_data); + os_msys_ctx->init_1_data = NULL; +#endif + nimble_platform_mem_free(os_msys_ctx); + os_msys_ctx = NULL; + return ESP_FAIL; + } + } + +#endif +#else #if OS_MSYS_1_BLOCK_COUNT > 0 os_msys_init_1_data = (os_membuf_t *)nimble_platform_mem_calloc(1, (sizeof(os_membuf_t) * SYSINIT_MSYS_1_MEMPOOL_SIZE)); if (!os_msys_init_1_data) { @@ -154,14 +250,34 @@ os_msys_buf_alloc(void) return ESP_FAIL; } #endif - +#endif // BLE_STATIC_TO_DYNAMIC return ESP_OK; } void os_msys_buf_free(void) { +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (os_msys_ctx) { #if OS_MSYS_1_BLOCK_COUNT > 0 + if (os_msys_ctx->init_1_data) { + nimble_platform_mem_free(os_msys_ctx->init_1_data); + os_msys_ctx->init_1_data = NULL; + } +#endif +#if OS_MSYS_2_BLOCK_COUNT > 0 + if (os_msys_ctx->init_2_data) { + nimble_platform_mem_free(os_msys_ctx->init_2_data); + os_msys_ctx->init_2_data = NULL; + } +#endif + nimble_platform_mem_free(os_msys_ctx); + os_msys_ctx = NULL; + } + +#else +#if OS_MSYS_1_BLOCK_COUNT > 0 + nimble_platform_mem_free(os_msys_init_1_data); os_msys_init_1_data = NULL; #endif @@ -170,7 +286,7 @@ os_msys_buf_free(void) nimble_platform_mem_free(os_msys_init_2_data); os_msys_init_2_data = NULL; #endif - +#endif } void os_msys_init(void) diff --git a/porting/npl/freertos/src/npl_os_freertos.c b/porting/npl/freertos/src/npl_os_freertos.c index 96db35a4f..9ef195149 100644 --- a/porting/npl/freertos/src/npl_os_freertos.c +++ b/porting/npl/freertos/src/npl_os_freertos.c @@ -37,6 +37,7 @@ #include "soc/soc_caps.h" #include "esp_nimble_mem.h" +#include "host/ble_hs.h" portMUX_TYPE ble_port_mutex = portMUX_INITIALIZER_UNLOCKED; @@ -106,60 +107,128 @@ static const char *TAG = "Timer"; #define BLE_TOTAL_MUTEX_COUNT (10) -#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +typedef struct { + struct os_mempool ev_pool; + struct os_mempool evq_pool; + struct os_mempool co_pool; + struct os_mempool sem_pool; + struct os_mempool mutex_pool; +#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED + os_membuf_t *ev_buf; +#else +#if MYNEWT_VAL(MP_RUNTIME_ALLOC) + os_membuf_t *ev_buf; +#else + os_membuf_t ev_buf[ + OS_MEMPOOL_SIZE(BLE_TOTAL_EV_COUNT, sizeof (struct ble_npl_event_freertos)) + ]; +#endif // MP_RUNTIME_ALLOC + +#endif + +#if CONFIG_BT_CONTROLLER_ENABLED + os_membuf_t *evq_buf; + os_membuf_t *co_buf; + os_membuf_t *sem_buf; + os_membuf_t *mutex_buf; +#else + os_membuf_t evq_buf[ + OS_MEMPOOL_SIZE(BLE_TOTAL_EVQ_COUNT, sizeof (struct ble_npl_eventq_freertos)) + ]; + + os_membuf_t co_buf[ + OS_MEMPOOL_SIZE(BLE_TOTAL_CO_COUNT, sizeof (struct ble_npl_callout_freertos)) + ]; + + os_membuf_t sem_buf[ + OS_MEMPOOL_SIZE(BLE_TOTAL_SEM_COUNT, sizeof (struct ble_npl_sem_freertos)) + ]; + + os_membuf_t mutex_buf[ + OS_MEMPOOL_SIZE(BLE_TOTAL_MUTEX_COUNT, sizeof (struct ble_npl_mutex_freertos)) + ]; +#endif /* CONFIG_BT_CONTROLLER_ENABLED */ +} ble_freertos_ctx_t; + +static ble_freertos_ctx_t *ble_freertos_ctx; + +#define ble_freertos_ev_pool (ble_freertos_ctx->ev_pool) +#define ble_freertos_evq_pool (ble_freertos_ctx->evq_pool) +#define ble_freertos_co_pool (ble_freertos_ctx->co_pool) +#define ble_freertos_sem_pool (ble_freertos_ctx->sem_pool) +#define ble_freertos_mutex_pool (ble_freertos_ctx->mutex_pool) + +#define ble_freertos_ev_buf (ble_freertos_ctx->ev_buf) +#define ble_freertos_evq_buf (ble_freertos_ctx->evq_buf) +#define ble_freertos_co_buf (ble_freertos_ctx->co_buf) +#define ble_freertos_sem_buf (ble_freertos_ctx->sem_buf) +#define ble_freertos_mutex_buf (ble_freertos_ctx->mutex_buf) +#else struct os_mempool ble_freertos_ev_pool; -static os_membuf_t *ble_freertos_ev_buf = NULL; + +struct os_mempool ble_freertos_evq_pool; +struct os_mempool ble_freertos_co_pool; +struct os_mempool ble_freertos_sem_pool; +struct os_mempool ble_freertos_mutex_pool; + +#if CONFIG_BT_CONTROLLER_ENABLED + +static os_membuf_t *ble_freertos_evq_buf = NULL; +static os_membuf_t *ble_freertos_co_buf = NULL; +static os_membuf_t *ble_freertos_sem_buf = NULL; +static os_membuf_t *ble_freertos_mutex_buf = NULL; #else -struct os_mempool ble_freertos_ev_pool; +static os_membuf_t ble_freertos_evq_buf[ + OS_MEMPOOL_SIZE(BLE_TOTAL_EVQ_COUNT, sizeof (struct ble_npl_eventq_freertos)) +]; + +static os_membuf_t ble_freertos_co_buf[ + OS_MEMPOOL_SIZE(BLE_TOTAL_CO_COUNT, sizeof (struct ble_npl_callout_freertos)) +]; + +static os_membuf_t ble_freertos_sem_buf[ + OS_MEMPOOL_SIZE(BLE_TOTAL_SEM_COUNT, sizeof (struct ble_npl_sem_freertos)) +]; + +static os_membuf_t ble_freertos_mutex_buf[ + OS_MEMPOOL_SIZE(BLE_TOTAL_MUTEX_COUNT, sizeof (struct ble_npl_mutex_freertos)) +]; + +#endif /* CONFIG_BT_CONTROLLER_ENABLED */ + +#if (SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED) +static os_membuf_t *ble_freertos_ev_buf = NULL; +#else #if MYNEWT_VAL(MP_RUNTIME_ALLOC) static os_membuf_t *ble_freertos_ev_buf = NULL; #else static os_membuf_t ble_freertos_ev_buf[ OS_MEMPOOL_SIZE(BLE_TOTAL_EV_COUNT, sizeof (struct ble_npl_event_freertos)) ]; -#endif +#endif // MP_RUNTIME_ALLOC #endif +#endif // BLE_STATIC_TO_DYNAMIC -#if CONFIG_BT_CONTROLLER_ENABLED +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) +static int +ble_freertos_ensure_ctx(void) +{ + if (ble_freertos_ctx != NULL) { + return 0; + } -struct os_mempool ble_freertos_evq_pool; -static os_membuf_t *ble_freertos_evq_buf = NULL; - -struct os_mempool ble_freertos_co_pool; -static os_membuf_t *ble_freertos_co_buf = NULL; - -struct os_mempool ble_freertos_sem_pool; -static os_membuf_t *ble_freertos_sem_buf = NULL; - -struct os_mempool ble_freertos_mutex_pool; -static os_membuf_t *ble_freertos_mutex_buf = NULL; - -#else - -struct os_mempool ble_freertos_evq_pool; -static os_membuf_t ble_freertos_evq_buf[ - OS_MEMPOOL_SIZE(BLE_TOTAL_EVQ_COUNT, sizeof (struct ble_npl_eventq_freertos)) -]; - -struct os_mempool ble_freertos_co_pool; -static os_membuf_t ble_freertos_co_buf[ - OS_MEMPOOL_SIZE(BLE_TOTAL_CO_COUNT, sizeof (struct ble_npl_callout_freertos)) -]; - -struct os_mempool ble_freertos_sem_pool; -static os_membuf_t ble_freertos_sem_buf[ - OS_MEMPOOL_SIZE(BLE_TOTAL_SEM_COUNT, sizeof (struct ble_npl_sem_freertos)) -]; - -struct os_mempool ble_freertos_mutex_pool; -static os_membuf_t ble_freertos_mutex_buf[ - OS_MEMPOOL_SIZE(BLE_TOTAL_MUTEX_COUNT, sizeof (struct ble_npl_mutex_freertos)) -]; + ble_freertos_ctx = nimble_platform_mem_calloc(1, sizeof(*ble_freertos_ctx)); + if (ble_freertos_ctx == NULL) { + return BLE_HS_ENOMEM; + } + return 0; +} #endif bool @@ -179,13 +248,15 @@ npl_freertos_event_init(struct ble_npl_event *ev, ble_npl_event_fn *fn, void *arg) { struct ble_npl_event_freertos *event = NULL; + #if OS_MEM_ALLOC if (!ev->event) { ev->event = os_memblock_get(&ble_freertos_ev_pool); } + #else if(!ev->event) { - ev->event = nimble_platform_mem_malloc(sizeof(struct ble_npl_event_freertos)); + ev->event = nimble_platform_mem_calloc(1,sizeof(struct ble_npl_event_freertos)); } #endif event = (struct ble_npl_event_freertos *)ev->event; @@ -201,6 +272,7 @@ npl_freertos_event_deinit(struct ble_npl_event *ev) { BLE_LL_ASSERT(ev->event); #if OS_MEM_ALLOC + os_memblock_put(&ble_freertos_ev_pool,ev->event); #else nimble_platform_mem_free(ev->event); @@ -220,6 +292,7 @@ void npl_freertos_eventq_init(struct ble_npl_eventq *evq) { struct ble_npl_eventq_freertos *eventq = NULL; + #if OS_MEM_ALLOC if (!evq->eventq) { evq->eventq = os_memblock_get(&ble_freertos_evq_pool); @@ -232,7 +305,7 @@ npl_freertos_eventq_init(struct ble_npl_eventq *evq) } #else if(!evq->eventq) { - evq->eventq = nimble_platform_mem_malloc(sizeof(struct ble_npl_eventq_freertos)); + evq->eventq = nimble_platform_mem_calloc(1,sizeof(struct ble_npl_eventq_freertos)); eventq = (struct ble_npl_eventq_freertos*)evq->eventq; BLE_LL_ASSERT(eventq); @@ -417,7 +490,7 @@ npl_freertos_mutex_init(struct ble_npl_mutex *mu) } #else if(!mu->mutex) { - mu->mutex = nimble_platform_mem_malloc(sizeof(struct ble_npl_mutex_freertos)); + mu->mutex = nimble_platform_mem_calloc(1,sizeof(struct ble_npl_mutex_freertos)); mutex = (struct ble_npl_mutex_freertos *)mu->mutex; if (!mutex) { @@ -564,7 +637,7 @@ npl_freertos_sem_init(struct ble_npl_sem *sem, uint16_t tokens) } #else if(!sem->sem) { - sem->sem = nimble_platform_mem_malloc(sizeof(struct ble_npl_sem_freertos)); + sem->sem = nimble_platform_mem_calloc(1,sizeof(struct ble_npl_sem_freertos)); semaphor = (struct ble_npl_sem_freertos *)sem->sem; if (!semaphor) { @@ -757,7 +830,7 @@ npl_freertos_callout_init(struct ble_npl_callout *co, struct ble_npl_eventq *evq #else if(!co->co) { - co->co = nimble_platform_mem_malloc(sizeof(struct ble_npl_callout_freertos)); + co->co = nimble_platform_mem_calloc(1,sizeof(struct ble_npl_callout_freertos)); callout = (struct ble_npl_callout_freertos *)co->co; if (!callout) { return -1; @@ -1143,9 +1216,8 @@ struct npl_funcs_t * npl_freertos_funcs_get(void) void npl_freertos_funcs_init(void) { - npl_funcs = (struct npl_funcs_t *)nimble_platform_mem_malloc(sizeof(struct npl_funcs_t)); + npl_funcs = (struct npl_funcs_t *)nimble_platform_mem_calloc(1,sizeof(struct npl_funcs_t)); if(!npl_funcs) { - printf("npl funcs init failed\n"); assert(0); } memcpy(npl_funcs, &npl_funcs_ro, sizeof(struct npl_funcs_t)); @@ -1155,8 +1227,14 @@ int npl_freertos_mempool_init(void) { int rc = -1; +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_freertos_ensure_ctx()) { + goto _error; + } +#endif + #if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED && !MYNEWT_VAL(MP_RUNTIME_ALLOC) - ble_freertos_ev_buf = nimble_platform_mem_malloc(OS_MEMPOOL_SIZE(BLE_TOTAL_EV_COUNT, sizeof (struct ble_npl_event_freertos)) * sizeof(os_membuf_t)); + ble_freertos_ev_buf = nimble_platform_mem_calloc(1,OS_MEMPOOL_SIZE(BLE_TOTAL_EV_COUNT, sizeof (struct ble_npl_event_freertos)) * sizeof(os_membuf_t)); if(!ble_freertos_ev_buf) { goto _error; } @@ -1164,21 +1242,21 @@ int npl_freertos_mempool_init(void) #if CONFIG_BT_CONTROLLER_ENABLED /* It is not recommended to use MP_RUNTIME_ALLOC when the block size is 4 bytes. */ - ble_freertos_evq_buf = nimble_platform_mem_malloc(OS_MEMPOOL_SIZE(BLE_TOTAL_EVQ_COUNT, sizeof (struct ble_npl_eventq_freertos)) * sizeof(os_membuf_t)); + ble_freertos_evq_buf = nimble_platform_mem_calloc(1,OS_MEMPOOL_SIZE(BLE_TOTAL_EVQ_COUNT, sizeof (struct ble_npl_eventq_freertos)) * sizeof(os_membuf_t)); if(!ble_freertos_evq_buf) { goto _error; } #if !MYNEWT_VAL(MP_RUNTIME_ALLOC) - ble_freertos_co_buf = nimble_platform_mem_malloc(OS_MEMPOOL_SIZE(BLE_TOTAL_CO_COUNT, sizeof (struct ble_npl_callout_freertos)) * sizeof(os_membuf_t)); + ble_freertos_co_buf = nimble_platform_mem_calloc(1,OS_MEMPOOL_SIZE(BLE_TOTAL_CO_COUNT, sizeof (struct ble_npl_callout_freertos)) * sizeof(os_membuf_t)); if(!ble_freertos_co_buf) { goto _error; } #endif - ble_freertos_sem_buf = nimble_platform_mem_malloc(OS_MEMPOOL_SIZE(BLE_TOTAL_SEM_COUNT, sizeof (struct ble_npl_sem_freertos)) * sizeof(os_membuf_t)); + ble_freertos_sem_buf = nimble_platform_mem_calloc(1,OS_MEMPOOL_SIZE(BLE_TOTAL_SEM_COUNT, sizeof (struct ble_npl_sem_freertos)) * sizeof(os_membuf_t)); if(!ble_freertos_sem_buf) { goto _error; } - ble_freertos_mutex_buf = nimble_platform_mem_malloc( OS_MEMPOOL_SIZE(BLE_TOTAL_MUTEX_COUNT, sizeof (struct ble_npl_mutex_freertos)) * sizeof(os_membuf_t)); + ble_freertos_mutex_buf = nimble_platform_mem_calloc(1, OS_MEMPOOL_SIZE(BLE_TOTAL_MUTEX_COUNT, sizeof (struct ble_npl_mutex_freertos)) * sizeof(os_membuf_t)); if(!ble_freertos_mutex_buf) { goto _error; } @@ -1188,6 +1266,7 @@ int npl_freertos_mempool_init(void) rc = os_mempool_init(&ble_freertos_ev_pool, BLE_TOTAL_EV_COUNT, sizeof (struct ble_npl_event_freertos), ble_freertos_ev_buf, "ble_freertos_ev_pool"); + if(rc != 0) { goto _error; } @@ -1195,30 +1274,33 @@ int npl_freertos_mempool_init(void) rc = os_mempool_init(&ble_freertos_evq_pool, BLE_TOTAL_EVQ_COUNT, sizeof (struct ble_npl_eventq_freertos), ble_freertos_evq_buf, "ble_freertos_evq_pool"); - if(rc != 0) { + + if(rc != 0) { goto _error; } rc = os_mempool_init(&ble_freertos_co_pool, BLE_TOTAL_CO_COUNT, sizeof (struct ble_npl_callout_freertos), ble_freertos_co_buf, "ble_freertos_co_pool"); + if(rc != 0) { goto _error; } - rc = os_mempool_init(&ble_freertos_sem_pool, BLE_TOTAL_SEM_COUNT, sizeof (struct ble_npl_sem_freertos), ble_freertos_sem_buf, "ble_freertos_sem_pool"); - if(rc != 0) { + + if(rc != 0) { goto _error; } - rc = os_mempool_init(&ble_freertos_mutex_pool, BLE_TOTAL_MUTEX_COUNT, sizeof (struct ble_npl_mutex_freertos), ble_freertos_mutex_buf, "ble_freertos_mutex_pool"); + if(rc == 0) { return rc; } + _error: #if CONFIG_BT_CONTROLLER_ENABLED @@ -1236,16 +1318,23 @@ _error: } if (ble_freertos_mutex_buf) { nimble_platform_mem_free(ble_freertos_mutex_buf); - ble_freertos_mutex_buf = NULL; + ble_freertos_mutex_buf = NULL; } #endif -#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED - if (ble_freertos_ev_buf) { +#if (SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED) + if(ble_freertos_ev_buf) { nimble_platform_mem_free(ble_freertos_ev_buf); - ble_freertos_ev_buf = NULL; + ble_freertos_ev_buf = NULL; + } + rc = -1; +#endif + +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_freertos_ctx) { + nimble_platform_mem_free(ble_freertos_ctx); + ble_freertos_ctx = NULL; } - return -1; #endif BLE_LL_ASSERT(rc == 0); @@ -1279,6 +1368,12 @@ void npl_freertos_mempool_deinit(void) ble_freertos_mutex_buf = NULL; } #endif +#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC) + if (ble_freertos_ctx) { + nimble_platform_mem_free(ble_freertos_ctx); + ble_freertos_ctx = NULL; + } +#endif } void npl_freertos_funcs_deinit(void)