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