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