blob: 9613c75e49e11515a840f324785173f15ffb3713 [file] [log] [blame]
Jack Hefcb2bbf2019-07-31 15:44:05 -07001/*
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#include <cstdint>
17#include <unordered_map>
18
Hansong Zhang7092a1f2019-08-29 14:28:40 -070019#include "common/bidi_queue.h"
Jack Hefcb2bbf2019-07-31 15:44:05 -070020#include "common/bind.h"
21#include "grpc/grpc_event_stream.h"
Martin Brabham94db40c2019-03-29 10:24:52 -070022#include "hci/address.h"
Hansong Zhang7092a1f2019-08-29 14:28:40 -070023#include "hci/facade.h"
Jack Heff38d892019-10-03 17:11:07 -070024#include "l2cap/classic/facade.grpc.pb.h"
25#include "l2cap/classic/facade.h"
26#include "l2cap/classic/l2cap_classic_module.h"
Jack Hefcb2bbf2019-07-31 15:44:05 -070027#include "l2cap/l2cap_packets.h"
28#include "os/log.h"
29#include "packet/raw_builder.h"
30
31using ::grpc::ServerAsyncResponseWriter;
32using ::grpc::ServerAsyncWriter;
33using ::grpc::ServerContext;
34
35using ::bluetooth::facade::EventStreamRequest;
36using ::bluetooth::packet::RawBuilder;
37
38namespace bluetooth {
39namespace l2cap {
Jack Heff38d892019-10-03 17:11:07 -070040namespace classic {
Jack Hefcb2bbf2019-07-31 15:44:05 -070041
42class L2capModuleFacadeService : public L2capModuleFacade::Service {
43 public:
Jack Heff38d892019-10-03 17:11:07 -070044 L2capModuleFacadeService(L2capClassicModule* l2cap_layer, os::Handler* facade_handler)
Jack Hefcb2bbf2019-07-31 15:44:05 -070045 : l2cap_layer_(l2cap_layer), facade_handler_(facade_handler) {
46 ASSERT(l2cap_layer_ != nullptr);
47 ASSERT(facade_handler_ != nullptr);
48 }
49
Hansong Zhang7092a1f2019-08-29 14:28:40 -070050 class ConnectionCompleteCallback
51 : public grpc::GrpcEventStreamCallback<ConnectionCompleteEvent, ConnectionCompleteEvent> {
52 public:
53 void OnWriteResponse(ConnectionCompleteEvent* response, const ConnectionCompleteEvent& event) override {
54 response->CopyFrom(event);
55 }
56
57 } connection_complete_callback_;
58 ::bluetooth::grpc::GrpcEventStream<ConnectionCompleteEvent, ConnectionCompleteEvent> connection_complete_stream_{
59 &connection_complete_callback_};
60
Hansong Zhangcd0c3192019-09-20 15:50:42 -070061 ::grpc::Status FetchConnectionComplete(::grpc::ServerContext* context,
62 const ::bluetooth::facade::EventStreamRequest* request,
63 ::grpc::ServerWriter<classic::ConnectionCompleteEvent>* writer) override {
Hansong Zhang7092a1f2019-08-29 14:28:40 -070064 return connection_complete_stream_.HandleRequest(context, request, writer);
65 }
66
67 ::grpc::Status Connect(::grpc::ServerContext* context, const facade::BluetoothAddress* request,
68 ::google::protobuf::Empty* response) override {
Jack Heff38d892019-10-03 17:11:07 -070069 auto fixed_channel_manager = l2cap_layer_->GetFixedChannelManager();
Hansong Zhang7092a1f2019-08-29 14:28:40 -070070 hci::Address peer;
71 ASSERT(hci::Address::FromString(request->address(), peer));
Jack Heff38d892019-10-03 17:11:07 -070072 fixed_channel_manager->ConnectServices(peer, common::BindOnce([](FixedChannelManager::ConnectionResult) {}),
Hansong Zhang7092a1f2019-08-29 14:28:40 -070073 facade_handler_);
Jack Hefcb2bbf2019-07-31 15:44:05 -070074 return ::grpc::Status::OK;
75 }
76
Hansong Zhangcd0c3192019-09-20 15:50:42 -070077 ::grpc::Status SendL2capPacket(::grpc::ServerContext* context, const classic::L2capPacket* request,
78 SendL2capPacketResult* response) override {
79 if (fixed_channel_helper_map_.find(request->channel()) == fixed_channel_helper_map_.end()) {
Hansong Zhang7092a1f2019-08-29 14:28:40 -070080 return ::grpc::Status(::grpc::StatusCode::FAILED_PRECONDITION, "Channel not registered");
81 }
82 std::vector<uint8_t> packet(request->payload().begin(), request->payload().end());
Hansong Zhangcd0c3192019-09-20 15:50:42 -070083 fixed_channel_helper_map_[request->channel()]->SendPacket(packet);
84 response->set_result_type(SendL2capPacketResultType::OK);
85 return ::grpc::Status::OK;
86 }
87
88 ::grpc::Status SendDynamicChannelPacket(::grpc::ServerContext* context, const DynamicChannelPacket* request,
89 ::google::protobuf::Empty* response) override {
90 if (dynamic_channel_helper_map_.find(request->psm()) == dynamic_channel_helper_map_.end()) {
91 return ::grpc::Status(::grpc::StatusCode::FAILED_PRECONDITION, "Psm not registered");
92 }
93 std::vector<uint8_t> packet(request->payload().begin(), request->payload().end());
94 dynamic_channel_helper_map_[request->psm()]->SendPacket(packet);
Hansong Zhang7092a1f2019-08-29 14:28:40 -070095 return ::grpc::Status::OK;
96 }
97
Hansong Zhangd1b6c9b2019-10-22 16:11:53 -070098 ::grpc::Status OpenChannel(::grpc::ServerContext* context,
99 const ::bluetooth::l2cap::classic::OpenChannelRequest* request,
100 ::google::protobuf::Empty* response) override {
101 auto psm = request->psm();
Hansong Zhanga6312532019-11-19 14:01:36 -0800102 auto mode = request->mode();
Hansong Zhangd1b6c9b2019-10-22 16:11:53 -0700103 dynamic_channel_helper_map_.emplace(
Hansong Zhanga6312532019-11-19 14:01:36 -0800104 psm, std::make_unique<L2capDynamicChannelHelper>(this, l2cap_layer_, facade_handler_, psm, mode));
Hansong Zhangd1b6c9b2019-10-22 16:11:53 -0700105 hci::Address peer;
106 ASSERT(hci::Address::FromString(request->remote().address(), peer));
107 dynamic_channel_helper_map_[psm]->Connect(peer);
108 return ::grpc::Status::OK;
109 }
110
Hansong Zhang7092a1f2019-08-29 14:28:40 -0700111 ::grpc::Status FetchL2capData(::grpc::ServerContext* context, const ::bluetooth::facade::EventStreamRequest* request,
Hansong Zhangcd0c3192019-09-20 15:50:42 -0700112 ::grpc::ServerWriter<classic::L2capPacket>* writer) override {
Hansong Zhang7092a1f2019-08-29 14:28:40 -0700113 return l2cap_stream_.HandleRequest(context, request, writer);
114 }
115
Hansong Zhangcd0c3192019-09-20 15:50:42 -0700116 ::grpc::Status RegisterChannel(::grpc::ServerContext* context, const classic::RegisterChannelRequest* request,
Hansong Zhang7092a1f2019-08-29 14:28:40 -0700117 ::google::protobuf::Empty* response) override {
Hansong Zhangcd0c3192019-09-20 15:50:42 -0700118 if (fixed_channel_helper_map_.find(request->channel()) != fixed_channel_helper_map_.end()) {
Hansong Zhang7092a1f2019-08-29 14:28:40 -0700119 return ::grpc::Status(::grpc::StatusCode::FAILED_PRECONDITION, "Already registered");
120 }
Hansong Zhangcd0c3192019-09-20 15:50:42 -0700121 fixed_channel_helper_map_.emplace(request->channel(), std::make_unique<L2capFixedChannelHelper>(
122 this, l2cap_layer_, facade_handler_, request->channel()));
Hansong Zhang7092a1f2019-08-29 14:28:40 -0700123
124 return ::grpc::Status::OK;
125 }
126
127 class L2capFixedChannelHelper {
128 public:
Jack Heff38d892019-10-03 17:11:07 -0700129 L2capFixedChannelHelper(L2capModuleFacadeService* service, L2capClassicModule* l2cap_layer, os::Handler* handler,
130 Cid cid)
Hansong Zhang7092a1f2019-08-29 14:28:40 -0700131 : facade_service_(service), l2cap_layer_(l2cap_layer), handler_(handler), cid_(cid) {
Jack Heff38d892019-10-03 17:11:07 -0700132 fixed_channel_manager_ = l2cap_layer_->GetFixedChannelManager();
Hansong Zhang7092a1f2019-08-29 14:28:40 -0700133 fixed_channel_manager_->RegisterService(
134 cid, {},
135 common::BindOnce(&L2capFixedChannelHelper::on_l2cap_service_registration_complete, common::Unretained(this)),
136 common::Bind(&L2capFixedChannelHelper::on_connection_open, common::Unretained(this)), handler_);
137 }
138
Jack Heff38d892019-10-03 17:11:07 -0700139 void on_l2cap_service_registration_complete(FixedChannelManager::RegistrationResult registration_result,
140 std::unique_ptr<FixedChannelService> service) {
Hansong Zhang7092a1f2019-08-29 14:28:40 -0700141 service_ = std::move(service);
142 }
143
Jack Heff38d892019-10-03 17:11:07 -0700144 void on_connection_open(std::unique_ptr<FixedChannel> channel) {
Hansong Zhang7092a1f2019-08-29 14:28:40 -0700145 ConnectionCompleteEvent event;
146 event.mutable_remote()->set_address(channel->GetDevice().ToString());
147 facade_service_->connection_complete_stream_.OnIncomingEvent(event);
148 channel_ = std::move(channel);
149 }
150
151 void SendPacket(std::vector<uint8_t> packet) {
152 if (channel_ == nullptr) {
153 LOG_WARN("Channel is not open");
154 return;
155 }
156 channel_->GetQueueUpEnd()->RegisterEnqueue(
157 handler_, common::Bind(&L2capFixedChannelHelper::enqueue_callback, common::Unretained(this), packet));
158 }
159
160 void on_incoming_packet() {
161 auto packet = channel_->GetQueueUpEnd()->TryDequeue();
162 std::string data = std::string(packet->begin(), packet->end());
163 L2capPacket l2cap_data;
164 l2cap_data.set_channel(cid_);
165 l2cap_data.set_payload(data);
166 facade_service_->l2cap_stream_.OnIncomingEvent(l2cap_data);
167 }
168
169 std::unique_ptr<packet::BasePacketBuilder> enqueue_callback(std::vector<uint8_t> packet) {
170 auto packet_one = std::make_unique<packet::RawBuilder>();
171 packet_one->AddOctets(packet);
172 channel_->GetQueueUpEnd()->UnregisterEnqueue();
173 return packet_one;
174 };
175
176 L2capModuleFacadeService* facade_service_;
Jack Heff38d892019-10-03 17:11:07 -0700177 L2capClassicModule* l2cap_layer_;
Hansong Zhang7092a1f2019-08-29 14:28:40 -0700178 os::Handler* handler_;
Jack Heff38d892019-10-03 17:11:07 -0700179 std::unique_ptr<FixedChannelManager> fixed_channel_manager_;
180 std::unique_ptr<FixedChannelService> service_;
181 std::unique_ptr<FixedChannel> channel_ = nullptr;
Hansong Zhang7092a1f2019-08-29 14:28:40 -0700182 Cid cid_;
183 };
184
Hansong Zhangcd0c3192019-09-20 15:50:42 -0700185 ::grpc::Status SetDynamicChannel(::grpc::ServerContext* context, const SetEnableDynamicChannelRequest* request,
186 google::protobuf::Empty* response) override {
Hansong Zhanga6312532019-11-19 14:01:36 -0800187 dynamic_channel_helper_map_.emplace(
188 request->psm(), std::make_unique<L2capDynamicChannelHelper>(this, l2cap_layer_, facade_handler_, request->psm(),
189 request->retransmission_mode()));
Hansong Zhangcd0c3192019-09-20 15:50:42 -0700190 return ::grpc::Status::OK;
191 }
192
193 class L2capDynamicChannelHelper {
194 public:
195 L2capDynamicChannelHelper(L2capModuleFacadeService* service, L2capClassicModule* l2cap_layer, os::Handler* handler,
Hansong Zhanga6312532019-11-19 14:01:36 -0800196 Psm psm, RetransmissionFlowControlMode mode)
Hansong Zhangcd0c3192019-09-20 15:50:42 -0700197 : facade_service_(service), l2cap_layer_(l2cap_layer), handler_(handler), psm_(psm) {
198 dynamic_channel_manager_ = l2cap_layer_->GetDynamicChannelManager();
Hansong Zhanga6312532019-11-19 14:01:36 -0800199 DynamicChannelConfigurationOption configuration_option;
200 if (mode == RetransmissionFlowControlMode::BASIC) {
201 configuration_option.channel_mode =
202 DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC;
203 } else if (mode == RetransmissionFlowControlMode::ERTM) {
204 configuration_option.channel_mode =
205 DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION;
206 }
Hansong Zhangcd0c3192019-09-20 15:50:42 -0700207 dynamic_channel_manager_->RegisterService(
Hansong Zhanga6312532019-11-19 14:01:36 -0800208 psm, configuration_option, {},
Hansong Zhangcd0c3192019-09-20 15:50:42 -0700209 common::BindOnce(&L2capDynamicChannelHelper::on_l2cap_service_registration_complete,
210 common::Unretained(this)),
211 common::Bind(&L2capDynamicChannelHelper::on_connection_open, common::Unretained(this)), handler_);
212 }
213
Hansong Zhangd1b6c9b2019-10-22 16:11:53 -0700214 void Connect(hci::Address address) {
Hansong Zhanga6312532019-11-19 14:01:36 -0800215 // TODO: specify channel mode
Hansong Zhangd1b6c9b2019-10-22 16:11:53 -0700216 dynamic_channel_manager_->ConnectChannel(
Hansong Zhanga6312532019-11-19 14:01:36 -0800217 address, {}, psm_, common::Bind(&L2capDynamicChannelHelper::on_connection_open, common::Unretained(this)),
Hansong Zhangd1b6c9b2019-10-22 16:11:53 -0700218 common::Bind(&L2capDynamicChannelHelper::on_connect_fail, common::Unretained(this)), handler_);
219 }
220
Hansong Zhangcd0c3192019-09-20 15:50:42 -0700221 void on_l2cap_service_registration_complete(DynamicChannelManager::RegistrationResult registration_result,
222 std::unique_ptr<DynamicChannelService> service) {}
223
224 void on_connection_open(std::unique_ptr<DynamicChannel> channel) {
225 ConnectionCompleteEvent event;
226 event.mutable_remote()->set_address(channel->GetDevice().ToString());
227 facade_service_->connection_complete_stream_.OnIncomingEvent(event);
228 channel_ = std::move(channel);
229 }
230
Hansong Zhangd1b6c9b2019-10-22 16:11:53 -0700231 void on_connect_fail(DynamicChannelManager::ConnectionResult result) {}
232
Hansong Zhangcd0c3192019-09-20 15:50:42 -0700233 void on_incoming_packet() {
234 auto packet = channel_->GetQueueUpEnd()->TryDequeue();
235 std::string data = std::string(packet->begin(), packet->end());
236 L2capPacket l2cap_data;
237 // l2cap_data.set_channel(cid_);
238 l2cap_data.set_payload(data);
239 facade_service_->l2cap_stream_.OnIncomingEvent(l2cap_data);
240 }
241
242 void SendPacket(std::vector<uint8_t> packet) {
243 if (channel_ == nullptr) {
244 LOG_WARN("Channel is not open");
245 return;
246 }
247 channel_->GetQueueUpEnd()->RegisterEnqueue(
248 handler_, common::Bind(&L2capDynamicChannelHelper::enqueue_callback, common::Unretained(this), packet));
249 }
250
251 std::unique_ptr<packet::BasePacketBuilder> enqueue_callback(std::vector<uint8_t> packet) {
Hansong Zhanga6312532019-11-19 14:01:36 -0800252 auto packet_one = std::make_unique<packet::RawBuilder>(2000);
Hansong Zhangcd0c3192019-09-20 15:50:42 -0700253 packet_one->AddOctets(packet);
254 channel_->GetQueueUpEnd()->UnregisterEnqueue();
255 return packet_one;
256 };
257
258 L2capModuleFacadeService* facade_service_;
259 L2capClassicModule* l2cap_layer_;
260 os::Handler* handler_;
261 std::unique_ptr<DynamicChannelManager> dynamic_channel_manager_;
262 std::unique_ptr<DynamicChannelService> service_;
263 std::unique_ptr<DynamicChannel> channel_ = nullptr;
264 Psm psm_;
265 };
266
267 L2capClassicModule* l2cap_layer_;
Jack Hefcb2bbf2019-07-31 15:44:05 -0700268 ::bluetooth::os::Handler* facade_handler_;
Hansong Zhangcd0c3192019-09-20 15:50:42 -0700269 std::map<Cid, std::unique_ptr<L2capFixedChannelHelper>> fixed_channel_helper_map_;
270 std::map<Psm, std::unique_ptr<L2capDynamicChannelHelper>> dynamic_channel_helper_map_;
Hansong Zhang7092a1f2019-08-29 14:28:40 -0700271
272 class L2capStreamCallback : public ::bluetooth::grpc::GrpcEventStreamCallback<L2capPacket, L2capPacket> {
273 public:
274 L2capStreamCallback(L2capModuleFacadeService* service) : service_(service) {}
275
276 ~L2capStreamCallback() {
Hansong Zhangcd0c3192019-09-20 15:50:42 -0700277 for (const auto& connection : service_->fixed_channel_helper_map_) {
278 if (subscribed_fixed_channel_[connection.first] && connection.second->channel_ != nullptr) {
Hansong Zhang7092a1f2019-08-29 14:28:40 -0700279 connection.second->channel_->GetQueueUpEnd()->UnregisterDequeue();
Hansong Zhangcd0c3192019-09-20 15:50:42 -0700280 subscribed_fixed_channel_[connection.first] = false;
281 }
282 }
283
284 for (const auto& connection : service_->dynamic_channel_helper_map_) {
285 if (subscribed_dynamic_channel_[connection.first] && connection.second->channel_ != nullptr) {
286 connection.second->channel_->GetQueueUpEnd()->UnregisterDequeue();
287 subscribed_dynamic_channel_[connection.first] = false;
Hansong Zhang7092a1f2019-08-29 14:28:40 -0700288 }
289 }
290 }
291
292 void OnSubscribe() override {
Hansong Zhangcd0c3192019-09-20 15:50:42 -0700293 for (auto& connection : service_->fixed_channel_helper_map_) {
294 if (!subscribed_fixed_channel_[connection.first] && connection.second->channel_ != nullptr) {
Hansong Zhang7092a1f2019-08-29 14:28:40 -0700295 connection.second->channel_->GetQueueUpEnd()->RegisterDequeue(
296 service_->facade_handler_,
297 common::Bind(&L2capFixedChannelHelper::on_incoming_packet, common::Unretained(connection.second.get())));
Hansong Zhangcd0c3192019-09-20 15:50:42 -0700298 subscribed_fixed_channel_[connection.first] = true;
299 }
300 }
301
302 for (auto& connection : service_->dynamic_channel_helper_map_) {
303 if (!subscribed_dynamic_channel_[connection.first] && connection.second->channel_ != nullptr) {
304 connection.second->channel_->GetQueueUpEnd()->RegisterDequeue(
305 service_->facade_handler_, common::Bind(&L2capDynamicChannelHelper::on_incoming_packet,
306 common::Unretained(connection.second.get())));
307 subscribed_dynamic_channel_[connection.first] = true;
Hansong Zhang7092a1f2019-08-29 14:28:40 -0700308 }
309 }
310 }
311
312 void OnUnsubscribe() override {
Hansong Zhangcd0c3192019-09-20 15:50:42 -0700313 for (const auto& connection : service_->fixed_channel_helper_map_) {
314 if (subscribed_fixed_channel_[connection.first] && connection.second->channel_ != nullptr) {
Hansong Zhang7092a1f2019-08-29 14:28:40 -0700315 connection.second->channel_->GetQueueUpEnd()->UnregisterDequeue();
Hansong Zhangcd0c3192019-09-20 15:50:42 -0700316 subscribed_fixed_channel_[connection.first] = false;
317 }
318 }
319
320 for (const auto& connection : service_->dynamic_channel_helper_map_) {
321 if (subscribed_dynamic_channel_[connection.first] && connection.second->channel_ != nullptr) {
322 connection.second->channel_->GetQueueUpEnd()->UnregisterDequeue();
323 subscribed_dynamic_channel_[connection.first] = false;
Hansong Zhang7092a1f2019-08-29 14:28:40 -0700324 }
325 }
326 }
327
328 void OnWriteResponse(L2capPacket* response, const L2capPacket& event) override {
329 response->CopyFrom(event);
330 }
331
332 L2capModuleFacadeService* service_;
Hansong Zhangcd0c3192019-09-20 15:50:42 -0700333 std::map<Cid, bool> subscribed_fixed_channel_;
334 std::map<Psm, bool> subscribed_dynamic_channel_;
Hansong Zhang7092a1f2019-08-29 14:28:40 -0700335
336 } l2cap_stream_callback_{this};
337 ::bluetooth::grpc::GrpcEventStream<L2capPacket, L2capPacket> l2cap_stream_{&l2cap_stream_callback_};
338
Jack Hefcb2bbf2019-07-31 15:44:05 -0700339 std::mutex mutex_;
340};
341
342void L2capModuleFacadeModule::ListDependencies(ModuleList* list) {
343 ::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
Jack Heff38d892019-10-03 17:11:07 -0700344 list->add<l2cap::classic::L2capClassicModule>();
Hansong Zhang7092a1f2019-08-29 14:28:40 -0700345 list->add<hci::HciLayer>();
Jack Hefcb2bbf2019-07-31 15:44:05 -0700346}
347
348void L2capModuleFacadeModule::Start() {
349 ::bluetooth::grpc::GrpcFacadeModule::Start();
Hansong Zhang7092a1f2019-08-29 14:28:40 -0700350 GetDependency<hci::HciLayer>()->EnqueueCommand(hci::WriteScanEnableBuilder::Create(hci::ScanEnable::PAGE_SCAN_ONLY),
351 common::BindOnce([](hci::CommandCompleteView) {}), GetHandler());
Jack Heff38d892019-10-03 17:11:07 -0700352 service_ = new L2capModuleFacadeService(GetDependency<l2cap::classic::L2capClassicModule>(), GetHandler());
Jack Hefcb2bbf2019-07-31 15:44:05 -0700353}
354
355void L2capModuleFacadeModule::Stop() {
356 delete service_;
357 ::bluetooth::grpc::GrpcFacadeModule::Stop();
358}
359
360::grpc::Service* L2capModuleFacadeModule::GetService() const {
361 return service_;
362}
363
364const ModuleFactory L2capModuleFacadeModule::Factory =
365 ::bluetooth::ModuleFactory([]() { return new L2capModuleFacadeModule(); });
366
Jack Heff38d892019-10-03 17:11:07 -0700367} // namespace classic
Jack Hefcb2bbf2019-07-31 15:44:05 -0700368} // namespace l2cap
369} // namespace bluetooth