1 /*
2 * Copyright 2019 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 #include "hci/facade/facade.h"
18
19 #include <memory>
20
21 #include "common/bind.h"
22 #include "grpc/grpc_event_queue.h"
23 #include "hci/controller.h"
24 #include "hci/facade/hci_facade.grpc.pb.h"
25 #include "hci/hci_layer.h"
26 #include "hci/hci_packets.h"
27
28 using ::grpc::ServerAsyncResponseWriter;
29 using ::grpc::ServerAsyncWriter;
30 using ::grpc::ServerContext;
31
32 namespace bluetooth {
33 namespace hci {
34 namespace facade {
35
36 class HciFacadeService : public HciFacade::Service {
37 public:
HciFacadeService(HciLayer * hci_layer,Controller * controller,::bluetooth::os::Handler * facade_handler)38 HciFacadeService(HciLayer* hci_layer, Controller* controller, ::bluetooth::os::Handler* facade_handler)
39 : hci_layer_(hci_layer), controller_(controller), facade_handler_(facade_handler) {}
40
~HciFacadeService()41 virtual ~HciFacadeService() {
42 if (unregister_acl_dequeue_) {
43 hci_layer_->GetAclQueueEnd()->UnregisterDequeue();
44 }
45 if (waiting_acl_packet_ != nullptr) {
46 hci_layer_->GetAclQueueEnd()->UnregisterEnqueue();
47 if (waiting_acl_packet_ != nullptr) {
48 waiting_acl_packet_.reset();
49 }
50 }
51 }
52
53 class TestCommandBuilder : public CommandBuilder {
54 public:
TestCommandBuilder(std::vector<uint8_t> bytes)55 explicit TestCommandBuilder(std::vector<uint8_t> bytes) : CommandBuilder(OpCode::NONE), bytes_(std::move(bytes)) {}
size() const56 size_t size() const override {
57 return bytes_.size();
58 }
Serialize(BitInserter & bit_inserter) const59 void Serialize(BitInserter& bit_inserter) const override {
60 for (auto&& b : bytes_) {
61 bit_inserter.insert_byte(b);
62 }
63 }
64
65 private:
66 std::vector<uint8_t> bytes_;
67 };
68
SendCommand(::grpc::ServerContext * context,const::bluetooth::facade::Data * command,::google::protobuf::Empty * response)69 ::grpc::Status SendCommand(
70 ::grpc::ServerContext* context,
71 const ::bluetooth::facade::Data* command,
72 ::google::protobuf::Empty* response) override {
73 auto payload = std::vector<uint8_t>(command->payload().begin(), command->payload().end());
74 auto packet = std::make_unique<TestCommandBuilder>(payload);
75 auto opcode = static_cast<const bluetooth::hci::OpCode>(payload.at(1) << 8 | payload.at(0));
76 if (Checker::IsCommandStatusOpcode(opcode)) {
77 hci_layer_->EnqueueCommand(std::move(packet), facade_handler_->BindOnceOn(this, &HciFacadeService::on_status));
78 } else {
79 hci_layer_->EnqueueCommand(std::move(packet), facade_handler_->BindOnceOn(this, &HciFacadeService::on_complete));
80 }
81 return ::grpc::Status::OK;
82 }
83
RequestEvent(::grpc::ServerContext * context,const::bluetooth::hci::EventRequest * event,::google::protobuf::Empty * response)84 ::grpc::Status RequestEvent(
85 ::grpc::ServerContext* context,
86 const ::bluetooth::hci::EventRequest* event,
87 ::google::protobuf::Empty* response) override {
88 hci_layer_->RegisterEventHandler(
89 static_cast<EventCode>(event->code()), facade_handler_->BindOn(this, &HciFacadeService::on_event));
90 return ::grpc::Status::OK;
91 }
92
RequestLeSubevent(::grpc::ServerContext * context,const::bluetooth::hci::EventRequest * event,::google::protobuf::Empty * response)93 ::grpc::Status RequestLeSubevent(
94 ::grpc::ServerContext* context,
95 const ::bluetooth::hci::EventRequest* event,
96 ::google::protobuf::Empty* response) override {
97 hci_layer_->RegisterLeEventHandler(
98 static_cast<SubeventCode>(event->code()), facade_handler_->BindOn(this, &HciFacadeService::on_le_subevent));
99 return ::grpc::Status::OK;
100 }
101
StreamEvents(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::grpc::ServerWriter<::bluetooth::facade::Data> * writer)102 ::grpc::Status StreamEvents(
103 ::grpc::ServerContext* context,
104 const ::google::protobuf::Empty* request,
105 ::grpc::ServerWriter<::bluetooth::facade::Data>* writer) override {
106 return pending_events_.RunLoop(context, writer);
107 };
108
StreamLeSubevents(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::grpc::ServerWriter<::bluetooth::facade::Data> * writer)109 ::grpc::Status StreamLeSubevents(
110 ::grpc::ServerContext* context,
111 const ::google::protobuf::Empty* request,
112 ::grpc::ServerWriter<::bluetooth::facade::Data>* writer) override {
113 return pending_le_events_.RunLoop(context, writer);
114 };
115
116 class TestAclBuilder : public AclBuilder {
117 public:
TestAclBuilder(std::vector<uint8_t> payload)118 explicit TestAclBuilder(std::vector<uint8_t> payload)
119 : AclBuilder(0xbad, PacketBoundaryFlag::CONTINUING_FRAGMENT, BroadcastFlag::ACTIVE_PERIPHERAL_BROADCAST),
120 bytes_(std::move(payload)) {}
121
size() const122 size_t size() const override {
123 return bytes_.size();
124 }
Serialize(BitInserter & bit_inserter) const125 void Serialize(BitInserter& bit_inserter) const override {
126 for (auto&& b : bytes_) {
127 bit_inserter.insert_byte(b);
128 }
129 }
130
131 private:
132 std::vector<uint8_t> bytes_;
133 };
134
SendAcl(::grpc::ServerContext * context,const::bluetooth::facade::Data * acl,::google::protobuf::Empty * response)135 ::grpc::Status SendAcl(
136 ::grpc::ServerContext* context,
137 const ::bluetooth::facade::Data* acl,
138 ::google::protobuf::Empty* response) override {
139 waiting_acl_packet_ =
140 std::make_unique<TestAclBuilder>(std::vector<uint8_t>(acl->payload().begin(), acl->payload().end()));
141 std::promise<void> enqueued;
142 auto future = enqueued.get_future();
143 if (!completed_packets_callback_registered_) {
144 controller_->RegisterCompletedAclPacketsCallback(
145 facade_handler_->Bind([](uint16_t, uint16_t) { /* do nothing */ }));
146 completed_packets_callback_registered_ = true;
147 }
148 hci_layer_->GetAclQueueEnd()->RegisterEnqueue(
149 facade_handler_,
150 common::Bind(&HciFacadeService::handle_enqueue_acl, common::Unretained(this), common::Unretained(&enqueued)));
151 auto result = future.wait_for(std::chrono::milliseconds(100));
152 ASSERT(std::future_status::ready == result);
153 return ::grpc::Status::OK;
154 }
155
StreamAcl(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::grpc::ServerWriter<::bluetooth::facade::Data> * writer)156 ::grpc::Status StreamAcl(
157 ::grpc::ServerContext* context,
158 const ::google::protobuf::Empty* request,
159 ::grpc::ServerWriter<::bluetooth::facade::Data>* writer) override {
160 hci_layer_->GetAclQueueEnd()->RegisterDequeue(
161 facade_handler_, common::Bind(&HciFacadeService::on_acl_ready, common::Unretained(this)));
162 unregister_acl_dequeue_ = true;
163 return pending_acl_events_.RunLoop(context, writer);
164 };
165
166 private:
handle_enqueue_acl(std::promise<void> * promise)167 std::unique_ptr<AclBuilder> handle_enqueue_acl(std::promise<void>* promise) {
168 promise->set_value();
169 hci_layer_->GetAclQueueEnd()->UnregisterEnqueue();
170 return std::move(waiting_acl_packet_);
171 }
172
on_acl_ready()173 void on_acl_ready() {
174 auto acl_ptr = hci_layer_->GetAclQueueEnd()->TryDequeue();
175 ASSERT(acl_ptr != nullptr);
176 ASSERT(acl_ptr->IsValid());
177 LOG_INFO("Got an Acl message for handle 0x%hx", acl_ptr->GetHandle());
178 ::bluetooth::facade::Data incoming;
179 incoming.set_payload(std::string(acl_ptr->begin(), acl_ptr->end()));
180 pending_acl_events_.OnIncomingEvent(std::move(incoming));
181 }
182
on_event(hci::EventView view)183 void on_event(hci::EventView view) {
184 ASSERT(view.IsValid());
185 LOG_INFO("Got an Event %s", EventCodeText(view.GetEventCode()).c_str());
186 ::bluetooth::facade::Data response;
187 response.set_payload(std::string(view.begin(), view.end()));
188 pending_events_.OnIncomingEvent(std::move(response));
189 }
190
on_le_subevent(hci::LeMetaEventView view)191 void on_le_subevent(hci::LeMetaEventView view) {
192 ASSERT(view.IsValid());
193 LOG_INFO("Got an LE Event %s", SubeventCodeText(view.GetSubeventCode()).c_str());
194 ::bluetooth::facade::Data response;
195 response.set_payload(std::string(view.begin(), view.end()));
196 pending_le_events_.OnIncomingEvent(std::move(response));
197 }
198
on_complete(hci::CommandCompleteView view)199 void on_complete(hci::CommandCompleteView view) {
200 ASSERT(view.IsValid());
201 LOG_INFO("Got a Command complete %s", OpCodeText(view.GetCommandOpCode()).c_str());
202 ::bluetooth::facade::Data response;
203 response.set_payload(std::string(view.begin(), view.end()));
204 pending_events_.OnIncomingEvent(std::move(response));
205 }
206
on_status(hci::CommandStatusView view)207 void on_status(hci::CommandStatusView view) {
208 ASSERT(view.IsValid());
209 LOG_INFO("Got a Command status %s", OpCodeText(view.GetCommandOpCode()).c_str());
210 ::bluetooth::facade::Data response;
211 response.set_payload(std::string(view.begin(), view.end()));
212 pending_events_.OnIncomingEvent(std::move(response));
213 }
214
215 HciLayer* hci_layer_;
216 Controller* controller_;
217 ::bluetooth::os::Handler* facade_handler_;
218 ::bluetooth::grpc::GrpcEventQueue<::bluetooth::facade::Data> pending_events_{"StreamEvents"};
219 ::bluetooth::grpc::GrpcEventQueue<::bluetooth::facade::Data> pending_le_events_{"StreamLeSubevents"};
220 ::bluetooth::grpc::GrpcEventQueue<::bluetooth::facade::Data> pending_acl_events_{"StreamAcl"};
221 bool unregister_acl_dequeue_{false};
222 std::unique_ptr<TestAclBuilder> waiting_acl_packet_;
223 bool completed_packets_callback_registered_{false};
224 };
225
ListDependencies(ModuleList * list)226 void HciFacadeModule::ListDependencies(ModuleList* list) {
227 ::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
228 list->add<HciLayer>();
229 list->add<Controller>();
230 }
231
Start()232 void HciFacadeModule::Start() {
233 ::bluetooth::grpc::GrpcFacadeModule::Start();
234 service_ = new HciFacadeService(GetDependency<HciLayer>(), GetDependency<Controller>(), GetHandler());
235 }
236
Stop()237 void HciFacadeModule::Stop() {
238 delete service_;
239 ::bluetooth::grpc::GrpcFacadeModule::Stop();
240 }
241
GetService() const242 ::grpc::Service* HciFacadeModule::GetService() const {
243 return service_;
244 }
245
__anon6b704d4c0202() 246 const ModuleFactory HciFacadeModule::Factory = ::bluetooth::ModuleFactory([]() { return new HciFacadeModule(); });
247
248 } // namespace facade
249 } // namespace hci
250 } // namespace bluetooth
251