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