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,
43 ::bluetooth::os::Handler* facade_handler)
44 : hci_layer_(hci_layer), controller_(controller), facade_handler_(facade_handler) {}
45
~HciFacadeService()46 virtual ~HciFacadeService() {
47 if (unregister_acl_dequeue_) {
48 hci_layer_->GetAclQueueEnd()->UnregisterDequeue();
49 }
50 if (waiting_acl_packet_ != nullptr) {
51 hci_layer_->GetAclQueueEnd()->UnregisterEnqueue();
52 if (waiting_acl_packet_ != nullptr) {
53 waiting_acl_packet_.reset();
54 }
55 }
56 }
57
58 class TestCommandBuilder : public CommandBuilder {
59 public:
TestCommandBuilder(std::vector<uint8_t> bytes)60 explicit TestCommandBuilder(std::vector<uint8_t> bytes)
61 : CommandBuilder(OpCode::NONE), bytes_(std::move(bytes)) {}
size() const62 size_t size() const override { return bytes_.size(); }
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(::grpc::ServerContext* /* context */,
74 const ::blueberry::facade::Data* command,
75 ::google::protobuf::Empty* /* response */) override {
76 auto payload = std::vector<uint8_t>(command->payload().begin(), command->payload().end());
77 auto packet = std::make_unique<TestCommandBuilder>(payload);
78 auto opcode = static_cast<const bluetooth::hci::OpCode>(payload.at(1) << 8 | payload.at(0));
79 if (Checker::IsCommandStatusOpcode(opcode)) {
80 hci_layer_->EnqueueCommand(std::move(packet),
81 facade_handler_->BindOnceOn(this, &HciFacadeService::on_status));
82 } else {
83 hci_layer_->EnqueueCommand(std::move(packet),
84 facade_handler_->BindOnceOn(this, &HciFacadeService::on_complete));
85 }
86 return ::grpc::Status::OK;
87 }
88
RequestEvent(::grpc::ServerContext *,const::blueberry::facade::hci::EventRequest * event,::google::protobuf::Empty *)89 ::grpc::Status RequestEvent(::grpc::ServerContext* /* context */,
90 const ::blueberry::facade::hci::EventRequest* event,
91 ::google::protobuf::Empty* /* response */) override {
92 hci_layer_->RegisterEventHandler(static_cast<EventCode>(event->code()),
93 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(::grpc::ServerContext* /* context */,
98 const ::blueberry::facade::hci::EventRequest* event,
99 ::google::protobuf::Empty* /* response */) override {
100 hci_layer_->RegisterLeEventHandler(
101 static_cast<SubeventCode>(event->code()),
102 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(::grpc::ServerContext* context,
107 const ::google::protobuf::Empty* /* request */,
108 ::grpc::ServerWriter<::blueberry::facade::Data>* writer) override {
109 return pending_events_.RunLoop(context, writer);
110 }
111
StreamLeSubevents(::grpc::ServerContext * context,const::google::protobuf::Empty *,::grpc::ServerWriter<::blueberry::facade::Data> * writer)112 ::grpc::Status StreamLeSubevents(
113 ::grpc::ServerContext* context, const ::google::protobuf::Empty* /* request */,
114 ::grpc::ServerWriter<::blueberry::facade::Data>* writer) override {
115 return pending_le_events_.RunLoop(context, writer);
116 }
117
118 class TestAclBuilder : public AclBuilder {
119 public:
TestAclBuilder(std::vector<uint8_t> payload)120 explicit TestAclBuilder(std::vector<uint8_t> payload)
121 : AclBuilder(0xbad, PacketBoundaryFlag::CONTINUING_FRAGMENT,
122 BroadcastFlag::ACTIVE_PERIPHERAL_BROADCAST),
123 bytes_(std::move(payload)) {}
124
size() const125 size_t size() const override { return bytes_.size(); }
Serialize(BitInserter & bit_inserter) const126 void Serialize(BitInserter& bit_inserter) const override {
127 for (auto&& b : bytes_) {
128 bit_inserter.insert_byte(b);
129 }
130 }
131
132 private:
133 std::vector<uint8_t> bytes_;
134 };
135
SendAcl(::grpc::ServerContext *,const::blueberry::facade::Data * acl,::google::protobuf::Empty *)136 ::grpc::Status SendAcl(::grpc::ServerContext* /* context */, const ::blueberry::facade::Data* acl,
137 ::google::protobuf::Empty* /* response */) override {
138 waiting_acl_packet_ = std::make_unique<TestAclBuilder>(
139 std::vector<uint8_t>(acl->payload().begin(), acl->payload().end()));
140 std::promise<void> enqueued;
141 auto future = enqueued.get_future();
142 if (!completed_packets_callback_registered_) {
143 controller_->RegisterCompletedAclPacketsCallback(
144 facade_handler_->Bind([](uint16_t, uint16_t) { /* do nothing */ }));
145 completed_packets_callback_registered_ = true;
146 }
147 hci_layer_->GetAclQueueEnd()->RegisterEnqueue(
148 facade_handler_, common::Bind(&HciFacadeService::handle_enqueue_acl,
149 common::Unretained(this), common::Unretained(&enqueued)));
150 auto result = future.wait_for(std::chrono::milliseconds(100));
151 log::assert_that(std::future_status::ready == result,
152 "assert failed: std::future_status::ready == result");
153 return ::grpc::Status::OK;
154 }
155
StreamAcl(::grpc::ServerContext * context,const::google::protobuf::Empty *,::grpc::ServerWriter<::blueberry::facade::Data> * writer)156 ::grpc::Status StreamAcl(::grpc::ServerContext* context,
157 const ::google::protobuf::Empty* /* request */,
158 ::grpc::ServerWriter<::blueberry::facade::Data>* writer) override {
159 hci_layer_->GetAclQueueEnd()->RegisterDequeue(
160 facade_handler_,
161 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 log::assert_that(acl_ptr != nullptr, "assert failed: acl_ptr != nullptr");
176 log::assert_that(acl_ptr->IsValid(), "assert failed: acl_ptr->IsValid()");
177 log::info("Got an Acl message for handle 0x{:x}", acl_ptr->GetHandle());
178 ::blueberry::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 log::assert_that(view.IsValid(), "assert failed: view.IsValid()");
185 log::info("Got an Event {}", EventCodeText(view.GetEventCode()));
186 ::blueberry::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 log::assert_that(view.IsValid(), "assert failed: view.IsValid()");
193 log::info("Got an LE Event {}", SubeventCodeText(view.GetSubeventCode()));
194 ::blueberry::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 log::assert_that(view.IsValid(), "assert failed: view.IsValid()");
201 log::info("Got a Command complete {}", OpCodeText(view.GetCommandOpCode()));
202 ::blueberry::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 log::assert_that(view.IsValid(), "assert failed: view.IsValid()");
209 log::info("Got a Command status {}", OpCodeText(view.GetCommandOpCode()));
210 ::blueberry::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<::blueberry::facade::Data> pending_events_{"StreamEvents"};
219 ::bluetooth::grpc::GrpcEventQueue<::blueberry::facade::Data> pending_le_events_{
220 "StreamLeSubevents"};
221 ::bluetooth::grpc::GrpcEventQueue<::blueberry::facade::Data> pending_acl_events_{"StreamAcl"};
222 bool unregister_acl_dequeue_{false};
223 std::unique_ptr<TestAclBuilder> waiting_acl_packet_;
224 bool completed_packets_callback_registered_{false};
225 };
226
ListDependencies(ModuleList * list) const227 void HciFacadeModule::ListDependencies(ModuleList* list) const {
228 ::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
229 list->add<HciLayer>();
230 list->add<Controller>();
231 }
232
Start()233 void HciFacadeModule::Start() {
234 ::bluetooth::grpc::GrpcFacadeModule::Start();
235 service_ = new HciFacadeService(GetDependency<HciLayer>(), GetDependency<Controller>(),
236 GetHandler());
237 }
238
Stop()239 void HciFacadeModule::Stop() {
240 delete service_;
241 ::bluetooth::grpc::GrpcFacadeModule::Stop();
242 }
243
GetService() const244 ::grpc::Service* HciFacadeModule::GetService() const { return service_; }
245
246 const ModuleFactory HciFacadeModule::Factory =
__anonea76b2ac0202() 247 ::bluetooth::ModuleFactory([]() { return new HciFacadeModule(); });
248
249 } // namespace facade
250 } // namespace hci
251 } // namespace bluetooth
252