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