• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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