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