• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright 2014 The Android Open Source Project
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  *  This file contains action functions for SDP search.
21  ******************************************************************************/
22 
23 #include <base/functional/bind.h>
24 #include <base/functional/callback.h>
25 #include <bluetooth/log.h>
26 #include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h>
27 #include <hardware/bt_sdp.h>
28 
29 #include <cstdint>
30 
31 #include "bta/include/bta_sdp_api.h"
32 #include "bta/sdp/bta_sdp_int.h"
33 #include "btif/include/btif_profile_storage.h"
34 #include "btif/include/btif_sock_sdp.h"
35 #include "main/shim/metrics_api.h"
36 #include "stack/include/bt_uuid16.h"
37 #include "stack/include/sdp_api.h"
38 #include "stack/include/sdpdefs.h"
39 #include "types/bluetooth/uuid.h"
40 #include "types/raw_address.h"
41 
42 using namespace bluetooth::legacy::stack::sdp;
43 using namespace bluetooth;
44 
bta_create_mns_sdp_record(bluetooth_sdp_record * record,tSDP_DISC_REC * p_rec)45 static void bta_create_mns_sdp_record(bluetooth_sdp_record* record, tSDP_DISC_REC* p_rec) {
46   tSDP_DISC_ATTR* p_attr;
47   tSDP_PROTOCOL_ELEM pe;
48   uint16_t pversion = 0;
49   record->mns.hdr.type = SDP_TYPE_MAP_MNS;
50   record->mns.hdr.service_name_length = 0;
51   record->mns.hdr.service_name = NULL;
52   record->mns.hdr.rfcomm_channel_number = 0;
53   record->mns.hdr.l2cap_psm = -1;
54   record->mns.hdr.profile_version = 0;
55   record->mns.supported_features = 0x0000001F;  // default value if not found
56 
57   p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
58           p_rec, ATTR_ID_MAP_SUPPORTED_FEATURES);
59   if (p_attr != NULL) {
60     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
61         SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 4) {
62       record->mns.supported_features = p_attr->attr_value.v.u32;
63     } else {
64       log::error("ATTR_ID_MAP_SUPPORTED_FEATURES attr type or size wrong!!");
65     }
66   } else {
67     log::error("ATTR_ID_MAP_SUPPORTED_FEATURES attr not found!!");
68   }
69 
70   p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
71   if (p_attr != NULL) {
72     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == TEXT_STR_DESC_TYPE) {
73       record->mns.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
74       record->mns.hdr.service_name = (char*)p_attr->attr_value.v.array;
75     } else {
76       log::error("ATTR_ID_SERVICE_NAME attr type not TEXT_STR_DESC_TYPE!!");
77     }
78   } else {
79     log::error("ATTR_ID_SERVICE_NAME attr not found!!");
80   }
81 
82   if (get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
83               p_rec, UUID_SERVCLASS_MAP_PROFILE, &pversion)) {
84     record->mns.hdr.profile_version = pversion;
85   }
86 
87   if (get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM,
88                                                                        &pe)) {
89     record->mns.hdr.rfcomm_channel_number = pe.params[0];
90   }
91 
92   p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM);
93   if (p_attr != NULL) {
94     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
95         SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) {
96       record->mns.hdr.l2cap_psm = p_attr->attr_value.v.u16;
97     } else {
98       log::error("ATTR_ID_GOEP_L2CAP_PSM attr type or len wrong!!");
99     }
100   } else {
101     log::error("ATTR_ID_GOEP_L2CAP_PSM attr not found!!");
102   }
103 }
104 
bta_create_mas_sdp_record(bluetooth_sdp_record * record,tSDP_DISC_REC * p_rec)105 static void bta_create_mas_sdp_record(bluetooth_sdp_record* record, tSDP_DISC_REC* p_rec) {
106   tSDP_DISC_ATTR* p_attr;
107   tSDP_PROTOCOL_ELEM pe;
108   uint16_t pversion = -1;
109 
110   record->mas.hdr.type = SDP_TYPE_MAP_MAS;
111   record->mas.hdr.service_name_length = 0;
112   record->mas.hdr.service_name = NULL;
113   record->mas.hdr.rfcomm_channel_number = 0;
114   record->mas.hdr.l2cap_psm = -1;
115   record->mas.hdr.profile_version = 0;
116   record->mas.mas_instance_id = 0;
117   record->mas.supported_features = 0x0000001F;
118   record->mas.supported_message_types = 0;
119 
120   p_attr =
121           get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(p_rec, ATTR_ID_MAS_INSTANCE_ID);
122   if (p_attr != NULL) {
123     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
124         SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 1) {
125       record->mas.mas_instance_id = p_attr->attr_value.v.u8;
126     } else {
127       log::error("ATTR_ID_MAS_INSTANCE_ID attr type or len wrong!!");
128     }
129   } else {
130     log::error("ATTR_ID_MAS_INSTANCE_ID attr not found!!");
131   }
132 
133   p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(p_rec,
134                                                                      ATTR_ID_SUPPORTED_MSG_TYPE);
135   if (p_attr != NULL) {
136     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
137         SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 1) {
138       record->mas.supported_message_types = p_attr->attr_value.v.u8;
139     } else {
140       log::error("ATTR_ID_SUPPORTED_MSG_TYPE attr type or len wrong!!");
141     }
142   } else {
143     log::error("ATTR_ID_SUPPORTED_MSG_TYPE attr not found!!");
144   }
145 
146   p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
147           p_rec, ATTR_ID_MAP_SUPPORTED_FEATURES);
148   if (p_attr != NULL) {
149     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
150         SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 4) {
151       record->mas.supported_features = p_attr->attr_value.v.u32;
152     } else {
153       log::error("ATTR_ID_MAP_SUPPORTED_FEATURES attr type or len wrong!!");
154     }
155   } else {
156     log::error("ATTR_ID_MAP_SUPPORTED_FEATURES attr not found!!");
157   }
158 
159   p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
160   if (p_attr != NULL) {
161     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == TEXT_STR_DESC_TYPE) {
162       record->mas.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
163       record->mas.hdr.service_name = (char*)p_attr->attr_value.v.array;
164     } else {
165       log::error("ATTR_ID_SERVICE_NAME attr type wrong!!");
166     }
167   } else {
168     log::error("ATTR_ID_SERVICE_NAME attr not found!!");
169   }
170 
171   if (get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
172               p_rec, UUID_SERVCLASS_MAP_PROFILE, &pversion)) {
173     record->mas.hdr.profile_version = pversion;
174   }
175 
176   if (get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM,
177                                                                        &pe)) {
178     record->mas.hdr.rfcomm_channel_number = pe.params[0];
179   }
180 
181   p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM);
182   if (p_attr != NULL) {
183     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
184         SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) {
185       record->mas.hdr.l2cap_psm = p_attr->attr_value.v.u16;
186     } else {
187       log::error("ATTR_ID_GOEP_L2CAP_PSM attr type or len wrong!!");
188     }
189   } else {
190     log::error("ATTR_ID_GOEP_L2CAP_PSM attr not found!!");
191   }
192 }
193 
bta_create_pse_sdp_record(bluetooth_sdp_record * record,tSDP_DISC_REC * p_rec)194 static void bta_create_pse_sdp_record(bluetooth_sdp_record* record, tSDP_DISC_REC* p_rec) {
195   tSDP_DISC_ATTR* p_attr;
196   uint16_t pversion;
197   tSDP_PROTOCOL_ELEM pe;
198 
199   record->pse.hdr.type = SDP_TYPE_PBAP_PSE;
200   record->pse.hdr.service_name_length = 0;
201   record->pse.hdr.service_name = NULL;
202   record->pse.hdr.rfcomm_channel_number = 0;
203   record->pse.hdr.l2cap_psm = -1;
204   record->pse.hdr.profile_version = 0;
205   record->pse.supported_features = 0x00000003;
206   record->pse.supported_repositories = 0;
207 
208   p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
209           p_rec, ATTR_ID_SUPPORTED_REPOSITORIES);
210   if (p_attr != NULL) {
211     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
212         SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 1) {
213       record->pse.supported_repositories = p_attr->attr_value.v.u8;
214     } else {
215       log::error("ATTR_ID_SUPPORTED_REPOSITORIES attr type or len wrong!!");
216     }
217   } else {
218     log::error("ATTR_ID_SUPPORTED_REPOSITORIES attr not found!!");
219   }
220   p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
221           p_rec, ATTR_ID_PBAP_SUPPORTED_FEATURES);
222   if (p_attr != NULL) {
223     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
224         SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 4) {
225       record->pse.supported_features = p_attr->attr_value.v.u32;
226     } else {
227       log::error("ATTR_ID_PBAP_SUPPORTED_FEATURES attr type or len wrong!!");
228     }
229   } else {
230     log::error("ATTR_ID_PBAP_SUPPORTED_FEATURES attr not found!!");
231   }
232 
233   p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
234   if (p_attr != NULL) {
235     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == TEXT_STR_DESC_TYPE) {
236       record->pse.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
237       // TODO: validate the lifetime of this value
238       record->pse.hdr.service_name = (char*)p_attr->attr_value.v.array;
239     } else {
240       log::error("ATTR_ID_SERVICE_NAME attr type NOT string!!");
241     }
242   } else {
243     log::error("ATTR_ID_SERVICE_NAME attr not found!!");
244   }
245 
246   if (get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
247               p_rec, UUID_SERVCLASS_PHONE_ACCESS, &pversion)) {
248     record->pse.hdr.profile_version = pversion;
249   }
250 
251   if (get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM,
252                                                                        &pe)) {
253     record->pse.hdr.rfcomm_channel_number = pe.params[0];
254   }
255 
256   p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM);
257   if (p_attr != NULL) {
258     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
259         SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) {
260       record->pse.hdr.l2cap_psm = p_attr->attr_value.v.u16;
261     } else {
262       log::error("ATTR_ID_GOEP_L2CAP_PSM attr type or len wrong!!");
263     }
264   } else {
265     log::error("ATTR_ID_GOEP_L2CAP_PSM attr not found!!");
266   }
267 }
268 
bta_create_ops_sdp_record(bluetooth_sdp_record * record,tSDP_DISC_REC * p_rec)269 static void bta_create_ops_sdp_record(bluetooth_sdp_record* record, tSDP_DISC_REC* p_rec) {
270   tSDP_DISC_ATTR *p_attr, *p_sattr;
271   tSDP_PROTOCOL_ELEM pe;
272   uint16_t pversion = -1;
273 
274   record->ops.hdr.type = SDP_TYPE_OPP_SERVER;
275   record->ops.hdr.service_name_length = 0;
276   record->ops.hdr.service_name = NULL;
277   record->ops.hdr.rfcomm_channel_number = 0;
278   record->ops.hdr.l2cap_psm = -1;
279   record->ops.hdr.profile_version = 0;
280   record->ops.supported_formats_list_len = 0;
281 
282   p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
283   if (p_attr != NULL) {
284     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == TEXT_STR_DESC_TYPE) {
285       record->ops.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
286       record->ops.hdr.service_name = (char*)p_attr->attr_value.v.array;
287     } else {
288       log::error("ATTR_ID_SERVICE_NAME attr type NOT string!!");
289     }
290   } else {
291     log::error("ATTR_ID_SERVICE_NAME attr not found!!");
292   }
293 
294   if (get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
295               p_rec, UUID_SERVCLASS_OBEX_OBJECT_PUSH, &pversion)) {
296     record->ops.hdr.profile_version = pversion;
297   }
298 
299   if (get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM,
300                                                                        &pe)) {
301     record->ops.hdr.rfcomm_channel_number = pe.params[0];
302   }
303 
304   p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM);
305   if (p_attr != NULL) {
306     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
307         SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) {
308       record->ops.hdr.l2cap_psm = p_attr->attr_value.v.u16;
309     } else {
310       log::error("ATTR_ID_GOEP_L2CAP_PSM attr type or len wrong!!");
311     }
312   } else {
313     log::error("ATTR_ID_GOEP_L2CAP_PSM attr not found!!");
314   }
315 
316   p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
317           p_rec, ATTR_ID_SUPPORTED_FORMATS_LIST);
318   if (p_attr != NULL) {
319     /* Safety check - each entry should itself be a sequence */
320     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE) {
321       record->ops.supported_formats_list_len = 0;
322       log::error("supported_formats_list - wrong attribute length/type: 0x{:02x} - expected 0x06",
323                  p_attr->attr_len_type);
324     } else {
325       int count = 0;
326       /* 1 byte for type/length 1 byte for value */
327       record->ops.supported_formats_list_len = SDP_DISC_ATTR_LEN(p_attr->attr_len_type) / 2;
328 
329       /* Extract each value into */
330       for (p_sattr = p_attr->attr_value.v.p_sub_attr; p_sattr != NULL;
331            p_sattr = p_sattr->p_next_attr) {
332         if ((SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) == UINT_DESC_TYPE) &&
333             (SDP_DISC_ATTR_LEN(p_sattr->attr_len_type) >= 1)) {
334           if (count == sizeof(record->ops.supported_formats_list)) {
335             log::error("supported_formats_list - count overflow - too many sub attributes!!");
336             /* If you hit this, new formats have been added,
337              * update SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH */
338             break;
339           }
340           record->ops.supported_formats_list[count] = p_sattr->attr_value.v.u8;
341           count++;
342         } else {
343           log::error(
344                   "supported_formats_list - wrong sub attribute length/type: "
345                   "0x{:02x} - expected 0x80",
346                   p_sattr->attr_len_type);
347           break;
348         }
349       }
350       if (record->ops.supported_formats_list_len != count) {
351         log::warn(
352                 "supported_formats_list - Length of attribute different from the "
353                 "actual number of sub-attributes in the sequence att-length: {} - "
354                 "number of elements: {}",
355                 record->ops.supported_formats_list_len, count);
356       }
357       record->ops.supported_formats_list_len = count;
358     }
359   }
360 }
361 
bta_create_sap_sdp_record(bluetooth_sdp_record * record,tSDP_DISC_REC * p_rec)362 static void bta_create_sap_sdp_record(bluetooth_sdp_record* record, tSDP_DISC_REC* p_rec) {
363   tSDP_DISC_ATTR* p_attr;
364   tSDP_PROTOCOL_ELEM pe;
365   uint16_t pversion = -1;
366 
367   record->sap.hdr.type = SDP_TYPE_MAP_MAS;
368   record->sap.hdr.service_name_length = 0;
369   record->sap.hdr.service_name = NULL;
370   record->sap.hdr.rfcomm_channel_number = 0;
371   record->sap.hdr.l2cap_psm = -1;
372   record->sap.hdr.profile_version = 0;
373 
374   p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
375   if (p_attr != NULL) {
376     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == TEXT_STR_DESC_TYPE) {
377       record->sap.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
378       record->sap.hdr.service_name = (char*)p_attr->attr_value.v.array;
379     } else {
380       log::error("ATTR_ID_SERVICE_NAME attr type NOT string!!");
381     }
382   } else {
383     log::error("ATTR_ID_SERVICE_NAME attr not found!!");
384   }
385 
386   if (get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_SAP,
387                                                                      &pversion)) {
388     record->sap.hdr.profile_version = pversion;
389   }
390 
391   if (get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM,
392                                                                        &pe)) {
393     record->sap.hdr.rfcomm_channel_number = pe.params[0];
394   }
395 }
396 
bta_create_dip_sdp_record(bluetooth_sdp_record * record,tSDP_DISC_REC * p_rec)397 static void bta_create_dip_sdp_record(bluetooth_sdp_record* record, tSDP_DISC_REC* p_rec) {
398   tSDP_DISC_ATTR* p_attr;
399 
400   log::verbose("");
401 
402   /* hdr is redundancy in dip */
403   record->dip.hdr.type = SDP_TYPE_DIP;
404   record->dip.hdr.service_name_length = 0;
405   record->dip.hdr.service_name = nullptr;
406   record->dip.hdr.rfcomm_channel_number = 0;
407   record->dip.hdr.l2cap_psm = -1;
408   record->dip.hdr.profile_version = 0;
409 
410   p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(p_rec,
411                                                                      ATTR_ID_SPECIFICATION_ID);
412   if (p_attr != nullptr) {
413     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
414         SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) {
415       record->dip.spec_id = p_attr->attr_value.v.u16;
416     } else {
417       log::error("ATTR_ID_SPECIFICATION_ID attr type or len wrong!!");
418     }
419   } else {
420     log::error("ATTR_ID_SPECIFICATION_ID not found");
421   }
422 
423   p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(p_rec, ATTR_ID_VENDOR_ID);
424   if (p_attr != nullptr) {
425     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
426         SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) {
427       record->dip.vendor = p_attr->attr_value.v.u16;
428     } else {
429       log::error("ATTR_ID_VENDOR_ID attr type or len wrong!!");
430     }
431   } else {
432     log::error("ATTR_ID_VENDOR_ID not found");
433   }
434 
435   p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(p_rec,
436                                                                      ATTR_ID_VENDOR_ID_SOURCE);
437   if (p_attr != nullptr) {
438     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
439         SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) {
440       record->dip.vendor_id_source = p_attr->attr_value.v.u16;
441     } else {
442       log::error("ATTR_ID_VENDOR_ID_SOURCE attr type or len wrong!!");
443     }
444   } else {
445     log::error("ATTR_ID_VENDOR_ID_SOURCE not found");
446   }
447 
448   p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(p_rec, ATTR_ID_PRODUCT_ID);
449   if (p_attr != nullptr) {
450     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
451         SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) {
452       record->dip.product = p_attr->attr_value.v.u16;
453     } else {
454       log::error("ATTR_ID_PRODUCT_ID attr type or len wrong!!");
455     }
456   } else {
457     log::error("ATTR_ID_PRODUCT_ID not found");
458   }
459 
460   p_attr =
461           get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(p_rec, ATTR_ID_PRODUCT_VERSION);
462   if (p_attr != nullptr) {
463     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE &&
464         SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) {
465       record->dip.version = p_attr->attr_value.v.u16;
466     } else {
467       log::error("ATTR_ID_PRODUCT_VERSION attr type or len wrong!!");
468     }
469   } else {
470     log::error("ATTR_ID_PRODUCT_VERSION not found");
471   }
472 
473   p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(p_rec, ATTR_ID_PRIMARY_RECORD);
474   if (p_attr != nullptr) {
475     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == BOOLEAN_DESC_TYPE &&
476         SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 1) {
477       record->dip.primary_record = !(!p_attr->attr_value.v.u8);
478     } else {
479       log::error("ATTR_ID_PRIMARY_RECORD attr type or len wrong!!");
480     }
481   } else {
482     log::error("ATTR_ID_PRIMARY_RECORD not found");
483   }
484 }
485 
bta_create_raw_sdp_record(bluetooth_sdp_record * record,tSDP_DISC_REC * p_rec)486 static void bta_create_raw_sdp_record(bluetooth_sdp_record* record, tSDP_DISC_REC* p_rec) {
487   tSDP_DISC_ATTR* p_attr;
488   tSDP_PROTOCOL_ELEM pe;
489 
490   record->hdr.type = SDP_TYPE_RAW;
491   record->hdr.service_name_length = 0;
492   record->hdr.service_name = NULL;
493   record->hdr.rfcomm_channel_number = -1;
494   record->hdr.l2cap_psm = -1;
495   record->hdr.profile_version = -1;
496 
497   /* Try to extract a service name */
498   p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
499   if (p_attr != NULL) {
500     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == TEXT_STR_DESC_TYPE) {
501       record->pse.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
502       record->pse.hdr.service_name = (char*)p_attr->attr_value.v.array;
503     } else {
504       log::error("ATTR_ID_SERVICE_NAME attr type NOT string!!");
505     }
506   } else {
507     log::error("ATTR_ID_SERVICE_NAME attr not found!!");
508   }
509 
510   /* Try to extract an RFCOMM channel */
511   if (get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM,
512                                                                        &pe)) {
513     record->pse.hdr.rfcomm_channel_number = pe.params[0];
514   }
515   record->hdr.user1_ptr_len = p_bta_sdp_cfg->p_sdp_db->raw_size;
516   record->hdr.user1_ptr = p_bta_sdp_cfg->p_sdp_db->raw_data;
517 }
518 
519 /** Callback from btm after search is completed */
bta_sdp_search_cback(Uuid uuid,const RawAddress &,tSDP_RESULT result)520 static void bta_sdp_search_cback(Uuid uuid, const RawAddress& /* bd_addr */, tSDP_RESULT result) {
521   tBTA_SDP_STATUS status = BTA_SDP_FAILURE;
522   int count = 0;
523   log::verbose("res: 0x{:x}", result);
524 
525   bta_sdp_cb.sdp_active = false;
526 
527   if (bta_sdp_cb.p_dm_cback == NULL) {
528     return;
529   }
530 
531   tBTA_SDP_SEARCH_COMP evt_data;
532   memset(&evt_data, 0, sizeof(evt_data));
533   evt_data.remote_addr = bta_sdp_cb.remote_addr;
534   evt_data.uuid = uuid;
535 
536   if (result == tSDP_STATUS::SDP_SUCCESS || result == tSDP_STATUS::SDP_DB_FULL) {
537     tSDP_DISC_REC* p_rec = NULL;
538     do {
539       p_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceUUIDInDb(p_bta_sdp_cfg->p_sdp_db, uuid,
540                                                                      p_rec);
541       /* generate the matching record data pointer */
542       if (!p_rec) {
543         log::verbose("UUID not found");
544         continue;
545       }
546 
547       status = BTA_SDP_SUCCESS;
548       if (uuid == UUID_MAP_MAS) {
549         log::verbose("found MAP (MAS) uuid");
550         bta_create_mas_sdp_record(&evt_data.records[count], p_rec);
551       } else if (uuid == UUID_MAP_MNS) {
552         log::verbose("found MAP (MNS) uuid");
553         bta_create_mns_sdp_record(&evt_data.records[count], p_rec);
554       } else if (uuid == UUID_PBAP_PSE) {
555         log::verbose("found PBAP (PSE) uuid");
556         bta_create_pse_sdp_record(&evt_data.records[count], p_rec);
557       } else if (uuid == UUID_OBEX_OBJECT_PUSH) {
558         log::verbose("found Object Push Server (OPS) uuid");
559         bta_create_ops_sdp_record(&evt_data.records[count], p_rec);
560       } else if (uuid == UUID_SAP) {
561         log::verbose("found SAP uuid");
562         bta_create_sap_sdp_record(&evt_data.records[count], p_rec);
563       } else if (uuid == UUID_PBAP_PCE) {
564         log::verbose("found PBAP (PCE) uuid");
565         if (p_rec != NULL) {
566           uint16_t peer_pce_version = 0;
567 
568           if (!get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
569                       p_rec, UUID_SERVCLASS_PHONE_ACCESS, &peer_pce_version)) {
570             log::warn("Unable to find PBAP profile version in SDP record");
571           }
572           if (peer_pce_version != 0) {
573             btif_storage_set_pce_profile_version(p_rec->remote_bd_addr, peer_pce_version);
574           }
575         } else {
576           log::verbose("PCE Record is null");
577         }
578       } else if (uuid == UUID_DIP) {
579         log::verbose("found DIP uuid");
580         bta_create_dip_sdp_record(&evt_data.records[count], p_rec);
581       } else {
582         /* we do not have specific structure for this */
583         log::verbose("profile not identified. using raw data");
584         bta_create_raw_sdp_record(&evt_data.records[count], p_rec);
585         p_rec = NULL;  // Terminate loop
586         /* For raw, we only extract the first entry, and then return the
587            entire raw data chunk.
588            TODO: Find a way to split the raw data into record chunks, and
589            iterate to extract generic data for each chunk - e.g. rfcomm
590            channel and service name. */
591       }
592       count++;
593     } while (p_rec != NULL && count < BTA_SDP_MAX_RECORDS);
594 
595     evt_data.record_count = count;
596   }
597   evt_data.status = status;
598 
599   tBTA_SDP bta_sdp;
600   bta_sdp.sdp_search_comp = evt_data;
601   bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, &bta_sdp, (void*)&uuid);
602   bluetooth::shim::CountCounterMetrics(android::bluetooth::CodePathCounterKeyEnum::SDP_SUCCESS, 1);
603 }
604 
605 /*******************************************************************************
606  *
607  * Function     bta_sdp_enable
608  *
609  * Description  Initializes the SDP I/F
610  *
611  * Returns      void
612  *
613  ******************************************************************************/
bta_sdp_enable(tBTA_SDP_DM_CBACK * p_cback)614 void bta_sdp_enable(tBTA_SDP_DM_CBACK* p_cback) {
615   log::verbose("in, sdp_active:{}", bta_sdp_cb.sdp_active);
616   tBTA_SDP_STATUS status = BTA_SDP_SUCCESS;
617   bta_sdp_cb.p_dm_cback = p_cback;
618   tBTA_SDP bta_sdp;
619   bta_sdp.status = status;
620   bta_sdp_cb.p_dm_cback(BTA_SDP_ENABLE_EVT, &bta_sdp, NULL);
621 }
622 
623 /*******************************************************************************
624  *
625  * Function     bta_sdp_search
626  *
627  * Description  Discovers all sdp records for an uuid on remote device
628  *
629  * Returns      void
630  *
631  ******************************************************************************/
bta_sdp_search(const RawAddress bd_addr,const bluetooth::Uuid uuid)632 void bta_sdp_search(const RawAddress bd_addr, const bluetooth::Uuid uuid) {
633   tBTA_SDP_STATUS status = BTA_SDP_FAILURE;
634 
635   log::verbose("in, sdp_active:{}", bta_sdp_cb.sdp_active);
636 
637   if (bta_sdp_cb.sdp_active) {
638     /* SDP is still in progress */
639     status = BTA_SDP_BUSY;
640     if (bta_sdp_cb.p_dm_cback) {
641       tBTA_SDP_SEARCH_COMP result;
642       memset(&result, 0, sizeof(result));
643       result.uuid = uuid;
644       result.remote_addr = bd_addr;
645       result.status = status;
646       tBTA_SDP bta_sdp;
647       bta_sdp.sdp_search_comp = result;
648       bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, &bta_sdp, NULL);
649     }
650     return;
651   }
652 
653   bta_sdp_cb.sdp_active = true;
654   bta_sdp_cb.remote_addr = bd_addr;
655 
656   /* initialize the search for the uuid */
657   log::verbose("init discovery with UUID: {}", uuid.ToString());
658   if (!get_legacy_stack_sdp_api()->service.SDP_InitDiscoveryDb(
659               p_bta_sdp_cfg->p_sdp_db, p_bta_sdp_cfg->sdp_db_size, 1, &uuid, 0, NULL)) {
660     log::warn("Unable to initialize SDP service search db peer:{}", bd_addr);
661   }
662 
663   if (!get_legacy_stack_sdp_api()->service.SDP_ServiceSearchAttributeRequest2(
664               bd_addr, p_bta_sdp_cfg->p_sdp_db, base::BindRepeating(bta_sdp_search_cback, uuid))) {
665     log::warn("Unable to start SDP service search attribute request peer:{}", bd_addr);
666     bta_sdp_cb.sdp_active = false;
667 
668     /* failed to start SDP. report the failure right away */
669     if (bta_sdp_cb.p_dm_cback) {
670       tBTA_SDP_SEARCH_COMP result;
671       memset(&result, 0, sizeof(result));
672       result.uuid = uuid;
673       result.remote_addr = bd_addr;
674       result.status = status;
675       tBTA_SDP bta_sdp;
676       bta_sdp.sdp_search_comp = result;
677       bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, &bta_sdp, NULL);
678       bluetooth::shim::CountCounterMetrics(android::bluetooth::CodePathCounterKeyEnum::SDP_FAILURE,
679                                            1);
680     }
681   }
682   /*
683   else report the result when the cback is called
684   */
685 }
686 
687 /*******************************************************************************
688  *
689  * Function     bta_sdp_record
690  *
691  * Description  Discovers all sdp records for an uuid on remote device
692  *
693  * Returns      void
694  *
695  ******************************************************************************/
bta_sdp_create_record(void * user_data)696 void bta_sdp_create_record(void* user_data) {
697   if (bta_sdp_cb.p_dm_cback) {
698     bta_sdp_cb.p_dm_cback(BTA_SDP_CREATE_RECORD_USER_EVT, NULL, user_data);
699   }
700 }
701 
702 /*******************************************************************************
703  *
704  * Function     bta_sdp_create_record
705  *
706  * Description  Discovers all sdp records for an uuid on remote device
707  *
708  * Returns      void
709  *
710  ******************************************************************************/
bta_sdp_remove_record(void * user_data)711 void bta_sdp_remove_record(void* user_data) {
712   if (bta_sdp_cb.p_dm_cback) {
713     bta_sdp_cb.p_dm_cback(BTA_SDP_REMOVE_RECORD_USER_EVT, NULL, user_data);
714   }
715 }
716 
717 namespace bluetooth {
718 namespace testing {
719 
bta_create_dip_sdp_record(bluetooth_sdp_record * record,tSDP_DISC_REC * p_rec)720 void bta_create_dip_sdp_record(bluetooth_sdp_record* record, tSDP_DISC_REC* p_rec) {
721   ::bta_create_dip_sdp_record(record, p_rec);
722 }
723 
bta_sdp_search_cback(Uuid uuid,const RawAddress & bd_addr,tSDP_RESULT result)724 void bta_sdp_search_cback(Uuid uuid, const RawAddress& bd_addr, tSDP_RESULT result) {
725   ::bta_sdp_search_cback(uuid, bd_addr, result);
726 }
727 
728 }  // namespace testing
729 }  // namespace bluetooth
730