1 #include <android/hardware/bluetooth/1.0/types.h>
2 #include <android/hardware/bluetooth/1.1/IBluetoothHci.h>
3 #include <android/hardware/bluetooth/1.1/IBluetoothHciCallbacks.h>
4 #include <stdlib.h>
5 
6 #include "../../os/log.h"
7 #include "src/ffi/hidl.h"
8 
9 using ::android::hardware::hidl_vec;
10 using ::android::hardware::Return;
11 using ::android::hardware::Void;
12 using ::android::hardware::bluetooth::V1_1::IBluetoothHci;
13 using ::android::hardware::bluetooth::V1_1::IBluetoothHciCallbacks;
14 using HidlStatus = ::android::hardware::bluetooth::V1_0::Status;
15 using IBluetoothHci_1_0 = ::android::hardware::bluetooth::V1_0::IBluetoothHci;
16 
17 namespace bluetooth {
18 namespace hal {
19 namespace {
20 
21 class HciDeathRecipient : public ::android::hardware::hidl_death_recipient {
22  public:
serviceDied(uint64_t,const android::wp<::android::hidl::base::V1_0::IBase> &)23   virtual void serviceDied(uint64_t /*cookie*/, const android::wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
24     LOG_ERROR("Bluetooth HAL service died!");
25     abort();
26   }
27 };
28 
29 class HciCallbackTrampoline : public IBluetoothHciCallbacks {
30  public:
HciCallbackTrampoline()31   HciCallbackTrampoline() {}
32 
initializationComplete(HidlStatus status)33   Return<void> initializationComplete(HidlStatus status) {
34     ASSERT(status == HidlStatus::SUCCESS);
35     on_init_complete();
36     return Void();
37   }
38 
hciEventReceived(const hidl_vec<uint8_t> & event)39   Return<void> hciEventReceived(const hidl_vec<uint8_t>& event) {
40     on_event(rust::Slice(&event[0], event.size()));
41     return Void();
42   }
43 
aclDataReceived(const hidl_vec<uint8_t> & data)44   Return<void> aclDataReceived(const hidl_vec<uint8_t>& data) {
45     on_acl(rust::Slice(&data[0], data.size()));
46     return Void();
47   }
48 
scoDataReceived(const hidl_vec<uint8_t> & data)49   Return<void> scoDataReceived(const hidl_vec<uint8_t>& data) {
50     on_sco(rust::Slice(&data[0], data.size()));
51     return Void();
52   }
53 
isoDataReceived(const hidl_vec<uint8_t> & data)54   Return<void> isoDataReceived(const hidl_vec<uint8_t>& data) {
55     on_iso(rust::Slice(&data[0], data.size()));
56     return Void();
57   }
58 };
59 
60 android::sp<HciDeathRecipient> hci_death_recipient_ = new HciDeathRecipient();
61 android::sp<IBluetoothHci_1_0> bt_hci_;
62 android::sp<IBluetoothHci> bt_hci_1_1_;
63 android::sp<HciCallbackTrampoline> trampoline_;
64 
65 }  // namespace
66 
start_hal()67 void start_hal() {
68   ASSERT(bt_hci_ == nullptr);
69 
70   bt_hci_1_1_ = IBluetoothHci::getService();
71   if (bt_hci_1_1_ != nullptr) {
72     bt_hci_ = bt_hci_1_1_;
73   } else {
74     bt_hci_ = IBluetoothHci_1_0::getService();
75   }
76 
77   ASSERT(bt_hci_ != nullptr);
78   auto death_link = bt_hci_->linkToDeath(hci_death_recipient_, 0);
79   ASSERT_LOG(death_link.isOk(), "Unable to set the death recipient for the Bluetooth HAL");
80 
81   trampoline_ = new HciCallbackTrampoline();
82   if (bt_hci_1_1_ != nullptr) {
83     bt_hci_1_1_->initialize_1_1(trampoline_);
84   } else {
85     bt_hci_->initialize(trampoline_);
86   }
87 }
88 
stop_hal()89 void stop_hal() {
90   ASSERT(bt_hci_ != nullptr);
91 
92   auto death_unlink = bt_hci_->unlinkToDeath(hci_death_recipient_);
93   if (!death_unlink.isOk()) {
94     LOG_ERROR("Error unlinking death recipient from the Bluetooth HAL");
95   }
96   bt_hci_->close();
97   bt_hci_ = nullptr;
98   bt_hci_1_1_ = nullptr;
99   trampoline_ = nullptr;
100 }
101 
send_command(rust::Slice<const uint8_t> data)102 void send_command(rust::Slice<const uint8_t> data) {
103   ASSERT(bt_hci_ != nullptr);
104   bt_hci_->sendHciCommand(hidl_vec<uint8_t>(data.data(), data.data() + data.length()));
105 }
106 
send_acl(rust::Slice<const uint8_t> data)107 void send_acl(rust::Slice<const uint8_t> data) {
108   ASSERT(bt_hci_ != nullptr);
109   bt_hci_->sendAclData(hidl_vec<uint8_t>(data.data(), data.data() + data.length()));
110 }
111 
send_sco(rust::Slice<const uint8_t> data)112 void send_sco(rust::Slice<const uint8_t> data) {
113   ASSERT(bt_hci_ != nullptr);
114   bt_hci_->sendScoData(hidl_vec<uint8_t>(data.data(), data.data() + data.length()));
115 }
116 
send_iso(rust::Slice<const uint8_t> data)117 void send_iso(rust::Slice<const uint8_t> data) {
118   if (bt_hci_1_1_ == nullptr) {
119     LOG_ERROR("ISO is not supported in HAL v1.0");
120     return;
121   }
122 
123   ASSERT(bt_hci_ != nullptr);
124   bt_hci_1_1_->sendIsoData(hidl_vec<uint8_t>(data.data(), data.data() + data.length()));
125 }
126 
127 }  // namespace hal
128 }  // namespace bluetooth
129