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