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