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