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