• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2021 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 "android.hardware.bluetooth@1.1.remote"
18 
19 #include "remote_bluetooth.h"
20 
21 #include <cutils/properties.h>
22 #include <fcntl.h>
23 #include <netdb.h>
24 #include <netinet/in.h>
25 #include <poll.h>
26 #include <string.h>
27 #include <sys/uio.h>
28 #include <termios.h>
29 #include <utils/Log.h>
30 #include "log/log.h"
31 
32 namespace {
SetTerminalRaw(int fd)33 int SetTerminalRaw(int fd) {
34   termios terminal_settings;
35   int rval = tcgetattr(fd, &terminal_settings);
36   if (rval < 0) {
37     return rval;
38   }
39   cfmakeraw(&terminal_settings);
40   rval = tcsetattr(fd, TCSANOW, &terminal_settings);
41   return rval;
42 }
43 }  // namespace
44 
45 namespace android {
46 namespace hardware {
47 namespace bluetooth {
48 namespace V1_1 {
49 namespace remote {
50 
51 using ::android::hardware::hidl_vec;
52 
53 class BluetoothDeathRecipient : public hidl_death_recipient {
54  public:
BluetoothDeathRecipient(const sp<IBluetoothHci> hci)55   BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {}
56 
serviceDied(uint64_t,const wp<::android::hidl::base::V1_0::IBase> &)57   void serviceDied(
58       uint64_t /* cookie */,
59       const wp<::android::hidl::base::V1_0::IBase>& /* who */) override {
60     LOG(ERROR)
61         << "BluetoothDeathRecipient::serviceDied - Bluetooth service died";
62     has_died_ = true;
63     mHci->close();
64   }
65   sp<IBluetoothHci> mHci;
getHasDied() const66   bool getHasDied() const { return has_died_; }
setHasDied(bool has_died)67   void setHasDied(bool has_died) { has_died_ = has_died; }
68 
69  private:
70   bool has_died_;
71 };
72 
BluetoothHci(const std::string & dev_path)73 BluetoothHci::BluetoothHci(const std::string& dev_path)
74     : death_recipient_(new BluetoothDeathRecipient(this)),
75       dev_path_(dev_path) {}
76 
initialize(const sp<V1_0::IBluetoothHciCallbacks> & cb)77 Return<void> BluetoothHci::initialize(
78     const sp<V1_0::IBluetoothHciCallbacks>& cb) {
79   return initialize_impl(cb, nullptr);
80 }
81 
initialize_1_1(const sp<V1_1::IBluetoothHciCallbacks> & cb)82 Return<void> BluetoothHci::initialize_1_1(
83     const sp<V1_1::IBluetoothHciCallbacks>& cb) {
84   return initialize_impl(cb, cb);
85 }
86 
initialize_impl(const sp<V1_0::IBluetoothHciCallbacks> & cb,const sp<V1_1::IBluetoothHciCallbacks> & cb_1_1)87 Return<void> BluetoothHci::initialize_impl(
88     const sp<V1_0::IBluetoothHciCallbacks>& cb,
89     const sp<V1_1::IBluetoothHciCallbacks>& cb_1_1) {
90   LOG(INFO) << __func__;
91 
92   cb_ = cb;
93   cb_1_1_ = cb_1_1;
94   fd_ = open(dev_path_.c_str(), O_RDWR);
95   if (fd_ < 0) {
96     LOG(FATAL) << "Could not connect to bt: " << fd_;
97   }
98   if (int ret = SetTerminalRaw(fd_) < 0) {
99     LOG(FATAL) << "Could not make " << fd_ << " a raw terminal: " << ret;
100   }
101 
102   if (cb == nullptr) {
103     LOG(ERROR)
104         << "cb == nullptr! -> Unable to call initializationComplete(ERR)";
105     return Void();
106   }
107 
108   death_recipient_->setHasDied(false);
109   auto link_ret = cb->linkToDeath(death_recipient_, 0);
110 
111   unlink_cb_ = [this, cb](sp<BluetoothDeathRecipient>& death_recipient) {
112     if (death_recipient->getHasDied())
113       LOG(INFO) << "Skipping unlink call, service died.";
114     else {
115       auto ret = cb->unlinkToDeath(death_recipient);
116       if (!ret.isOk()) {
117         CHECK(death_recipient_->getHasDied())
118             << "Error calling unlink, but no death notification.";
119       }
120     }
121   };
122 
123   auto init_ret = cb->initializationComplete(V1_0::Status::SUCCESS);
124   if (!init_ret.isOk()) {
125     CHECK(death_recipient_->getHasDied())
126         << "Error sending init callback, but no death notification.";
127   }
128   h4_ = test_vendor_lib::H4Packetizer(
129       fd_,
130       [](const std::vector<uint8_t>& /* raw_command */) {
131         LOG_ALWAYS_FATAL("Unexpected command!");
132       },
133       [this](const std::vector<uint8_t>& raw_event) {
134         cb_->hciEventReceived(hidl_vec<uint8_t>(raw_event));
135       },
136       [this](const std::vector<uint8_t>& raw_acl) {
137         cb_->hciEventReceived(hidl_vec<uint8_t>(raw_acl));
138       },
139       [this](const std::vector<uint8_t>& raw_sco) {
140         cb_->hciEventReceived(hidl_vec<uint8_t>(raw_sco));
141       },
142       [this](const std::vector<uint8_t>& raw_iso) {
143         if (cb_1_1_) {
144           cb_1_1_->hciEventReceived(hidl_vec<uint8_t>(raw_iso));
145         }
146       },
147       []() { LOG(INFO) << "HCI socket device disconnected"; });
148   fd_watcher_.WatchFdForNonBlockingReads(
149       fd_, [this](int fd) { h4_.OnDataReady(fd); });
150   return Void();
151 }
152 
close()153 Return<void> BluetoothHci::close() {
154   LOG(INFO) << __func__;
155   fd_watcher_.StopWatchingFileDescriptors();
156   ::close(fd_);
157 
158   return Void();
159 }
160 
sendHciCommand(const hidl_vec<uint8_t> & packet)161 Return<void> BluetoothHci::sendHciCommand(const hidl_vec<uint8_t>& packet) {
162   send(test_vendor_lib::PacketType::COMMAND, packet);
163   return Void();
164 }
165 
sendAclData(const hidl_vec<uint8_t> & packet)166 Return<void> BluetoothHci::sendAclData(const hidl_vec<uint8_t>& packet) {
167   send(test_vendor_lib::PacketType::ACL, packet);
168   return Void();
169 }
170 
sendScoData(const hidl_vec<uint8_t> & packet)171 Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& packet) {
172   send(test_vendor_lib::PacketType::SCO, packet);
173   return Void();
174 }
175 
sendIsoData(const hidl_vec<uint8_t> & packet)176 Return<void> BluetoothHci::sendIsoData(const hidl_vec<uint8_t>& packet) {
177   send(test_vendor_lib::PacketType::ISO, packet);
178   return Void();
179 }
180 
send(test_vendor_lib::PacketType type,const::android::hardware::hidl_vec<uint8_t> & v)181 void BluetoothHci::send(test_vendor_lib::PacketType type,
182                         const ::android::hardware::hidl_vec<uint8_t>& v) {
183   h4_.Send(static_cast<uint8_t>(type), v.data(), v.size());
184 }
185 
186 /* Fallback to shared library if there is no service. */
HIDL_FETCH_IBluetoothHci(const char *)187 IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* /* name */) {
188   return new BluetoothHci();
189 }
190 
191 }  // namespace remote
192 }  // namespace V1_1
193 }  // namespace bluetooth
194 }  // namespace hardware
195 }  // namespace android
196