1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 /**
17  * @addtogroup Bluetooth
18  * @{
19  *
20  * @brief This file is a part of BTStack.
21  *
22  */
23 
24 /**
25  * @file sdp.h
26  *
27  * @brief Service discovery protocol (SDP) interface.
28  *
29  */
30 #ifndef SDP_H
31 #define SDP_H
32 
33 #include <stdlib.h>
34 #include <stdbool.h>
35 
36 #include "btstack.h"
37 
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 
42 /* Define service class UUIDs */
43 #define SDP_PUBLIC_BROWSE_GROUP_ROOT_UUID 0x1002
44 
45 /* Define service attribute IDs. */
46 #define SDP_ATTRIBUTE_SERVICE_RECORD_HANDLE 0x0000
47 #define SDP_ATTRIBUTE_SERVICE_CLASS_ID_LIST 0x0001
48 #define SDP_ATTRIBUTE_SERVICE_RECORD_STATE 0x0002
49 #define SDP_ATTRIBUTE_SERVICE_ID 0x0003
50 #define SDP_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST 0x0004
51 #define SDP_ATTRIBUTE_ADDITIONAL_PROTOCOL_DESCRIPTOR_LIST 0x000D
52 #define SDP_ATTRIBUTE_BROWSE_GROUP_LIST 0x0005
53 #define SDP_ATTRIBUTE_LANGUAGE_BASE_ATTRIBUTE_ID_LIST 0x0006
54 #define SDP_ATTRIBUTE_SERVICE_INFO_TIME_TO_LIVE 0x0007
55 #define SDP_ATTRIBUTE_SERVICE_AVAILABILITY 0x0008
56 #define SDP_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST 0x0009
57 #define SDP_ATTRIBUTE_DOCUMENTATION_URL 0x000A
58 #define SDP_ATTRIBUTE_CLIENT_EXECUTABLE_URL 0x000B
59 #define SDP_ATTRIBUTE_ICON_URL 0x000C
60 #define SDP_ATTRIBUTE_SERVICE_NAME 0x0000
61 #define SDP_ATTRIBUTE_DESCRIPTOR 0x0001
62 #define SDP_ATTRIBUTE_PROVIDER_NAME 0x0002
63 
64 /* Define base attribute ID value for the primary language. */
65 #define SDP_ATTRIBUTE_PRIMARY_LANGUAGE_BASE 0x0100
66 
67 /* Define protocol UUIDs. */
68 #define UUID_PROTOCOL_SDP 0x0001
69 #define UUID_PROTOCOL_RFCOMM 0x0003
70 #define UUID_PROTOCOL_ATT 0x0007
71 #define UUID_PROTOCOL_OBEX 0x0008
72 #define UUID_PROTOCOL_AVCTP 0x0017
73 #define UUID_PROTOCOL_AVDTP 0x0019
74 #define UUID_PROTOCOL_AVCTP_BROWSING 0x001B
75 #define UUID_PROTOCOL_L2CAP 0x0100
76 
77 /* Define specified buffer size. */
78 #define SDP_PROTOCOL_PARAMETER_MAX_COUNT 4
79 #define SDP_PROTOCOL_DESCRIPTOR_MAX_COUNT 4
80 #define SDP_ATTRIBUTE_ID_LIST_MAX_COUNT 12
81 
82 /* Data type. */
83 typedef enum {
84     SDP_TYPE_BOOL,
85     SDP_TYPE_UINT_8,
86     SDP_TYPE_UINT_16,
87     SDP_TYPE_UINT_32,
88     SDP_TYPE_INT_8,
89     SDP_TYPE_INT_16,
90     SDP_TYPE_INT_32,
91     SDP_TYPE_UUID_16,
92     SDP_TYPE_UUID_32,
93     SDP_TYPE_UUID_128,
94     SDP_TYPE_TEXT,
95     SDP_TYPE_URL,
96 } SdpDataType;
97 
98 /**
99  *  @brief Protocol patameter
100  */
101 typedef struct {
102     SdpDataType type;
103     uint32_t value;
104 } SdpProtocolParameter;
105 
106 /**
107  *  @brief Protocol descriptor
108  */
109 typedef struct {
110     BtUuid protocolUuid;
111     uint16_t parameterNumber;
112     SdpProtocolParameter parameter[SDP_PROTOCOL_PARAMETER_MAX_COUNT];
113 } SdpProtocolDescriptor;
114 
115 /**
116  *  @brief Additional protocol descriptor
117  */
118 typedef struct {
119     uint16_t protocolDescriptorNumber;
120     SdpProtocolDescriptor parameter[SDP_PROTOCOL_DESCRIPTOR_MAX_COUNT];
121 } SdpAdditionalProtocolDescriptor;
122 
123 /**
124  *  @brief Language attribute
125  */
126 typedef struct {
127     uint16_t languageIdentifier;
128     uint16_t characterEncodingIdentifier;
129     uint16_t baseAttributeId;
130 } SdpLanguageBaseAttributeId;
131 
132 /**
133  *  @brief Profile descriptor
134  */
135 typedef struct {
136     BtUuid profileUuid;
137     uint16_t versionNumber;
138 } SdpProfileDescriptor;
139 
140 /**
141  * @brief  Create service record.
142  *
143  * @return Returns service record handle value.
144  */
145 uint32_t BTSTACK_API SDP_CreateServiceRecord();
146 
147 /**
148  * @brief Destroy service record.
149  *
150  * @param handle Service record handle.
151  * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
152  */
153 int BTSTACK_API SDP_DestroyServiceRecord(uint32_t handle);
154 
155 /**
156  * @brief Register service record.
157  *
158  * @param handle Service record handle.
159  * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
160  */
161 int BTSTACK_API SDP_RegisterServiceRecord(uint32_t handle);
162 
163 /**
164  * @brief Deregister service record.
165  *
166  * @param handle Service record handle.
167  * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
168  */
169 int BTSTACK_API SDP_DeregisterServiceRecord(uint32_t handle);
170 
171 /**
172  * @brief Add ServiceClassIDList Attribute to service record. The ServiceClassIDList shall contain
173  *        at least one service class UUID. Refer to charter 5.1.2 of Core 5.0.
174  *
175  * @param handle  Service record handle.
176  * @param classid The list of UUIDs representing the service classes.
177  * @param classidNumber The number of classid.
178  * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
179  */
180 int BTSTACK_API SDP_AddServiceClassIdList(uint32_t handle, const BtUuid *classid, uint16_t classidNumber);
181 
182 /**
183  * @brief Add ServiceRecordState Attribute to service record. Refer to charter 5.1.3 of Core 5.0.
184  *
185  * @param handle Service record handle.
186  * @param state  Service record state.
187  * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
188  */
189 int BTSTACK_API SDP_AddServiceRecordState(uint32_t handle, uint32_t state);
190 
191 /**
192  * @brief Add ServiceRecordState Attribute to service record. Refer to charter 5.1.4 of Core 5.0.
193  *
194  * @param handle    Service record handle.
195  * @param serviceid The UUID that uniquely identifies the service.
196  * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
197  */
198 int BTSTACK_API SDP_AddServiceId(uint32_t handle, const BtUuid *serviceid);
199 
200 /**
201  * @brief Add ProtocolDescriptorList Attribute to record. The ProtocolDescriptorList attribute
202  *        describes one or more protocol stacks that can be used to gain access to the service
203  *        described by the service record.Refer to charter 5.1.5 of Core 5.0.
204  *
205  * @param handle     Service record handle.
206  * @param descriptor One or more protocol descriptor.
207  * @param descriptorNumber The number of protocol.
208  * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
209  */
210 int BTSTACK_API SDP_AddProtocolDescriptorList(
211     uint32_t handle, const SdpProtocolDescriptor *descriptor, uint16_t descriptorNumber);
212 
213 /**
214  * @brief Add AdditionalProtocolDescriptorList Attribute to record. The AdditionalProtocolDescriptorLists
215  *        attribute supports services that require more channels in addition to the service described
216  *        in ProtocolDescriptorList. Refer to charter 5.1.6 of Core 5.0.
217  *
218  * @param handle           Service record handle.
219  * @param descriptorList   A sequence of ProtocolDescriptorList-elements.
220  * @param descriptorNumber The number of ProtocolDescriptorList-element.
221  * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
222  */
223 int BTSTACK_API SDP_AddAdditionalProtocolDescriptorList(
224     uint32_t handle, const SdpAdditionalProtocolDescriptor *descriptorList, uint16_t descriptorListNumber);
225 
226 /**
227  * @brief Add BrowseGroupList Attribute to record. The top-level browse group ID, called PublicBrowseRoot
228  *        and representing the root of the browsing hierarchy, has the default value 0x1002 (UUID16).
229  *        Refer to charter 5.1.7 of Core 5.0.
230  *
231  * @param handle           Service record handle.
232  * @param browseUuid       The list of UUIDs that represents a browse group.
233  * @param browseUuidNumber The number of UUIDs
234  * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
235  */
236 int BTSTACK_API SDP_AddBrowseGroupList(uint32_t handle, const BtUuid *browseUuid, uint16_t browseUuidNumber);
237 
238 /**
239  * @brief Add LanguageBaseAttributeIDList Attribute to record. The LanguageBaseAttributeIDList attribute
240  *        is a list in which each member containsa language identifier, a character encoding identifier,
241  *        and a base attribute ID for each of the natural languages used in the service record.
242  *        Refer to charter 5.1.8 of Core 5.0.
243  *
244  * @param handle                Service record handle.
245  * @param baseAttributeId       The list of the natural languages' attribute IDs.
246  * @param baseAttributeIdNum the number of the natural languages used in the service record.
247  * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
248  */
249 int BTSTACK_API SDP_AddLanguageBaseAttributeIdList(
250     uint32_t handle, const SdpLanguageBaseAttributeId *baseAttributeId, uint16_t baseAttributeIdNum);
251 
252 /**
253  * @brief Add ServiceInfoTimeToLive Attribute to record. The ServiceTimeToLive attribute is a 32-bit
254  *        integer that contains the number of seconds for which the information in a service record
255  *        is expected to remain valid and unchanged. Refer to charter 5.1.9 of Core 5.0.
256  *
257  * @param handle Service record handle.
258  * @param value  Time interval in seconds.
259  * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
260  */
261 int BTSTACK_API SDP_AddServiceInfoTimeToLive(uint32_t handle, uint32_t value);
262 
263 /**
264  * @brief Add ServiceAvailability Attribute to record. The ServiceAvailability attribute is an 8-bit unsigned
265  *        integer that represents therelative ability of the service to accept additional clients.
266  *        Refer to charter 5.1.10 of Core 5.0.
267  *
268  * @param handle Service record handle.
269  * @param value  The relative ability of the service (idle - 0xFF, busy - 0x00).
270  * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
271  */
272 int BTSTACK_API SDP_AddServiceAvailability(uint32_t handle, uint8_t value);
273 
274 /**
275  * @brief Add BluetoothProfileDescriptorList Attribute to record. The BluetoothProfileDescriptorList attribute
276  *        consists of a data element sequence in which each element is a profile descriptor contains information
277  *        about a Bluetooth profile to which the service represented by this service record conforms.
278  *        Refer to charter 5.1.11 of Core 5.0.
279  *
280  * @param handle                  Service record handle.
281  * @param profileDescriptor       The list of UUIDs and a 16-bit profile version number.
282  * @param profileDescriptorNum The number of profile descriptors.
283  * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
284  */
285 int BTSTACK_API SDP_AddBluetoothProfileDescriptorList(
286     uint32_t handle, const SdpProfileDescriptor *profileDescriptor, uint16_t profileDescriptorNum);
287 
288 /**
289  * @brief Add DocumentationURL Attribute to record. The DocumentationURL attribute is a URL which points to
290  *        documentation on the service described by a service record. Refer to charter 5.1.12 of Core 5.0.
291  *
292  * @param handle Service record handle.
293  * @param url    The documentation url.
294  * @param urlLen The length of url.
295  * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
296  */
297 int BTSTACK_API SDP_AddDocumentationUrl(uint32_t handle, const uint8_t *url, uint16_t urlLen);
298 
299 /**
300  * @brief Add ClientExecutableURL Attribute to record. The ClientExecutableURL attribute is a URL that refers to
301  *        the location of an application that can be used to utilize the service described by the service record.
302  *        Refer to charter 5.1.13 of Core 5.0.
303  *
304  * @param handle Service record handle.
305  * @param url    The client executable url.
306  * @param urlLen The length of url.
307  * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
308  */
309 int BTSTACK_API SDP_AddClientExecutableUrl(uint32_t handle, const uint8_t *url, uint16_t urlLen);
310 
311 /**
312  * @brief Add IconURL Attribute to record. The IconURL attribute is a URL that refers to the location of an icon that
313  *        can be used to represent the service described by the service record. Refer to charter 5.1.14 of Core 5.0.
314  *
315  * @param handle Service record handle.
316  * @param url    The icon url.
317  * @param urlLen The length of url.
318  * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
319  */
320 int BTSTACK_API SDP_AddIconUrl(uint32_t handle, const uint8_t *url, uint16_t urlLen);
321 
322 /**
323  * @brief Add ServiceName Attribute to record. The ServiceName attribute is a string containing the name of
324  *        the service represented by a service record. Refer to charter 5.1.15 of Core 5.0.
325  *
326  * @param handle          Service record handle.
327  * @param baseAttributeId The attribute ID base (default 0x0100).
328  * @param name            The service name.
329  * @param nameLen         The length of name.
330  * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
331  */
332 int BTSTACK_API SDP_AddServiceName(uint32_t handle, uint16_t baseAttributeId, const char *name, uint16_t nameLen);
333 
334 /**
335  * @brief Add ServiceDescription Attribute to record. The ServiceDescription attribute is a string
336  *        containing a brief description of the service. Refer to charter 5.1.16 of Core 5.0.
337  *
338  * @param handle          Service record handle.
339  * @param baseAttributeId The attribute ID base (default 0x0100).
340  * @param description     A brief description of the service.
341  * @param descriptionLen  The length of description.
342  * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
343  */
344 int BTSTACK_API SDP_AddServiceDescription(
345     uint32_t handle, uint16_t baseAttributeId, const char *description, uint16_t descriptionLen);
346 
347 /**
348  * @brief Add ProviderName Attribute to record. This ProviderName attribute is a string containing the name of
349  *        the person or organization providing the service. Refer to charter 5.1.17 of Core 5.0.
350  *
351  * @param handle          Service record handle.
352  * @param baseAttributeId The attribute ID base (default 0x0100).
353  * @param name            The name of the person or organization providing the service.
354  * @param nameLen         The length of name.
355  * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
356  */
357 int BTSTACK_API SDP_AddProviderName(uint32_t handle, uint16_t baseAttributeId, const char *name, uint16_t nameLen);
358 
359 /**
360  * @brief Add attribute undefined in Core 5.0 specification. Refer to charter 2.2 of Core 5.0.
361  *
362  * @param handle               Service record handle.
363  * @param attributeId          Attribute undefined in Core 5.0.
364  * @param type                 The type of attribute value.
365  * @param attributeValue       Attribute value.
366  * @param attributeValueLength The length of attribute value.
367  * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
368  */
369 int BTSTACK_API SDP_AddAttribute(
370     uint32_t handle, uint16_t attributeId, SdpDataType type, void *attributeValue, uint16_t attributeValueLength);
371 
372 /**
373  * @brief Add attribute, which value is sequence, undefined in Core 5.0 specification. Refer to charter 2.2 of
374  * Core 5.0.
375  *
376  * @param handle               Service record handle.
377  * @param attributeId          Attribute undefined in Core 5.0.
378  * @param attributeValue       Attribute value.
379  * @param attributeValueLength The length of attribute value.
380  * @return Returns <b>BT_SUCCESS</b> if the operation is successful, otherwise the operation fails.
381  */
382 int BTSTACK_API SDP_AddSequenceAttribute(
383     uint32_t handle, uint16_t attributeId, const uint8_t *attributeValue, uint16_t attributeValueLength);
384 
385 /**
386  *  @brief Type of AttributeID list.
387  */
388 typedef enum {
389     SDP_TYPE_LIST,
390     SDP_TYPE_RANGE,
391 } SdpAttributeIdListType;
392 
393 /**
394  *  @brief Uuid list.
395  */
396 typedef struct {
397     uint16_t uuidNum;
398     BtUuid *uuid;
399 } SdpUuid;
400 
401 /**
402  *  @brief The list is either some attribute IDs or a range of attribute IDs.
403  */
404 typedef struct {
405     SdpAttributeIdListType type;
406     union {
407         struct {
408             uint16_t attributeIdNumber;
409             uint16_t attributeId[SDP_ATTRIBUTE_ID_LIST_MAX_COUNT];
410         } attributeIdList;
411 
412         struct {
413             uint16_t start;
414             uint16_t end;
415         } attributeIdRange;
416     };
417 } SdpAttributeIdList;
418 
419 /**
420  *  @brief Get undefined attribute in Core 5.0.
421  */
422 typedef struct {
423     uint16_t attributeId;
424     SdpDataType type;
425     uint16_t attributeValueLength;
426     void *attributeValue;
427 } SdpAttribute;
428 
429 /**
430  *  @brief Add undefined attribute in Core 5.0, which value is sequence.
431  */
432 typedef struct {
433     uint16_t attributeId;
434     uint16_t attributeValueLength;
435     uint8_t *attributeValue;
436 } SdpSequenceAttribute;
437 
438 /**
439  *  @brief Callback all attribute value.
440  */
441 typedef struct {
442     uint32_t handle;
443 
444     uint16_t classIdNumber;
445     BtUuid *classId;
446 
447     uint32_t state;
448     BtUuid serviceId;
449 
450     uint16_t descriptorNumber;
451     SdpProtocolDescriptor *descriptor;
452 
453     uint16_t descriptorListNumber;
454     SdpAdditionalProtocolDescriptor *descriptorList;
455 
456     uint16_t browseUuidNumber;
457     BtUuid *browseUuid;
458 
459     uint16_t baseAttributeIdNumber;
460     SdpLanguageBaseAttributeId *baseAttributeId;
461 
462     uint32_t serviceInfoTimeToLive;
463     uint8_t serviceAvailability;
464 
465     uint16_t profileDescriptorNumber;
466     SdpProfileDescriptor *profileDescriptor;
467 
468     char *documentationUrl;
469     char *clientExecutableUrl;
470     char *iconUrl;
471 
472     char *serviceName;
473     char *serviceDescription;
474     char *providerName;
475 
476     uint16_t attributeNumber;
477     SdpAttribute *attribute;
478 
479     uint16_t sequenceAttributeNumber;
480     SdpSequenceAttribute *sequenceAttribute;
481 } SdpService;
482 
483 /**
484  * @brief The SDP client generates an SDP_ServiceSearchRequest to locate service records that match the service
485  *        search pattern given as the first parameter of the PDU. Refer to charter 4.5.1 and 4.5.2 of Core 5.0.
486  *
487  * @param addr      The remote bluetooth device address.
488  * @param uuidArray The list of uuids.
489  * @param uuidNum   The number of uuids.
490  * @param context   The context from upper layer.
491  * @param ServiceSearchCb callback.
492  * @return Returns <b>BT_NO_ERROE</b> if the operation is successful; returns <b>false</b> if the operation fails.
493  */
494 int BTSTACK_API SDP_ServiceSearch(const BtAddr *addr, const SdpUuid *uuidArray, void *context,
495     void (*serviceSearchCb)(const BtAddr *addr, const uint32_t *handleArray, uint16_t handleNum, void *context));
496 
497 /**
498  * @brief The SDP client generates an SDP_ServiceAttributeRequest to retrieve specified attribute values
499  *        from a specific service record. Refer to charter 4.6.1 and 4.6.2 of Core 5.0.
500 
501  * @param addr   The remote bluetooth device address.
502  * @param handle A service record handle.
503  * @param attributeIdList The list is either an attribute ID or a range of attribute IDs. Note that
504  *                        all attributes can be requested by specifying a range of 0x0000-0xFFFF.
505  * @param context The context from upper layer.
506  * @param ServiceAttributeCb callback
507  * @return Returns <b>BT_NO_ERROE</b> if the operation is successful; returns <b>false</b> if the operation fails.
508  */
509 int BTSTACK_API SDP_ServiceAttribute(const BtAddr *addr, uint32_t handle, SdpAttributeIdList attributeIdList,
510     void *context, void (*serviceAttributeCb)(const BtAddr *addr, const SdpService *service, void *context));
511 
512 /**
513  * @brief The SDP_ServiceSearchAttributeRequest transaction combines the capabilities of the SDP_ServiceSearchRequest
514  *        and the SDP_ServiceAttributeRequest into a single request. Refer to charter 4.7.1 and 4.7.2 of Core 5.0.
515  *
516  * @param addr      The remote bluetooth device address.
517  * @param uuidArray The list of uuids.
518  * @param attributeIdList The list is either an attribute ID or a range of attribute IDs. Note that
519  *                        all attributes can be requested by specifying a range of 0x0000-0xFFFF.
520  * @param context   The context from upper layer.
521  * @param ServiceSearchAttributeCb callback.
522  * @return Returns <b>BT_NO_ERROE</b> if the operation is successful; returns <b>false</b> if the operation fails.
523  */
524 int BTSTACK_API SDP_ServiceSearchAttribute(const BtAddr *addr, const SdpUuid *uuidArray,
525     SdpAttributeIdList attributeIdList, void *context,
526     void (*searchAttributeCb)(const BtAddr *addr, const SdpService *serviceArray, uint16_t serviceNum, void *context));
527 
528 /**
529  * @brief Browse all record handles of remote device. Refer to charter 2.6 of Core 5.0.
530  *
531  * @param addr    The remote bluetooth device address.
532  * @param context The context from upper layer.
533  * @param ServiceBrowseCb callback.
534  * @return Returns <b>BT_NO_ERROE</b> if the operation is successful; returns <b>false</b> if the operation fails.
535  */
536 int BTSTACK_API SDP_ServiceBrowse(const BtAddr *addr, void *context,
537     void (*ServiceBrowseCb)(const BtAddr *addr, const uint32_t *handleArray, uint16_t handleNum, void *context));
538 
539 #ifdef __cplusplus
540 }
541 #endif
542 
543 #endif  // SDP_H