1 /*
2  * Copyright 2018 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 "avrcp"
18 
19 #include "connection_handler.h"
20 
21 #include <base/functional/bind.h>
22 #include <bluetooth/log.h>
23 #include <com_android_bluetooth_flags.h>
24 
25 #include <map>
26 #include <mutex>
27 
28 #include "avrc_defs.h"
29 #include "avrcp_message_converter.h"
30 #include "bta/include/bta_av_api.h"
31 #include "device/include/interop.h"
32 #include "internal_include/bt_target.h"
33 #include "osi/include/allocator.h"
34 #include "osi/include/properties.h"
35 #include "packet/avrcp/avrcp_packet.h"
36 #include "stack/include/bt_hdr.h"
37 #include "stack/include/bt_uuid16.h"
38 #include "types/raw_address.h"
39 
40 extern bool btif_av_peer_is_connected_sink(const RawAddress& peer_address);
41 extern bool btif_av_peer_is_connected_source(const RawAddress& peer_address);
42 extern bool btif_av_both_enable(void);
43 extern bool btif_av_src_sink_coexist_enabled(void);
44 extern bool btif_av_peer_is_source(const RawAddress& peer_address);
45 
46 namespace bluetooth {
47 namespace avrcp {
48 
49 ConnectionHandler* ConnectionHandler::instance_ = nullptr;
50 
51 // ConnectionHandler::CleanUp take the lock and calls
52 // ConnectionHandler::AcceptorControlCB with AVRC_CLOSE_IND_EVT
53 // which also takes the lock, so use a recursive_mutex.
54 std::recursive_mutex device_map_lock;
55 
Get()56 ConnectionHandler* ConnectionHandler::Get() {
57   log::assert_that(instance_ != nullptr, "assert failed: instance_ != nullptr");
58 
59   return instance_;
60 }
61 
IsAbsoluteVolumeEnabled(const RawAddress * bdaddr)62 bool IsAbsoluteVolumeEnabled(const RawAddress* bdaddr) {
63   char volume_disabled[PROPERTY_VALUE_MAX] = {0};
64   osi_property_get("persist.bluetooth.disableabsvol", volume_disabled, "false");
65   if (strncmp(volume_disabled, "true", 4) == 0) {
66     log::info("Absolute volume disabled by property");
67     return false;
68   }
69   if (interop_match_addr(INTEROP_DISABLE_ABSOLUTE_VOLUME, bdaddr)) {
70     log::info("Absolute volume disabled by IOP table");
71     return false;
72   }
73   return true;
74 }
75 
Initialize(const ConnectionCallback & callback,AvrcpInterface * avrcp,SdpInterface * sdp,VolumeInterface * vol)76 bool ConnectionHandler::Initialize(const ConnectionCallback& callback,
77                                    AvrcpInterface* avrcp, SdpInterface* sdp,
78                                    VolumeInterface* vol) {
79   log::assert_that(instance_ == nullptr, "assert failed: instance_ == nullptr");
80   log::assert_that(avrcp != nullptr, "assert failed: avrcp != nullptr");
81   log::assert_that(sdp != nullptr, "assert failed: sdp != nullptr");
82 
83   // TODO (apanicke): When transitioning to using this service, implement
84   // SDP Initialization for AVRCP Here.
85   instance_ = new ConnectionHandler();
86   instance_->connection_cb_ = callback;
87   instance_->avrc_ = avrcp;
88   instance_->sdp_ = sdp;
89   instance_->vol_ = vol;
90 
91   // Set up the AVRCP acceptor connection
92   if (!instance_->AvrcpConnect(false, RawAddress::kAny)) {
93     instance_->CleanUp();
94     return false;
95   }
96 
97   return true;
98 }
99 
CleanUp()100 bool ConnectionHandler::CleanUp() {
101   log::assert_that(instance_ != nullptr, "assert failed: instance_ != nullptr");
102 
103   // TODO (apanicke): Cleanup the SDP Entries here
104   std::lock_guard<std::recursive_mutex> lock(device_map_lock);
105   for (auto entry = instance_->device_map_.begin();
106        entry != instance_->device_map_.end();) {
107     auto curr = entry;
108     entry++;
109     curr->second->DeviceDisconnected();
110     instance_->avrc_->Close(curr->first);
111   }
112   instance_->device_map_.clear();
113   instance_->feature_map_.clear();
114 
115   instance_->weak_ptr_factory_.InvalidateWeakPtrs();
116 
117   delete instance_;
118   instance_ = nullptr;
119 
120   return true;
121 }
122 
InitForTesting(ConnectionHandler * handler)123 void ConnectionHandler::InitForTesting(ConnectionHandler* handler) {
124   log::assert_that(instance_ == nullptr, "assert failed: instance_ == nullptr");
125   instance_ = handler;
126 }
127 
ConnectDevice(const RawAddress & bdaddr)128 bool ConnectionHandler::ConnectDevice(const RawAddress& bdaddr) {
129   log::info("Attempting to connect to device {}", bdaddr);
130 
131   for (const auto& pair : device_map_) {
132     if (bdaddr == pair.second->GetAddress()) {
133       log::warn("Already connected to device with address {}", bdaddr);
134       return false;
135     }
136   }
137 
138   auto connection_lambda = [](ConnectionHandler* instance_,
139                               const RawAddress& bdaddr, uint16_t status,
140                               uint16_t version, uint16_t features) {
141     log::info("SDP Completed features=0x{:x}", features);
142     if (status != AVRC_SUCCESS || !(features & BTA_AV_FEAT_RCCT)) {
143       log::error(
144           "Failed to do SDP: status=0x{:x} features=0x{:x} supports "
145           "controller: {}",
146           status, features, features & BTA_AV_FEAT_RCCT);
147       instance_->connection_cb_.Run(std::shared_ptr<Device>());
148     }
149 
150     instance_->feature_map_[bdaddr] = features;
151     instance_->AvrcpConnect(true, bdaddr);
152     return;
153   };
154 
155   return SdpLookup(bdaddr, base::Bind(connection_lambda, this, bdaddr), false);
156 }
157 
DisconnectDevice(const RawAddress & bdaddr)158 bool ConnectionHandler::DisconnectDevice(const RawAddress& bdaddr) {
159   for (auto it = device_map_.begin(); it != device_map_.end(); it++) {
160     if (bdaddr == it->second->GetAddress()) {
161       uint8_t handle = it->first;
162       return avrc_->Close(handle) == AVRC_SUCCESS;
163     }
164   }
165 
166   return false;
167 }
168 
SetBipClientStatus(const RawAddress & bdaddr,bool connected)169 void ConnectionHandler::SetBipClientStatus(const RawAddress& bdaddr,
170                                            bool connected) {
171   for (auto it = device_map_.begin(); it != device_map_.end(); it++) {
172     if (bdaddr == it->second->GetAddress()) {
173       it->second->SetBipClientStatus(connected);
174       return;
175     }
176   }
177 }
178 
GetListOfDevices() const179 std::vector<std::shared_ptr<Device>> ConnectionHandler::GetListOfDevices()
180     const {
181   std::vector<std::shared_ptr<Device>> list;
182   std::lock_guard<std::recursive_mutex> lock(device_map_lock);
183   for (const auto& device : device_map_) {
184     list.push_back(device.second);
185   }
186   return list;
187 }
188 
SdpLookup(const RawAddress & bdaddr,SdpCallback cb,bool retry)189 bool ConnectionHandler::SdpLookup(const RawAddress& bdaddr, SdpCallback cb,
190                                   bool retry) {
191   log::info("");
192 
193   tAVRC_SDP_DB_PARAMS db_params;
194   // TODO (apanicke): This needs to be replaced with smarter memory management.
195   tSDP_DISCOVERY_DB* disc_db =
196       (tSDP_DISCOVERY_DB*)osi_malloc(BT_DEFAULT_BUFFER_SIZE);
197   uint16_t attr_list[] = {ATTR_ID_SERVICE_CLASS_ID_LIST,
198                           ATTR_ID_BT_PROFILE_DESC_LIST,
199                           ATTR_ID_SUPPORTED_FEATURES};
200 
201   db_params.db_len =
202       BT_DEFAULT_BUFFER_SIZE;  // Some magic number found in the AVRCP code
203   db_params.num_attr = sizeof(attr_list) / sizeof(attr_list[0]);
204   db_params.p_db = disc_db;
205   db_params.p_attrs = attr_list;
206 
207   return avrc_->FindService(UUID_SERVCLASS_AV_REMOTE_CONTROL, bdaddr,
208                             &db_params,
209                             base::Bind(&ConnectionHandler::SdpCb,
210                                        weak_ptr_factory_.GetWeakPtr(), bdaddr,
211                                        cb, disc_db, retry)) == AVRC_SUCCESS;
212 }
213 
AvrcpConnect(bool initiator,const RawAddress & bdaddr)214 bool ConnectionHandler::AvrcpConnect(bool initiator, const RawAddress& bdaddr) {
215   log::info("Connect to device {}", bdaddr);
216 
217   tAVRC_CONN_CB open_cb;
218   if (initiator) {
219     open_cb.ctrl_cback = base::Bind(&ConnectionHandler::InitiatorControlCb,
220                                     weak_ptr_factory_.GetWeakPtr());
221   } else {
222     open_cb.ctrl_cback = base::Bind(&ConnectionHandler::AcceptorControlCb,
223                                     weak_ptr_factory_.GetWeakPtr());
224   }
225   open_cb.msg_cback =
226       base::Bind(&ConnectionHandler::MessageCb, weak_ptr_factory_.GetWeakPtr());
227   open_cb.company_id = AVRC_CO_GOOGLE;
228   open_cb.conn = initiator ? AVRC_CONN_INT
229                            : AVRC_CONN_ACP;  // 0 if initiator, 1 if acceptor
230   // TODO (apanicke): We shouldn't need RCCT to do absolute volume. The current
231   // AVRC_API requires it though.
232   open_cb.control = BTA_AV_FEAT_RCTG | BTA_AV_FEAT_RCCT | BTA_AV_FEAT_METADATA |
233                     AVRC_CT_PASSIVE;
234 
235   uint8_t handle = 0;
236   uint16_t status = avrc_->Open(&handle, &open_cb, bdaddr);
237   log::info("handle=0x{:x} status= 0x{:x}", handle, status);
238   return status == AVRC_SUCCESS;
239 }
240 
InitiatorControlCb(uint8_t handle,uint8_t event,uint16_t result,const RawAddress * peer_addr)241 void ConnectionHandler::InitiatorControlCb(uint8_t handle, uint8_t event,
242                                            uint16_t result,
243                                            const RawAddress* peer_addr) {
244   DCHECK(!connection_cb_.is_null());
245 
246   log::info("handle=0x{:x} result=0x{:x} addr={}", handle, result,
247             peer_addr ? ADDRESS_TO_LOGGABLE_STR(*peer_addr) : "none");
248 
249   switch (event) {
250     case AVRC_OPEN_IND_EVT: {
251       log::info("Connection Opened Event");
252 
253       const auto& feature_iter = feature_map_.find(*peer_addr);
254       if (feature_iter == feature_map_.end()) {
255         log::error(
256             "Features do not exist even though SDP should have been "
257             "done first");
258         return;
259       }
260 
261       bool supports_browsing = feature_iter->second & BTA_AV_FEAT_BROWSE;
262 
263       if (supports_browsing) {
264         avrc_->OpenBrowse(handle, AVCT_INT);
265       }
266 
267       // TODO (apanicke): Implement a system to cache SDP entries. For most
268       // devices SDP is completed after the device connects AVRCP so that
269       // information isn't very useful when trying to control our
270       // capabilities. For now always use AVRCP 1.6.
271       auto&& callback = base::BindRepeating(&ConnectionHandler::SendMessage,
272                                             base::Unretained(this), handle);
273       auto&& ctrl_mtu = avrc_->GetPeerMtu(handle) - AVCT_HDR_LEN;
274       auto&& browse_mtu = avrc_->GetBrowseMtu(handle) - AVCT_HDR_LEN;
275       std::shared_ptr<Device> newDevice = std::make_shared<Device>(
276           *peer_addr, !supports_browsing, callback, ctrl_mtu, browse_mtu);
277 
278       device_map_[handle] = newDevice;
279       // TODO (apanicke): Create the device with all of the interfaces it
280       // needs. Return the new device where the service will register the
281       // interfaces it needs.
282       connection_cb_.Run(newDevice);
283 
284       if (!btif_av_src_sink_coexist_enabled() ||
285           (btif_av_src_sink_coexist_enabled() &&
286            btif_av_peer_is_connected_sink(newDevice->GetAddress()))) {
287         if (feature_iter->second & BTA_AV_FEAT_ADV_CTRL) {
288           newDevice->RegisterVolumeChanged();
289         } else if (instance_->vol_ != nullptr) {
290           instance_->vol_->DeviceConnected(newDevice->GetAddress());
291         }
292       }
293 
294     } break;
295 
296     case AVRC_CLOSE_IND_EVT: {
297       log::info("Connection Closed Event");
298 
299       if (device_map_.find(handle) == device_map_.end()) {
300         log::warn("Connection Close received from device that doesn't exist");
301         return;
302       }
303       std::lock_guard<std::recursive_mutex> lock(device_map_lock);
304       avrc_->Close(handle);
305       feature_map_.erase(device_map_[handle]->GetAddress());
306       device_map_[handle]->DeviceDisconnected();
307       device_map_.erase(handle);
308     } break;
309 
310     case AVRC_BROWSE_OPEN_IND_EVT: {
311       log::info("Browse Open Event");
312       // NOTE (apanicke): We don't need to explicitly handle this message
313       // since the AVCTP Layer will still send us browsing messages
314       // regardless. It would be useful to note this though for future
315       // compatibility issues.
316       if (device_map_.find(handle) == device_map_.end()) {
317         log::warn("Browse Opened received from device that doesn't exist");
318         return;
319       }
320 
321       auto browse_mtu = avrc_->GetBrowseMtu(handle) - AVCT_HDR_LEN;
322       device_map_[handle]->SetBrowseMtu(browse_mtu);
323     } break;
324     case AVRC_BROWSE_CLOSE_IND_EVT:
325       log::info("Browse Close Event");
326       break;
327     default:
328       log::error("Unknown AVRCP Control event");
329       break;
330   }
331 }
332 
AcceptorControlCb(uint8_t handle,uint8_t event,uint16_t result,const RawAddress * peer_addr)333 void ConnectionHandler::AcceptorControlCb(uint8_t handle, uint8_t event,
334                                           uint16_t result,
335                                           const RawAddress* peer_addr) {
336   DCHECK(!connection_cb_.is_null());
337 
338   log::info("handle=0x{:x} result=0x{:x} addr={}", handle, result,
339             peer_addr ? ADDRESS_TO_LOGGABLE_STR(*peer_addr) : "none");
340 
341   switch (event) {
342     case AVRC_OPEN_IND_EVT: {
343       log::info("Connection Opened Event");
344       if (peer_addr == NULL) {
345         return;
346       }
347       if (btif_av_src_sink_coexist_enabled() &&
348           btif_av_peer_is_connected_source(*peer_addr)) {
349         log::warn("peer is src, close new avrcp cback");
350         if (device_map_.find(handle) != device_map_.end()) {
351           std::lock_guard<std::recursive_mutex> lock(device_map_lock);
352           feature_map_.erase(device_map_[handle]->GetAddress());
353           device_map_[handle]->DeviceDisconnected();
354           device_map_.erase(handle);
355         }
356         avrc_->Close(handle);
357         AvrcpConnect(false, RawAddress::kAny);
358         return;
359       }
360       auto&& callback =
361           base::BindRepeating(&ConnectionHandler::SendMessage,
362                               weak_ptr_factory_.GetWeakPtr(), handle);
363       auto&& ctrl_mtu = avrc_->GetPeerMtu(handle) - AVCT_HDR_LEN;
364       auto&& browse_mtu = avrc_->GetBrowseMtu(handle) - AVCT_HDR_LEN;
365       std::shared_ptr<Device> newDevice = std::make_shared<Device>(
366           *peer_addr, false, callback, ctrl_mtu, browse_mtu);
367 
368       device_map_[handle] = newDevice;
369       connection_cb_.Run(newDevice);
370 
371       log::info("Performing SDP on connected device. address={}", *peer_addr);
372       auto sdp_lambda = [](ConnectionHandler* instance_, uint8_t handle,
373                            uint16_t status, uint16_t version,
374                            uint16_t features) {
375         if (instance_->device_map_.find(handle) ==
376             instance_->device_map_.end()) {
377           log::warn("No device found for handle: 0x{:x}", handle);
378           return;
379         }
380 
381         auto device = instance_->device_map_[handle];
382         instance_->feature_map_[device->GetAddress()] = features;
383 
384         // TODO (apanicke): Report to the VolumeInterface that a new Device is
385         // connected that doesn't support absolute volume.
386         if (!btif_av_src_sink_coexist_enabled() ||
387             (btif_av_src_sink_coexist_enabled() &&
388              btif_av_peer_is_connected_sink(device->GetAddress()))) {
389           if (features & BTA_AV_FEAT_ADV_CTRL) {
390             device->RegisterVolumeChanged();
391           } else if (instance_->vol_ != nullptr) {
392             instance_->vol_->DeviceConnected(device->GetAddress());
393           }
394         }
395       };
396 
397       if (SdpLookup(*peer_addr, base::Bind(sdp_lambda, this, handle), false)) {
398         avrc_->OpenBrowse(handle, AVCT_ACP);
399       } else {
400         // SDP search failed, this could be due to a collision between outgoing
401         // and incoming connection. In any case, we need to reject the current
402         // connection.
403         log::error("SDP search failed for handle: 0x{:x}, closing connection",
404                    handle);
405         DisconnectDevice(*peer_addr);
406       }
407       // Open for the next incoming connection. The handle will not be the same
408       // as this one which will be closed when the device is disconnected.
409       AvrcpConnect(false, RawAddress::kAny);
410 
411       if (com::android::bluetooth::flags::avrcp_connect_a2dp_delayed()) {
412         // Check peer audio role: src or sink and connect A2DP after 3 seconds
413         SdpLookupAudioRole(handle);
414       }
415     } break;
416 
417     case AVRC_CLOSE_IND_EVT: {
418       log::info("Connection Closed Event");
419 
420       if (device_map_.find(handle) == device_map_.end()) {
421         log::warn("Connection Close received from device that doesn't exist");
422         return;
423       }
424       {
425         std::lock_guard<std::recursive_mutex> lock(device_map_lock);
426         feature_map_.erase(device_map_[handle]->GetAddress());
427         device_map_[handle]->DeviceDisconnected();
428         device_map_.erase(handle);
429       }
430       avrc_->Close(handle);
431     } break;
432 
433     case AVRC_BROWSE_OPEN_IND_EVT: {
434       log::info("Browse Open Event");
435       // NOTE (apanicke): We don't need to explicitly handle this message
436       // since the AVCTP Layer will still send us browsing messages
437       // regardless. It would be useful to note this though for future
438       // compatibility issues.
439       if (device_map_.find(handle) == device_map_.end()) {
440         log::warn("Browse Opened received from device that doesn't exist");
441         return;
442       }
443 
444       auto browse_mtu = avrc_->GetBrowseMtu(handle) - AVCT_HDR_LEN;
445       device_map_[handle]->SetBrowseMtu(browse_mtu);
446     } break;
447     case AVRC_BROWSE_CLOSE_IND_EVT:
448       log::info("Browse Close Event");
449       break;
450     default:
451       log::error("Unknown AVRCP Control event");
452       break;
453   }
454 }
455 
MessageCb(uint8_t handle,uint8_t label,uint8_t opcode,tAVRC_MSG * p_msg)456 void ConnectionHandler::MessageCb(uint8_t handle, uint8_t label, uint8_t opcode,
457                                   tAVRC_MSG* p_msg) {
458   if (device_map_.find(handle) == device_map_.end()) {
459     log::error("Message received for unconnected device: handle=0x{:x}",
460                handle);
461     return;
462   }
463 
464   auto pkt = AvrcpMessageConverter::Parse(p_msg);
465 
466   if (opcode == AVRC_OP_BROWSE) {
467     if (btif_av_src_sink_coexist_enabled() && btif_av_both_enable()) {
468       if (p_msg->browse.hdr.ctype == AVCT_RSP) {
469         log::verbose("ignore response handle {}", (unsigned int)handle);
470         return;
471       }
472     }
473     log::verbose("Browse Message received on handle {}", (unsigned int)handle);
474     device_map_[handle]->BrowseMessageReceived(label, BrowsePacket::Parse(pkt));
475     return;
476   }
477 
478   log::verbose("Message received on handle {}", (unsigned int)handle);
479   device_map_[handle]->MessageReceived(label, Packet::Parse(pkt));
480 }
481 
SdpCb(RawAddress bdaddr,SdpCallback cb,tSDP_DISCOVERY_DB * disc_db,bool retry,uint16_t status)482 void ConnectionHandler::SdpCb(RawAddress bdaddr, SdpCallback cb,
483                               tSDP_DISCOVERY_DB* disc_db, bool retry,
484                               uint16_t status) {
485   log::verbose("SDP lookup callback received");
486 
487   if (status == SDP_CONN_FAILED && !retry) {
488     log::warn("SDP Failure retry again");
489     SdpLookup(bdaddr, cb, true);
490     return;
491   } else if (status != AVRC_SUCCESS) {
492     log::error("SDP Failure: status = {}", (unsigned int)status);
493     cb.Run(status, 0, 0);
494     osi_free(disc_db);
495     return;
496   }
497 
498   // Check the peer features
499   tSDP_DISC_REC* sdp_record = nullptr;
500   uint16_t peer_features = 0;
501   uint16_t peer_avrcp_version = 0;
502 
503   // TODO (apanicke): Replace this in favor of our own supported features.
504   sdp_record =
505       sdp_->FindServiceInDb(disc_db, UUID_SERVCLASS_AV_REMOTE_CONTROL, nullptr);
506   if (sdp_record != nullptr) {
507     log::info("Device {} supports remote control", bdaddr);
508     peer_features |= BTA_AV_FEAT_RCCT;
509 
510     if ((sdp_->FindAttributeInRec(sdp_record, ATTR_ID_BT_PROFILE_DESC_LIST)) !=
511         NULL) {
512       /* get profile version (if failure, version parameter is not updated) */
513       sdp_->FindProfileVersionInRec(
514           sdp_record, UUID_SERVCLASS_AV_REMOTE_CONTROL, &peer_avrcp_version);
515       log::verbose("Device {} peer avrcp version=0x{:x}", bdaddr,
516                    peer_avrcp_version);
517 
518       if (peer_avrcp_version >= AVRC_REV_1_3) {
519         // These are the standard features, another way to check this is to
520         // search for CAT1 on the remote device
521         log::verbose("Device {} supports metadata", bdaddr);
522         peer_features |= (BTA_AV_FEAT_VENDOR | BTA_AV_FEAT_METADATA);
523       }
524       if (peer_avrcp_version >= AVRC_REV_1_4) {
525         /* get supported categories */
526         log::verbose("Get Supported categories");
527         tSDP_DISC_ATTR* sdp_attribute =
528             sdp_->FindAttributeInRec(sdp_record, ATTR_ID_SUPPORTED_FEATURES);
529         if (sdp_attribute != NULL &&
530             SDP_DISC_ATTR_TYPE(sdp_attribute->attr_len_type) == UINT_DESC_TYPE &&
531             SDP_DISC_ATTR_LEN(sdp_attribute->attr_len_type) >= 2) {
532           log::verbose("Get Supported categories SDP ATTRIBUTES != null");
533           uint16_t categories = sdp_attribute->attr_value.v.u16;
534           if (categories & AVRC_SUPF_CT_CAT2) {
535             log::verbose("Device {} supports advanced control", bdaddr);
536             if (IsAbsoluteVolumeEnabled(&bdaddr)) {
537               peer_features |= (BTA_AV_FEAT_ADV_CTRL);
538             }
539           }
540           if (categories & AVRC_SUPF_CT_BROWSE) {
541             log::verbose("Device {} supports browsing", bdaddr);
542             peer_features |= (BTA_AV_FEAT_BROWSE);
543           }
544         }
545       }
546 
547       if (osi_property_get_bool(AVRC_DYNAMIC_AVRCP_ENABLE_PROPERTY, true)) {
548         avrc_->SaveControllerVersion(bdaddr, peer_avrcp_version);
549       }
550     }
551   }
552 
553   sdp_record = sdp_->FindServiceInDb(disc_db, UUID_SERVCLASS_AV_REM_CTRL_TARGET,
554                                      nullptr);
555   if (sdp_record != nullptr) {
556     log::verbose("Device {} supports remote control target", bdaddr);
557 
558     uint16_t peer_avrcp_target_version = 0;
559     sdp_->FindProfileVersionInRec(sdp_record, UUID_SERVCLASS_AV_REMOTE_CONTROL,
560                                   &peer_avrcp_target_version);
561     log::verbose("Device {} peer avrcp target version=0x{:x}", bdaddr,
562                  peer_avrcp_target_version);
563 
564     if ((sdp_->FindAttributeInRec(sdp_record, ATTR_ID_BT_PROFILE_DESC_LIST)) !=
565         NULL) {
566       if (peer_avrcp_target_version >= AVRC_REV_1_4) {
567         /* get supported categories */
568         log::verbose("Get Supported categories");
569         tSDP_DISC_ATTR* sdp_attribute =
570             sdp_->FindAttributeInRec(sdp_record, ATTR_ID_SUPPORTED_FEATURES);
571         if (sdp_attribute != NULL &&
572             SDP_DISC_ATTR_TYPE(sdp_attribute->attr_len_type) == UINT_DESC_TYPE &&
573             SDP_DISC_ATTR_LEN(sdp_attribute->attr_len_type) >= 2) {
574           log::verbose("Get Supported categories SDP ATTRIBUTES != null");
575           uint16_t categories = sdp_attribute->attr_value.v.u16;
576           if (categories & AVRC_SUPF_CT_CAT2) {
577             log::verbose("Device {} supports advanced control", bdaddr);
578             if (IsAbsoluteVolumeEnabled(&bdaddr)) {
579               peer_features |= (BTA_AV_FEAT_ADV_CTRL);
580             }
581           }
582         }
583       }
584     }
585   }
586 
587   osi_free(disc_db);
588 
589   cb.Run(status, peer_avrcp_version, peer_features);
590 }
591 
SendMessage(uint8_t handle,uint8_t label,bool browse,std::unique_ptr<::bluetooth::PacketBuilder> message)592 void ConnectionHandler::SendMessage(
593     uint8_t handle, uint8_t label, bool browse,
594     std::unique_ptr<::bluetooth::PacketBuilder> message) {
595   std::shared_ptr<::bluetooth::Packet> packet = VectorPacket::Make();
596   message->Serialize(packet);
597 
598   uint8_t ctype = AVRC_RSP_ACCEPT;
599   if (!browse) {
600     ctype =
601         (uint8_t)(::bluetooth::Packet::Specialize<Packet>(packet)->GetCType());
602   }
603 
604   log::info("SendMessage to handle=0x{:x}", handle);
605 
606   BT_HDR* pkt = (BT_HDR*)osi_malloc(BT_DEFAULT_BUFFER_SIZE);
607 
608   pkt->offset = AVCT_MSG_OFFSET;
609   // TODO (apanicke): Update this constant. Currently this is a unique event
610   // used to tell the AVRCP API layer that the data is properly formatted and
611   // doesn't need to be processed. In the future, this is the only place sending
612   // the packet so none of these layer specific fields will be used.
613   pkt->event = 0xFFFF;
614   /* Handle for AVRCP fragment */
615   uint16_t op_code =
616       (uint16_t)(::bluetooth::Packet::Specialize<Packet>(packet)->GetOpcode());
617   if (!browse && (op_code == (uint16_t)(Opcode::VENDOR))) {
618     pkt->event = op_code;
619   }
620 
621   // TODO (apanicke): This layer specific stuff can go away once we move over
622   // to the new service.
623   pkt->layer_specific = AVCT_DATA_CTRL;
624   if (browse) {
625     pkt->layer_specific = AVCT_DATA_BROWSE;
626   }
627 
628   pkt->len = packet->size();
629   uint8_t* p_data = (uint8_t*)(pkt + 1) + pkt->offset;
630   for (auto it = packet->begin(); it != packet->end(); it++) {
631     *p_data++ = *it;
632   }
633 
634   avrc_->MsgReq(handle, label, ctype, pkt);
635 }
636 
RegisterVolChanged(const RawAddress & bdaddr)637 void ConnectionHandler::RegisterVolChanged(const RawAddress& bdaddr) {
638   log::info("Attempting to RegisterVolChanged device {}", bdaddr);
639   for (auto it = device_map_.begin(); it != device_map_.end(); it++) {
640     if (bdaddr == it->second->GetAddress()) {
641       const auto& feature_iter = feature_map_.find(bdaddr);
642       if (feature_iter->second & BTA_AV_FEAT_ADV_CTRL) {
643         it->second->RegisterVolumeChanged();
644       } else if (instance_->vol_ != nullptr) {
645         instance_->vol_->DeviceConnected(bdaddr);
646       }
647       break;
648     }
649   }
650 }
651 
SdpLookupAudioRole(uint16_t handle)652 bool ConnectionHandler::SdpLookupAudioRole(uint16_t handle) {
653   if (device_map_.find(handle) == device_map_.end()) {
654     log::warn("No device found for handle: {}", loghex(handle));
655     return false;
656   }
657   auto device = device_map_[handle];
658 
659   log::info(
660       "Performing SDP for AUDIO_SINK on connected device: address={}, "
661       "handle={}",
662       ADDRESS_TO_LOGGABLE_STR(device->GetAddress()), handle);
663 
664   return device->find_sink_service(
665       base::Bind(&ConnectionHandler::SdpLookupAudioRoleCb,
666                  weak_ptr_factory_.GetWeakPtr(), handle));
667 }
668 
SdpLookupAudioRoleCb(uint16_t handle,bool found,tA2DP_Service * p_service,const RawAddress & peer_address)669 void ConnectionHandler::SdpLookupAudioRoleCb(uint16_t handle, bool found,
670                                              tA2DP_Service* p_service,
671                                              const RawAddress& peer_address) {
672   if (device_map_.find(handle) == device_map_.end()) {
673     log::warn("No device found for handle: {}", loghex(handle));
674     return;
675   }
676   auto device = device_map_[handle];
677 
678   log::debug("SDP callback for address={}, handle={}, AUDIO_SINK {}",
679              ADDRESS_TO_LOGGABLE_STR(device->GetAddress()), handle,
680              found ? "found" : "not found");
681 
682   if (found) {
683     device->connect_a2dp_sink_delayed(handle);
684   }
685 }
686 
687 }  // namespace avrcp
688 }  // namespace bluetooth
689