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 "hal/facade.h"
18 
19 #include <memory>
20 #include <mutex>
21 
22 #include "grpc/grpc_event_queue.h"
23 #include "hal/hal_facade.grpc.pb.h"
24 #include "hal/hci_hal.h"
25 
26 using ::grpc::ServerAsyncResponseWriter;
27 using ::grpc::ServerAsyncWriter;
28 using ::grpc::ServerContext;
29 
30 namespace bluetooth {
31 namespace hal {
32 
33 class HciHalFacadeService : public HciHalFacade::Service, public ::bluetooth::hal::HciHalCallbacks {
34  public:
HciHalFacadeService(HciHal * hal)35   explicit HciHalFacadeService(HciHal* hal) : hal_(hal) {
36     hal->registerIncomingPacketCallback(this);
37   }
38 
~HciHalFacadeService()39   ~HciHalFacadeService() {
40     hal_->unregisterIncomingPacketCallback();
41   }
42 
SendCommand(::grpc::ServerContext * context,const::bluetooth::facade::Data * request,::google::protobuf::Empty * response)43   ::grpc::Status SendCommand(
44       ::grpc::ServerContext* context,
45       const ::bluetooth::facade::Data* request,
46       ::google::protobuf::Empty* response) override {
47     std::unique_lock<std::mutex> lock(mutex_);
48     can_send_hci_command_ = false;
49     std::string req_string = request->payload();
50     hal_->sendHciCommand(std::vector<uint8_t>(req_string.begin(), req_string.end()));
51     while (!can_send_hci_command_) {
52       cv_.wait(lock);
53     }
54     return ::grpc::Status::OK;
55   }
56 
SendAcl(::grpc::ServerContext * context,const::bluetooth::facade::Data * request,::google::protobuf::Empty * response)57   ::grpc::Status SendAcl(
58       ::grpc::ServerContext* context,
59       const ::bluetooth::facade::Data* request,
60       ::google::protobuf::Empty* response) override {
61     std::string req_string = request->payload();
62     hal_->sendAclData(std::vector<uint8_t>(req_string.begin(), req_string.end()));
63     return ::grpc::Status::OK;
64   }
65 
SendSco(::grpc::ServerContext * context,const::bluetooth::facade::Data * request,::google::protobuf::Empty * response)66   ::grpc::Status SendSco(
67       ::grpc::ServerContext* context,
68       const ::bluetooth::facade::Data* request,
69       ::google::protobuf::Empty* response) override {
70     std::string req_string = request->payload();
71     hal_->sendScoData(std::vector<uint8_t>(req_string.begin(), req_string.end()));
72     return ::grpc::Status::OK;
73   }
74 
StreamEvents(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::grpc::ServerWriter<::bluetooth::facade::Data> * writer)75   ::grpc::Status StreamEvents(
76       ::grpc::ServerContext* context,
77       const ::google::protobuf::Empty* request,
78       ::grpc::ServerWriter<::bluetooth::facade::Data>* writer) override {
79     return pending_hci_events_.RunLoop(context, writer);
80   };
81 
StreamAcl(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::grpc::ServerWriter<::bluetooth::facade::Data> * writer)82   ::grpc::Status StreamAcl(
83       ::grpc::ServerContext* context,
84       const ::google::protobuf::Empty* request,
85       ::grpc::ServerWriter<::bluetooth::facade::Data>* writer) override {
86     return pending_acl_events_.RunLoop(context, writer);
87   };
88 
StreamSco(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::grpc::ServerWriter<::bluetooth::facade::Data> * writer)89   ::grpc::Status StreamSco(
90       ::grpc::ServerContext* context,
91       const ::google::protobuf::Empty* request,
92       ::grpc::ServerWriter<::bluetooth::facade::Data>* writer) override {
93     return pending_sco_events_.RunLoop(context, writer);
94   };
95 
StreamIso(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::grpc::ServerWriter<::bluetooth::facade::Data> * writer)96   ::grpc::Status StreamIso(
97       ::grpc::ServerContext* context,
98       const ::google::protobuf::Empty* request,
99       ::grpc::ServerWriter<::bluetooth::facade::Data>* writer) override {
100     return pending_iso_events_.RunLoop(context, writer);
101   };
102 
hciEventReceived(bluetooth::hal::HciPacket event)103   void hciEventReceived(bluetooth::hal::HciPacket event) override {
104     {
105       ::bluetooth::facade::Data response;
106       response.set_payload(std::string(event.begin(), event.end()));
107       pending_hci_events_.OnIncomingEvent(std::move(response));
108     }
109     can_send_hci_command_ = true;
110     cv_.notify_one();
111   }
112 
aclDataReceived(bluetooth::hal::HciPacket data)113   void aclDataReceived(bluetooth::hal::HciPacket data) override {
114     ::bluetooth::facade::Data response;
115     response.set_payload(std::string(data.begin(), data.end()));
116     pending_acl_events_.OnIncomingEvent(std::move(response));
117   }
118 
scoDataReceived(bluetooth::hal::HciPacket data)119   void scoDataReceived(bluetooth::hal::HciPacket data) override {
120     ::bluetooth::facade::Data response;
121     response.set_payload(std::string(data.begin(), data.end()));
122     pending_sco_events_.OnIncomingEvent(std::move(response));
123   }
124 
isoDataReceived(bluetooth::hal::HciPacket data)125   void isoDataReceived(bluetooth::hal::HciPacket data) override {
126     ::bluetooth::facade::Data response;
127     response.set_payload(std::string(data.begin(), data.end()));
128     pending_iso_events_.OnIncomingEvent(std::move(response));
129   }
130 
131  private:
132   HciHal* hal_;
133   bool can_send_hci_command_ = true;
134   mutable std::mutex mutex_;
135   std::condition_variable cv_;
136   ::bluetooth::grpc::GrpcEventQueue<::bluetooth::facade::Data> pending_hci_events_{"StreamEvents"};
137   ::bluetooth::grpc::GrpcEventQueue<::bluetooth::facade::Data> pending_acl_events_{"StreamAcl"};
138   ::bluetooth::grpc::GrpcEventQueue<::bluetooth::facade::Data> pending_sco_events_{"StreamSco"};
139   ::bluetooth::grpc::GrpcEventQueue<::bluetooth::facade::Data> pending_iso_events_{"StreamIso"};
140 };
141 
ListDependencies(ModuleList * list)142 void HciHalFacadeModule::ListDependencies(ModuleList* list) {
143   ::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
144   list->add<HciHal>();
145 }
146 
Start()147 void HciHalFacadeModule::Start() {
148   ::bluetooth::grpc::GrpcFacadeModule::Start();
149   service_ = new HciHalFacadeService(GetDependency<HciHal>());
150 }
151 
Stop()152 void HciHalFacadeModule::Stop() {
153   delete service_;
154   ::bluetooth::grpc::GrpcFacadeModule::Stop();
155 }
156 
GetService() const157 ::grpc::Service* HciHalFacadeModule::GetService() const {
158   return service_;
159 }
160 
__anon8b612eea0102() 161 const ModuleFactory HciHalFacadeModule::Factory = ::bluetooth::ModuleFactory([]() { return new HciHalFacadeModule(); });
162 
163 }  // namespace hal
164 }  // namespace bluetooth
165