fix(nimble): Memory optimization + dynamic memory support

This commit is contained in:
Rahul Tank
2025-11-26 12:21:42 +05:30
parent 450d35aae0
commit e2f8239def
91 changed files with 5206 additions and 868 deletions
+8
View File
@@ -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)
/**
+5
View File
@@ -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
+11
View File
@@ -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
+1
View File
@@ -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
+2
View File
@@ -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
}
+5
View File
@@ -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
+2 -1
View File
@@ -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;
+24 -13
View File
@@ -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,
},
{
+17 -10
View File
@@ -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.
*/
+1 -1
View File
@@ -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
+54 -44
View File
@@ -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
#endif
+19 -11
View File
@@ -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. */
},
@@ -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.
+134 -71
View File
@@ -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();
@@ -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
+191 -23
View File
@@ -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
+23 -12
View File
@@ -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. */
},
+88 -32
View File
@@ -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], &params, 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
+18 -11
View File
@@ -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,
},
{
+18 -13
View File
@@ -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. */
},
};
+3 -1
View File
@@ -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,
},
{
+17 -11
View File
@@ -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. */
},
+24 -14
View File
@@ -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;
@@ -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
}
+91 -22
View File
@@ -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();
+17 -11
View File
@@ -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. */
},
+12 -3
View File
@@ -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
+12 -6
View File
@@ -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 *
+4 -1
View File
@@ -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);
+117 -10
View File
@@ -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;
}
}
+112 -15
View File
@@ -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
+5 -2
View File
@@ -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
+399 -67
View File
File diff suppressed because it is too large Load Diff
+4
View File
@@ -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);
+10
View File
@@ -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);
+388 -53
View File
@@ -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
+114 -22
View File
@@ -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) */
+110 -5
View File
@@ -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 */
+3
View File
@@ -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);
+282 -66
View File
@@ -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;
}
+6 -1
View File
@@ -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");
+225 -31
View File
@@ -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
}
+79 -1
View File
@@ -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
+107 -6
View File
@@ -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
+15 -1
View File
@@ -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
+45 -4
View File
@@ -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)
}
+112 -33
View File
@@ -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
}
+252 -28
View File
@@ -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);
+4
View File
@@ -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
+6
View File
@@ -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,
+75 -5
View File
@@ -20,13 +20,56 @@
#include <string.h>
#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);
}
}
+1
View File
@@ -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);
+1 -1
View File
@@ -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;
}
+5 -1
View File
@@ -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
+99 -5
View File
@@ -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;
}
+1 -1
View File
@@ -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
+19
View File
@@ -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)
+57 -6
View File
@@ -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
+5
View File
@@ -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
+12 -4
View File
@@ -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;
}
+5 -1
View File
@@ -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();
+43 -2
View File
@@ -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
}
+122 -8
View File
@@ -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
+74 -3
View File
@@ -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
+4
View File
@@ -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) {
+13
View File
@@ -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,
+81 -3
View File
@@ -46,6 +46,7 @@
#include <errno.h>
#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
+3
View File
@@ -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
}
+184 -12
View File
@@ -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
+34 -4
View File
@@ -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);
+6
View File
@@ -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
+10 -1
View File
@@ -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
}
+81 -6
View File
@@ -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
+179 -1
View File
@@ -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
}
+38
View File
@@ -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
+57
View File
@@ -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
+1
View File
@@ -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
}
+32 -11
View File
@@ -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
@@ -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)
{
@@ -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
@@ -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)
+3 -2
View File
@@ -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) {
+3 -3
View File
@@ -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,
+153 -21
View File
@@ -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))
{
+2
View File
@@ -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)
+10 -3
View File
@@ -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;
+72 -6
View File
@@ -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;
}
+33
View File
@@ -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;
+83 -17
View File
@@ -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);
}
+121 -5
View File
@@ -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)
+154 -59
View File
@@ -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)