Bluetooth: SDP: Implement ServiceSearchAttribute request PDU
Initial implementation one of basic UUID resolving request PDU based on Service Search Attribute PDU specification [Core 4.2 Vol 3 Part B 4.7.1] The request applies approach to query using single only UUID pattern and getting all attributes for given UUID. The initial PDU transaction is requested on PSM SDP L2CAP channel connected state. > ACL Data RX: Handle 77 flags 0x02 dlen 18 L2CAP: Configure Response (0x05) ident 12 len 10 Source CID: 64 Flags: 0x0000 Result: Success (0x0000) Option: Maximum Transmission Unit (0x01) [mandatory] MTU: 64 > HCI Event: Number of Completed Packets (0x13) plen 5 Num handles: 1 Handle: 77 Count: 1 < HCI Command: Host Number of Completed Packets (0x03|0x0035) plen 5 Num handles: 1 Handle: 77 Count: 1 < ACL Data TX: Handle 77 flags 0x00 dlen 24 Channel: 64 len 20 [PSM 1 mode 0] {chan 0} SDP: Service Search Attribute Request (0x06) tid 3 len 15 Search pattern: [len 5] Sequence (6) with 3 bytes [8 extra bits] len 5 UUID (3) with 2 bytes [0 extra bits] len 3 OBEX Object Push (0x1105) Max record count: 65535 Attribute list: [len 7] Sequence (6) with 5 bytes [8 extra bits] len 7 Unsigned Integer (1) with 4 bytes [0 extra bits] len 5 0x0000ffff Continuation state: 0 > HCI Event: Number of Completed Packets (0x13) plen 5 Num handles: 1 Handle: 77 Count: 1 > ACL Data RX: Handle 77 flags 0x02 dlen 68 Channel: 64 len 64 [PSM 1 mode 0] {chan 0} SDP: Service Search Attribute Response (0x07) tid 3 len 59 Attribute bytes: 48 Continuation state: 8 8d 55 59 58 30 00 00 00 .UYX0... Jira: ZEP-1112 Change-Id: I0ed1d989a5abe030f1c70d4d1f104d488eafb2b3 Signed-off-by: Arkadiusz Lichwa <arkadiusz.lichwa@tieto.com>
This commit is contained in:
parent
9055f57850
commit
7fc2a8a4e2
2 changed files with 102 additions and 3 deletions
|
@ -62,9 +62,13 @@ NET_BUF_POOL_DEFINE(sdp_pool, CONFIG_BLUETOOTH_MAX_CONN,
|
|||
#define SDP_CLIENT_MTU 64
|
||||
|
||||
struct bt_sdp_client {
|
||||
struct bt_l2cap_br_chan chan;
|
||||
struct bt_l2cap_br_chan chan;
|
||||
/* list of waiting to be resolved UUID params */
|
||||
sys_slist_t reqs;
|
||||
sys_slist_t reqs;
|
||||
/* required SDP transaction ID */
|
||||
uint16_t tid;
|
||||
/* UUID params holder being now resolved */
|
||||
const struct bt_sdp_discover_params *param;
|
||||
};
|
||||
|
||||
static struct bt_sdp_client bt_sdp_client_pool[CONFIG_BLUETOOTH_MAX_CONN];
|
||||
|
@ -319,6 +323,98 @@ int bt_sdp_register_service(struct bt_sdp_record *service)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define GET_PARAM(__node) \
|
||||
CONTAINER_OF(__node, struct bt_sdp_discover_params, _node)
|
||||
|
||||
/* ServiceSearchAttribute PDU, ref to BT Core 4.2, Vol 3, part B, 4.7.1 */
|
||||
static int sdp_client_ssa_search(struct bt_sdp_client *session)
|
||||
{
|
||||
const struct bt_sdp_discover_params *param;
|
||||
struct bt_sdp_hdr *hdr;
|
||||
struct net_buf *buf;
|
||||
|
||||
/*
|
||||
* Select proper user params, if session->param is invalid it means
|
||||
* getting new UUID from top of to be resolved params list. Otherwise
|
||||
* the context is in a middle of partial SDP PDU responses and cached
|
||||
* value from context can be used.
|
||||
*/
|
||||
if (!session->param) {
|
||||
param = GET_PARAM(sys_slist_peek_head(&session->reqs));
|
||||
} else {
|
||||
param = session->param;
|
||||
}
|
||||
|
||||
if (!param) {
|
||||
BT_WARN("No UUIDs to be resolved on remote");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
buf = bt_l2cap_create_pdu(&sdp_pool, 0);
|
||||
if (!buf) {
|
||||
BT_ERR("No bufs for PDU");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
hdr = net_buf_add(buf, sizeof(*hdr));
|
||||
|
||||
hdr->op_code = BT_SDP_SVC_SEARCH_ATTR_REQ;
|
||||
/* BT_SDP_SEQ8 means length of sequence is on additional next byte */
|
||||
net_buf_add_u8(buf, BT_SDP_SEQ8);
|
||||
|
||||
switch (param->uuid->type) {
|
||||
case BT_UUID_TYPE_16:
|
||||
/* Seq length */
|
||||
net_buf_add_u8(buf, 0x03);
|
||||
/* Seq type */
|
||||
net_buf_add_u8(buf, BT_SDP_UUID16);
|
||||
/* Seq value */
|
||||
net_buf_add_be16(buf, BT_UUID_16(param->uuid)->val);
|
||||
break;
|
||||
case BT_UUID_TYPE_32:
|
||||
net_buf_add_u8(buf, 0x05);
|
||||
net_buf_add_u8(buf, BT_SDP_UUID32);
|
||||
net_buf_add_be32(buf, BT_UUID_32(param->uuid)->val);
|
||||
break;
|
||||
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));
|
||||
break;
|
||||
default:
|
||||
BT_ERR("Unknown UUID type %u", param->uuid->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Set attribute max bytes count to be returned from server */
|
||||
net_buf_add_be16(buf, BT_SDP_MAX_ATTR_LEN);
|
||||
/*
|
||||
* Sequence definition where data is sequence of elements and where
|
||||
* additional next byte points the size of elements within
|
||||
*/
|
||||
net_buf_add_u8(buf, BT_SDP_SEQ8);
|
||||
net_buf_add_u8(buf, 0x05);
|
||||
/* Data element definition for two following 16bits range elements */
|
||||
net_buf_add_u8(buf, BT_SDP_UINT32);
|
||||
/* Get all attributes. It enables filter out wanted only attributes */
|
||||
net_buf_add_be16(buf, 0x0000);
|
||||
net_buf_add_be16(buf, 0xffff);
|
||||
|
||||
/* Initial continuation state octet */
|
||||
net_buf_add_u8(buf, 0x00);
|
||||
|
||||
/* set overall PDU length */
|
||||
hdr->param_len = sys_cpu_to_be16(buf->len - sizeof(*hdr));
|
||||
|
||||
/* Update context param to the one being resolving now */
|
||||
session->param = param;
|
||||
session->tid++;
|
||||
hdr->tid = sys_cpu_to_be16(session->tid);
|
||||
|
||||
return bt_l2cap_chan_send(&session->chan.chan, buf);
|
||||
}
|
||||
|
||||
static void sdp_client_receive(struct bt_l2cap_chan *chan, struct net_buf *buf)
|
||||
{
|
||||
struct bt_sdp_client *session = SDP_CLIENT_CHAN(chan);
|
||||
|
@ -363,7 +459,7 @@ static void sdp_client_connected(struct bt_l2cap_chan *chan)
|
|||
|
||||
BT_DBG("session %p chan %p connected", session, chan);
|
||||
|
||||
ARG_UNUSED(session);
|
||||
sdp_client_ssa_search(session);
|
||||
}
|
||||
|
||||
static void sdp_client_disconnected(struct bt_l2cap_chan *chan)
|
||||
|
|
|
@ -53,4 +53,7 @@ struct bt_sdp_hdr {
|
|||
uint16_t param_len;
|
||||
} __packed;
|
||||
|
||||
/* Allowed attributes length in SSA Request PDU to be taken from server */
|
||||
#define BT_SDP_MAX_ATTR_LEN 0xffff
|
||||
|
||||
void bt_sdp_init(void);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue