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