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