diff --git a/apps/blecent/src/main.c b/apps/blecent/src/main.c index f794937e2..a88e9234c 100644 --- a/apps/blecent/src/main.c +++ b/apps/blecent/src/main.c @@ -216,7 +216,7 @@ static void blecent_scan(void) { uint8_t own_addr_type; - struct ble_gap_disc_params disc_params; + struct ble_gap_disc_params disc_params = {0}; int rc; /* Figure out address to use while advertising (no privacy for now) */ diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index 8b2d55564..1fc0e575a 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -344,6 +344,9 @@ struct ble_gap_ext_disc_params { /** If passive scan should be used */ uint8_t passive:1; + + /** If observation procedure is to be disabled. By default all advertisement reports are accepted */ + uint8_t disable_observer_mode:1; }; /** @brief Discovery parameters */ @@ -365,6 +368,9 @@ struct ble_gap_disc_params { /** If enable duplicates filtering */ uint8_t filter_duplicates:1; + + /** If observation procedure is to be disabled. By default all advertisement reports are accepted */ + uint8_t disable_observer_mode:1; }; /** @brief Connection parameters update parameters */ diff --git a/nimble/host/include/host/ble_hs.h b/nimble/host/include/host/ble_hs.h index 6b6b33c42..79718b40c 100644 --- a/nimble/host/include/host/ble_hs.h +++ b/nimble/host/include/host/ble_hs.h @@ -323,6 +323,17 @@ struct ble_hs_cfg { */ unsigned sm_sc_only:1; + /** @brief Security Manager - Security Mode 1 Level for GATT related operations + * + * Possible values are: + * 0: Default value, ignored + * 1: No security + * 2: Unauthenticated pairing with encryption + * 3. Authenticated pairing with encryption + * 4. Authenticated LE Secure Connections pairing with encryption using a 128-bit strength encryption key + */ + uint8_t sm_sec_lvl; + /** @brief Security Manager Key Press Notification flag * * Currently unsupported and should not be set. @@ -344,6 +355,9 @@ struct ble_hs_cfg { /** @brief Security Manager Remote Key Distribution Mask */ uint8_t sm_their_key_dist; + /** @brief Weather to use GATT caching or not for discovery operations */ + uint8_t gatt_use_cache; + /** @brief Stack reset callback * * This callback is executed when the host resets itself and the controller diff --git a/nimble/host/mesh/src/adv.c b/nimble/host/mesh/src/adv.c index d6ed29f38..4b8d732ef 100644 --- a/nimble/host/mesh/src/adv.c +++ b/nimble/host/mesh/src/adv.c @@ -217,7 +217,7 @@ int bt_mesh_scan_enable(void) #if MYNEWT_VAL(BLE_EXT_ADV) struct ble_gap_ext_disc_params uncoded_params = { .itvl = MESH_SCAN_INTERVAL, .window = MESH_SCAN_WINDOW, - .passive = 1 }; + .passive = 1, .disable_observer_mode = 0}; BT_DBG(""); diff --git a/nimble/host/services/gap/include/services/gap/ble_svc_gap.h b/nimble/host/services/gap/include/services/gap/ble_svc_gap.h index 88a04b2c1..92d305fb1 100644 --- a/nimble/host/services/gap/include/services/gap/ble_svc_gap.h +++ b/nimble/host/services/gap/include/services/gap/ble_svc_gap.h @@ -34,6 +34,7 @@ extern "C" { #define BLE_SVC_GAP_CHR_UUID16_APPEARANCE 0x2a01 #define BLE_SVC_GAP_CHR_UUID16_PERIPH_PREF_CONN_PARAMS 0x2a04 #define BLE_SVC_GAP_CHR_UUID16_CENTRAL_ADDRESS_RESOLUTION 0x2aa6 +#define BLE_SVC_GAP_CHR_UUID16_RPA_ONLY 0x2AC9 #define BLE_SVC_GAP_CHR_UUID16_LE_GATT_SECURITY_LEVELS 0x2BF5 #if MYNEWT_VAL(ENC_ADV_DATA) diff --git a/nimble/host/services/gap/src/ble_svc_gap.c b/nimble/host/services/gap/src/ble_svc_gap.c index a684f1e6f..0625fb568 100644 --- a/nimble/host/services/gap/src/ble_svc_gap.c +++ b/nimble/host/services/gap/src/ble_svc_gap.c @@ -95,6 +95,13 @@ static const struct ble_gatt_svc_def ble_svc_gap_defs[] = { .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), + .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), .access_cb = ble_svc_gap_access, @@ -234,6 +241,15 @@ ble_svc_gap_access(uint16_t conn_handle, uint16_t attr_handle, htole16(MYNEWT_VAL(BLE_SVC_GAP_PPCP_SLAVE_LATENCY)), htole16(MYNEWT_VAL(BLE_SVC_GAP_PPCP_SUPERVISION_TMO)) }; +#endif +#if MYNEWT_VAL(BLE_SVC_GAP_RPA_ONLY) + /* As per Core Specification 6.0, Vol 3: Host, Part C: GAP, 12.5 + * The only allowed value for the characteristic is zero. + * All other values are RFU. + * As such, the presence of the characteristic itself indicates that + * the device is RPA only + */ + uint8_t rpa_only = 0; #endif int rc; @@ -277,6 +293,13 @@ ble_svc_gap_access(uint16_t conn_handle, uint16_t attr_handle, return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; #endif +#if MYNEWT_VAL(BLE_SVC_GAP_RPA_ONLY) + case BLE_SVC_GAP_CHR_UUID16_RPA_ONLY: + assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR); + rc = os_mbuf_append(ctxt->om, &rpa_only, sizeof(rpa_only)); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; +#endif + #if MYNEWT_VAL(ENC_ADV_DATA) case BLE_SVC_GAP_CHR_UUID16_KEY_MATERIAL: rc = os_mbuf_append(ctxt->om, &(km.session_key), sizeof(km.session_key)); diff --git a/nimble/host/services/hid/include/services/hid/ble_svc_hid.h b/nimble/host/services/hid/include/services/hid/ble_svc_hid.h index dcdf129cb..1916695bc 100644 --- a/nimble/host/services/hid/include/services/hid/ble_svc_hid.h +++ b/nimble/host/services/hid/include/services/hid/ble_svc_hid.h @@ -65,6 +65,8 @@ struct ble_svc_hid_params{ unsigned int kbd_inp_present : 1; unsigned int kbd_out_present : 1; unsigned int mouse_inp_present : 1; + unsigned int kbd_inp_write_perm:1; + unsigned int mouse_inp_write_perm:1; /* protocol mode char */ uint8_t proto_mode; uint16_t proto_mode_handle; diff --git a/nimble/host/services/hid/src/ble_svc_hid.c b/nimble/host/services/hid/src/ble_svc_hid.c index fee6b94e2..1e608ca4b 100644 --- a/nimble/host/services/hid/src/ble_svc_hid.c +++ b/nimble/host/services/hid/src/ble_svc_hid.c @@ -180,10 +180,21 @@ void fill_boot_kbd_inp(uint8_t instance) { struct ble_gatt_chr_def *chr, demo_chr; + uint16_t write_flags; if (!hid_instances[instance].kbd_inp_present) { return; } + + write_flags = BLE_GATT_CHR_F_WRITE | +#if MYNEWT_VAL(BLE_SM_LVL) == 2 + BLE_GATT_CHR_F_WRITE_ENC | +#elif MYNEWT_VAL(BLE_SM_LVL) == 3 + BLE_GATT_CHR_F_WRITE_ENC | BLE_GATT_CHR_F_WRITE_AUTHEN +#endif + 0; + write_flags = (hid_instances[instance].kbd_inp_write_perm ? write_flags : 0); + demo_chr = (struct ble_gatt_chr_def) { /*** Report Map characteristic */ .uuid = uuid_boot_kbd_inp, @@ -196,7 +207,7 @@ fill_boot_kbd_inp(uint8_t instance) BLE_GATT_CHR_F_READ_AUTHEN | BLE_GATT_CHR_F_READ_ENC | #endif - 0, + write_flags, }; chr = ble_svc_hid_get_chr_block(); @@ -236,10 +247,21 @@ void fill_boot_mouse_inp(uint8_t instance) { struct ble_gatt_chr_def *chr, demo_chr; + uint16_t write_flags; if (!hid_instances[instance].mouse_inp_present) { return; } + + write_flags = BLE_GATT_CHR_F_WRITE | +#if MYNEWT_VAL(BLE_SM_LVL) == 2 + BLE_GATT_CHR_F_WRITE_ENC | +#elif MYNEWT_VAL(BLE_SM_LVL) == 3 + BLE_GATT_CHR_F_WRITE_ENC | BLE_GATT_CHR_F_WRITE_AUTHEN +#endif + 0; + write_flags = (hid_instances[instance].mouse_inp_write_perm ? write_flags : 0); + demo_chr = (struct ble_gatt_chr_def) { /*** Report Map characteristic */ .uuid = uuid_boot_mouse_inp, @@ -252,7 +274,7 @@ fill_boot_mouse_inp(uint8_t instance) BLE_GATT_CHR_F_READ_AUTHEN | BLE_GATT_CHR_F_READ_ENC | #endif - 0, + write_flags, }; chr = ble_svc_hid_get_chr_block(); diff --git a/nimble/host/services/lls/src/ble_svc_lls.c b/nimble/host/services/lls/src/ble_svc_lls.c index b5f7f9bd4..71fea3426 100644 --- a/nimble/host/services/lls/src/ble_svc_lls.c +++ b/nimble/host/services/lls/src/ble_svc_lls.c @@ -134,7 +134,9 @@ void ble_svc_lls_on_gap_disconnect(int reason) { if (reason == BLE_HS_HCI_ERR(BLE_ERR_CONN_SPVN_TMO)) { + if (ble_svc_lls_cb_fn != NULL) { ble_svc_lls_cb_fn(ble_svc_lls_alert_level); + } } } diff --git a/nimble/host/services/sps/include/services/sps/ble_svc_sps.h b/nimble/host/services/sps/include/services/sps/ble_svc_sps.h index e6675f750..0ff9580f7 100644 --- a/nimble/host/services/sps/include/services/sps/ble_svc_sps.h +++ b/nimble/host/services/sps/include/services/sps/ble_svc_sps.h @@ -27,6 +27,9 @@ #define BLE_SVC_SPS_CHR_UUID16_SCAN_ITVL_WINDOW 0x2A4F #define BLE_SVC_SPS_CHR_UUID16_SCAN_REFRESH 0x2A31 +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); #endif diff --git a/nimble/host/services/sps/src/ble_svc_sps.c b/nimble/host/services/sps/src/ble_svc_sps.c index 825643484..955deae56 100644 --- a/nimble/host/services/sps/src/ble_svc_sps.c +++ b/nimble/host/services/sps/src/ble_svc_sps.c @@ -29,6 +29,7 @@ static uint8_t ble_scan_refresh; static uint16_t ble_scan_itvl_handle; static uint16_t ble_scan_refresh_handle; +static ble_svc_sps_event_fn *ble_svc_sps_cb_fn; /* Access function */ static int @@ -104,6 +105,9 @@ ble_svc_sps_access(uint16_t conn_handle, uint16_t attr_handle, ble_scan_itvl = (write_val & 0xffff0000) >> 16; ble_scan_window = (write_val & 0x0000ffff); } + if (ble_svc_sps_cb_fn) { + ble_svc_sps_cb_fn(ble_scan_itvl, ble_scan_window); + } return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; case BLE_SVC_SPS_CHR_UUID16_SCAN_REFRESH: assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR && conn_handle == BLE_HS_CONN_HANDLE_NONE); @@ -118,6 +122,11 @@ ble_svc_sps_access(uint16_t conn_handle, uint16_t attr_handle, return 0; } +void +ble_svc_sps_set_cb(ble_svc_sps_event_fn *cb) +{ + ble_svc_sps_cb_fn = cb; +} /** * Initialize the SPS package. diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c index 5526edb73..d15565179 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -2983,7 +2983,7 @@ ble_att_svr_rx_notify(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) /* All indications shall be confirmed, but only these with required * security established shall be pass to application */ - if (MYNEWT_VAL(BLE_SM_LVL) >= 2 && !sec_state.encrypted) { + if (ble_hs_cfg.sm_sec_lvl >= 2 && !sec_state.encrypted) { return 0; } @@ -3135,7 +3135,7 @@ ble_att_svr_rx_indicate(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxo /* All indications shall be confirmed, but only these with required * security established shall be pass to application */ - if (MYNEWT_VAL(BLE_SM_LVL) >= 2 && !sec_state.encrypted) { + if (ble_hs_cfg.sm_sec_lvl >= 2 && !sec_state.encrypted) { goto done; } diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 82cab68c7..1bbca410b 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -199,6 +199,7 @@ struct ble_gap_master_state { struct { uint8_t limited:1; + uint8_t observer:1; } disc; }; }; @@ -1880,7 +1881,7 @@ ble_gap_rx_adv_report_sanity_check(const uint8_t *adv_data, uint8_t adv_data_len return -1; } - if (MYNEWT_VAL(BLE_ROLE_OBSERVER)) { + if (ble_gap_master.disc.observer) { /* Observer role is enabled; All adv reports regardless of * Flags AD Type need to be discovered. */ @@ -6211,6 +6212,7 @@ ble_gap_ext_disc(uint8_t own_addr_type, uint16_t duration, uint16_t period, if (uncoded_params) { ble_gap_ext_scan_params_to_hci(uncoded_params, &ucp); ble_gap_ext_disc_fill_dflts(limited, &ucp); + ble_gap_master.disc.observer = !uncoded_params->disable_observer_mode; /* XXX: We should do it only once */ if (!uncoded_params->passive) { @@ -6224,6 +6226,7 @@ ble_gap_ext_disc(uint8_t own_addr_type, uint16_t duration, uint16_t period, if (coded_params) { ble_gap_ext_scan_params_to_hci(coded_params, &cp); ble_gap_ext_disc_fill_dflts(limited, &cp); + ble_gap_master.disc.observer = !coded_params->disable_observer_mode; /* XXX: We should do it only once */ if (!coded_params->passive) { @@ -6337,6 +6340,7 @@ ble_gap_disc(uint8_t own_addr_type, int32_t duration_ms, p.itvl = disc_params->itvl; p.passive = disc_params->passive; p.window = disc_params->window; + p.disable_observer_mode = disc_params->disable_observer_mode; if (duration_ms == BLE_HS_FOREVER) { duration_ms = 0; @@ -6393,6 +6397,7 @@ ble_gap_disc(uint8_t own_addr_type, int32_t duration_ms, } ble_gap_master.disc.limited = params.limited; + ble_gap_master.disc.observer = !params.disable_observer_mode; ble_gap_master.cb = cb; ble_gap_master.cb_arg = cb_arg; diff --git a/nimble/host/src/ble_gattc_cache_conn.c b/nimble/host/src/ble_gattc_cache_conn.c index bb0c3c5f9..b27897470 100644 --- a/nimble/host/src/ble_gattc_cache_conn.c +++ b/nimble/host/src/ble_gattc_cache_conn.c @@ -35,6 +35,9 @@ #define CHECK_CACHE_CONN_STATE(cache_state, cb, cb_arg, opcode, \ s_handle, e_handle, p_uuid) \ + if (ble_hs_cfg.gatt_use_cache == 0) { \ + return BLE_HS_ENOTSUP; \ + } \ op = &conn->pending_op; \ switch(cache_state) { \ case SVC_DISC_IN_PROGRESS: \ @@ -829,7 +832,7 @@ ble_gattc_cache_conn_disc_complete(struct ble_gattc_cache_conn *peer, int rc) } break; case BLE_GATT_OP_DISC_SVC_UUID : - rc = ble_gattc_cache_conn_search_svc_by_uuid(peer->conn_handle, &op->uuid, op->cb, op->cb_arg); + rc = ble_gattc_cache_conn_search_svc_by_uuid(peer->conn_handle, op->uuid, op->cb, op->cb_arg); if (rc != 0) { BLE_HS_LOG(ERROR, "search service by uuid failed"); } @@ -847,7 +850,7 @@ ble_gattc_cache_conn_disc_complete(struct ble_gattc_cache_conn *peer, int rc) } break; case BLE_GATT_OP_DISC_CHR_UUID : - rc = ble_gattc_cache_conn_search_chrs_by_uuid(peer->conn_handle, op->start_handle, op->end_handle, &op->uuid, op->cb, op->cb_arg); + rc = ble_gattc_cache_conn_search_chrs_by_uuid(peer->conn_handle, op->start_handle, op->end_handle, op->uuid, op->cb, op->cb_arg); if (rc != 0) { BLE_HS_LOG(ERROR, "search chars by uuid failed"); } @@ -1267,7 +1270,7 @@ ble_gattc_cache_conn_get_svc_changed_handle(uint16_t conn_handle) BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_SERVICE_CHANGED_UUID16)); if (chr == NULL) { - BLE_HS_LOG(ERROR, "Cannot find service change characteristic"); + BLE_HS_LOG(DEBUG, "Cannot find service change characteristic"); return -1; } return chr->chr.val_handle; @@ -1299,12 +1302,12 @@ ble_gattc_cache_conn_init() int max_dscs; void *storage_cb; - max_ble_gattc_cache_conns = MYNEWT_VAL(BLE_MAX_CONNECTIONS); - max_svcs = (MYNEWT_VAL(BLE_MAX_CONNECTIONS)) * + max_ble_gattc_cache_conns = MYNEWT_VAL(BLE_GATT_CACHING_MAX_CONNS); + max_svcs = (MYNEWT_VAL(BLE_GATT_CACHING_MAX_CONNS)) * (MYNEWT_VAL(BLE_GATT_CACHING_MAX_SVCS)); - max_chrs = (MYNEWT_VAL(BLE_MAX_CONNECTIONS)) * + max_chrs = (MYNEWT_VAL(BLE_GATT_CACHING_MAX_CONNS)) * (MYNEWT_VAL(BLE_GATT_CACHING_MAX_CHRS)); - max_dscs = (MYNEWT_VAL(BLE_MAX_CONNECTIONS)) * + max_dscs = (MYNEWT_VAL(BLE_GATT_CACHING_MAX_CONNS)) * (MYNEWT_VAL(BLE_GATT_CACHING_MAX_DSCS)); /* Free memory first in case this function gets called more than once. */ ble_gattc_cache_conn_free_mem(); @@ -1470,7 +1473,7 @@ static void ble_gattc_cache_search_all_svcs_cb(struct ble_npl_event *ev) static void ble_gattc_cache_conn_fill_op(struct ble_gattc_cache_conn_op *op, uint16_t start_handle, uint16_t end_handle, - ble_uuid_t uuid, + const ble_uuid_t *uuid, void *cb, void *cb_arg, uint8_t cb_type) @@ -1505,7 +1508,7 @@ ble_gattc_cache_conn_search_all_svcs(uint16_t conn_handle, } CHECK_CACHE_CONN_STATE(conn->cache_state, cb, cb_arg, BLE_GATT_OP_DISC_ALL_SVCS, - 0, 0, uuid); + 0, 0, &uuid); /* put the event in the queue to mimic the gattc behaviour */ ble_npl_event_init(&conn->disc_ev, ble_gattc_cache_search_all_svcs_cb, &conn->conn_handle); ble_npl_eventq_put((struct ble_npl_eventq *)ble_hs_evq_get(), &conn->disc_ev); @@ -1534,7 +1537,7 @@ ble_gattc_cache_conn_search_svc_by_uuid_cb(struct ble_npl_event *ev) op = &conn->pending_op; dcb = op->cb; SLIST_FOREACH(svc, &conn->svcs, next) { - if (svc->type == BLE_GATT_SVC_TYPE_PRIMARY && ble_uuid_cmp(&svc->svc.uuid.u, &op->uuid) == 0) { + if (svc->type == BLE_GATT_SVC_TYPE_PRIMARY && ble_uuid_cmp(&svc->svc.uuid.u, op->uuid) == 0) { dcb(conn_handle, ble_gattc_cache_error(status, 0), &svc->svc, op->cb_arg); } } @@ -1566,7 +1569,7 @@ ble_gattc_cache_conn_search_svc_by_uuid(uint16_t conn_handle, const ble_uuid_t * } CHECK_CACHE_CONN_STATE(conn->cache_state, cb, cb_arg, BLE_GATT_OP_DISC_SVC_UUID, - 0, 0, *uuid); + 0, 0, uuid); /* put the event in the queue to mimic the gattc behaviour */ ble_npl_event_init(&conn->disc_ev, ble_gattc_cache_conn_search_svc_by_uuid_cb, &conn->conn_handle); ble_npl_eventq_put((struct ble_npl_eventq *)ble_hs_evq_get(), &conn->disc_ev); @@ -1629,7 +1632,7 @@ ble_gattc_cache_conn_search_inc_svcs(uint16_t conn_handle, uint16_t start_handle } CHECK_CACHE_CONN_STATE(conn->cache_state, cb, cb_arg, BLE_GATT_OP_DISC_ALL_CHRS, - start_handle, end_handle, uuid); + start_handle, end_handle, &uuid); /* put the event in the queue to mimic the gattc behaviour */ ble_npl_event_init(&conn->disc_ev, ble_gattc_cache_conn_search_inc_svcs_cb, &conn->conn_handle); ble_npl_eventq_put((struct ble_npl_eventq *)ble_hs_evq_get(), &conn->disc_ev); @@ -1692,7 +1695,7 @@ ble_gattc_cache_conn_search_all_chrs(uint16_t conn_handle, uint16_t start_handle } CHECK_CACHE_CONN_STATE(conn->cache_state, cb, cb_arg, BLE_GATT_OP_DISC_ALL_CHRS, - start_handle, end_handle, uuid); + start_handle, end_handle, &uuid); /* put the event in the queue to mimic the gattc behaviour */ ble_npl_event_init(&conn->disc_ev, ble_gattc_cache_conn_search_all_chrs_cb, &conn->conn_handle); ble_npl_eventq_put((struct ble_npl_eventq *)ble_hs_evq_get(), &conn->disc_ev); @@ -1723,7 +1726,7 @@ ble_gattc_cache_conn_search_chrs_by_uuid_cb(struct ble_npl_event *ev) svc = ble_gattc_cache_conn_svc_find_range(conn, op->start_handle); /* return all chrs */ SLIST_FOREACH(chr, &svc->chrs, next) { - if (ble_uuid_cmp(&chr->chr.uuid.u, &op->uuid) == 0) { + if (ble_uuid_cmp(&chr->chr.uuid.u, op->uuid) == 0) { dcb(conn_handle, ble_gattc_cache_error(status, 0), &chr->chr, op->cb_arg); } } @@ -1756,7 +1759,7 @@ ble_gattc_cache_conn_search_chrs_by_uuid(uint16_t conn_handle, uint16_t start_ha } CHECK_CACHE_CONN_STATE(conn->cache_state, cb, cb_arg, BLE_GATT_OP_DISC_CHR_UUID, - start_handle, end_handle, *uuid); + start_handle, end_handle, uuid); /* put the event in the queue to mimic the gattc behaviour */ ble_npl_event_init(&conn->disc_ev, ble_gattc_cache_conn_search_chrs_by_uuid_cb, &conn->conn_handle); ble_npl_eventq_put((struct ble_npl_eventq *)ble_hs_evq_get(), &conn->disc_ev); @@ -1820,7 +1823,7 @@ ble_gattc_cache_conn_search_all_dscs(uint16_t conn_handle, uint16_t start_handle } CHECK_CACHE_CONN_STATE(conn->cache_state, cb, cb_arg, BLE_GATT_OP_DISC_ALL_DSCS, - start_handle, end_handle, uuid); + start_handle, end_handle, &uuid); /* put the event in the queue to mimic the gattc behaviour */ ble_npl_event_init(&conn->disc_ev, ble_gattc_cache_conn_search_all_dscs_cb, &conn->conn_handle); ble_npl_eventq_put((struct ble_npl_eventq *)ble_hs_evq_get(), &conn->disc_ev); diff --git a/nimble/host/src/ble_gattc_cache_priv.h b/nimble/host/src/ble_gattc_cache_priv.h index 85b9c8fb2..9c43a97a6 100644 --- a/nimble/host/src/ble_gattc_cache_priv.h +++ b/nimble/host/src/ble_gattc_cache_priv.h @@ -96,7 +96,7 @@ struct ble_gattc_cache_conn_op { request comes while the cache is building */ uint16_t start_handle; uint16_t end_handle; - ble_uuid_t uuid; + const ble_uuid_t *uuid; void *cb; void *cb_arg; uint8_t cb_type; diff --git a/nimble/host/src/ble_hs_cfg.c b/nimble/host/src/ble_hs_cfg.c index ef12d88d6..d750fa04f 100644 --- a/nimble/host/src/ble_hs_cfg.c +++ b/nimble/host/src/ble_hs_cfg.c @@ -28,8 +28,10 @@ struct ble_hs_cfg ble_hs_cfg = { .sm_mitm = MYNEWT_VAL(BLE_SM_MITM), .sm_sc = MYNEWT_VAL(BLE_SM_SC), .sm_sc_only = MYNEWT_VAL(BLE_SM_SC_ONLY), + .sm_sec_lvl = MYNEWT_VAL(BLE_SM_LVL), .sm_keypress = MYNEWT_VAL(BLE_SM_KEYPRESS), .sm_our_key_dist = MYNEWT_VAL(BLE_SM_OUR_KEY_DIST), .sm_their_key_dist = MYNEWT_VAL(BLE_SM_THEIR_KEY_DIST), .eatt = MYNEWT_VAL(BLE_EATT_CHAN_NUM), + .gatt_use_cache = MYNEWT_VAL(BLE_GATT_CACHING), }; diff --git a/nimble/host/src/ble_l2cap_sig.c b/nimble/host/src/ble_l2cap_sig.c index 1641ea454..aca61cd0f 100644 --- a/nimble/host/src/ble_l2cap_sig.c +++ b/nimble/host/src/ble_l2cap_sig.c @@ -428,6 +428,10 @@ ble_l2cap_sig_update_req_rx(uint16_t conn_handle, return rc; } + if (OS_MBUF_PKTLEN(*om) != BLE_L2CAP_SIG_UPDATE_REQ_SZ) { + return BLE_HS_EBADDATA; + } + rc = ble_hs_atomic_conn_flags(conn_handle, &conn_flags); if (rc != 0) { return rc; @@ -506,6 +510,10 @@ ble_l2cap_sig_update_rsp_rx(uint16_t conn_handle, goto done; } + if (OS_MBUF_PKTLEN(*om) != BLE_L2CAP_SIG_UPDATE_RSP_SZ) { + return BLE_HS_EBADDATA; + } + rsp = (struct ble_l2cap_sig_update_rsp *)(*om)->om_data; switch (le16toh(rsp->result)) { @@ -904,6 +912,10 @@ ble_l2cap_sig_credit_base_reconfig_rsp_rx(uint16_t conn_handle, return rc; } + if (OS_MBUF_PKTLEN(*om) != sizeof(*rsp)) { + return BLE_HS_EBADDATA; + } + rsp = (struct ble_l2cap_sig_credit_base_reconfig_rsp *)(*om)->om_data; ble_l2cap_sig_coc_reconfig_cb(proc, (rsp->result > 0) ? BLE_HS_EREJECT : 0); ble_l2cap_sig_proc_free(proc); @@ -1181,11 +1193,15 @@ ble_l2cap_sig_coc_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, struct ble_hs_conn *conn; uint16_t scid; - rc = ble_hs_mbuf_pullup_base(om, sizeof(req)); + rc = ble_hs_mbuf_pullup_base(om, sizeof(*req)); if (rc != 0) { return rc; } + if (OS_MBUF_PKTLEN(*om) != sizeof(*req)) { + return BLE_HS_EBADDATA; + } + rsp = ble_l2cap_sig_cmd_get(BLE_L2CAP_SIG_OP_LE_CREDIT_CONNECT_RSP, hdr->identifier, sizeof(*rsp), &txom); if (!rsp) { @@ -1300,6 +1316,10 @@ ble_l2cap_sig_coc_rsp_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, goto done; } + if (OS_MBUF_PKTLEN(*om) != sizeof(*rsp)) { + return BLE_HS_EBADDATA; + } + rsp = (struct ble_l2cap_sig_le_con_rsp *)(*om)->om_data; chan = proc->connect.chan[0]; @@ -1592,6 +1612,10 @@ ble_l2cap_sig_disc_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, ble_hs_lock(); conn = ble_hs_conn_find_assert(conn_handle); + if (OS_MBUF_PKTLEN(*om) != sizeof(*req)) { + return BLE_HS_EBADDATA; + } + req = (struct ble_l2cap_sig_disc_req *) (*om)->om_data; /* Let's find matching channel. Note that destination CID in the request @@ -1677,6 +1701,10 @@ ble_l2cap_sig_disc_rsp_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, goto done; } + if (OS_MBUF_PKTLEN(*om) != sizeof(*rsp)) { + return BLE_HS_EBADDATA; + } + chan = proc->disconnect.chan; if (!chan) { goto done; @@ -1752,6 +1780,10 @@ ble_l2cap_sig_le_credits_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, return 0; } + if (OS_MBUF_PKTLEN(*om) != sizeof(*req)) { + return BLE_HS_EBADDATA; + } + req = (struct ble_l2cap_sig_le_credits *) (*om)->om_data; /* Ignore when peer sends zero credits */ diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index 22ba8ca6f..1ce9be905 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -1838,7 +1838,7 @@ ble_sm_verify_auth_requirements(uint8_t cmd) /* Fail if security level forces MITM protection and remote does not * support it */ - if (MYNEWT_VAL(BLE_SM_LVL) >= 3 && !(cmd & BLE_SM_PAIR_AUTHREQ_MITM)) { + if (ble_hs_cfg.sm_sec_lvl >= 3 && !(cmd & BLE_SM_PAIR_AUTHREQ_MITM)) { return false; } return true; @@ -1922,7 +1922,7 @@ ble_sm_pair_req_rx(uint16_t conn_handle, struct os_mbuf **om, if (conn->bhc_flags & BLE_HS_CONN_F_MASTER) { res->sm_err = BLE_SM_ERR_CMD_NOT_SUPP; res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_CMD_NOT_SUPP); - } else if (MYNEWT_VAL(BLE_SM_LVL) == 1) { + } else if (ble_hs_cfg.sm_sec_lvl == 1) { res->sm_err = BLE_SM_ERR_CMD_NOT_SUPP; res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_CMD_NOT_SUPP); } else if (req->max_enc_key_size < BLE_SM_PAIR_KEY_SZ_MIN) { diff --git a/nimble/host/test/src/ble_hs_pvcy_test.c b/nimble/host/test/src/ble_hs_pvcy_test.c index 79b93b833..7fd357d05 100644 --- a/nimble/host/test/src/ble_hs_pvcy_test.c +++ b/nimble/host/test/src/ble_hs_pvcy_test.c @@ -51,7 +51,7 @@ ble_hs_pvcy_test_util_all_gap_procs(int adv_status, int conn_status, int disc_status) { - struct ble_gap_disc_params disc_params; + struct ble_gap_disc_params disc_params = {0}; ble_addr_t peer_addr; int rc; @@ -338,7 +338,7 @@ TEST_CASE_SELF(ble_hs_pvcy_test_case_add_irk_adv) /*** Discovery active. */ TEST_CASE_SELF(ble_hs_pvcy_test_case_add_irk_disc) { - struct ble_gap_disc_params disc_params; + struct ble_gap_disc_params disc_params = {0}; int rc; ble_hs_pvcy_test_util_init(); @@ -407,7 +407,7 @@ TEST_CASE_SELF(ble_hs_pvcy_test_case_add_irk_conn) /*** Advertising and discovery active. */ TEST_CASE_SELF(ble_hs_pvcy_test_case_add_irk_adv_disc) { - struct ble_gap_disc_params disc_params; + struct ble_gap_disc_params disc_params = {0}; int rc; ble_hs_pvcy_test_util_init(); diff --git a/nimble/host/test/src/ble_os_test.c b/nimble/host/test/src/ble_os_test.c index 6588c6798..1703a0cf1 100644 --- a/nimble/host/test/src/ble_os_test.c +++ b/nimble/host/test/src/ble_os_test.c @@ -193,7 +193,7 @@ ble_os_disc_test_cb(struct ble_gap_event *event, void *arg) static void ble_os_disc_test_task_handler(void *arg) { - struct ble_gap_disc_params disc_params; + struct ble_gap_disc_params disc_params = {0}; int cb_called; int rc;