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