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