1 /******************************************************************************
2  *
3  * Copyright 2014 Samsung System LSI
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 
19 /*******************************************************************************
20  *
21  *  Filename:      btif_sdp_server.cc
22  *  Description:   SDP server Bluetooth Interface to create and remove SDP
23  *                 records.
24  *                 To be used in combination with the RFCOMM/L2CAP(LE) sockets.
25  *
26  *
27  ******************************************************************************/
28 
29 #define LOG_TAG "bt_btif_sdp_server"
30 
31 #include <bluetooth/log.h>
32 #include <hardware/bluetooth.h>
33 #include <hardware/bt_sdp.h>
34 #include <pthread.h>
35 #include <stdlib.h>
36 #include <string.h>
37 
38 #include <mutex>
39 
40 #include "bta/include/bta_sdp_api.h"
41 #include "bta/sys/bta_sys.h"
42 #include "btif_common.h"
43 #include "btif_sock_sdp.h"
44 #include "osi/include/allocator.h"
45 #include "stack/include/bt_types.h"
46 #include "stack/include/bt_uuid16.h"
47 #include "stack/include/sdp_api.h"
48 #include "types/bluetooth/uuid.h"
49 #include "utl.h"
50 
51 // TODO(b/369381361) Enfore -Wmissing-prototypes
52 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
53 
54 using namespace bluetooth::legacy::stack::sdp;
55 using namespace bluetooth;
56 
57 // Protects the sdp_slots array from concurrent access.
58 static std::recursive_mutex sdp_lock;
59 
60 /**
61  * The need for a state variable have been reduced to two states.
62  * The remaining state control is handled by program flow
63  */
64 typedef enum {
65   SDP_RECORD_FREE = 0,
66   SDP_RECORD_ALLOCED,
67 } sdp_state_t;
68 
69 typedef struct {
70   sdp_state_t state;
71   int sdp_handle;
72   bluetooth_sdp_record* record_data;
73 } sdp_slot_t;
74 
75 namespace std {
76 template <>
77 struct formatter<sdp_state_t> : enum_formatter<sdp_state_t> {};
78 }  // namespace std
79 
80 #define MAX_SDP_SLOTS 128
81 static sdp_slot_t sdp_slots[MAX_SDP_SLOTS];
82 
83 /*****************************************************************************
84  * LOCAL Functions
85  *****************************************************************************/
86 static int add_maps_sdp(const bluetooth_sdp_mas_record* rec);
87 static int add_mapc_sdp(const bluetooth_sdp_mns_record* rec);
88 static int add_pbapc_sdp(const bluetooth_sdp_pce_record* rec);
89 static int add_pbaps_sdp(const bluetooth_sdp_pse_record* rec);
90 static int add_opps_sdp(const bluetooth_sdp_ops_record* rec);
91 static int add_saps_sdp(const bluetooth_sdp_sap_record* rec);
92 static int add_mps_sdp(const bluetooth_sdp_mps_record* rec);
93 bt_status_t remove_sdp_record(int record_id);
94 static int free_sdp_slot(int id);
95 
96 /******************************************************************************
97  * WARNING: Functions below are not called in BTU context.
98  * Introduced to make it possible to create SDP records from JAVA with both a
99  * RFCOMM channel and a L2CAP PSM.
100  * Overall architecture:
101  *  1) JAVA calls createRecord() which returns a pseudo ID which at a later
102  *     point will be linked to a specific SDP handle.
103  *  2) createRecord() requests the BTU task(thread) to call a callback in SDP
104  *     which creates the actual record, and updates the ID<->SDPHandle map
105  *     based on the ID being passed to BTA as user_data.
106  *****************************************************************************/
107 
init_sdp_slots()108 static void init_sdp_slots() {
109   int i;
110   memset(sdp_slots, 0, sizeof(sdp_slot_t) * MAX_SDP_SLOTS);
111   /* if SDP_RECORD_FREE is zero - no need to set the value */
112   if (SDP_RECORD_FREE != 0) {
113     for (i = 0; i < MAX_SDP_SLOTS; i++) {
114       sdp_slots[i].state = SDP_RECORD_FREE;
115     }
116   }
117 }
118 
sdp_server_init()119 bt_status_t sdp_server_init() {
120   log::verbose("Sdp Server Init");
121   init_sdp_slots();
122   return BT_STATUS_SUCCESS;
123 }
124 
sdp_server_cleanup()125 void sdp_server_cleanup() {
126   log::verbose("Sdp Server Cleanup");
127   std::unique_lock<std::recursive_mutex> lock(sdp_lock);
128   int i;
129   for (i = 0; i < MAX_SDP_SLOTS; i++) {
130     /*remove_sdp_record(i); we cannot send messages to the other threads, since
131      * they might
132      *                       have been shut down already. Just do local cleanup.
133      */
134     free_sdp_slot(i);
135   }
136 }
137 
get_sdp_records_size(bluetooth_sdp_record * in_record,int count)138 int get_sdp_records_size(bluetooth_sdp_record* in_record, int count) {
139   bluetooth_sdp_record* record = in_record;
140   int records_size = 0;
141   int i;
142   for (i = 0; i < count; i++) {
143     record = &in_record[i];
144     records_size += sizeof(bluetooth_sdp_record);
145     records_size += record->hdr.service_name_length;
146     if (record->hdr.service_name_length > 0) {
147       records_size++; /* + '\0' termination of string */
148     }
149     records_size += record->hdr.user1_ptr_len;
150     records_size += record->hdr.user2_ptr_len;
151   }
152   return records_size;
153 }
154 
155 /* Deep copy all content of in_records into out_records.
156  * out_records must point to a chunk of memory large enough to contain all
157  * the data. Use getSdpRecordsSize() to calculate the needed size. */
copy_sdp_records(bluetooth_sdp_record * in_records,bluetooth_sdp_record * out_records,int count)158 void copy_sdp_records(bluetooth_sdp_record* in_records, bluetooth_sdp_record* out_records,
159                       int count) {
160   int i;
161   bluetooth_sdp_record* in_record;
162   bluetooth_sdp_record* out_record;
163   char* free_ptr = (char*)(&out_records[count]); /* set pointer to after the last entry */
164 
165   for (i = 0; i < count; i++) {
166     in_record = &in_records[i];
167     out_record = &out_records[i];
168     *out_record = *in_record;
169 
170     if (in_record->hdr.service_name == NULL || in_record->hdr.service_name_length == 0) {
171       out_record->hdr.service_name = NULL;
172       out_record->hdr.service_name_length = 0;
173     } else {
174       out_record->hdr.service_name = free_ptr;  // Update service_name pointer
175       // Copy string
176       memcpy(free_ptr, in_record->hdr.service_name, in_record->hdr.service_name_length);
177       free_ptr += in_record->hdr.service_name_length;
178       *(free_ptr) = '\0';  // Set '\0' termination of string
179       free_ptr++;
180     }
181     if (in_record->hdr.user1_ptr != NULL) {
182       out_record->hdr.user1_ptr = (uint8_t*)free_ptr;  // Update pointer
183       memcpy(free_ptr, in_record->hdr.user1_ptr,
184              in_record->hdr.user1_ptr_len);  // Copy content
185       free_ptr += in_record->hdr.user1_ptr_len;
186     }
187     if (in_record->hdr.user2_ptr != NULL) {
188       out_record->hdr.user2_ptr = (uint8_t*)free_ptr;  // Update pointer
189       memcpy(free_ptr, in_record->hdr.user2_ptr,
190              in_record->hdr.user2_ptr_len);  // Copy content
191       free_ptr += in_record->hdr.user2_ptr_len;
192     }
193   }
194   return;
195 }
196 
197 /* Reserve a slot in sdp_slots, copy data and set a reference to the copy.
198  * The record_data will contain both the record and any data pointed to by
199  * the record.
200  * Currently this covers:
201  *   service_name string,
202  *   user1_ptr and
203  *   user2_ptr. */
alloc_sdp_slot(bluetooth_sdp_record * in_record)204 static int alloc_sdp_slot(bluetooth_sdp_record* in_record) {
205   int record_size = get_sdp_records_size(in_record, 1);
206   /* We are optimists here, and preallocate the record.
207    * This is to reduce the time we hold the sdp_lock. */
208   bluetooth_sdp_record* record = (bluetooth_sdp_record*)osi_malloc(record_size);
209 
210   copy_sdp_records(in_record, record, 1);
211   {
212     std::unique_lock<std::recursive_mutex> lock(sdp_lock);
213     for (int i = 0; i < MAX_SDP_SLOTS; i++) {
214       if (sdp_slots[i].state == SDP_RECORD_FREE) {
215         sdp_slots[i].state = SDP_RECORD_ALLOCED;
216         sdp_slots[i].record_data = record;
217         return i;
218       }
219     }
220   }
221   log::error("failed - no more free slots!");
222   /* Rearly the optimist is too optimistic, and cleanup is needed...*/
223   osi_free(record);
224   return -1;
225 }
226 
free_sdp_slot(int id)227 static int free_sdp_slot(int id) {
228   int handle = -1;
229   bluetooth_sdp_record* record = NULL;
230   if (id < 0 || id >= MAX_SDP_SLOTS) {
231     log::error("failed - id {} is invalid", id);
232     return handle;
233   }
234 
235   {
236     std::unique_lock<std::recursive_mutex> lock(sdp_lock);
237     handle = sdp_slots[id].sdp_handle;
238     sdp_slots[id].sdp_handle = 0;
239     if (sdp_slots[id].state != SDP_RECORD_FREE) {
240       /* safe a copy of the pointer, and free after unlock() */
241       record = sdp_slots[id].record_data;
242     }
243     sdp_slots[id].state = SDP_RECORD_FREE;
244   }
245 
246   if (record != NULL) {
247     osi_free(record);
248   } else {
249     // Record have already been freed
250     handle = -1;
251   }
252   return handle;
253 }
254 
255 /***
256  * Use this to get a reference to a SDP slot AND change the state to
257  * SDP_RECORD_CREATE_INITIATED.
258  */
start_create_sdp(int id)259 static const sdp_slot_t* start_create_sdp(int id) {
260   if (id >= MAX_SDP_SLOTS) {
261     log::error("failed - id {} is invalid", id);
262     return NULL;
263   }
264 
265   std::unique_lock<std::recursive_mutex> lock(sdp_lock);
266   if (sdp_slots[id].state != SDP_RECORD_ALLOCED) {
267     /* The record have been removed before this event occurred - e.g. deinit */
268     log::error("failed - state for id {} is sdp_slots[id].state = {} expected {}", id,
269                sdp_slots[id].state, SDP_RECORD_ALLOCED);
270     return NULL;
271   }
272 
273   return &(sdp_slots[id]);
274 }
275 
set_sdp_handle(int id,int handle)276 static void set_sdp_handle(int id, int handle) {
277   std::unique_lock<std::recursive_mutex> lock(sdp_lock);
278   sdp_slots[id].sdp_handle = handle;
279 }
280 
create_sdp_record(bluetooth_sdp_record * record,int * record_handle)281 bt_status_t create_sdp_record(bluetooth_sdp_record* record, int* record_handle) {
282   int handle;
283 
284   handle = alloc_sdp_slot(record);
285   log::verbose("handle = 0x{:08x}", handle);
286 
287   if (handle < 0) {
288     return BT_STATUS_NOMEM;
289   }
290 
291   BTA_SdpCreateRecordByUser(INT_TO_PTR(handle));
292 
293   *record_handle = handle;
294 
295   return BT_STATUS_SUCCESS;
296 }
297 
remove_sdp_record(int record_id)298 bt_status_t remove_sdp_record(int record_id) {
299   int handle;
300 
301   if (record_id >= MAX_SDP_SLOTS) {
302     return BT_STATUS_PARM_INVALID;
303   }
304 
305   bluetooth_sdp_record* record;
306   bluetooth_sdp_types sdp_type = SDP_TYPE_RAW;
307   {
308     std::unique_lock<std::recursive_mutex> lock(sdp_lock);
309     record = sdp_slots[record_id].record_data;
310     if (record != NULL) {
311       sdp_type = record->hdr.type;
312     }
313   }
314   tBTA_SERVICE_ID service_id = 0;
315   switch (sdp_type) {
316     case SDP_TYPE_MAP_MAS:
317       service_id = BTA_MAP_SERVICE_ID;
318       break;
319     case SDP_TYPE_MAP_MNS:
320       service_id = BTA_MN_SERVICE_ID;
321       break;
322     case SDP_TYPE_PBAP_PSE:
323       service_id = BTA_PBAP_SERVICE_ID;
324       break;
325     case SDP_TYPE_PBAP_PCE:
326       service_id = BTA_PCE_SERVICE_ID;
327       break;
328     default:
329       /* other enumeration values were not enabled in {@link on_create_record_event} */
330       break;
331   }
332   if (service_id > 0) {
333     // {@link btif_disable_service} sets the mask {@link btif_enabled_services}.
334     btif_disable_service(service_id);
335   }
336 
337   /* Get the Record handle, and free the slot */
338   handle = free_sdp_slot(record_id);
339   log::verbose("Sdp Server id={} to handle=0x{:08x}", record_id, handle);
340 
341   /* Pass the actual record handle */
342   if (handle > 0) {
343     BTA_SdpRemoveRecordByUser(INT_TO_PTR(handle));
344     return BT_STATUS_SUCCESS;
345   }
346   log::verbose("Sdp Server - record already removed - or never created");
347   return BT_STATUS_DONE;
348 }
349 
350 /******************************************************************************
351  * CALLBACK FUNCTIONS
352  * Called in BTA context to create/remove SDP records.
353  ******************************************************************************/
354 
on_create_record_event(int id)355 void on_create_record_event(int id) {
356   /*
357    * 1) Fetch the record pointer, and change its state?
358    * 2) switch on the type to create the correct record
359    * 3) Update state on completion
360    * 4) What to do at fail?
361    * */
362   log::verbose("Sdp Server");
363   const sdp_slot_t* sdp_slot = start_create_sdp(id);
364   tBTA_SERVICE_ID service_id = 0;
365   bluetooth_sdp_record* record;
366   /* In the case we are shutting down, sdp_slot is NULL */
367   if (sdp_slot != nullptr && (record = sdp_slot->record_data) != nullptr) {
368     int handle = -1;
369     switch (record->hdr.type) {
370       case SDP_TYPE_MAP_MAS:
371         handle = add_maps_sdp(&record->mas);
372         service_id = BTA_MAP_SERVICE_ID;
373         break;
374       case SDP_TYPE_MAP_MNS:
375         handle = add_mapc_sdp(&record->mns);
376         service_id = BTA_MN_SERVICE_ID;
377         break;
378       case SDP_TYPE_PBAP_PSE:
379         handle = add_pbaps_sdp(&record->pse);
380         service_id = BTA_PBAP_SERVICE_ID;
381         break;
382       case SDP_TYPE_OPP_SERVER:
383         handle = add_opps_sdp(&record->ops);
384         break;
385       case SDP_TYPE_SAP_SERVER:
386         handle = add_saps_sdp(&record->sap);
387         break;
388       case SDP_TYPE_PBAP_PCE:
389         handle = add_pbapc_sdp(&record->pce);
390         service_id = BTA_PCE_SERVICE_ID;
391         break;
392       case SDP_TYPE_MPS:
393         handle = add_mps_sdp(&record->mps);
394         break;
395       case SDP_TYPE_RAW:
396         if (record->hdr.rfcomm_channel_number > 0) {
397           handle = add_rfc_sdp_rec(record->hdr.service_name, record->hdr.uuid,
398                                    record->hdr.rfcomm_channel_number);
399         }
400         break;
401       default:
402         log::verbose("Record type {} is not supported", record->hdr.type);
403         break;
404     }
405     if (handle != -1) {
406       set_sdp_handle(id, handle);
407       if (service_id > 0) {
408         /**
409          * {@link btif_enable_service} calls {@link btif_dm_enable_service}, which calls {@link
410          * btif_in_execute_service_request}.
411          *     - {@link btif_enable_service} sets the mask {@link btif_enabled_services}.
412          *     - {@link btif_dm_enable_service} invokes the java callback to return uuids based
413          *       on the enabled services mask.
414          *     - {@link btif_in_execute_service_request} gates the java callback in {@link
415          *       btif_dm_enable_service}.
416          */
417         btif_enable_service(service_id);
418       }
419     }
420   }
421 }
422 
on_remove_record_event(int handle)423 void on_remove_record_event(int handle) {
424   log::verbose("Sdp Server");
425 
426   // User data carries the actual SDP handle, not the ID.
427   if (handle != -1 && handle != 0) {
428     bool result;
429     result = get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(handle);
430     if (!result) {
431       log::error("Unable to remove handle 0x{:08x}", handle);
432     }
433   }
434 }
435 
436 /****
437  * Below the actual functions accessing BTA context data - hence only call from
438  * BTA context!
439  */
440 
441 /* Create a MAP MAS SDP record based on information stored in a
442  * bluetooth_sdp_mas_record */
add_maps_sdp(const bluetooth_sdp_mas_record * rec)443 static int add_maps_sdp(const bluetooth_sdp_mas_record* rec) {
444   tSDP_PROTOCOL_ELEM protoList[3];
445   uint16_t service = UUID_SERVCLASS_MESSAGE_ACCESS;
446   uint16_t browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
447   bool status = true;
448   uint32_t sdp_handle = 0;
449   uint8_t temp[4];
450   uint8_t* p_temp = temp;
451 
452   sdp_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
453   if (sdp_handle == 0) {
454     log::error("Unable to register MAPS Service");
455     return sdp_handle;
456   }
457 
458   /* add service class */
459   status &= get_legacy_stack_sdp_api()->handle.SDP_AddServiceClassIdList(sdp_handle, 1, &service);
460   memset(protoList, 0, 3 * sizeof(tSDP_PROTOCOL_ELEM));
461 
462   /* add protocol list, including RFCOMM scn */
463   protoList[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
464   protoList[0].num_params = 0;
465   protoList[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
466   protoList[1].num_params = 1;
467   protoList[1].params[0] = rec->hdr.rfcomm_channel_number;
468   protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX;
469   protoList[2].num_params = 0;
470   status &= get_legacy_stack_sdp_api()->handle.SDP_AddProtocolList(sdp_handle, 3, protoList);
471 
472   /* Add a name entry */
473   status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
474           sdp_handle, (uint16_t)ATTR_ID_SERVICE_NAME, (uint8_t)TEXT_STR_DESC_TYPE,
475           (uint32_t)(rec->hdr.service_name_length + 1), (uint8_t*)rec->hdr.service_name);
476 
477   /* Add in the Bluetooth Profile Descriptor List */
478   status &= get_legacy_stack_sdp_api()->handle.SDP_AddProfileDescriptorList(
479           sdp_handle, UUID_SERVCLASS_MAP_PROFILE, rec->hdr.profile_version);
480 
481   /* Add MAS instance ID */
482   status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(sdp_handle, ATTR_ID_MAS_INSTANCE_ID,
483                                                                 UINT_DESC_TYPE, (uint32_t)1,
484                                                                 (uint8_t*)&rec->mas_instance_id);
485 
486   /* Add supported message types */
487   status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
488           sdp_handle, ATTR_ID_SUPPORTED_MSG_TYPE, UINT_DESC_TYPE, (uint32_t)1,
489           (uint8_t*)&rec->supported_message_types);
490 
491   /* Add supported feature */
492   UINT32_TO_BE_STREAM(p_temp, rec->supported_features);
493   status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
494           sdp_handle, ATTR_ID_MAP_SUPPORTED_FEATURES, UINT_DESC_TYPE, (uint32_t)4, temp);
495 
496   /* Add the L2CAP PSM if present */
497   if (rec->hdr.l2cap_psm != -1) {
498     p_temp = temp;  // The macro modifies p_temp, hence rewind.
499     UINT16_TO_BE_STREAM(p_temp, rec->hdr.l2cap_psm);
500     status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
501             sdp_handle, ATTR_ID_GOEP_L2CAP_PSM, UINT_DESC_TYPE, (uint32_t)2, temp);
502   }
503 
504   /* Make the service browseable */
505   status &= get_legacy_stack_sdp_api()->handle.SDP_AddUuidSequence(
506           sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
507 
508   if (!status) {
509     if (!get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(sdp_handle)) {
510       log::warn("Unable to delete SDP record handle:{}", sdp_handle);
511     }
512     sdp_handle = 0;
513     log::error("FAILED");
514   } else {
515     bta_sys_add_uuid(service); /* UUID_SERVCLASS_MESSAGE_ACCESS */
516     log::verbose("SDP Registered (handle 0x{:08x})", sdp_handle);
517   }
518   return sdp_handle;
519 }
520 
521 /* Create a MAP MNS SDP record based on information stored in a
522  * bluetooth_sdp_mns_record */
add_mapc_sdp(const bluetooth_sdp_mns_record * rec)523 static int add_mapc_sdp(const bluetooth_sdp_mns_record* rec) {
524   tSDP_PROTOCOL_ELEM protoList[3];
525   uint16_t service = UUID_SERVCLASS_MESSAGE_NOTIFICATION;
526   uint16_t browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
527   bool status = true;
528   uint32_t sdp_handle = 0;
529   uint8_t temp[4];
530   uint8_t* p_temp = temp;
531 
532   sdp_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
533   if (sdp_handle == 0) {
534     log::error("Unable to register MAP Notification Service");
535     return sdp_handle;
536   }
537 
538   /* add service class */
539   status &= get_legacy_stack_sdp_api()->handle.SDP_AddServiceClassIdList(sdp_handle, 1, &service);
540   memset(protoList, 0, 3 * sizeof(tSDP_PROTOCOL_ELEM));
541 
542   /* add protocol list, including RFCOMM scn */
543   protoList[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
544   protoList[0].num_params = 0;
545   protoList[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
546   protoList[1].num_params = 1;
547   protoList[1].params[0] = rec->hdr.rfcomm_channel_number;
548   protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX;
549   protoList[2].num_params = 0;
550   status &= get_legacy_stack_sdp_api()->handle.SDP_AddProtocolList(sdp_handle, 3, protoList);
551 
552   /* Add a name entry */
553   status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
554           sdp_handle, (uint16_t)ATTR_ID_SERVICE_NAME, (uint8_t)TEXT_STR_DESC_TYPE,
555           (uint32_t)(rec->hdr.service_name_length + 1), (uint8_t*)rec->hdr.service_name);
556 
557   /* Add in the Bluetooth Profile Descriptor List */
558   status &= get_legacy_stack_sdp_api()->handle.SDP_AddProfileDescriptorList(
559           sdp_handle, UUID_SERVCLASS_MAP_PROFILE, rec->hdr.profile_version);
560 
561   /* Add supported feature */
562   UINT32_TO_BE_STREAM(p_temp, rec->supported_features);
563   status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
564           sdp_handle, ATTR_ID_MAP_SUPPORTED_FEATURES, UINT_DESC_TYPE, (uint32_t)4, temp);
565 
566   /* Add the L2CAP PSM if present */
567   if (rec->hdr.l2cap_psm != -1) {
568     p_temp = temp;  // The macro modifies p_temp, hence rewind.
569     UINT16_TO_BE_STREAM(p_temp, rec->hdr.l2cap_psm);
570     status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
571             sdp_handle, ATTR_ID_GOEP_L2CAP_PSM, UINT_DESC_TYPE, (uint32_t)2, temp);
572   }
573 
574   /* Make the service browseable */
575   status &= get_legacy_stack_sdp_api()->handle.SDP_AddUuidSequence(
576           sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
577 
578   if (!status) {
579     if (!get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(sdp_handle)) {
580       log::warn("Unable to delete SDP record handle:{}", sdp_handle);
581     }
582     sdp_handle = 0;
583     log::error("FAILED");
584   } else {
585     bta_sys_add_uuid(service); /* UUID_SERVCLASS_MESSAGE_ACCESS */
586     log::verbose("SDP Registered (handle 0x{:08x})", sdp_handle);
587   }
588   return sdp_handle;
589 }
590 
591 /* Create a PBAP Client SDP record based on information stored in a
592  * bluetooth_sdp_pce_record */
add_pbapc_sdp(const bluetooth_sdp_pce_record * rec)593 static int add_pbapc_sdp(const bluetooth_sdp_pce_record* rec) {
594   uint16_t service = UUID_SERVCLASS_PBAP_PCE;
595   uint16_t browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
596   bool status = true;
597   uint32_t sdp_handle = 0;
598 
599   sdp_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
600   if (sdp_handle == 0) {
601     log::error("Unable to register PBAP Client Service");
602     return sdp_handle;
603   }
604 
605   status &= get_legacy_stack_sdp_api()->handle.SDP_AddServiceClassIdList(sdp_handle, 1, &service);
606 
607   /* Add a name entry */
608   status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
609           sdp_handle, (uint16_t)ATTR_ID_SERVICE_NAME, (uint8_t)TEXT_STR_DESC_TYPE,
610           (uint32_t)(rec->hdr.service_name_length + 1), (uint8_t*)rec->hdr.service_name);
611 
612   /* Add in the Bluetooth Profile Descriptor List */
613   status &= get_legacy_stack_sdp_api()->handle.SDP_AddProfileDescriptorList(
614           sdp_handle, UUID_SERVCLASS_PHONE_ACCESS, rec->hdr.profile_version);
615 
616   /* Make the service browseable */
617   status &= get_legacy_stack_sdp_api()->handle.SDP_AddUuidSequence(
618           sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
619 
620   if (!status) {
621     if (!get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(sdp_handle)) {
622       log::error("Unable to remove handle 0x{:08x}", sdp_handle);
623     }
624     sdp_handle = 0;
625     log::error("FAILED");
626     return sdp_handle;
627   }
628   bta_sys_add_uuid(service); /* UUID_SERVCLASS_PBAP_PCE */
629   log::verbose("SDP Registered (handle 0x{:08x})", sdp_handle);
630   return sdp_handle;
631 }
632 
633 /* Create a PBAP Server SDP record based on information stored in a
634  * bluetooth_sdp_pse_record */
add_pbaps_sdp(const bluetooth_sdp_pse_record * rec)635 static int add_pbaps_sdp(const bluetooth_sdp_pse_record* rec) {
636   tSDP_PROTOCOL_ELEM protoList[3];
637   uint16_t service = UUID_SERVCLASS_PBAP_PSE;
638   uint16_t browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
639   bool status = true;
640   uint32_t sdp_handle = 0;
641   uint8_t temp[4];
642   uint8_t* p_temp = temp;
643 
644   sdp_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
645   if (sdp_handle == 0) {
646     log::error("Unable to register PBAP Server Service");
647     return sdp_handle;
648   }
649 
650   /* add service class */
651   status &= get_legacy_stack_sdp_api()->handle.SDP_AddServiceClassIdList(sdp_handle, 1, &service);
652   memset(protoList, 0, 3 * sizeof(tSDP_PROTOCOL_ELEM));
653 
654   /* add protocol list, including RFCOMM scn */
655   protoList[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
656   protoList[0].num_params = 0;
657   protoList[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
658   protoList[1].num_params = 1;
659   protoList[1].params[0] = rec->hdr.rfcomm_channel_number;
660   protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX;
661   protoList[2].num_params = 0;
662   status &= get_legacy_stack_sdp_api()->handle.SDP_AddProtocolList(sdp_handle, 3, protoList);
663 
664   /* Add a name entry */
665   status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
666           sdp_handle, (uint16_t)ATTR_ID_SERVICE_NAME, (uint8_t)TEXT_STR_DESC_TYPE,
667           (uint32_t)(rec->hdr.service_name_length + 1), (uint8_t*)rec->hdr.service_name);
668   /* Add in the Bluetooth Profile Descriptor List */
669   status &= get_legacy_stack_sdp_api()->handle.SDP_AddProfileDescriptorList(
670           sdp_handle, UUID_SERVCLASS_PHONE_ACCESS, rec->hdr.profile_version);
671 
672   /* Add supported repositories 1 byte */
673   status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
674           sdp_handle, ATTR_ID_SUPPORTED_REPOSITORIES, UINT_DESC_TYPE, (uint32_t)1,
675           (uint8_t*)&rec->supported_repositories);
676   /* Add supported feature 4 bytes*/
677   UINT32_TO_BE_STREAM(p_temp, rec->supported_features);
678   status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
679           sdp_handle, ATTR_ID_PBAP_SUPPORTED_FEATURES, UINT_DESC_TYPE, (uint32_t)4, temp);
680 
681   /* Add the L2CAP PSM if present */
682   if (rec->hdr.l2cap_psm != -1) {
683     p_temp = temp;  // The macro modifies p_temp, hence rewind.
684     UINT16_TO_BE_STREAM(p_temp, rec->hdr.l2cap_psm);
685     status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
686             sdp_handle, ATTR_ID_GOEP_L2CAP_PSM, UINT_DESC_TYPE, (uint32_t)2, temp);
687 #if 0
688   status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
689       sdp_handle, (uint16_t)ATTR_ID_SERVICE_NAME, (uint8_t)TEXT_STR_DESC_TYPE,
690       (uint32_t)(rec->hdr.service_name_length + 1),
691       (uint8_t*)rec->hdr.service_name);
692 
693   /* Add in the Bluetooth Profile Descriptor List */
694   status &= get_legacy_stack_sdp_api()->handle.SDP_AddProfileDescriptorList(
695       sdp_handle, UUID_SERVCLASS_PHONE_ACCESS, rec->hdr.profile_version);
696 
697   /* Add supported repositories 1 byte */
698   status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
699       sdp_handle, ATTR_ID_SUPPORTED_REPOSITORIES, UINT_DESC_TYPE, (uint32_t)1,
700       (uint8_t*)&rec->supported_repositories);
701 
702   /* Add supported feature 4 bytes*/
703   UINT32_TO_BE_STREAM(p_temp, rec->supported_features);
704   status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
705       sdp_handle, ATTR_ID_PBAP_SUPPORTED_FEATURES, UINT_DESC_TYPE, (uint32_t)4,
706       temp);
707 
708   /* Add the L2CAP PSM if present */
709   if (rec->hdr.l2cap_psm != -1) {
710     p_temp = temp;  // The macro modifies p_temp, hence rewind.
711     UINT16_TO_BE_STREAM(p_temp, rec->hdr.l2cap_psm);
712     status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
713         sdp_handle, ATTR_ID_GOEP_L2CAP_PSM, UINT_DESC_TYPE, (uint32_t)2, temp);
714 #endif
715   }
716 
717   /* Make the service browseable */
718   status &= get_legacy_stack_sdp_api()->handle.SDP_AddUuidSequence(
719           sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
720 
721   if (!status) {
722     if (!get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(sdp_handle)) {
723       log::error("Unable to remove handle 0x{:08x}", sdp_handle);
724     }
725     sdp_handle = 0;
726     log::error("FAILED");
727   } else {
728     bta_sys_add_uuid(service); /* UUID_SERVCLASS_MESSAGE_ACCESS */
729     log::verbose("SDP Registered (handle 0x{:08x})", sdp_handle);
730   }
731   return sdp_handle;
732 }
733 
734 /* Create a OPP Server SDP record based on information stored in a
735  * bluetooth_sdp_ops_record */
736 static int add_opps_sdp(const bluetooth_sdp_ops_record* rec) {
737   tSDP_PROTOCOL_ELEM protoList[3];
738   uint16_t service = UUID_SERVCLASS_OBEX_OBJECT_PUSH;
739   uint16_t browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
740   uint8_t type_len[rec->supported_formats_list_len];
741   uint8_t desc_type[rec->supported_formats_list_len];
742   uint8_t* type_value[rec->supported_formats_list_len];
743   bool status = true;
744   uint32_t sdp_handle = 0;
745   uint8_t temp[4];
746   uint8_t* p_temp = temp;
747   tBTA_UTL_COD cod;
748   int i, j;
749 
750   sdp_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
751   if (sdp_handle == 0) {
752     log::error("Unable to register Object Push Server Service");
753     return sdp_handle;
754   }
755 
756   /* add service class */
757   status &= get_legacy_stack_sdp_api()->handle.SDP_AddServiceClassIdList(sdp_handle, 1, &service);
758   memset(protoList, 0, 3 * sizeof(tSDP_PROTOCOL_ELEM));
759 
760   /* add protocol list, including RFCOMM scn */
761   protoList[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
762   protoList[0].num_params = 0;
763   protoList[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
764   protoList[1].num_params = 1;
765   protoList[1].params[0] = rec->hdr.rfcomm_channel_number;
766   protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX;
767   protoList[2].num_params = 0;
768   status &= get_legacy_stack_sdp_api()->handle.SDP_AddProtocolList(sdp_handle, 3, protoList);
769 
770   /* Add a name entry */
771   status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
772           sdp_handle, (uint16_t)ATTR_ID_SERVICE_NAME, (uint8_t)TEXT_STR_DESC_TYPE,
773           (uint32_t)(rec->hdr.service_name_length + 1), (uint8_t*)rec->hdr.service_name);
774 
775   /* Add in the Bluetooth Profile Descriptor List */
776   status &= get_legacy_stack_sdp_api()->handle.SDP_AddProfileDescriptorList(
777           sdp_handle, UUID_SERVCLASS_OBEX_OBJECT_PUSH, rec->hdr.profile_version);
778 
779   /* add sequence for supported types */
780   for (i = 0, j = 0; i < rec->supported_formats_list_len; i++) {
781     type_value[j] = (uint8_t*)&rec->supported_formats_list[i];
782     desc_type[j] = UINT_DESC_TYPE;
783     type_len[j++] = 1;
784   }
785 
786   status &= get_legacy_stack_sdp_api()->handle.SDP_AddSequence(
787           sdp_handle, (uint16_t)ATTR_ID_SUPPORTED_FORMATS_LIST,
788           (uint8_t)rec->supported_formats_list_len, desc_type, type_len, type_value);
789 
790   /* Add the L2CAP PSM if present */
791   if (rec->hdr.l2cap_psm != -1) {
792     p_temp = temp;  // The macro modifies p_temp, hence rewind.
793     UINT16_TO_BE_STREAM(p_temp, rec->hdr.l2cap_psm);
794     status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
795             sdp_handle, ATTR_ID_GOEP_L2CAP_PSM, UINT_DESC_TYPE, (uint32_t)2, temp);
796   }
797 
798   /* Make the service browseable */
799   status &= get_legacy_stack_sdp_api()->handle.SDP_AddUuidSequence(
800           sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
801 
802   if (!status) {
803     if (!get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(sdp_handle)) {
804       log::error("Unable to remove handle 0x{:08x}", sdp_handle);
805     }
806     sdp_handle = 0;
807     log::error("FAILED");
808   } else {
809     /* set class of device */
810     cod.service = BTM_COD_SERVICE_OBJ_TRANSFER;
811     utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
812 
813     bta_sys_add_uuid(service); /* UUID_SERVCLASS_OBEX_OBJECT_PUSH */
814     log::verbose("SDP Registered (handle 0x{:08x})", sdp_handle);
815   }
816   return sdp_handle;
817 }
818 
819 // Create a Sim Access Profile SDP record based on information stored in a
820 // bluetooth_sdp_sap_record.
821 static int add_saps_sdp(const bluetooth_sdp_sap_record* rec) {
822   tSDP_PROTOCOL_ELEM protoList[2];
823   uint16_t services[2];
824   uint16_t browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
825   bool status = true;
826   uint32_t sdp_handle = 0;
827 
828   sdp_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
829   if (sdp_handle == 0) {
830     log::error("Unable to register SAPS Service");
831     return sdp_handle;
832   }
833 
834   services[0] = UUID_SERVCLASS_SAP;
835   services[1] = UUID_SERVCLASS_GENERIC_TELEPHONY;
836 
837   // add service class
838   status &= get_legacy_stack_sdp_api()->handle.SDP_AddServiceClassIdList(sdp_handle, 2, services);
839   memset(protoList, 0, 2 * sizeof(tSDP_PROTOCOL_ELEM));
840 
841   // add protocol list, including RFCOMM scn
842   protoList[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
843   protoList[0].num_params = 0;
844   protoList[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
845   protoList[1].num_params = 1;
846   protoList[1].params[0] = rec->hdr.rfcomm_channel_number;
847   status &= get_legacy_stack_sdp_api()->handle.SDP_AddProtocolList(sdp_handle, 2, protoList);
848 
849   // Add a name entry
850   status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
851           sdp_handle, (uint16_t)ATTR_ID_SERVICE_NAME, (uint8_t)TEXT_STR_DESC_TYPE,
852           (uint32_t)(rec->hdr.service_name_length + 1), (uint8_t*)rec->hdr.service_name);
853 
854   // Add in the Bluetooth Profile Descriptor List
855   status &= get_legacy_stack_sdp_api()->handle.SDP_AddProfileDescriptorList(
856           sdp_handle, UUID_SERVCLASS_SAP, rec->hdr.profile_version);
857 
858   // Make the service browseable
859   status &= get_legacy_stack_sdp_api()->handle.SDP_AddUuidSequence(
860           sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
861 
862   if (!status) {
863     if (!get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(sdp_handle)) {
864       log::error("Unable to remove handle 0x{:08x}", sdp_handle);
865     }
866     sdp_handle = 0;
867     log::error("FAILED deleting record");
868   } else {
869     bta_sys_add_uuid(UUID_SERVCLASS_SAP);
870     log::verbose("SDP Registered (handle 0x{:08x})", sdp_handle);
871   }
872   return sdp_handle;
873 }
874 
875 /* Create a Multi-Profile Specification SDP record based on information stored
876  * in a bluetooth_sdp_mps_record */
877 static int add_mps_sdp(const bluetooth_sdp_mps_record* rec) {
878   uint16_t service = UUID_SERVCLASS_MPS_SC;
879   uint16_t browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
880   bool status = true;
881   uint32_t sdp_handle = 0;
882 
883   sdp_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
884   if (sdp_handle == 0) {
885     log::error("Unable to register MPS record");
886     return sdp_handle;
887   }
888 
889   status &= get_legacy_stack_sdp_api()->handle.SDP_AddServiceClassIdList(sdp_handle, 1, &service);
890 
891   /* Add in the Bluetooth Profile Descriptor List */
892   status &= get_legacy_stack_sdp_api()->handle.SDP_AddProfileDescriptorList(
893           sdp_handle, UUID_SERVCLASS_MPS_PROFILE, rec->hdr.profile_version);
894 
895   /* Add supported scenarios MPSD */
896   status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
897           sdp_handle, ATTR_ID_MPS_SUPPORTED_SCENARIOS_MPSD, UINT_DESC_TYPE, (uint32_t)8,
898           (uint8_t*)&rec->supported_scenarios_mpsd);
899   /* Add supported scenarios MPMD */
900   status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
901           sdp_handle, ATTR_ID_MPS_SUPPORTED_SCENARIOS_MPMD, UINT_DESC_TYPE, (uint32_t)8,
902           (uint8_t*)&rec->supported_scenarios_mpmd);
903   /* Add supported dependencies */
904   status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
905           sdp_handle, ATTR_ID_MPS_SUPPORTED_DEPENDENCIES, UINT_DESC_TYPE, (uint32_t)2,
906           (uint8_t*)&rec->supported_dependencies);
907 
908   /* Make the service browseable */
909   status &= get_legacy_stack_sdp_api()->handle.SDP_AddUuidSequence(
910           sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
911 
912   if (!status) {
913     if (!get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(sdp_handle)) {
914       log::warn("Unable to delete SDP record handle:{}", sdp_handle);
915     }
916     sdp_handle = 0;
917     log::error("FAILED");
918     return sdp_handle;
919   }
920   bta_sys_add_uuid(service); /* UUID_SERVCLASS_MPS_SC */
921   log::verbose("SDP Registered (handle 0x{:08x})", sdp_handle);
922   return sdp_handle;
923 }
924