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