Skip to content

Commit 22346b4

Browse files
lylezhu2012kartben
authored andcommitted
Bluetooth: Classic: SDP: Support ATTR ID list setting for SA/SSA REQ
In current implementation, the ATTR ID list is set with fixed value (0x0000, 0xffff). For the case that responding a lot of SDP record data, the responded data cannot be processed properly due to the receiving buffer size limitation. In this case, the ATTR ID list can be used to reduce the length of the responding data. In this way, it will help reduce the SDP's requirement for receiving data buffer size. Add the attribute ID list configuration to the SDP discovery request structure `struct bt_sdp_discover_params`. If the `struct bt_sdp_discover_params::ids` is NULL, or `struct bt_sdp_discover_params::ids::count` is 0, the default range (0x0000, 0xffff) is used. Signed-off-by: Lyle Zhu <[email protected]>
1 parent fc6fe95 commit 22346b4

File tree

2 files changed

+152
-24
lines changed
  • include/zephyr/bluetooth/classic
  • subsys/bluetooth/host/classic

2 files changed

+152
-24
lines changed

include/zephyr/bluetooth/classic/sdp.h

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,30 @@ enum {
566566
BT_SDP_DISCOVER_SERVICE_SEARCH_ATTR,
567567
};
568568

569+
/** Initializes SDP attribute ID range */
570+
#define BT_SDP_ATTR_ID_RANGE(beginning, ending) {(beginning), (ending)}
571+
572+
/**
573+
* @brief SDP attribute ID range
574+
*
575+
* If the beginning attribute ID is same with the ending attribute ID, the range represents a
576+
* single attribute ID.
577+
*/
578+
struct bt_sdp_attribute_id_range {
579+
/** Beginning attribute ID of the range */
580+
uint16_t beginning;
581+
/** Ending attribute ID of the range */
582+
uint16_t ending;
583+
};
584+
585+
/** @brief SDP attribute ID list for Service Attribute and Service Search Attribute transactions */
586+
struct bt_sdp_attribute_id_list {
587+
/** Count of the SDP attribute ID range */
588+
size_t count;
589+
/** Attribute ID range array list */
590+
struct bt_sdp_attribute_id_range *ranges;
591+
};
592+
569593
/** @brief Main user structure used in SDP discovery of remote. */
570594
struct bt_sdp_discover_params {
571595
sys_snode_t _node;
@@ -581,6 +605,13 @@ struct bt_sdp_discover_params {
581605
struct net_buf_pool *pool;
582606
/** Discover type */
583607
uint8_t type;
608+
/**
609+
* Attribute ID list for Service Attribute and Service Search Attribute transactions
610+
*
611+
* If the `ids` is NULL or `ids->count` is 0, the default range `(0x0000, 0xffff)` will
612+
* be used.
613+
*/
614+
struct bt_sdp_attribute_id_list *ids;
584615
};
585616

586617
/** @brief Allows user to start SDP discovery session.
@@ -604,12 +635,14 @@ struct bt_sdp_discover_params {
604635
* Service Attribute: The SDP Client generates an
605636
* SDP_SERVICE_ATTR_REQ to retrieve specified
606637
* attribute values from a specific service
607-
* record (`params->handle`).
638+
* record (`params->handle`). The AttributeIDList
639+
* is specified by `params->ids`.
608640
* Service Search Attribute: The SDP Client generates an
609641
* SDP_SERVICE_SEARCH_ATTR_REQ to retrieve
610642
* specified attribute values that match the
611643
* service search pattern (`params->uuid`)
612644
* given as the first parameter of the PDU.
645+
* The AttributeIDList is specified by `params->ids`.
613646
*
614647
* @param conn Object identifying connection to remote.
615648
* @param params SDP discovery parameters.

subsys/bluetooth/host/classic/sdp.c

Lines changed: 118 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,11 +1773,89 @@ static int sdp_client_ss_search(struct bt_sdp_client *session,
17731773
return bt_sdp_send(&session->chan.chan, buf, BT_SDP_SVC_SEARCH_REQ, session->tid);
17741774
}
17751775

1776+
static uint16_t sdp_client_get_attribute_id_list_len(struct bt_sdp_attribute_id_list *ids)
1777+
{
1778+
uint16_t len = 0;
1779+
1780+
if (ids == NULL || ids->count == 0) {
1781+
return sizeof(uint8_t) + sizeof(uint32_t);
1782+
}
1783+
1784+
for (size_t i = 0; i < ids->count; i++) {
1785+
if (ids->ranges[i].beginning == ids->ranges[i].ending) {
1786+
len += sizeof(uint8_t) + sizeof(uint16_t);
1787+
} else {
1788+
len += sizeof(uint8_t) + sizeof(uint32_t);
1789+
}
1790+
}
1791+
1792+
return len;
1793+
}
1794+
1795+
static void sdp_client_add_attribute_id(struct net_buf *buf, struct bt_sdp_attribute_id_list *ids)
1796+
{
1797+
uint16_t len;
1798+
1799+
len = sdp_client_get_attribute_id_list_len(ids);
1800+
/*
1801+
* Sequence definition where data is sequence of elements and where
1802+
* additional next byte points the size of elements within
1803+
*/
1804+
if (len > UINT8_MAX) {
1805+
net_buf_add_u8(buf, BT_SDP_SEQ16);
1806+
net_buf_add_be16(buf, len);
1807+
} else {
1808+
net_buf_add_u8(buf, BT_SDP_SEQ8);
1809+
net_buf_add_u8(buf, len);
1810+
}
1811+
1812+
if (ids == NULL || ids->count == 0) {
1813+
/* Data element definition for two following 16bits range elements */
1814+
net_buf_add_u8(buf, BT_SDP_UINT32);
1815+
/* Get all attributes. It enables filter out wanted only attributes */
1816+
net_buf_add_be16(buf, 0x0000);
1817+
net_buf_add_be16(buf, 0xffff);
1818+
return;
1819+
}
1820+
1821+
for (size_t i = 0; i < ids->count; i++) {
1822+
if (ids->ranges[i].beginning == ids->ranges[i].ending) {
1823+
/* Data element definition for one following 16bits range elements */
1824+
net_buf_add_u8(buf, BT_SDP_UINT16);
1825+
/* Get all attributes. It enables filter out wanted only attributes */
1826+
net_buf_add_be16(buf, ids->ranges[i].beginning);
1827+
} else {
1828+
/* Data element definition for two following 16bits range elements */
1829+
net_buf_add_u8(buf, BT_SDP_UINT32);
1830+
/* Get all attributes. It enables filter out wanted only attributes */
1831+
net_buf_add_be16(buf, ids->ranges[i].beginning);
1832+
net_buf_add_be16(buf, ids->ranges[i].ending);
1833+
}
1834+
}
1835+
}
1836+
1837+
static uint16_t sdp_client_get_total_len(struct bt_sdp_client *session,
1838+
const struct bt_sdp_discover_params *param)
1839+
{
1840+
uint16_t len;
1841+
1842+
len = sdp_client_get_attribute_id_list_len(param->ids);
1843+
if (len > UINT8_MAX) {
1844+
len += sizeof(uint8_t) + sizeof(uint16_t);
1845+
} else {
1846+
len += sizeof(uint8_t) + sizeof(uint8_t);
1847+
}
1848+
len += sizeof(session->cstate.length) + session->cstate.length;
1849+
1850+
return len;
1851+
}
1852+
17761853
/* ServiceAttribute PDU, ref to BT Core 5.4, Vol 3, part B, 4.6.1 */
17771854
static int sdp_client_sa_search(struct bt_sdp_client *session,
17781855
const struct bt_sdp_discover_params *param)
17791856
{
17801857
struct net_buf *buf;
1858+
uint16_t len;
17811859

17821860
/* Update context param directly. */
17831861
session->param = param;
@@ -1789,17 +1867,17 @@ static int sdp_client_sa_search(struct bt_sdp_client *session,
17891867

17901868
/* Set attribute max bytes count to be returned from server */
17911869
net_buf_add_be16(buf, net_buf_tailroom(session->rec_buf));
1792-
/*
1793-
* Sequence definition where data is sequence of elements and where
1794-
* additional next byte points the size of elements within
1795-
*/
1796-
net_buf_add_u8(buf, BT_SDP_SEQ8);
1797-
net_buf_add_u8(buf, 0x05);
1798-
/* Data element definition for two following 16bits range elements */
1799-
net_buf_add_u8(buf, BT_SDP_UINT32);
1800-
/* Get all attributes. It enables filter out wanted only attributes */
1801-
net_buf_add_be16(buf, 0x0000);
1802-
net_buf_add_be16(buf, 0xffff);
1870+
1871+
/* Check the tailroom of the buffer */
1872+
len = sdp_client_get_total_len(session, param);
1873+
if (len > net_buf_tailroom(buf)) {
1874+
LOG_ERR("No space to add attribute ID");
1875+
net_buf_unref(buf);
1876+
return -ENOMEM;
1877+
}
1878+
1879+
/* Add attribute ID List */
1880+
sdp_client_add_attribute_id(buf, param->ids);
18031881

18041882
/*
18051883
* Update and validate PDU ContinuationState. Initial SSA Request has
@@ -1825,6 +1903,7 @@ static int sdp_client_ssa_search(struct bt_sdp_client *session,
18251903
{
18261904
struct net_buf *buf;
18271905
uint8_t uuid128[BT_UUID_SIZE_128];
1906+
uint16_t len;
18281907

18291908
/* Update context param directly. */
18301909
session->param = param;
@@ -1862,17 +1941,17 @@ static int sdp_client_ssa_search(struct bt_sdp_client *session,
18621941

18631942
/* Set attribute max bytes count to be returned from server */
18641943
net_buf_add_be16(buf, net_buf_tailroom(session->rec_buf));
1865-
/*
1866-
* Sequence definition where data is sequence of elements and where
1867-
* additional next byte points the size of elements within
1868-
*/
1869-
net_buf_add_u8(buf, BT_SDP_SEQ8);
1870-
net_buf_add_u8(buf, 0x05);
1871-
/* Data element definition for two following 16bits range elements */
1872-
net_buf_add_u8(buf, BT_SDP_UINT32);
1873-
/* Get all attributes. It enables filter out wanted only attributes */
1874-
net_buf_add_be16(buf, 0x0000);
1875-
net_buf_add_be16(buf, 0xffff);
1944+
1945+
/* Check the tailroom of the buffer */
1946+
len = sdp_client_get_total_len(session, param);
1947+
if (len > net_buf_tailroom(buf)) {
1948+
LOG_ERR("No space to add attribute ID");
1949+
net_buf_unref(buf);
1950+
return -ENOMEM;
1951+
}
1952+
1953+
/* Add attribute ID List */
1954+
sdp_client_add_attribute_id(buf, param->ids);
18761955

18771956
/*
18781957
* Update and validate PDU ContinuationState. Initial SSA Request has
@@ -2714,11 +2793,27 @@ static int sdp_client_discovery_start(struct bt_conn *conn,
27142793
int bt_sdp_discover(struct bt_conn *conn,
27152794
struct bt_sdp_discover_params *params)
27162795
{
2717-
if (!params || !params->uuid || !params->func || !params->pool) {
2796+
if (params == NULL || params->uuid == NULL || params->func == NULL ||
2797+
params->pool == NULL ||
2798+
(params->ids != NULL && params->ids->count != 0 && params->ids->ranges == NULL)) {
27182799
LOG_WRN("Invalid user params");
27192800
return -EINVAL;
27202801
}
27212802

2803+
if (params->ids != NULL) {
2804+
for (size_t i = 0; i < params->ids->count; i++) {
2805+
struct bt_sdp_attribute_id_range *range;
2806+
2807+
range = &params->ids->ranges[i];
2808+
if (range->beginning <= range->ending) {
2809+
continue;
2810+
}
2811+
2812+
LOG_WRN("Invalid range %u > %u", range->beginning, range->ending);
2813+
return -EINVAL;
2814+
}
2815+
}
2816+
27222817
return sdp_client_discovery_start(conn, params);
27232818
}
27242819

0 commit comments

Comments
 (0)