• 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 "acl_packet.h"
26 #include "event_packet.h"
27 #include "hci_internals.h"
28 #include "sco_packet.h"
29 
30 namespace android {
31 namespace hardware {
32 namespace bluetooth {
33 namespace V1_0 {
34 namespace sim {
35 
36 using android::hardware::hidl_vec;
37 using test_vendor_lib::AclPacket;
38 using test_vendor_lib::AsyncManager;
39 using test_vendor_lib::AsyncTaskId;
40 using test_vendor_lib::CommandPacket;
41 using test_vendor_lib::DualModeController;
42 using test_vendor_lib::EventPacket;
43 using test_vendor_lib::ScoPacket;
44 using test_vendor_lib::TaskCallback;
45 using test_vendor_lib::TestChannelTransport;
46 
47 class BluetoothDeathRecipient : public hidl_death_recipient {
48  public:
BluetoothDeathRecipient(const sp<IBluetoothHci> hci)49   BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {}
50 
serviceDied(uint64_t,const wp<::android::hidl::base::V1_0::IBase> &)51   virtual void serviceDied(
52       uint64_t /* cookie */,
53       const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
54     ALOGE("BluetoothDeathRecipient::serviceDied - Bluetooth service died");
55     has_died_ = true;
56     mHci->close();
57   }
58   sp<IBluetoothHci> mHci;
getHasDied() const59   bool getHasDied() const { return has_died_; }
setHasDied(bool has_died)60   void setHasDied(bool has_died) { has_died_ = has_died; }
61 
62  private:
63   bool has_died_;
64 };
65 
BluetoothHci()66 BluetoothHci::BluetoothHci()
67     : death_recipient_(new BluetoothDeathRecipient(this)) {}
68 
initialize(const sp<IBluetoothHciCallbacks> & cb)69 Return<void> BluetoothHci::initialize(const sp<IBluetoothHciCallbacks>& cb) {
70   ALOGI("%s", __func__);
71 
72   if (cb == nullptr) {
73     ALOGE("cb == nullptr! -> Unable to call initializationComplete(ERR)");
74     return Void();
75   }
76 
77   death_recipient_->setHasDied(false);
78   cb->linkToDeath(death_recipient_, 0);
79 
80   test_channel_transport_.RegisterCommandHandler(
81       [this](const std::string& name, const std::vector<std::string>& args) {
82         async_manager_.ExecAsync(
83             std::chrono::milliseconds(0), [this, name, args]() {
84               controller_.HandleTestChannelCommand(name, args);
85             });
86       });
87 
88   controller_.RegisterEventChannel([cb](std::unique_ptr<EventPacket> event) {
89     size_t header_bytes = event->GetHeaderSize();
90     size_t payload_bytes = event->GetPayloadSize();
91     hidl_vec<uint8_t> hci_event;
92     hci_event.resize(header_bytes + payload_bytes);
93     memcpy(hci_event.data(), event->GetHeader().data(), header_bytes);
94     memcpy(hci_event.data() + header_bytes, event->GetPayload().data(),
95            payload_bytes);
96 
97     cb->hciEventReceived(hci_event);
98   });
99 
100   controller_.RegisterAclChannel([cb](std::unique_ptr<AclPacket> packet) {
101     std::vector<uint8_t> acl_vector = packet->GetPacket();
102     hidl_vec<uint8_t> acl_packet = acl_vector;
103 
104     cb->aclDataReceived(acl_packet);
105   });
106 
107   controller_.RegisterScoChannel([cb](std::unique_ptr<ScoPacket> packet) {
108     size_t header_bytes = packet->GetHeaderSize();
109     size_t payload_bytes = packet->GetPayloadSize();
110     hidl_vec<uint8_t> sco_packet;
111     sco_packet.resize(header_bytes + payload_bytes);
112     memcpy(sco_packet.data(), packet->GetHeader().data(), header_bytes);
113     memcpy(sco_packet.data() + header_bytes, packet->GetPayload().data(),
114            payload_bytes);
115 
116     cb->scoDataReceived(sco_packet);
117   });
118 
119   controller_.RegisterTaskScheduler(
120       [this](std::chrono::milliseconds delay, const TaskCallback& task) {
121         return async_manager_.ExecAsync(delay, task);
122       });
123 
124   controller_.RegisterPeriodicTaskScheduler(
125       [this](std::chrono::milliseconds delay, std::chrono::milliseconds period,
126              const TaskCallback& task) {
127         return async_manager_.ExecAsyncPeriodically(delay, period, task);
128       });
129 
130   controller_.RegisterTaskCancel(
131       [this](AsyncTaskId task) { async_manager_.CancelAsyncTask(task); });
132 
133   SetUpTestChannel(6111);
134 
135   unlink_cb_ = [cb](sp<BluetoothDeathRecipient>& death_recipient) {
136     if (death_recipient->getHasDied())
137       ALOGI("Skipping unlink call, service died.");
138     else
139       cb->unlinkToDeath(death_recipient);
140   };
141 
142   cb->initializationComplete(Status::SUCCESS);
143   return Void();
144 }
145 
close()146 Return<void> BluetoothHci::close() {
147   ALOGI("%s", __func__);
148   return Void();
149 }
150 
sendHciCommand(const hidl_vec<uint8_t> & packet)151 Return<void> BluetoothHci::sendHciCommand(const hidl_vec<uint8_t>& packet) {
152   async_manager_.ExecAsync(std::chrono::milliseconds(0), [this, packet]() {
153     uint16_t opcode = packet[0] | (packet[1] << 8);
154     std::unique_ptr<CommandPacket> command =
155         std::unique_ptr<CommandPacket>(new CommandPacket(opcode));
156     for (size_t i = 3; i < packet.size(); i++)
157       command->AddPayloadOctets1(packet[i]);
158 
159     controller_.HandleCommand(std::move(command));
160   });
161   return Void();
162 }
163 
sendAclData(const hidl_vec<uint8_t> & packet)164 Return<void> BluetoothHci::sendAclData(const hidl_vec<uint8_t>& packet) {
165   async_manager_.ExecAsync(std::chrono::milliseconds(0), [this, packet]() {
166     uint16_t channel = (packet[0] | (packet[1] << 8)) & 0xfff;
167     AclPacket::PacketBoundaryFlags boundary_flags =
168         static_cast<AclPacket::PacketBoundaryFlags>((packet[1] & 0x30) >> 4);
169     AclPacket::BroadcastFlags broadcast_flags =
170         static_cast<AclPacket::BroadcastFlags>((packet[1] & 0xC0) >> 6);
171 
172     std::unique_ptr<AclPacket> acl = std::unique_ptr<AclPacket>(
173         new AclPacket(channel, boundary_flags, broadcast_flags));
174     for (size_t i = 4; i < packet.size(); i++)
175       acl->AddPayloadOctets1(packet[i]);
176 
177     controller_.HandleAcl(std::move(acl));
178   });
179   return Void();
180 }
181 
sendScoData(const hidl_vec<uint8_t> & packet)182 Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& packet) {
183   async_manager_.ExecAsync(std::chrono::milliseconds(0), [this, packet]() {
184     uint16_t channel = (packet[0] | (packet[1] << 8)) & 0xfff;
185     ScoPacket::PacketStatusFlags packet_status =
186         static_cast<ScoPacket::PacketStatusFlags>((packet[1] & 0x30) >> 4);
187     std::unique_ptr<ScoPacket> sco =
188         std::unique_ptr<ScoPacket>(new ScoPacket(channel, packet_status));
189     for (size_t i = 3; i < packet.size(); i++)
190       sco->AddPayloadOctets1(packet[i]);
191 
192     controller_.HandleSco(std::move(sco));
193   });
194   return Void();
195 }
196 
SetUpTestChannel(int port)197 void BluetoothHci::SetUpTestChannel(int port) {
198   int socket_fd = test_channel_transport_.SetUp(port);
199 
200   if (socket_fd == -1) {
201     ALOGE("Test channel SetUp(%d) failed.", port);
202     return;
203   }
204 
205   ALOGI("Test channel SetUp() successful");
206   async_manager_.WatchFdForNonBlockingReads(socket_fd, [this](int socket_fd) {
207     int conn_fd = test_channel_transport_.Accept(socket_fd);
208     if (conn_fd < 0) {
209       ALOGE("Error watching test channel fd.");
210       return;
211     }
212     ALOGI("Test channel connection accepted.");
213     async_manager_.WatchFdForNonBlockingReads(conn_fd, [this](int conn_fd) {
214       test_channel_transport_.OnCommandReady(conn_fd, [this, conn_fd]() {
215         async_manager_.StopWatchingFileDescriptor(conn_fd);
216       });
217     });
218   });
219 }
220 
221 /* Fallback to shared library if there is no service. */
HIDL_FETCH_IBluetoothHci(const char *)222 IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* /* name */) {
223   return new BluetoothHci();
224 }
225 
226 }  // namespace gce
227 }  // namespace V1_0
228 }  // namespace bluetooth
229 }  // namespace hardware
230 }  // namespace android
231