• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2017 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.0.sim"
18 
19 #include "bluetooth_hci.h"
20 
21 #include <base/logging.h>
22 #include <string.h>
23 #include <utils/Log.h>
24 
25 #include "hci_internals.h"
26 
27 namespace android {
28 namespace hardware {
29 namespace bluetooth {
30 namespace V1_0 {
31 namespace sim {
32 
33 using android::hardware::hidl_vec;
34 using test_vendor_lib::AsyncManager;
35 using test_vendor_lib::AsyncTaskId;
36 using test_vendor_lib::CommandPacket;
37 using test_vendor_lib::DualModeController;
38 using test_vendor_lib::EventPacket;
39 using test_vendor_lib::TaskCallback;
40 using test_vendor_lib::TestChannelTransport;
41 
42 class BluetoothDeathRecipient : public hidl_death_recipient {
43  public:
BluetoothDeathRecipient(const sp<IBluetoothHci> hci)44   BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {}
45 
serviceDied(uint64_t,const wp<::android::hidl::base::V1_0::IBase> &)46   virtual void serviceDied(
47       uint64_t /* cookie */,
48       const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
49     ALOGE("BluetoothDeathRecipient::serviceDied - Bluetooth service died");
50     has_died_ = true;
51     mHci->close();
52   }
53   sp<IBluetoothHci> mHci;
getHasDied() const54   bool getHasDied() const { return has_died_; }
setHasDied(bool has_died)55   void setHasDied(bool has_died) { has_died_ = has_died; }
56 
57  private:
58   bool has_died_;
59 };
60 
BluetoothHci()61 BluetoothHci::BluetoothHci()
62     : death_recipient_(new BluetoothDeathRecipient(this)) {}
63 
initialize(const sp<IBluetoothHciCallbacks> & cb)64 Return<void> BluetoothHci::initialize(const sp<IBluetoothHciCallbacks>& cb) {
65   ALOGI("%s", __func__);
66 
67   if (cb == nullptr) {
68     ALOGE("cb == nullptr! -> Unable to call initializationComplete(ERR)");
69     return Void();
70   }
71 
72   death_recipient_->setHasDied(false);
73   cb->linkToDeath(death_recipient_, 0);
74 
75   test_channel_transport_.RegisterCommandHandler(
76       [this](const std::string& name, const std::vector<std::string>& args) {
77         async_manager_.ExecAsync(
78             std::chrono::milliseconds(0), [this, name, args]() {
79               controller_.HandleTestChannelCommand(name, args);
80             });
81       });
82 
83   controller_.RegisterEventChannel([cb](std::unique_ptr<EventPacket> event) {
84     size_t header_bytes = event->GetHeaderSize();
85     size_t payload_bytes = event->GetPayloadSize();
86     hidl_vec<uint8_t> hci_event;
87     hci_event.resize(header_bytes + payload_bytes);
88     memcpy(hci_event.data(), event->GetHeader().data(), header_bytes);
89     memcpy(hci_event.data() + header_bytes, event->GetPayload().data(),
90            payload_bytes);
91 
92     cb->hciEventReceived(hci_event);
93   });
94 
95   /* RegisterAcl and RegisterSco
96         cb->aclDataReceived(hci_packet);
97         cb->scoDataReceived(hci_packet);
98   */
99 
100   controller_.RegisterTaskScheduler(
101       [this](std::chrono::milliseconds delay, const TaskCallback& task) {
102         return async_manager_.ExecAsync(delay, task);
103       });
104 
105   controller_.RegisterPeriodicTaskScheduler(
106       [this](std::chrono::milliseconds delay, std::chrono::milliseconds period,
107              const TaskCallback& task) {
108         return async_manager_.ExecAsyncPeriodically(delay, period, task);
109       });
110 
111   controller_.RegisterTaskCancel(
112       [this](AsyncTaskId task) { async_manager_.CancelAsyncTask(task); });
113 
114   SetUpTestChannel(6111);
115 
116   unlink_cb_ = [cb](sp<BluetoothDeathRecipient>& death_recipient) {
117     if (death_recipient->getHasDied())
118       ALOGI("Skipping unlink call, service died.");
119     else
120       cb->unlinkToDeath(death_recipient);
121   };
122 
123   cb->initializationComplete(Status::SUCCESS);
124   return Void();
125 }
126 
close()127 Return<void> BluetoothHci::close() {
128   ALOGI("%s", __func__);
129   return Void();
130 }
131 
sendHciCommand(const hidl_vec<uint8_t> & packet)132 Return<void> BluetoothHci::sendHciCommand(const hidl_vec<uint8_t>& packet) {
133   async_manager_.ExecAsync(std::chrono::milliseconds(0), [this, packet]() {
134     uint16_t opcode = packet[0] | (packet[1] << 8);
135     std::unique_ptr<CommandPacket> command =
136         std::unique_ptr<CommandPacket>(new CommandPacket(opcode));
137     for (size_t i = 3; i < packet.size(); i++)
138       command->AddPayloadOctets1(packet[i]);
139 
140     controller_.HandleCommand(std::move(command));
141   });
142   return Void();
143 }
144 
sendAclData(const hidl_vec<uint8_t> &)145 Return<void> BluetoothHci::sendAclData(const hidl_vec<uint8_t>& /* packet */) {
146   CHECK(false) << __func__ << " not yet implemented";
147   return Void();
148 }
149 
sendScoData(const hidl_vec<uint8_t> &)150 Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& /* packet */) {
151   CHECK(false) << __func__ << " not yet implemented";
152   return Void();
153 }
154 
SetUpTestChannel(int port)155 void BluetoothHci::SetUpTestChannel(int port) {
156   int socket_fd = test_channel_transport_.SetUp(port);
157 
158   if (socket_fd == -1) {
159     ALOGE("Test channel SetUp(%d) failed.", port);
160     return;
161   }
162 
163   ALOGI("Test channel SetUp() successful");
164   async_manager_.WatchFdForNonBlockingReads(socket_fd, [this](int socket_fd) {
165     int conn_fd = test_channel_transport_.Accept(socket_fd);
166     if (conn_fd < 0) {
167       ALOGE("Error watching test channel fd.");
168       return;
169     }
170     ALOGI("Test channel connection accepted.");
171     async_manager_.WatchFdForNonBlockingReads(conn_fd, [this](int conn_fd) {
172       test_channel_transport_.OnCommandReady(conn_fd, [this, conn_fd]() {
173         async_manager_.StopWatchingFileDescriptor(conn_fd);
174       });
175     });
176   });
177 }
178 
179 }  // namespace gce
180 }  // namespace V1_0
181 }  // namespace bluetooth
182 }  // namespace hardware
183 }  // namespace android
184