Bluetooth: Classic: SDP: Improve UUID 128 support

In current implementation, the UUID 128 is not well supported. The
found issue includes,
Issue 1: No clear byte order of the UUID 128 in local SDP record.
Issue 2: No clear byte order of the UUID 128 of the SDP discover
parameter.

For issue 1,
Add the description to note that if the SDP attribute type is
`BT_SDP_UINT128`, `BT_SDP_INT128`, and `BT_SDP_UUID128`, the byte
order should be little-endian.

And swap the 128bit from little-endian to big-endian when responding
the peer SDP discovery request.

For issue 2,
Add the description to note that if the SDP discovery type is
`Service Search` and `Service Search Attribute`, and UUID is UUID 128,
the passed UUID data of the discovery request parameter should be
represented as the little-endian byte-order sequence.

And swap the 128bit from little-endian to big-endian when packing the
SDP discovery packet.

Signed-off-by: Lyle Zhu <lyle.zhu@nxp.com>
This commit is contained in:
Lyle Zhu 2025-07-23 18:22:26 +08:00 committed by Fabio Baltieri
parent a128f55b5d
commit af42036ca6
4 changed files with 66 additions and 17 deletions

View File

@ -241,6 +241,13 @@ extern "C" {
* TextString and URLString can be of size 2^{8, 16, 32} bytes
* DataSequence and DataSequenceAlternates can be of size 2^{8, 16, 32}
* The size are computed post-facto in the API and are not known apriori.
*
* For the type BT_SDP_UINT128, BT_SDP_INT128, and BT_SDP_UUID128, the
* byteorder of data should be little-endian. Such as, SPP UUID128:
* `00001101-0000-1000-8000-00805F9B34FB` will be represented as
* {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00,
* 0x01, 0x11, 0x00, 0x00}
* For UUID 128, @ref BT_SDP_ARRAY_UUID_128 is used to declare the array.
* @{
*/
#define BT_SDP_DATA_NIL 0x00 /**< Nil, the null type */
@ -327,6 +334,31 @@ struct bt_sdp_record {
*/
#define BT_SDP_ARRAY_32(...) ((uint32_t[]) {__VA_ARGS__})
/**
* @brief Declare a UUID 128 in little-endian format in an attribute.
*
* Helper macro to initialize a 128-bit UUID array value from the readable form
* of UUIDs.
*
* Example of how to declare the UUID `00001101-0000-1000-8000-00805F9B34FB`
*
* @code
* BT_SDP_ARRAY_UUID_128(0x6E400001, 0xB5A3, 0xF393, 0xE0A9, 0xE50E24DCCA9E)
* @endcode
*
* Just replace the hyphen by the comma and add `0x` prefixes.
*
* @param w32 First part of the UUID (32 bits)
* @param w1 Second part of the UUID (16 bits)
* @param w2 Third part of the UUID (16 bits)
* @param w3 Fourth part of the UUID (16 bits)
* @param w48 Fifth part of the UUID (48 bits)
*
* @return The comma separated values for UUID 128.
*/
#define BT_SDP_ARRAY_UUID_128(w32, w1, w2, w3, w48) \
BT_SDP_ARRAY_8(BT_UUID_128_ENCODE(w32, w1, w2, w3, w48))
/**
* @brief Declare a fixed-size data element header.
*
@ -560,6 +592,10 @@ struct bt_sdp_discover_params {
* On the service discovery completion the callback function will be
* called to get feedback to user about findings.
*
* If the UUID is UUID 128 for discovery type `Service Search` and
* `Service Search Attribute`, the UUID data should be represented as the
* little-endian byteorder sequence.
*
* Service Search: The SDP Client generates an
* SDP_SERVICE_SEARCH_REQ to locate service
* records that match the service search

View File

@ -778,9 +778,15 @@ static uint32_t copy_attribute(struct bt_sdp_data_elem *elem,
net_buf_add_be16(buf, *((uint16_t *)elem->data));
} else if (seq_size == 4U) {
net_buf_add_be32(buf, *((uint32_t *)elem->data));
} else if (seq_size == 8U) {
net_buf_add_be64(buf, *((uint64_t *)elem->data));
} else {
/* TODO: Convert 32bit and 128bit values to big-endian*/
net_buf_add_mem(buf, elem->data, seq_size);
__ASSERT(seq_size == 0x10, "Invalid sequence size");
uint8_t val[seq_size];
sys_memcpy_swap(val, elem->data, sizeof(val));
net_buf_add_mem(buf, val, seq_size);
}
} else {
net_buf_add_mem(buf, elem->data, seq_size);
@ -1504,6 +1510,7 @@ static int sdp_client_ss_search(struct bt_sdp_client *session,
const struct bt_sdp_discover_params *param)
{
struct net_buf *buf;
uint8_t uuid128[BT_UUID_SIZE_128];
/* Update context param directly. */
session->param = param;
@ -1530,8 +1537,8 @@ static int sdp_client_ss_search(struct bt_sdp_client *session,
case BT_UUID_TYPE_128:
net_buf_add_u8(buf, 0x11);
net_buf_add_u8(buf, BT_SDP_UUID128);
net_buf_add_mem(buf, BT_UUID_128(param->uuid)->val,
ARRAY_SIZE(BT_UUID_128(param->uuid)->val));
sys_memcpy_swap(uuid128, BT_UUID_128(param->uuid)->val, sizeof(uuid128));
net_buf_add_mem(buf, uuid128, sizeof(uuid128));
break;
default:
LOG_ERR("Unknown UUID type %u", param->uuid->type);
@ -1610,6 +1617,7 @@ static int sdp_client_ssa_search(struct bt_sdp_client *session,
const struct bt_sdp_discover_params *param)
{
struct net_buf *buf;
uint8_t uuid128[BT_UUID_SIZE_128];
/* Update context param directly. */
session->param = param;
@ -1636,8 +1644,8 @@ static int sdp_client_ssa_search(struct bt_sdp_client *session,
case BT_UUID_TYPE_128:
net_buf_add_u8(buf, 0x11);
net_buf_add_u8(buf, BT_SDP_UUID128);
net_buf_add_mem(buf, BT_UUID_128(param->uuid)->val,
ARRAY_SIZE(BT_UUID_128(param->uuid)->val));
sys_memcpy_swap(uuid128, BT_UUID_128(param->uuid)->val, sizeof(uuid128));
net_buf_add_mem(buf, uuid128, sizeof(uuid128));
break;
default:
LOG_ERR("Unknown UUID type %u", param->uuid->type);
@ -2498,6 +2506,11 @@ static inline ssize_t sdp_get_uuid_len(const uint8_t *data, size_t len)
return 5;
case BT_SDP_UUID128:
if (len < (BT_UUID_SIZE_128 + sizeof(uint8_t))) {
break;
}
return BT_UUID_SIZE_128 + sizeof(uint8_t);
default:
LOG_ERR("Invalid/unhandled DTD 0x%02x", data[0]);
return -EINVAL;

View File

@ -170,6 +170,7 @@ static int cmd_ssa_discovery(const struct shell *sh, size_t argc, char *argv[])
{
int err;
size_t len;
uint8_t uuid128[BT_UUID_SIZE_128];
len = strlen(argv[1]);
@ -189,8 +190,8 @@ static int cmd_ssa_discovery(const struct shell *sh, size_t argc, char *argv[])
sdp_discover.uuid = &sdp_discover_uuid.u32.uuid;
} else if (len == (BT_UUID_SIZE_128 * 2)) {
sdp_discover_uuid.u128.uuid.type = BT_UUID_TYPE_128;
hex2bin(argv[1], len, &sdp_discover_uuid.u128.val[0],
sizeof(sdp_discover_uuid.u128.val));
hex2bin(argv[1], len, &uuid128[0], sizeof(uuid128));
sys_memcpy_swap(sdp_discover_uuid.u128.val, uuid128, sizeof(uuid128));
sdp_discover.uuid = &sdp_discover_uuid.u128.uuid;
} else {
shell_error(sh, "Invalid UUID");
@ -213,6 +214,7 @@ static int cmd_ss_discovery(const struct shell *sh, size_t argc, char *argv[])
{
int err;
size_t len;
uint8_t uuid128[BT_UUID_SIZE_128];
len = strlen(argv[1]);
@ -232,8 +234,8 @@ static int cmd_ss_discovery(const struct shell *sh, size_t argc, char *argv[])
sdp_discover.uuid = &sdp_discover_uuid.u32.uuid;
} else if (len == (BT_UUID_SIZE_128 * 2)) {
sdp_discover_uuid.u128.uuid.type = BT_UUID_TYPE_128;
hex2bin(argv[1], len, &sdp_discover_uuid.u128.val[0],
sizeof(sdp_discover_uuid.u128.val));
hex2bin(argv[1], len, &uuid128[0], sizeof(uuid128));
sys_memcpy_swap(sdp_discover_uuid.u128.val, uuid128, sizeof(uuid128));
sdp_discover.uuid = &sdp_discover_uuid.u128.uuid;
} else {
shell_error(sh, "Invalid UUID");
@ -310,9 +312,9 @@ static int cmd_ssa_discovery_fail(const struct shell *sh, size_t argc, char *arg
}
SHELL_STATIC_SUBCMD_SET_CREATE(sdp_client_cmds,
SHELL_CMD_ARG(ss_discovery, NULL, "<UUID>", cmd_ss_discovery, 2, 0),
SHELL_CMD_ARG(ss_discovery, NULL, "<Big endian UUID>", cmd_ss_discovery, 2, 0),
SHELL_CMD_ARG(sa_discovery, NULL, "<Service Record Handle>", cmd_sa_discovery, 2, 0),
SHELL_CMD_ARG(ssa_discovery, NULL, "<UUID>", cmd_ssa_discovery, 2, 0),
SHELL_CMD_ARG(ssa_discovery, NULL, "<Big endian UUID>", cmd_ssa_discovery, 2, 0),
SHELL_CMD_ARG(ssa_discovery_fail, NULL, "", cmd_ssa_discovery_fail, 1, 0),
SHELL_SUBCMD_SET_END
);

View File

@ -296,9 +296,6 @@ static int cmd_register_sdp_large_valid(const struct shell *sh, size_t argc, cha
return 0;
}
uint8_t serial_port_svclass_uuid128[16] = {0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x10, 0x00,
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
static struct bt_sdp_attribute spp_attrs_uuid128[] = {
BT_SDP_NEW_SERVICE,
BT_SDP_LIST(
@ -307,7 +304,7 @@ static struct bt_sdp_attribute spp_attrs_uuid128[] = {
BT_SDP_DATA_ELEM_LIST(
{
BT_SDP_TYPE_SIZE(BT_SDP_UUID128),
serial_port_svclass_uuid128
BT_SDP_ARRAY_UUID_128(0x00001101, 0x0000, 0x1000, 0x8000, 0x00805F9B34FB),
},
)
),
@ -348,7 +345,8 @@ static struct bt_sdp_attribute spp_attrs_uuid128[] = {
BT_SDP_DATA_ELEM_LIST(
{
BT_SDP_TYPE_SIZE(BT_SDP_UUID128),
serial_port_svclass_uuid128
BT_SDP_ARRAY_UUID_128(0x00001101, 0x0000, 0x1000, 0x8000,
0x00805F9B34FB),
},
{
BT_SDP_TYPE_SIZE(BT_SDP_UINT16),