diff --git a/include/zephyr/bluetooth/classic/sdp.h b/include/zephyr/bluetooth/classic/sdp.h index 1999015b745..7873eb1a125 100644 --- a/include/zephyr/bluetooth/classic/sdp.h +++ b/include/zephyr/bluetooth/classic/sdp.h @@ -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 diff --git a/subsys/bluetooth/host/classic/sdp.c b/subsys/bluetooth/host/classic/sdp.c index 80d2468a7ef..8b9184dac1c 100644 --- a/subsys/bluetooth/host/classic/sdp.c +++ b/subsys/bluetooth/host/classic/sdp.c @@ -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; diff --git a/tests/bluetooth/classic/sdp_c/src/sdp_client.c b/tests/bluetooth/classic/sdp_c/src/sdp_client.c index 5539b16d350..71626fc5ca0 100644 --- a/tests/bluetooth/classic/sdp_c/src/sdp_client.c +++ b/tests/bluetooth/classic/sdp_c/src/sdp_client.c @@ -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, "", cmd_ss_discovery, 2, 0), + SHELL_CMD_ARG(ss_discovery, NULL, "", cmd_ss_discovery, 2, 0), SHELL_CMD_ARG(sa_discovery, NULL, "", cmd_sa_discovery, 2, 0), - SHELL_CMD_ARG(ssa_discovery, NULL, "", cmd_ssa_discovery, 2, 0), + SHELL_CMD_ARG(ssa_discovery, NULL, "", cmd_ssa_discovery, 2, 0), SHELL_CMD_ARG(ssa_discovery_fail, NULL, "", cmd_ssa_discovery_fail, 1, 0), SHELL_SUBCMD_SET_END ); diff --git a/tests/bluetooth/classic/sdp_s/src/sdp_server.c b/tests/bluetooth/classic/sdp_s/src/sdp_server.c index dc502393d75..749e37679f3 100644 --- a/tests/bluetooth/classic/sdp_s/src/sdp_server.c +++ b/tests/bluetooth/classic/sdp_s/src/sdp_server.c @@ -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),