1 /******************************************************************************
2 *
3 * Copyright 1999-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18 #ifndef SDP_API_H
19 #define SDP_API_H
20
21 #include <base/strings/stringprintf.h>
22
23 #include <cstdint>
24
25 #include "bt_target.h"
26 #include "sdpdefs.h"
27 #include "types/bluetooth/uuid.h"
28 #include "types/raw_address.h"
29
30 /*****************************************************************************
31 * Constants
32 ****************************************************************************/
33
34 /* Success code and error codes */
35 typedef enum : uint16_t {
36 SDP_SUCCESS = 0x0000,
37 SDP_INVALID_VERSION = 0x0001,
38 SDP_INVALID_SERV_REC_HDL = 0x0002,
39 SDP_INVALID_REQ_SYNTAX = 0x0003,
40 SDP_INVALID_PDU_SIZE = 0x0004,
41 SDP_INVALID_CONT_STATE = 0x0005,
42 SDP_NO_RESOURCES = 0x0006,
43 SDP_DI_REG_FAILED = 0x0007,
44 SDP_DI_DISC_FAILED = 0x0008,
45 SDP_NO_DI_RECORD_FOUND = 0x0009,
46 SDP_ERR_ATTR_NOT_PRESENT = 0x000A,
47 SDP_ILLEGAL_PARAMETER = 0x000B,
48
49 HID_SDP_NO_SERV_UUID = (SDP_ILLEGAL_PARAMETER + 1),
50 HID_SDP_MANDATORY_MISSING,
51
52 SDP_NO_RECS_MATCH = 0xFFF0,
53 SDP_CONN_FAILED = 0xFFF1,
54 SDP_CFG_FAILED = 0xFFF2,
55 SDP_GENERIC_ERROR = 0xFFF3,
56 SDP_DB_FULL = 0xFFF4,
57 SDP_CANCEL = 0xFFF8,
58 } tSDP_STATUS;
59 using tSDP_RESULT = tSDP_STATUS;
60 using tSDP_REASON = tSDP_STATUS;
61
62 #define CASE_RETURN_TEXT(code) \
63 case code: \
64 return #code
65
sdp_status_text(const tSDP_STATUS & status)66 inline std::string sdp_status_text(const tSDP_STATUS& status) {
67 switch (status) {
68 CASE_RETURN_TEXT(SDP_SUCCESS);
69 CASE_RETURN_TEXT(SDP_INVALID_VERSION);
70 CASE_RETURN_TEXT(SDP_INVALID_SERV_REC_HDL);
71 CASE_RETURN_TEXT(SDP_INVALID_REQ_SYNTAX);
72 CASE_RETURN_TEXT(SDP_INVALID_PDU_SIZE);
73 CASE_RETURN_TEXT(SDP_INVALID_CONT_STATE);
74 CASE_RETURN_TEXT(SDP_NO_RESOURCES);
75 CASE_RETURN_TEXT(SDP_DI_REG_FAILED);
76 CASE_RETURN_TEXT(SDP_DI_DISC_FAILED);
77 CASE_RETURN_TEXT(SDP_NO_DI_RECORD_FOUND);
78 CASE_RETURN_TEXT(SDP_ERR_ATTR_NOT_PRESENT);
79 CASE_RETURN_TEXT(SDP_ILLEGAL_PARAMETER);
80
81 CASE_RETURN_TEXT(HID_SDP_NO_SERV_UUID);
82 CASE_RETURN_TEXT(HID_SDP_MANDATORY_MISSING);
83
84 CASE_RETURN_TEXT(SDP_NO_RECS_MATCH);
85 CASE_RETURN_TEXT(SDP_CONN_FAILED);
86 CASE_RETURN_TEXT(SDP_CFG_FAILED);
87 CASE_RETURN_TEXT(SDP_GENERIC_ERROR);
88 CASE_RETURN_TEXT(SDP_DB_FULL);
89 CASE_RETURN_TEXT(SDP_CANCEL);
90 default:
91 return base::StringPrintf("UNKNOWN[%hu]", status);
92 }
93 }
94 #undef CASE_RETURN_TEXT
95
96 /* Masks for attr_value field of tSDP_DISC_ATTR */
97 #define SDP_DISC_ATTR_LEN_MASK 0x0FFF
98 #define SDP_DISC_ATTR_TYPE(len_type) ((len_type) >> 12)
99 #define SDP_DISC_ATTR_LEN(len_type) ((len_type)&SDP_DISC_ATTR_LEN_MASK)
100
101 /* Maximum number of protocol list items (list_elem in tSDP_PROTOCOL_ELEM) */
102 #define SDP_MAX_LIST_ELEMS 3
103
104 /*****************************************************************************
105 * Type Definitions
106 ****************************************************************************/
107
108 /* Define a callback function for when discovery is complete. */
109 typedef void(tSDP_DISC_CMPL_CB)(tSDP_RESULT result);
110 typedef void(tSDP_DISC_CMPL_CB2)(tSDP_RESULT result, const void* user_data);
111
112 typedef struct {
113 RawAddress peer_addr;
114 uint16_t peer_mtu;
115 } tSDP_DR_OPEN;
116
117 typedef struct {
118 uint8_t* p_data;
119 uint16_t data_len;
120 } tSDP_DR_DATA;
121
122 typedef union {
123 tSDP_DR_OPEN open;
124 tSDP_DR_DATA data;
125 } tSDP_DATA;
126
127 /* Define a structure to hold the discovered service information. */
128 typedef struct {
129 union {
130 uint8_t u8; /* 8-bit integer */
131 uint16_t u16; /* 16-bit integer */
132 uint32_t u32; /* 32-bit integer */
133 struct t_sdp_disc_attr* p_sub_attr; /* Addr of first sub-attr (list)*/
134 uint8_t array[]; /* Variable length field */
135 /* flexible array member */
136 /* requiring backing store */
137 /* from SDP DB */
138 } v;
139
140 } tSDP_DISC_ATVAL;
141
142 typedef struct t_sdp_disc_attr {
143 struct t_sdp_disc_attr* p_next_attr; /* Addr of next linked attr */
144 uint16_t attr_id; /* Attribute ID */
145 uint16_t attr_len_type; /* Length and type fields */
146 tSDP_DISC_ATVAL attr_value; /* Variable length entry data */
147 } tSDP_DISC_ATTR;
148
149 typedef struct t_sdp_disc_rec {
150 tSDP_DISC_ATTR* p_first_attr; /* First attribute of record */
151 struct t_sdp_disc_rec* p_next_rec; /* Addr of next linked record */
152 uint32_t time_read; /* The time the record was read */
153 RawAddress remote_bd_addr; /* Remote BD address */
154 } tSDP_DISC_REC;
155
156 typedef struct {
157 uint32_t mem_size; /* Memory size of the DB */
158 uint32_t mem_free; /* Memory still available */
159 tSDP_DISC_REC* p_first_rec; /* Addr of first record in DB */
160 uint16_t num_uuid_filters; /* Number of UUIds to filter */
161 bluetooth::Uuid uuid_filters[SDP_MAX_UUID_FILTERS]; /* UUIDs to filter */
162 uint16_t num_attr_filters; /* Number of attribute filters */
163 uint16_t attr_filters[SDP_MAX_ATTR_FILTERS]; /* Attributes to filter */
164 uint8_t* p_free_mem; /* Pointer to free memory */
165 uint8_t*
166 raw_data; /* Received record from server. allocated/released by client */
167 uint32_t raw_size; /* size of raw_data */
168 uint32_t raw_used; /* length of raw_data used */
169 } tSDP_DISCOVERY_DB;
170
171 /* This structure is used to add protocol lists and find protocol elements */
172 typedef struct {
173 uint16_t protocol_uuid;
174 uint16_t num_params;
175 uint16_t params[SDP_MAX_PROTOCOL_PARAMS];
176 } tSDP_PROTOCOL_ELEM;
177
178 typedef struct {
179 uint16_t num_elems;
180 tSDP_PROTOCOL_ELEM list_elem[SDP_MAX_LIST_ELEMS];
181 } tSDP_PROTO_LIST_ELEM;
182
183 /* Device Identification (DI) data structure
184 */
185 /* Used to set the DI record */
186 typedef struct t_sdp_di_record {
187 uint16_t vendor;
188 uint16_t vendor_id_source;
189 uint16_t product;
190 uint16_t version;
191 bool primary_record;
192 char client_executable_url[SDP_MAX_ATTR_LEN]; /* optional */
193 char service_description[SDP_MAX_ATTR_LEN]; /* optional */
194 char documentation_url[SDP_MAX_ATTR_LEN]; /* optional */
195 } tSDP_DI_RECORD;
196
197 /* Used to get the DI record */
198 typedef struct t_sdp_di_get_record {
199 uint16_t spec_id;
200 tSDP_DI_RECORD rec;
201 } tSDP_DI_GET_RECORD;
202
203 /* API into the SDP layer for service discovery. */
204
205 /*******************************************************************************
206 *
207 * Function SDP_InitDiscoveryDb
208 *
209 * Description This function is called to initialize a discovery database.
210 *
211 * Returns true if successful, false if one or more parameters are bad
212 *
213 ******************************************************************************/
214 bool SDP_InitDiscoveryDb(tSDP_DISCOVERY_DB* p_db, uint32_t len,
215 uint16_t num_uuid, const bluetooth::Uuid* p_uuid_list,
216 uint16_t num_attr, const uint16_t* p_attr_list);
217
218 /*******************************************************************************
219 *
220 * Function SDP_CancelServiceSearch
221 *
222 * Description This function cancels an active query to an SDP server.
223 *
224 * Returns true if discovery cancelled, false if a matching activity is
225 * not found.
226 *
227 ******************************************************************************/
228 bool SDP_CancelServiceSearch(const tSDP_DISCOVERY_DB* p_db);
229
230 /*******************************************************************************
231 *
232 * Function SDP_ServiceSearchRequest
233 *
234 * Description This function queries an SDP server for information.
235 *
236 * Returns true if discovery started, false if failed.
237 *
238 ******************************************************************************/
239 bool SDP_ServiceSearchRequest(const RawAddress& p_bd_addr,
240 tSDP_DISCOVERY_DB* p_db, tSDP_DISC_CMPL_CB* p_cb);
241
242 /*******************************************************************************
243 *
244 * Function SDP_ServiceSearchAttributeRequest
245 *
246 * Description This function queries an SDP server for information.
247 *
248 * The difference between this API function and the function
249 * SDP_ServiceSearchRequest is that this one does a
250 * combined ServiceSearchAttributeRequest SDP function.
251 *
252 * Returns true if discovery started, false if failed.
253 *
254 ******************************************************************************/
255 bool SDP_ServiceSearchAttributeRequest(const RawAddress& p_bd_addr,
256 tSDP_DISCOVERY_DB* p_db,
257 tSDP_DISC_CMPL_CB* p_cb);
258
259 /*******************************************************************************
260 *
261 * Function SDP_ServiceSearchAttributeRequest2
262 *
263 * Description This function queries an SDP server for information.
264 *
265 * The difference between this API function and the function
266 * SDP_ServiceSearchRequest is that this one does a
267 * combined ServiceSearchAttributeRequest SDP function with the
268 * user data piggyback
269 *
270 * Returns true if discovery started, false if failed.
271 *
272 ******************************************************************************/
273 bool SDP_ServiceSearchAttributeRequest2(const RawAddress& p_bd_addr,
274 tSDP_DISCOVERY_DB* p_db,
275 tSDP_DISC_CMPL_CB2* p_cb,
276 const void* user_data);
277
278 /* API of utilities to find data in the local discovery database */
279
280 /*******************************************************************************
281 *
282 * Function SDP_FindAttributeInRec
283 *
284 * Description This function searches an SDP discovery record for a
285 * specific attribute.
286 *
287 * Returns Pointer to matching attribute entry, or NULL
288 *
289 ******************************************************************************/
290 tSDP_DISC_ATTR* SDP_FindAttributeInRec(const tSDP_DISC_REC* p_rec,
291 uint16_t attr_id);
292
293 /*******************************************************************************
294 *
295 * Function SDP_FindServiceInDb
296 *
297 * Description This function queries an SDP database for a specific
298 * service. If the p_start_rec pointer is NULL, it looks from
299 * the beginning of the database, else it continues from the
300 * next record after p_start_rec.
301 *
302 * Returns Pointer to record containing service class, or NULL
303 *
304 ******************************************************************************/
305 tSDP_DISC_REC* SDP_FindServiceInDb(const tSDP_DISCOVERY_DB* p_db,
306 uint16_t service_uuid,
307 tSDP_DISC_REC* p_start_rec);
308
309 /*******************************************************************************
310 *
311 * Function SDP_FindServiceUUIDInDb
312 *
313 * Description This function queries an SDP database for a specific
314 * service. If the p_start_rec pointer is NULL, it looks from
315 * the beginning of the database, else it continues from the
316 * next record after p_start_rec.
317 *
318 * NOTE the only difference between this function and the previous
319 * function "SDP_FindServiceInDb()" is that this function takes
320 * a Uuid input.
321 *
322 * Returns Pointer to record containing service class, or NULL
323 *
324 ******************************************************************************/
325 tSDP_DISC_REC* SDP_FindServiceUUIDInDb(const tSDP_DISCOVERY_DB* p_db,
326 const bluetooth::Uuid& uuid,
327 tSDP_DISC_REC* p_start_rec);
328
329 /*******************************************************************************
330 *
331 * Function SDP_FindServiceUUIDInRec_128bit
332 *
333 * Description Read the 128-bit service UUID within a record,
334 * if there is any.
335 *
336 * Parameters: p_rec - pointer to a SDP record.
337 * p_uuid - output parameter to save the UUID found.
338 *
339 * Returns true if found, otherwise false.
340 *
341 ******************************************************************************/
342 bool SDP_FindServiceUUIDInRec_128bit(const tSDP_DISC_REC* p_rec,
343 bluetooth::Uuid* p_uuid);
344
345 /*******************************************************************************
346 *
347 * Function SDP_FindServiceInDb_128bit
348 *
349 * Description Query an SDP database for a specific service.
350 * If the p_start_rec pointer is NULL, look from the beginning
351 * of the database, else continue from the next record after
352 * p_start_rec.
353 *
354 * Returns Pointer to record containing service class, or NULL
355 *
356 ******************************************************************************/
357 tSDP_DISC_REC* SDP_FindServiceInDb_128bit(const tSDP_DISCOVERY_DB* p_db,
358 tSDP_DISC_REC* p_start_rec);
359
360 /*******************************************************************************
361 *
362 * Function SDP_FindProtocolListElemInRec
363 *
364 * Description This function looks at a specific discovery record for a
365 * protocol list element.
366 *
367 * Returns true if found, false if not
368 * If found, the passed protocol list element is filled in.
369 *
370 ******************************************************************************/
371 bool SDP_FindProtocolListElemInRec(const tSDP_DISC_REC* p_rec,
372 uint16_t layer_uuid,
373 tSDP_PROTOCOL_ELEM* p_elem);
374
375 /*******************************************************************************
376 *
377 * Function SDP_FindProfileVersionInRec
378 *
379 * Description This function looks at a specific discovery record for the
380 * Profile list descriptor, and pulls out the version number.
381 * The version number consists of an 8-bit major version and
382 * an 8-bit minor version.
383 *
384 * Returns true if found, false if not
385 * If found, the major and minor version numbers that were
386 * passed in are filled in.
387 *
388 ******************************************************************************/
389 bool SDP_FindProfileVersionInRec(const tSDP_DISC_REC* p_rec,
390 uint16_t profile_uuid, uint16_t* p_version);
391
392 /* API into SDP for local service database updates */
393
394 /*******************************************************************************
395 *
396 * Function SDP_CreateRecord
397 *
398 * Description This function is called to create a record in the database.
399 * This would be through the SDP database maintenance API. The
400 * record is created empty, teh application should then call
401 * "add_attribute" to add the record's attributes.
402 *
403 * Returns Record handle if OK, else 0.
404 *
405 ******************************************************************************/
406 uint32_t SDP_CreateRecord(void);
407
408 /*******************************************************************************
409 *
410 * Function SDP_DeleteRecord
411 *
412 * Description This function is called to add a record (or all records)
413 * from the database. This would be through the SDP database
414 * maintenance API.
415 *
416 * If a record handle of 0 is passed, all records are deleted.
417 *
418 * Returns true if succeeded, else false
419 *
420 ******************************************************************************/
421 bool SDP_DeleteRecord(uint32_t handle);
422
423 /*******************************************************************************
424 *
425 * Function SDP_AddAttribute
426 *
427 * Description This function is called to add an attribute to a record.
428 * This would be through the SDP database maintenance API.
429 * If the attribute already exists in the record, it is
430 * replaced with the new value.
431 *
432 * NOTE Attribute values must be passed as a Big Endian stream.
433 *
434 * Returns true if added OK, else false
435 *
436 ******************************************************************************/
437 bool SDP_AddAttribute(uint32_t handle, uint16_t attr_id, uint8_t attr_type,
438 uint32_t attr_len, uint8_t* p_val);
439
440 /*******************************************************************************
441 *
442 * Function SDP_AddSequence
443 *
444 * Description This function is called to add a sequence to a record.
445 * This would be through the SDP database maintenance API.
446 * If the sequence already exists in the record, it is replaced
447 * with the new sequence.
448 *
449 * NOTE Element values must be passed as a Big Endian stream.
450 *
451 * Returns true if added OK, else false
452 *
453 ******************************************************************************/
454 bool SDP_AddSequence(uint32_t handle, uint16_t attr_id, uint16_t num_elem,
455 uint8_t type[], uint8_t len[], uint8_t* p_val[]);
456
457 /*******************************************************************************
458 *
459 * Function SDP_AddUuidSequence
460 *
461 * Description This function is called to add a UUID sequence to a record.
462 * This would be through the SDP database maintenance API.
463 * If the sequence already exists in the record, it is replaced
464 * with the new sequence.
465 *
466 * Returns true if added OK, else false
467 *
468 ******************************************************************************/
469 bool SDP_AddUuidSequence(uint32_t handle, uint16_t attr_id, uint16_t num_uuids,
470 uint16_t* p_uuids);
471
472 /*******************************************************************************
473 *
474 * Function SDP_AddProtocolList
475 *
476 * Description This function is called to add a protocol descriptor list to
477 * a record. This would be through the SDP database
478 * maintenance API. If the protocol list already exists in the
479 * record, it is replaced with the new list.
480 *
481 * Returns true if added OK, else false
482 *
483 ******************************************************************************/
484 bool SDP_AddProtocolList(uint32_t handle, uint16_t num_elem,
485 tSDP_PROTOCOL_ELEM* p_elem_list);
486
487 /*******************************************************************************
488 *
489 * Function SDP_AddAdditionProtoLists
490 *
491 * Description This function is called to add a protocol descriptor list to
492 * a record. This would be through the SDP database maintenance
493 * API. If the protocol list already exists in the record, it
494 * is replaced with the new list.
495 *
496 * Returns true if added OK, else false
497 *
498 ******************************************************************************/
499 bool SDP_AddAdditionProtoLists(uint32_t handle, uint16_t num_elem,
500 tSDP_PROTO_LIST_ELEM* p_proto_list);
501
502 /*******************************************************************************
503 *
504 * Function SDP_AddProfileDescriptorList
505 *
506 * Description This function is called to add a profile descriptor list to
507 * a record. This would be through the SDP database maintenance
508 * API. If the version already exists in the record, it is
509 * replaced with the new one.
510 *
511 * Returns true if added OK, else false
512 *
513 ******************************************************************************/
514 bool SDP_AddProfileDescriptorList(uint32_t handle, uint16_t profile_uuid,
515 uint16_t version);
516
517 /*******************************************************************************
518 *
519 * Function SDP_AddLanguageBaseAttrIDList
520 *
521 * Description This function is called to add a language base attr list to
522 * a record. This would be through the SDP database maintenance
523 * API. If the version already exists in the record, it is
524 * replaced with the new one.
525 *
526 * Returns true if added OK, else false
527 *
528 ******************************************************************************/
529 bool SDP_AddLanguageBaseAttrIDList(uint32_t handle, uint16_t lang,
530 uint16_t char_enc, uint16_t base_id);
531
532 /*******************************************************************************
533 *
534 * Function SDP_AddServiceClassIdList
535 *
536 * Description This function is called to add a service list to a record.
537 * This would be through the SDP database maintenance API.
538 * If the service list already exists in the record, it is
539 * replaced with the new list.
540 *
541 * Returns true if added OK, else false
542 *
543 ******************************************************************************/
544 bool SDP_AddServiceClassIdList(uint32_t handle, uint16_t num_services,
545 uint16_t* p_service_uuids);
546
547 /*******************************************************************************
548 *
549 * Function SDP_DeleteAttribute
550 *
551 * Description Delete an attribute from a record.
552 * This would be through the SDP database maintenance API.
553 *
554 * Returns true if deleted OK, else false if not found
555 *
556 ******************************************************************************/
557 bool SDP_DeleteAttribute(uint32_t handle, uint16_t attr_id);
558
559 /* Device Identification APIs */
560
561 /*******************************************************************************
562 *
563 * Function SDP_SetLocalDiRecord
564 *
565 * Description This function adds a DI record to the local SDP database.
566 *
567 * Returns Returns SDP_SUCCESS if record added successfully, else error
568 *
569 ******************************************************************************/
570 uint16_t SDP_SetLocalDiRecord(const tSDP_DI_RECORD* device_info,
571 uint32_t* p_handle);
572
573 /*******************************************************************************
574 *
575 * Function SDP_DiDiscover
576 *
577 * Description This function queries a remote device for DI information.
578 *
579 * Returns SDP_SUCCESS if query started successfully, else error
580 *
581 ******************************************************************************/
582 tSDP_STATUS SDP_DiDiscover(const RawAddress& remote_device,
583 tSDP_DISCOVERY_DB* p_db, uint32_t len,
584 tSDP_DISC_CMPL_CB* p_cb);
585
586 /*******************************************************************************
587 *
588 * Function SDP_GetNumDiRecords
589 *
590 * Description Searches specified database for DI records
591 *
592 * Returns number of DI records found
593 *
594 ******************************************************************************/
595 uint8_t SDP_GetNumDiRecords(const tSDP_DISCOVERY_DB* p_db);
596
597 /*******************************************************************************
598 *
599 * Function SDP_GetDiRecord
600 *
601 * Description This function retrieves a remote device's DI record from
602 * the specified database.
603 *
604 * Returns SDP_SUCCESS if record retrieved, else error
605 *
606 ******************************************************************************/
607 uint16_t SDP_GetDiRecord(uint8_t getRecordIndex,
608 tSDP_DI_GET_RECORD* device_info,
609 const tSDP_DISCOVERY_DB* p_db);
610
611 /*******************************************************************************
612 *
613 * Function SDP_SetTraceLevel
614 *
615 * Description This function sets the trace level for SDP. If called with
616 * a value of 0xFF, it simply reads the current trace level.
617 *
618 * Returns the new (current) trace level
619 *
620 ******************************************************************************/
621 uint8_t SDP_SetTraceLevel(uint8_t new_level);
622
623 /*******************************************************************************
624 *
625 * Function SDP_FindServiceUUIDInRec
626 *
627 * Description Read the service UUID within a record,
628 * if there is any.
629 *
630 * Parameters: p_rec - pointer to a SDP record.
631 *
632 * Returns true if found, otherwise false.
633 *
634 ******************************************************************************/
635 bool SDP_FindServiceUUIDInRec(const tSDP_DISC_REC* p_rec,
636 bluetooth::Uuid* p_uuid);
637
638 #endif /* SDP_API_H */
639