feat(nimble): additional AD types for advertisements

This commit is contained in:
Sumeet Singh
2024-02-29 16:23:47 +05:30
committed by Abhinav Kudnar
parent e37744410e
commit 5668e0c2f2
2 changed files with 196 additions and 0 deletions
+40
View File
@@ -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);
+156
View File
@@ -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;