diff --git a/nimble/host/include/host/ble_hs_adv.h b/nimble/host/include/host/ble_hs_adv.h index e3b6ea709..8d5e26a39 100644 --- a/nimble/host/include/host/ble_hs_adv.h +++ b/nimble/host/include/host/ble_hs_adv.h @@ -72,6 +72,22 @@ struct ble_hs_adv_fields { /*** 0x0d - Slave connection interval range. */ const uint8_t *slave_itvl_range; + /*** 0x10 - Security Manager TK value */ + const uint8_t *sm_tk_value; + unsigned sm_tk_value_is_present:1; + + /*** 0x11 - Security Manager OOB flag */ + uint8_t sm_oob_flag; + unsigned sm_oob_flag_is_present:1; + + /*** 0x14 - 16-bit service soliciation list. */ + const ble_uuid16_t *sol_uuids16; + uint8_t sol_num_uuids16; + + /*** 0x15 - 128-bit service solicitation UUIDs. */ + const ble_uuid128_t *sol_uuids128; + uint8_t sol_num_uuids128; + /*** 0x16 - Service data - 16-bit UUID. */ const uint8_t *svc_data_uuid16; uint8_t svc_data_uuid16_len; @@ -80,6 +96,10 @@ struct ble_hs_adv_fields { const uint8_t *public_tgt_addr; uint8_t num_public_tgt_addrs; + /*** 0x18 - Random target address. */ + const uint8_t *random_tgt_addr; + uint8_t num_random_tgt_addrs; + /*** 0x19 - Appearance. */ uint16_t appearance; unsigned appearance_is_present:1; @@ -88,6 +108,19 @@ struct ble_hs_adv_fields { uint16_t adv_itvl; unsigned adv_itvl_is_present:1; + /*** 0x1b - LE Bluetooth device address */ + const uint8_t *device_addr; + unsigned device_addr_type; + unsigned device_addr_is_present:1; + + /*** 0xF1 - 32-bit service solicitation UUIDs */ + const ble_uuid32_t *sol_uuids32; + uint8_t sol_num_uuids32; + + /*** 0x1c - LE Role */ + uint8_t le_role; + unsigned le_role_is_present:1; + /*** 0x20 - Service data - 32-bit UUID. */ const uint8_t *svc_data_uuid32; uint8_t svc_data_uuid32_len; @@ -115,6 +148,8 @@ struct ble_hs_adv_fields { #define BLE_HS_ADV_TYPE_INCOMP_NAME 0x08 #define BLE_HS_ADV_TYPE_COMP_NAME 0x09 #define BLE_HS_ADV_TYPE_TX_PWR_LVL 0x0a +#define BLE_HS_ADV_TYPE_SEC_MGR_TK_VALUE 0x10 +#define BLE_HS_ADV_TYPE_SEC_MGR_OOB_FLAG 0x11 #define BLE_HS_ADV_TYPE_SLAVE_ITVL_RANGE 0x12 #define BLE_HS_ADV_TYPE_SOL_UUIDS16 0x14 #define BLE_HS_ADV_TYPE_SOL_UUIDS128 0x15 @@ -123,6 +158,9 @@ struct ble_hs_adv_fields { #define BLE_HS_ADV_TYPE_RANDOM_TGT_ADDR 0x18 #define BLE_HS_ADV_TYPE_APPEARANCE 0x19 #define BLE_HS_ADV_TYPE_ADV_ITVL 0x1a +#define BLE_HS_ADV_TYPE_DEVICE_ADDR 0x1b +#define BLE_HS_ADV_TYPE_LE_ROLE 0x1c +#define BLE_HS_ADV_TYPE_SOL_UUIDS32 0x1f #define BLE_HS_ADV_TYPE_SVC_DATA_UUID32 0x20 #define BLE_HS_ADV_TYPE_SVC_DATA_UUID128 0x21 #define BLE_HS_ADV_TYPE_URI 0x24 @@ -158,6 +196,8 @@ struct ble_hs_adv_fields { #define BLE_HS_ADV_SVC_DATA_UUID128_MIN_LEN 16 +#define BLE_HS_ADV_ADDR_TYPE_LEN 1 + int ble_hs_adv_set_fields_mbuf(const struct ble_hs_adv_fields *adv_fields, struct os_mbuf *om); diff --git a/nimble/host/src/ble_hs_adv.c b/nimble/host/src/ble_hs_adv.c index 1d938b958..aef917f79 100644 --- a/nimble/host/src/ble_hs_adv.c +++ b/nimble/host/src/ble_hs_adv.c @@ -236,6 +236,7 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, uint8_t type; int8_t tx_pwr_lvl; uint8_t dst_len_local; + uint8_t dev_addr_ad[7]; int rc; dst_len_local = 0; @@ -343,6 +344,28 @@ adv_set_fields(const struct ble_hs_adv_fields *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, + adv_fields->sm_tk_value, dst, &dst_len_local, + max_len, om); + + if (rc != 0) { + return rc; + } + } + + /*** 0x11 - Security Manager OOB flag */ + if (adv_fields->sm_oob_flag_is_present) { + + rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_SEC_MGR_OOB_FLAG, 1, + &adv_fields->sm_oob_flag, dst, &dst_len_local, + max_len, om); + if (rc != 0) { + return rc; + } + } + /*** 0x12 - Slave connection interval range. */ if (adv_fields->slave_itvl_range != NULL) { rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_SLAVE_ITVL_RANGE, @@ -354,6 +377,26 @@ adv_set_fields(const struct ble_hs_adv_fields *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, + adv_fields->sol_uuids16, dst, &dst_len_local, + max_len, om); + if (rc != 0) { + return rc; + } + } + + /*** 0x15 - 128-bit service solicitation. */ + if (adv_fields->sol_uuids128 != NULL) { + rc = ble_hs_adv_set_array_uuid128(BLE_HS_ADV_TYPE_SOL_UUIDS128, adv_fields->sol_num_uuids128, + adv_fields->sol_uuids128, dst, &dst_len_local, + max_len, om); + if (rc != 0) { + return rc; + } + } + /*** 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, @@ -379,6 +422,20 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, } } + /*** 0x18 - Random target address. */ + if (adv_fields->random_tgt_addr != NULL && + adv_fields->num_random_tgt_addrs != 0) { + + rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_RANDOM_TGT_ADDR, + BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN * + adv_fields->num_random_tgt_addrs, + adv_fields->random_tgt_addr, dst, &dst_len_local, + max_len, om); + if (rc != 0) { + return rc; + } + } + /*** 0x19 - Appearance. */ if (adv_fields->appearance_is_present) { rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_APPEARANCE, @@ -400,6 +457,43 @@ adv_set_fields(const struct ble_hs_adv_fields *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++) { + dev_addr_ad[i] = adv_fields->device_addr[i]; + } + dev_addr_ad[BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN] = adv_fields->device_addr_type; + + rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_DEVICE_ADDR, + BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN + BLE_HS_ADV_ADDR_TYPE_LEN, + dev_addr_ad, dst, &dst_len_local, + max_len, om); + if (rc != 0) { + return rc; + } + } + + /*** 0x1c - LE Role */ + if (adv_fields->le_role_is_present) { + rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_LE_ROLE, 1, + &adv_fields->le_role, dst, &dst_len_local, + max_len, om); + if (rc != 0) { + return rc; + } + } + + /*** 0x1f - 32-bit service solicitation UUIDs */ + if (adv_fields->sol_uuids32 != NULL && adv_fields->sol_num_uuids32) { + + rc = ble_hs_adv_set_array_uuid32(BLE_HS_ADV_TYPE_SOL_UUIDS32, adv_fields->sol_num_uuids32, + adv_fields->sol_uuids32, dst, &dst_len_local, + max_len, om); + if (rc != 0) { + return rc; + } + } + /*** 0x20 - Service data - 32-bit UUID. */ if (adv_fields->svc_data_uuid32 != NULL && adv_fields->svc_data_uuid32_len) { rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_SVC_DATA_UUID32, @@ -645,6 +739,22 @@ ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields, adv_fields->tx_pwr_lvl_is_present = 1; break; + case BLE_HS_ADV_TYPE_SEC_MGR_TK_VALUE: + if (data_len != 16) { + return BLE_HS_EBADDATA; + } + adv_fields->sm_tk_value = data; + adv_fields->sm_tk_value_is_present = 1; + break; + + case BLE_HS_ADV_TYPE_SEC_MGR_OOB_FLAG: + if (data_len != 1) { + return BLE_HS_EBADDATA; + } + adv_fields->sm_oob_flag = *data; + adv_fields->sm_oob_flag_is_present = 1; + break; + case BLE_HS_ADV_TYPE_SLAVE_ITVL_RANGE: if (data_len != BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN) { return BLE_HS_EBADDATA; @@ -652,6 +762,20 @@ ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields, adv_fields->slave_itvl_range = data; break; + case BLE_HS_ADV_TYPE_SOL_UUIDS16: + rc = ble_hs_adv_parse_uuids16(adv_fields, data, data_len); + if (rc != 0) { + return rc; + } + break; + + case BLE_HS_ADV_TYPE_SOL_UUIDS128: + rc = ble_hs_adv_parse_uuids128(adv_fields, data, data_len); + if (rc != 0) { + return rc; + } + break; + case BLE_HS_ADV_TYPE_SVC_DATA_UUID16: if (data_len < BLE_HS_ADV_SVC_DATA_UUID16_MIN_LEN) { return BLE_HS_EBADDATA; @@ -669,6 +793,15 @@ ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields, data_len / BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN; break; + case BLE_HS_ADV_TYPE_RANDOM_TGT_ADDR: + if (data_len % BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN != 0) { + return BLE_HS_EBADDATA; + } + adv_fields->random_tgt_addr = data; + adv_fields->num_random_tgt_addrs = + data_len / BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN; + break; + case BLE_HS_ADV_TYPE_APPEARANCE: if (data_len != BLE_HS_ADV_APPEARANCE_LEN) { return BLE_HS_EBADDATA; @@ -677,6 +810,22 @@ ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields, adv_fields->appearance_is_present = 1; break; + case BLE_HS_ADV_TYPE_DEVICE_ADDR: + if (data_len != 7) { + return BLE_HS_EBADDATA; + } + adv_fields->device_addr = data; + adv_fields->device_addr_type = data[6]; + break; + + case BLE_HS_ADV_TYPE_LE_ROLE: + if (data_len != 1) { + return BLE_HS_EBADDATA; + } + adv_fields->le_role = *data; + adv_fields->le_role_is_present = 1; + break; + case BLE_HS_ADV_TYPE_ADV_ITVL: if (data_len != BLE_HS_ADV_ADV_ITVL_LEN) { return BLE_HS_EBADDATA; @@ -706,6 +855,13 @@ ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields, adv_fields->uri_len = data_len; break; + case BLE_HS_ADV_TYPE_SOL_UUIDS32: + rc = ble_hs_adv_parse_uuids32(adv_fields, data, data_len); + if (rc != 0) { + return rc; + } + break; + case BLE_HS_ADV_TYPE_MFG_DATA: adv_fields->mfg_data = data; adv_fields->mfg_data_len = data_len;