• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "bt_bta_dm"
18 
19 #include <base/functional/bind.h>
20 #include <bluetooth/log.h>
21 #include <com_android_bluetooth_flags.h>
22 
23 #include <string>
24 #include <vector>
25 
26 #include "bta/dm/bta_dm_disc.h"
27 #include "bta/dm/bta_dm_disc_int.h"
28 #include "bta/include/bta_sdp_api.h"
29 #include "btif/include/btif_config.h"
30 #include "com_android_bluetooth_flags.h"
31 #include "common/strings.h"
32 #include "internal_include/bt_target.h"
33 #include "stack/include/bt_uuid16.h"
34 #include "stack/include/btm_log_history.h"
35 #include "stack/include/hidh_api.h"
36 #include "stack/include/main_thread.h"
37 #include "stack/include/sdp_status.h"
38 #include "stack/sdp/sdpint.h"  // is_sdp_pbap_pce_disabled
39 #include "storage/config_keys.h"
40 #include "types/raw_address.h"
41 
42 #ifdef TARGET_FLOSS
43 #include "stack/include/srvc_api.h"
44 #endif
45 
46 using bluetooth::Uuid;
47 using namespace bluetooth::legacy::stack::sdp;
48 using namespace bluetooth;
49 
50 const uint16_t bta_service_id_to_uuid_lkup_tbl[BTA_MAX_SERVICE_ID] = {
51         UUID_SERVCLASS_PNP_INFORMATION,       /* Reserved */
52         UUID_SERVCLASS_SERIAL_PORT,           /* BTA_SPP_SERVICE_ID */
53         UUID_SERVCLASS_DIALUP_NETWORKING,     /* BTA_DUN_SERVICE_ID */
54         UUID_SERVCLASS_AUDIO_SOURCE,          /* BTA_A2DP_SOURCE_SERVICE_ID */
55         UUID_SERVCLASS_LAN_ACCESS_USING_PPP,  /* BTA_LAP_SERVICE_ID */
56         UUID_SERVCLASS_HEADSET,               /* BTA_HSP_HS_SERVICE_ID */
57         UUID_SERVCLASS_HF_HANDSFREE,          /* BTA_HFP_HS_SERVICE_ID */
58         UUID_SERVCLASS_OBEX_OBJECT_PUSH,      /* BTA_OPP_SERVICE_ID */
59         UUID_SERVCLASS_OBEX_FILE_TRANSFER,    /* BTA_FTP_SERVICE_ID */
60         UUID_SERVCLASS_CORDLESS_TELEPHONY,    /* BTA_CTP_SERVICE_ID */
61         UUID_SERVCLASS_INTERCOM,              /* BTA_ICP_SERVICE_ID */
62         UUID_SERVCLASS_IRMC_SYNC,             /* BTA_SYNC_SERVICE_ID */
63         UUID_SERVCLASS_DIRECT_PRINTING,       /* BTA_BPP_SERVICE_ID */
64         UUID_SERVCLASS_IMAGING_RESPONDER,     /* BTA_BIP_SERVICE_ID */
65         UUID_SERVCLASS_PANU,                  /* BTA_PANU_SERVICE_ID */
66         UUID_SERVCLASS_NAP,                   /* BTA_NAP_SERVICE_ID */
67         UUID_SERVCLASS_GN,                    /* BTA_GN_SERVICE_ID */
68         UUID_SERVCLASS_SAP,                   /* BTA_SAP_SERVICE_ID */
69         UUID_SERVCLASS_AUDIO_SINK,            /* BTA_A2DP_SERVICE_ID */
70         UUID_SERVCLASS_AV_REMOTE_CONTROL,     /* BTA_AVRCP_SERVICE_ID */
71         UUID_SERVCLASS_HUMAN_INTERFACE,       /* BTA_HID_SERVICE_ID */
72         UUID_SERVCLASS_VIDEO_SINK,            /* BTA_VDP_SERVICE_ID */
73         UUID_SERVCLASS_PBAP_PSE,              /* BTA_PBAP_SERVICE_ID */
74         UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY, /* BTA_HSP_SERVICE_ID */
75         UUID_SERVCLASS_AG_HANDSFREE,          /* BTA_HFP_SERVICE_ID */
76         UUID_SERVCLASS_MESSAGE_ACCESS,        /* BTA_MAP_SERVICE_ID */
77         UUID_SERVCLASS_MESSAGE_NOTIFICATION,  /* BTA_MN_SERVICE_ID */
78         UUID_SERVCLASS_HDP_PROFILE,           /* BTA_HDP_SERVICE_ID */
79         UUID_SERVCLASS_PBAP_PCE,              /* BTA_PCE_SERVICE_ID */
80         UUID_PROTOCOL_ATT                     /* BTA_GATT_SERVICE_ID */
81 };
82 
83 namespace {
84 constexpr char kBtmLogTag[] = "SDP";
85 }
86 
store_avrcp_profile_feature(tSDP_DISC_REC * sdp_rec)87 static void store_avrcp_profile_feature(tSDP_DISC_REC* sdp_rec) {
88   tSDP_DISC_ATTR* p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
89           sdp_rec, ATTR_ID_SUPPORTED_FEATURES);
90   if (p_attr == NULL) {
91     return;
92   }
93 
94   uint16_t avrcp_features = p_attr->attr_value.v.u16;
95   if (avrcp_features == 0) {
96     return;
97   }
98 
99   if (btif_config_set_bin(sdp_rec->remote_bd_addr.ToString().c_str(),
100                           BTIF_STORAGE_KEY_AV_REM_CTRL_FEATURES, (const uint8_t*)&avrcp_features,
101                           sizeof(avrcp_features))) {
102     log::info("Saving avrcp_features: 0x{:x}", avrcp_features);
103   } else {
104     log::info("Failed to store avrcp_features 0x{:x} for {}", avrcp_features,
105               sdp_rec->remote_bd_addr);
106   }
107 }
108 
bta_dm_store_audio_profiles_version(tSDP_DISCOVERY_DB * p_sdp_db)109 static void bta_dm_store_audio_profiles_version(tSDP_DISCOVERY_DB* p_sdp_db) {
110   struct AudioProfile {
111     const uint16_t servclass_uuid;
112     const uint16_t btprofile_uuid;
113     const char* profile_key;
114     void (*store_audio_profile_feature)(tSDP_DISC_REC*);
115   };
116 
117   std::array<AudioProfile, 1> audio_profiles = {{
118           {
119                   .servclass_uuid = UUID_SERVCLASS_AV_REMOTE_CONTROL,
120                   .btprofile_uuid = UUID_SERVCLASS_AV_REMOTE_CONTROL,
121                   .profile_key = BTIF_STORAGE_KEY_AVRCP_CONTROLLER_VERSION,
122                   .store_audio_profile_feature = store_avrcp_profile_feature,
123           },
124   }};
125 
126   for (const auto& audio_profile : audio_profiles) {
127     tSDP_DISC_REC* sdp_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
128             p_sdp_db, audio_profile.servclass_uuid, NULL);
129     if (sdp_rec == NULL) {
130       continue;
131     }
132 
133     if (get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
134                 sdp_rec, ATTR_ID_BT_PROFILE_DESC_LIST) == NULL) {
135       continue;
136     }
137 
138     uint16_t profile_version = 0;
139     /* get profile version (if failure, version parameter is not updated) */
140     if (!get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
141                 sdp_rec, audio_profile.btprofile_uuid, &profile_version)) {
142       log::warn("Unable to find SDP profile version in record peer:{}", sdp_rec->remote_bd_addr);
143     }
144     if (profile_version != 0) {
145       if (btif_config_set_bin(sdp_rec->remote_bd_addr.ToString().c_str(), audio_profile.profile_key,
146                               (const uint8_t*)&profile_version, sizeof(profile_version))) {
147       } else {
148         log::info("Failed to store peer profile version for {}", sdp_rec->remote_bd_addr);
149       }
150     }
151     audio_profile.store_audio_profile_feature(sdp_rec);
152   }
153 }
154 
155 /* Process the discovery result from sdp */
bta_dm_sdp_result(tSDP_STATUS sdp_result,tBTA_DM_SDP_STATE * sdp_state)156 void bta_dm_sdp_result(tSDP_STATUS sdp_result, tBTA_DM_SDP_STATE* sdp_state) {
157   tSDP_DISC_REC* p_sdp_rec = NULL;
158   bool scn_found = false;
159   uint16_t service = 0xFFFF;
160   tSDP_PROTOCOL_ELEM pe;
161 
162   std::vector<Uuid> uuid_list;
163   tSDP_DISCOVERY_DB* p_sdp_db = (tSDP_DISCOVERY_DB*)sdp_state->sdp_db_buffer;
164 
165   if ((sdp_result == tSDP_STATUS::SDP_SUCCESS) || (sdp_result == tSDP_STATUS::SDP_NO_RECS_MATCH) ||
166       (sdp_result == tSDP_STATUS::SDP_DB_FULL)) {
167     log::verbose("sdp_result::0x{:x}", sdp_result);
168     std::vector<Uuid> gatt_uuids;
169     do {
170       p_sdp_rec = NULL;
171       if (sdp_state->service_index == (BTA_USER_SERVICE_ID + 1)) {
172         if (p_sdp_rec && get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec(
173                                  p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
174           sdp_state->peer_scn = (uint8_t)pe.params[0];
175           scn_found = true;
176         }
177       } else {
178         service = bta_service_id_to_uuid_lkup_tbl[sdp_state->service_index - 1];
179         p_sdp_rec =
180                 get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(p_sdp_db, service, p_sdp_rec);
181       }
182       /* finished with BR/EDR services, now we check the result for GATT based
183        * service UUID */
184       if (sdp_state->service_index == BTA_MAX_SERVICE_ID) {
185         /* all GATT based services */
186         do {
187           /* find a service record, report it */
188           p_sdp_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(p_sdp_db, 0, p_sdp_rec);
189           if (p_sdp_rec) {
190             Uuid service_uuid;
191             if (get_legacy_stack_sdp_api()->record.SDP_FindServiceUUIDInRec(p_sdp_rec,
192                                                                             &service_uuid)) {
193               gatt_uuids.push_back(service_uuid);
194             }
195           }
196         } while (p_sdp_rec);
197 
198         if (!gatt_uuids.empty()) {
199           log::info("GATT services discovered using SDP");
200         }
201       } else {
202         if (p_sdp_rec != NULL && service != UUID_SERVCLASS_PNP_INFORMATION) {
203           sdp_state->services_found |=
204                   (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(sdp_state->service_index - 1));
205           uint16_t tmp_svc = bta_service_id_to_uuid_lkup_tbl[sdp_state->service_index - 1];
206           /* Add to the list of UUIDs */
207           uuid_list.push_back(Uuid::From16Bit(tmp_svc));
208         }
209       }
210 
211       if (sdp_state->services_to_search == 0) {
212         sdp_state->service_index++;
213       } else { /* regular one service per search or PNP search */
214         break;
215       }
216     } while (sdp_state->service_index <= BTA_MAX_SERVICE_ID);
217 
218     log::verbose("services_found = {:04x}", sdp_state->services_found);
219 
220     /* Collect the 128-bit services here and put them into the list */
221     p_sdp_rec = NULL;
222     do {
223       /* find a service record, report it */
224       p_sdp_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb_128bit(p_sdp_db, p_sdp_rec);
225       if (p_sdp_rec) {
226         // SDP_FindServiceUUIDInRec_128bit is used only once, refactor?
227         Uuid temp_uuid;
228         if (get_legacy_stack_sdp_api()->record.SDP_FindServiceUUIDInRec_128bit(p_sdp_rec,
229                                                                                &temp_uuid)) {
230           uuid_list.push_back(temp_uuid);
231         }
232       }
233     } while (p_sdp_rec);
234 
235     if (sdp_state->services_to_search == 0) {
236       bta_dm_store_audio_profiles_version(p_sdp_db);
237     }
238 
239 #if TARGET_FLOSS
240     tSDP_DI_GET_RECORD di_record;
241     if (get_legacy_stack_sdp_api()->device_id.SDP_GetDiRecord(1, &di_record, p_sdp_db) ==
242         tSDP_STATUS::SDP_SUCCESS) {
243       bta_dm_sdp_received_di(sdp_state->bd_addr, di_record);
244     }
245 #endif
246 
247     /* if there are more services to search for */
248     if (sdp_state->services_to_search) {
249       bta_dm_sdp_find_services(sdp_state);
250       return;
251     }
252 
253     /* callbacks */
254     /* start next bd_addr if necessary */
255     BTM_LogHistory(kBtmLogTag, sdp_state->bd_addr, "Discovery completed",
256                    std::format("Result:{} services_found:0x{:x} service_index:0x{}",
257                                sdp_result_text(sdp_result), sdp_state->services_found,
258                                sdp_state->service_index));
259 
260     // Copy the raw_data to the discovery result structure
261     if (p_sdp_db != NULL && p_sdp_db->raw_used != 0 && p_sdp_db->raw_data != NULL) {
262       log::verbose("raw_data used = 0x{:x} raw_data_ptr = 0x{}", p_sdp_db->raw_used,
263                    std::format_ptr(p_sdp_db->raw_data));
264 
265       p_sdp_db->raw_data = NULL;  // no need to free this - it is a global assigned.
266       p_sdp_db->raw_used = 0;
267       p_sdp_db->raw_size = 0;
268     } else {
269       log::verbose("raw data size is 0 or raw_data is null!!");
270     }
271 
272     tBTA_STATUS result = BTA_SUCCESS;
273     // Piggy back the SCN over result field
274     if (scn_found) {
275       result = static_cast<tBTA_STATUS>(3 + sdp_state->peer_scn);
276 
277       log::verbose("Piggy back the SCN over result field  SCN={}", sdp_state->peer_scn);
278     }
279 
280     bta_dm_sdp_finished(sdp_state->bd_addr, result, uuid_list, gatt_uuids);
281   } else {
282     BTM_LogHistory(kBtmLogTag, sdp_state->bd_addr, "Discovery failed",
283                    std::format("Result:{}", sdp_result_text(sdp_result)));
284     log::error("SDP connection failed {}", sdp_status_text(sdp_result));
285 
286     /* not able to connect go to next device */
287     bta_dm_sdp_finished(sdp_state->bd_addr, BTA_FAILURE);
288   }
289 }
290 
291 /*******************************************************************************
292  *
293  * Function         bta_dm_sdp_find_services
294  *
295  * Description      Starts discovery on a device
296  *
297  * Returns          void
298  *
299  ******************************************************************************/
bta_dm_sdp_find_services(tBTA_DM_SDP_STATE * sdp_state)300 void bta_dm_sdp_find_services(tBTA_DM_SDP_STATE* sdp_state) {
301   while (sdp_state->service_index < BTA_MAX_SERVICE_ID) {
302     if (sdp_state->services_to_search &
303         (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(sdp_state->service_index))) {
304       break;
305     }
306     sdp_state->service_index++;
307   }
308 
309   /* no more services to be discovered */
310   if (sdp_state->service_index >= BTA_MAX_SERVICE_ID) {
311     log::info("SDP - no more services to discover");
312     bta_dm_sdp_finished(sdp_state->bd_addr, BTA_SUCCESS);
313     return;
314   }
315 
316   /* try to search all services by search based on L2CAP UUID */
317   log::info("services_to_search={:08x}", sdp_state->services_to_search);
318   Uuid uuid = Uuid::kEmpty;
319   if (sdp_state->services_to_search & BTA_RES_SERVICE_MASK) {
320     uuid = Uuid::From16Bit(bta_service_id_to_uuid_lkup_tbl[0]);
321     sdp_state->services_to_search &= ~BTA_RES_SERVICE_MASK;
322   } else {
323     uuid = Uuid::From16Bit(UUID_PROTOCOL_L2CAP);
324     sdp_state->services_to_search = 0;
325   }
326 
327   tSDP_DISCOVERY_DB* p_sdp_db = (tSDP_DISCOVERY_DB*)sdp_state->sdp_db_buffer;
328 
329   log::info("search UUID = {}", uuid.ToString());
330   if (!get_legacy_stack_sdp_api()->service.SDP_InitDiscoveryDb(p_sdp_db, BTA_DM_SDP_DB_SIZE, 1,
331                                                                &uuid, 0, NULL)) {
332     log::warn("Unable to initialize SDP service discovery db peer:{}", sdp_state->bd_addr);
333   }
334 
335   sdp_state->g_disc_raw_data_buf = {};
336   p_sdp_db->raw_data = sdp_state->g_disc_raw_data_buf.data();
337 
338   p_sdp_db->raw_size = MAX_DISC_RAW_DATA_BUF;
339 
340   if (!get_legacy_stack_sdp_api()->service.SDP_ServiceSearchAttributeRequest(
341               sdp_state->bd_addr, p_sdp_db, &bta_dm_sdp_callback)) {
342     /*
343      * If discovery is not successful with this device, then
344      * proceed with the next one.
345      */
346     log::warn("Unable to start SDP service search attribute request peer:{}", sdp_state->bd_addr);
347 
348     sdp_state->service_index = BTA_MAX_SERVICE_ID;
349     bta_dm_sdp_finished(sdp_state->bd_addr, BTA_SUCCESS);
350     return;
351   }
352 
353   if (uuid == Uuid::From16Bit(UUID_PROTOCOL_L2CAP)) {
354     if (!is_sdp_pbap_pce_disabled(sdp_state->bd_addr)) {
355       log::debug("SDP search for PBAP Client");
356       BTA_SdpSearch(sdp_state->bd_addr, Uuid::From16Bit(UUID_SERVCLASS_PBAP_PCE));
357     }
358   }
359   sdp_state->service_index++;
360 }
361