nimble/host: Add support for setting extended adv_data and scan_rsp

Data from application can come fragmented but host make sure all is
sent using minimal number of HCI commands.

X-Original-Commit: 6e7c6cc3892d1414531fe6e2712496086dc34b89
This commit is contained in:
Szymon Janc
2017-11-22 16:12:50 +01:00
parent 026a9846c4
commit 0351e3011e
6 changed files with 366 additions and 103 deletions
+3
View File
@@ -158,6 +158,9 @@ struct ble_hs_adv_fields {
#define BLE_HS_ADV_SVC_DATA_UUID128_MIN_LEN 16
int ble_hs_adv_set_fields_mbuf(const struct ble_hs_adv_fields *adv_fields,
struct os_mbuf *om);
int ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
uint8_t *dst, uint8_t *dst_len, uint8_t max_len);
+191 -2
View File
@@ -2729,16 +2729,205 @@ ble_gap_ext_adv_stop(uint8_t instance)
return rc;
}
static int
ble_gap_ext_adv_set_data_validate(uint8_t instance, struct os_mbuf *data)
{
uint16_t len = OS_MBUF_PKTLEN(data);
if (!ble_gap_slave[instance].configured) {
return BLE_HS_EINVAL;
}
/* not allowed with directed advertising */
if (ble_gap_slave[instance].directed) {
return BLE_HS_EINVAL;
}
/* always allowed with legacy PDU but limited to legacy length */
if (ble_gap_slave[instance].legacy_pdu) {
if (len > BLE_HS_ADV_MAX_SZ) {
return BLE_HS_EINVAL;
}
return 0;
}
/* if already advertising, data must fit in single HCI command */
if (ble_gap_slave[instance].op == BLE_GAP_OP_S_ADV) {
if (len > min(MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE), 251)) {
return EINVAL;
}
}
/* not allowed with scannable advertising */
if (ble_gap_slave[instance].scannable) {
return BLE_HS_EINVAL;
}
return 0;
}
static int
ble_gap_ext_adv_set(uint8_t instance, uint16_t opcode, struct os_mbuf *data)
{
/* in that case we always fit all data in single HCI command */
#if MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE) <= BLE_HCI_MAX_EXT_ADV_DATA_LEN
static uint8_t buf[BLE_HCI_SET_EXT_ADV_DATA_HDR_LEN + \
MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE)];
uint16_t len = OS_MBUF_PKTLEN(data);
int rc;
opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, opcode);
rc = ble_hs_hci_cmd_build_le_ext_adv_data(instance,
BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_COMPLETE,
0, data, len, buf, sizeof(buf));
if (rc) {
return rc;
}
return ble_hs_hci_cmd_tx_empty_ack(opcode, buf,
BLE_HCI_SET_EXT_ADV_DATA_HDR_LEN + len);
#else
static uint8_t buf[BLE_HCI_SET_EXT_ADV_DATA_HDR_LEN + \
BLE_HCI_MAX_EXT_ADV_DATA_LEN];
uint16_t len = OS_MBUF_PKTLEN(data);
uint16_t off = 0;
uint8_t op;
int rc;
opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, opcode);
/* complete data */
if (len <= BLE_HCI_MAX_EXT_ADV_DATA_LEN) {
rc = ble_hs_hci_cmd_build_le_ext_adv_data(instance,
BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_COMPLETE,
0, data, len, buf,sizeof(buf));
if (rc) {
return rc;
}
return ble_hs_hci_cmd_tx_empty_ack(opcode, buf,
BLE_HCI_SET_EXT_ADV_DATA_HDR_LEN + len);
}
/* first fragment */
op = BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_FIRST;
do {
rc = ble_hs_hci_cmd_build_le_ext_adv_data(instance, op, 0, data,
BLE_HCI_MAX_EXT_ADV_DATA_LEN,
buf, sizeof(buf));
if (rc) {
return rc;
}
rc = ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf));
if (rc) {
return rc;
}
len -= BLE_HCI_MAX_EXT_ADV_DATA_LEN;
off += BLE_HCI_MAX_EXT_ADV_DATA_LEN;
op = BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_INT;
} while (len > BLE_HCI_MAX_EXT_ADV_DATA_LEN);
/* last fragment */
rc = ble_hs_hci_cmd_build_le_ext_adv_data(instance,
BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_LAST,
0, data, len, buf, sizeof(buf));
if (rc) {
return rc;
}
return ble_hs_hci_cmd_tx_empty_ack(opcode, buf,
BLE_HCI_SET_EXT_ADV_DATA_HDR_LEN + len);
#endif
}
int
ble_gap_ext_adv_set_data(uint8_t instance, struct os_mbuf *data)
{
return -1;
int rc;
if (instance >= BLE_ADV_INSTANCES) {
return BLE_HS_EINVAL;
}
ble_hs_lock();
rc = ble_gap_ext_adv_set_data_validate(instance, data);
if (rc != 0) {
ble_hs_unlock();
return rc;
}
rc = ble_gap_ext_adv_set(instance, BLE_HCI_OCF_LE_SET_EXT_ADV_DATA, data);
ble_hs_unlock();
return rc;
}
static int
ble_gap_ext_adv_rsp_set_validate(uint8_t instance, struct os_mbuf *data)
{
uint16_t len = OS_MBUF_PKTLEN(data);
if (!ble_gap_slave[instance].configured) {
return BLE_HS_EINVAL;
}
/* not allowed with directed advertising */
if (ble_gap_slave[instance].directed) {
return BLE_HS_EINVAL;
}
/* only allowed with scannable advertising */
if (!ble_gap_slave[instance].scannable) {
return BLE_HS_EINVAL;
}
/* with legacy PDU limited to legacy length */
if (ble_gap_slave[instance].legacy_pdu) {
if (len > BLE_HS_ADV_MAX_SZ) {
return BLE_HS_EINVAL;
}
return 0;
}
/* if already advertising, data must fit in single HCI command */
if (ble_gap_slave[instance].op == BLE_GAP_OP_S_ADV) {
if (len > min(MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE), 251)) {
return EINVAL;
}
}
return 0;
}
int
ble_gap_ext_adv_rsp_set_data(uint8_t instance, struct os_mbuf *data)
{
return -1;
int rc;
if (instance >= BLE_ADV_INSTANCES) {
return BLE_HS_EINVAL;
}
ble_hs_lock();
rc = ble_gap_ext_adv_rsp_set_validate(instance, data);
if (rc != 0) {
ble_hs_unlock();
return rc;
}
rc = ble_gap_ext_adv_set(instance, BLE_HCI_OCF_LE_SET_EXT_SCAN_RSP_DATA,
data);
ble_hs_unlock();
return rc;
}
int
+161 -71
View File
@@ -34,8 +34,21 @@ static ble_uuid128_t ble_hs_adv_uuids128[BLE_HS_ADV_MAX_FIELD_SZ / 16];
static int
ble_hs_adv_set_hdr(uint8_t type, uint8_t data_len, uint8_t max_len,
uint8_t *dst, uint8_t *dst_len)
uint8_t *dst, uint8_t *dst_len, struct os_mbuf *om)
{
int rc;
if (om ) {
data_len++;
rc = os_mbuf_append(om, &data_len, sizeof(data_len));
if (rc) {
return rc;
}
return os_mbuf_append(om, &type, sizeof(type));
}
if (*dst_len + 2 + data_len > max_len) {
return BLE_HS_EMSGSIZE;
}
@@ -48,46 +61,67 @@ ble_hs_adv_set_hdr(uint8_t type, uint8_t data_len, uint8_t max_len,
return 0;
}
int
ble_hs_adv_set_flat(uint8_t type, int data_len, const void *data,
uint8_t *dst, uint8_t *dst_len, uint8_t max_len)
static int
ble_hs_adv_set_flat_mbuf(uint8_t type, int data_len, const void *data,
uint8_t *dst, uint8_t *dst_len, uint8_t max_len,
struct os_mbuf *om)
{
#if !NIMBLE_BLE_ADVERTISE
return BLE_HS_ENOTSUP;
#endif
int rc;
BLE_HS_DBG_ASSERT(data_len > 0);
rc = ble_hs_adv_set_hdr(type, data_len, max_len, dst, dst_len);
rc = ble_hs_adv_set_hdr(type, data_len, max_len, dst, dst_len, om);
if (rc != 0) {
return rc;
}
if (om) {
return os_mbuf_append(om, data, data_len);
}
memcpy(dst + *dst_len, data, data_len);
*dst_len += data_len;
return 0;
}
int
ble_hs_adv_set_flat(uint8_t type, int data_len, const void *data,
uint8_t *dst, uint8_t *dst_len, uint8_t max_len)
{
#if !NIMBLE_BLE_ADVERTISE
return BLE_HS_ENOTSUP;
#endif
return ble_hs_adv_set_flat_mbuf(type, data_len, data, dst, dst_len, max_len,
NULL);
}
static int
ble_hs_adv_set_array_uuid16(uint8_t type, uint8_t num_elems,
const ble_uuid16_t *elems, uint8_t *dst,
uint8_t *dst_len, uint8_t max_len)
uint8_t *dst_len, uint8_t max_len,
struct os_mbuf *om)
{
int rc;
int i;
rc = ble_hs_adv_set_hdr(type, num_elems * 2, max_len, dst,
dst_len);
dst_len, om);
if (rc != 0) {
return rc;
}
for (i = 0; i < num_elems; i++) {
ble_uuid_flat(&elems[i].u, dst + *dst_len);
*dst_len += 2;
if (om) {
rc = ble_uuid_to_mbuf(&elems[i].u, om);
if (rc) {
return rc;
}
} else {
ble_uuid_flat(&elems[i].u, dst + *dst_len);
*dst_len += 2;
}
}
return 0;
@@ -96,13 +130,15 @@ ble_hs_adv_set_array_uuid16(uint8_t type, uint8_t num_elems,
static int
ble_hs_adv_set_array_uuid32(uint8_t type, uint8_t num_elems,
const ble_uuid32_t *elems, uint8_t *dst,
uint8_t *dst_len, uint8_t max_len)
uint8_t *dst_len, uint8_t max_len,
struct os_mbuf *om)
{
uint32_t uuid_le;
int rc;
int i;
rc = ble_hs_adv_set_hdr(type, num_elems * 4, max_len, dst,
dst_len);
dst_len, om);
if (rc != 0) {
return rc;
}
@@ -112,8 +148,16 @@ ble_hs_adv_set_array_uuid32(uint8_t type, uint8_t num_elems,
* 128-bit as ATT requires. In AD, 32-bit UUID shall be written as an
* actual 32-bit value.
*/
put_le32(dst + *dst_len, elems[i].value);
*dst_len += 4;
if (om) {
uuid_le = htole32(elems[i].value);
rc = os_mbuf_append(om, &uuid_le, sizeof(uuid_le));
if (rc) {
return rc;
}
} else {
put_le32(dst + *dst_len, elems[i].value);
*dst_len += 4;
}
}
return 0;
@@ -122,20 +166,28 @@ ble_hs_adv_set_array_uuid32(uint8_t type, uint8_t num_elems,
static int
ble_hs_adv_set_array_uuid128(uint8_t type, uint8_t num_elems,
const ble_uuid128_t *elems, uint8_t *dst,
uint8_t *dst_len, uint8_t max_len)
uint8_t *dst_len, uint8_t max_len,
struct os_mbuf *om)
{
int rc;
int i;
rc = ble_hs_adv_set_hdr(type, num_elems * 16, max_len, dst,
dst_len);
dst_len, om);
if (rc != 0) {
return rc;
}
for (i = 0; i < num_elems; i++) {
ble_uuid_flat(&elems[i].u, dst + *dst_len);
*dst_len += 16;
if (om) {
rc = ble_uuid_to_mbuf(&elems[i].u, om);
if (rc) {
return rc;
}
} else {
ble_uuid_flat(&elems[i].u, dst + *dst_len);
*dst_len += 16;
}
}
return 0;
@@ -143,33 +195,39 @@ ble_hs_adv_set_array_uuid128(uint8_t type, uint8_t num_elems,
static int
ble_hs_adv_set_array16(uint8_t type, uint8_t num_elems, const uint16_t *elems,
uint8_t *dst, uint8_t *dst_len, uint8_t max_len)
uint8_t *dst, uint8_t *dst_len, uint8_t max_len,
struct os_mbuf *om)
{
uint16_t tmp;
int rc;
int i;
rc = ble_hs_adv_set_hdr(type, num_elems * sizeof *elems, max_len, dst,
dst_len);
dst_len, om);
if (rc != 0) {
return rc;
}
for (i = 0; i < num_elems; i++) {
put_le16(dst + *dst_len, elems[i]);
*dst_len += sizeof elems[i];
if (om) {
tmp = htole16(elems[i]);
rc = os_mbuf_append(om, &tmp, sizeof(tmp));
if (rc) {
return rc;
}
} else {
put_le16(dst + *dst_len, elems[i]);
*dst_len += sizeof elems[i];
}
}
return 0;
}
/**
* Converts a high-level set of fields to a byte buffer.
*
* @return 0 on success; nonzero on failure.
*/
int
ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
uint8_t *dst, uint8_t *dst_len, uint8_t max_len)
static int
adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
uint8_t *dst, uint8_t *dst_len, uint8_t max_len,
struct os_mbuf *om)
{
#if !NIMBLE_BLE_ADVERTISE
return BLE_HS_ENOTSUP;
@@ -179,7 +237,9 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
int8_t tx_pwr_lvl;
int rc;
*dst_len = 0;
if (dst_len) {
*dst_len = 0;
}
/*** 0x01 - Flags. */
/* The application has two options concerning the flags field:
@@ -190,8 +250,9 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
* of specifying option 1 vs. 2 is sound.
*/
if (adv_fields->flags != 0) {
rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_FLAGS, 1, &adv_fields->flags,
dst, dst_len, max_len);
rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_FLAGS, 1,
&adv_fields->flags, dst, dst_len,
max_len, om);
if (rc != 0) {
return rc;
@@ -208,7 +269,7 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
rc = ble_hs_adv_set_array_uuid16(type, adv_fields->num_uuids16,
adv_fields->uuids16, dst, dst_len,
max_len);
max_len, om);
if (rc != 0) {
return rc;
}
@@ -224,7 +285,7 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
rc = ble_hs_adv_set_array_uuid32(type, adv_fields->num_uuids32,
adv_fields->uuids32, dst, dst_len,
max_len);
max_len, om);
if (rc != 0) {
return rc;
}
@@ -240,7 +301,7 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
rc = ble_hs_adv_set_array_uuid128(type, adv_fields->num_uuids128,
adv_fields->uuids128, dst, dst_len,
max_len);
max_len, om);
if (rc != 0) {
return rc;
}
@@ -254,8 +315,9 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
type = BLE_HS_ADV_TYPE_INCOMP_NAME;
}
rc = ble_hs_adv_set_flat(type, adv_fields->name_len, adv_fields->name,
dst, dst_len, max_len);
rc = ble_hs_adv_set_flat_mbuf(type, adv_fields->name_len,
adv_fields->name, dst, dst_len, max_len,
om);
if (rc != 0) {
return rc;
}
@@ -275,8 +337,8 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
tx_pwr_lvl = adv_fields->tx_pwr_lvl;
}
rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_TX_PWR_LVL, 1, &tx_pwr_lvl,
dst, dst_len, max_len);
rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_TX_PWR_LVL, 1,
&tx_pwr_lvl, dst, dst_len, max_len, om);
if (rc != 0) {
return rc;
}
@@ -284,10 +346,10 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
/*** 0x12 - Slave connection interval range. */
if (adv_fields->slave_itvl_range != NULL) {
rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_SLAVE_ITVL_RANGE,
BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN,
adv_fields->slave_itvl_range, dst, dst_len,
max_len);
rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_SLAVE_ITVL_RANGE,
BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN,
adv_fields->slave_itvl_range, dst,
dst_len, max_len, om);
if (rc != 0) {
return rc;
}
@@ -295,10 +357,10 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
/*** 0x16 - Service data - 16-bit UUID. */
if (adv_fields->svc_data_uuid16 != NULL) {
rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_SVC_DATA_UUID16,
adv_fields->svc_data_uuid16_len,
adv_fields->svc_data_uuid16, dst, dst_len,
max_len);
rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_SVC_DATA_UUID16,
adv_fields->svc_data_uuid16_len,
adv_fields->svc_data_uuid16, dst, dst_len,
max_len, om);
if (rc != 0) {
return rc;
}
@@ -308,11 +370,11 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
if (adv_fields->public_tgt_addr != NULL &&
adv_fields->num_public_tgt_addrs != 0) {
rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_PUBLIC_TGT_ADDR,
rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_PUBLIC_TGT_ADDR,
BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN *
adv_fields->num_public_tgt_addrs,
adv_fields->public_tgt_addr, dst, dst_len,
max_len);
max_len, om);
if (rc != 0) {
return rc;
}
@@ -320,10 +382,10 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
/*** 0x19 - Appearance. */
if (adv_fields->appearance_is_present) {
rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_APPEARANCE,
BLE_HS_ADV_APPEARANCE_LEN,
&adv_fields->appearance, dst, dst_len,
max_len);
rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_APPEARANCE,
BLE_HS_ADV_APPEARANCE_LEN,
&adv_fields->appearance, dst, dst_len,
max_len, om);
if (rc != 0) {
return rc;
}
@@ -333,7 +395,7 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
if (adv_fields->adv_itvl_is_present) {
rc = ble_hs_adv_set_array16(BLE_HS_ADV_TYPE_ADV_ITVL, 1,
&adv_fields->adv_itvl, dst, dst_len,
max_len);
max_len, om);
if (rc != 0) {
return rc;
}
@@ -341,10 +403,10 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
/*** 0x20 - Service data - 32-bit UUID. */
if (adv_fields->svc_data_uuid32 != NULL) {
rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_SVC_DATA_UUID32,
adv_fields->svc_data_uuid32_len,
adv_fields->svc_data_uuid32, dst, dst_len,
max_len);
rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_SVC_DATA_UUID32,
adv_fields->svc_data_uuid32_len,
adv_fields->svc_data_uuid32, dst, dst_len,
max_len, om);
if (rc != 0) {
return rc;
}
@@ -352,10 +414,10 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
/*** 0x21 - Service data - 128-bit UUID. */
if (adv_fields->svc_data_uuid128 != NULL) {
rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_SVC_DATA_UUID128,
adv_fields->svc_data_uuid128_len,
adv_fields->svc_data_uuid128, dst, dst_len,
max_len);
rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_SVC_DATA_UUID128,
adv_fields->svc_data_uuid128_len,
adv_fields->svc_data_uuid128, dst,
dst_len, max_len, om);
if (rc != 0) {
return rc;
}
@@ -363,8 +425,9 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
/*** 0x24 - URI. */
if (adv_fields->uri != NULL) {
rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_URI, adv_fields->uri_len,
adv_fields->uri, dst, dst_len, max_len);
rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_URI, adv_fields->uri_len,
adv_fields->uri, dst, dst_len, max_len,
om);
if (rc != 0) {
return rc;
}
@@ -372,9 +435,10 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
/*** 0xff - Manufacturer specific data. */
if (adv_fields->mfg_data != NULL) {
rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_MFG_DATA,
adv_fields->mfg_data_len,
adv_fields->mfg_data, dst, dst_len, max_len);
rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_MFG_DATA,
adv_fields->mfg_data_len,
adv_fields->mfg_data,
dst, dst_len, max_len, om);
if (rc != 0) {
return rc;
}
@@ -383,6 +447,32 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
return 0;
}
/**
* Converts a high-level set of fields to a byte buffer.
*
* @return 0 on success; nonzero on failure.
*/
int
ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
uint8_t *dst, uint8_t *dst_len, uint8_t max_len)
{
#if !NIMBLE_BLE_ADVERTISE
return BLE_HS_ENOTSUP;
#endif
return adv_set_fields(adv_fields, dst, dst_len, max_len, NULL);
}
int
ble_hs_adv_set_fields_mbuf(const struct ble_hs_adv_fields *adv_fields,
struct os_mbuf *om)
{
#if !NIMBLE_BLE_ADVERTISE
return BLE_HS_ENOTSUP;
#endif
return adv_set_fields(adv_fields, NULL, NULL, 0, om);
}
static int
ble_hs_adv_parse_uuids16(struct ble_hs_adv_fields *adv_fields,
const uint8_t *data, uint8_t data_len)
+3 -20
View File
@@ -1471,8 +1471,8 @@ ble_hs_hci_cmd_build_le_ext_adv_set_random_addr(uint8_t handle,
int
ble_hs_hci_cmd_build_le_ext_adv_data(uint8_t handle, uint8_t operation,
uint8_t frag_pref,
const uint8_t *data, uint8_t data_len,
uint8_t frag_pref, struct os_mbuf *data,
uint8_t data_len,
uint8_t *cmd, int cmd_len)
{
BLE_HS_DBG_ASSERT(cmd_len >= 4 + data_len);
@@ -1481,24 +1481,7 @@ ble_hs_hci_cmd_build_le_ext_adv_data(uint8_t handle, uint8_t operation,
cmd[1] = operation;
cmd[2] = frag_pref;
cmd[3] = data_len;
memcpy(cmd + 4, data, data_len);
return 0;
}
int
ble_hs_hci_cmd_build_le_ext_adv_scan_rsp(uint8_t handle, uint8_t operation,
uint8_t frag_pref,
const uint8_t *data, uint8_t data_len,
uint8_t *cmd, int cmd_len)
{
BLE_HS_DBG_ASSERT(cmd_len >= 4 + data_len);
cmd[0] = handle;
cmd[1] = operation;
cmd[2] = frag_pref;
cmd[3] = data_len;
memcpy(cmd + 4, data, data_len);
os_mbuf_copydata(data, 0, data_len, cmd + 4);
return 0;
}
+2 -10
View File
@@ -212,20 +212,12 @@ ble_hs_hci_cmd_build_le_ext_adv_set_random_addr(uint8_t handle,
const uint8_t *addr,
uint8_t *cmd, int cmd_len);
int
ble_hs_hci_cmd_build_le_ext_adv_data(uint8_t handle, uint8_t operation,
uint8_t frag_pref,
const uint8_t *data, uint8_t data_len,
uint8_t frag_pref, struct os_mbuf *data,
uint8_t data_len,
uint8_t *cmd, int cmd_len);
int
ble_hs_hci_cmd_build_le_ext_adv_scan_rsp(uint8_t handle, uint8_t operation,
uint8_t frag_pref,
const uint8_t *data, uint8_t data_len,
uint8_t *cmd, int cmd_len);
int
ble_hs_hci_cmd_build_le_ext_adv_enable(uint8_t enable, uint8_t sets_num,
const struct hci_ext_adv_set *sets,
+6
View File
@@ -491,6 +491,9 @@ extern "C" {
#define BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_NONCONN (0x0010)
/* --- LE set extended advertising data (OCF 0x0037) */
#define BLE_HCI_MAX_EXT_ADV_DATA_LEN (251)
#define BLE_HCI_SET_EXT_ADV_DATA_HDR_LEN (4)
#define BLE_HCI_LE_SET_EXT_ADV_DATA_LEN BLE_HCI_VARIABLE_LEN
#define BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_INT (0)
#define BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_FIRST (1)
@@ -499,6 +502,9 @@ extern "C" {
#define BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_UNCHANGED (4)
/* --- LE set extended scan response data (OCF 0x0038) */
#define BLE_HCI_MAX_EXT_SCAN_RSP_DATA_LEN (251)
#define BLE_HCI_SET_EXT_SCAN_RSP_DATA_HDR_LEN (4)
#define BLE_HCI_LE_SET_EXT_SCAN_RSP_DATA_LEN BLE_HCI_VARIABLE_LEN
#define BLE_HCI_LE_SET_EXT_SCAN_RSP_DATA_OPER_INT (0)
#define BLE_HCI_LE_SET_EXT_SCAN_RSP_DATA_OPER_FIRST (1)