1 /*
2  * Copyright 2021 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 "iso/facade.h"
17 
18 #include "common/contextual_callback.h"
19 #include "grpc/grpc_event_queue.h"
20 #include "hci/acl_manager.h"
21 #include "hci/address_with_type.h"
22 #include "hci/le_address_manager.h"
23 #include "iso/facade.grpc.pb.h"
24 #include "iso/iso_module.h"
25 #include "os/handler.h"
26 
27 using bluetooth::hci::AclManager;
28 
29 namespace bluetooth {
30 namespace iso {
31 
32 class IsoModuleFacadeService : public IsoModuleFacade::Service {
33  public:
IsoModuleFacadeService(IsoModule * iso_module,AclManager * acl_manager,::bluetooth::os::Handler * iso_handler)34   IsoModuleFacadeService(IsoModule* iso_module, AclManager* acl_manager, ::bluetooth::os::Handler* iso_handler)
35       : iso_module_(iso_module), acl_manager_(acl_manager), iso_handler_(iso_handler) {
36     ASSERT(iso_module_);
37     ASSERT(iso_handler_);
38 
39     iso_module_->GetIsoManager()->RegisterIsoEstablishedCallback(iso_handler_->Bind(
40         [](::bluetooth::grpc::GrpcEventQueue<LeIsoEventsMsg>* le_iso_events_, uint16_t cis_connection_handle) {
41           LeIsoEventsMsg msg;
42           msg.set_message_type(IsoMsgType::ISO_CIS_ESTABLISHED);
43           msg.add_cis_handle(cis_connection_handle);
44           le_iso_events_->OnIncomingEvent(msg);
45         },
46         &le_iso_events_));
47 
48     iso_module_->GetIsoManager()->RegisterIsoDataCallback(
49         iso_handler_->BindOn(this, &IsoModuleFacadeService::OnIsoPacketReceived));
50   }
51 
LeSetCigParameters(::grpc::ServerContext * context,const::bluetooth::iso::LeSetCigParametersRequest * request,::google::protobuf::Empty * response)52   ::grpc::Status LeSetCigParameters(
53       ::grpc::ServerContext* context,
54       const ::bluetooth::iso::LeSetCigParametersRequest* request,
55       ::google::protobuf::Empty* response) override {
56     std::vector<hci::CisParametersConfig> cis_config;
57 
58     hci::CisParametersConfig cfg;
59     cfg.cis_id_ = request->cis_id();
60     cfg.max_sdu_m_to_s_ = request->max_sdu_m_to_s();
61     cfg.max_sdu_s_to_m_ = request->max_sdu_s_to_m();
62     cfg.phy_m_to_s_ = request->phy_m_to_s();
63     cfg.phy_s_to_m_ = request->phy_s_to_m();
64     cfg.rtn_m_to_s_ = request->rtn_m_to_s();
65     cfg.rtn_s_to_m_ = request->rtn_s_to_m();
66 
67     cis_config.push_back(cfg);
68 
69     iso_module_->GetIsoManager()->SetCigParameters(
70         request->cig_id(),
71         request->sdu_interval_m_to_s(),
72         request->sdu_interval_s_to_m(),
73         static_cast<hci::ClockAccuracy>(request->peripherals_clock_accuracy()),
74         static_cast<hci::Packing>(request->packing()),
75         static_cast<hci::Enable>(request->framing()),
76         request->max_transport_latency_m_to_s(),
77         request->max_transport_latency_s_to_m(),
78         cis_config,
79         iso_handler_->BindOnce(
80             [](::bluetooth::grpc::GrpcEventQueue<LeIsoEventsMsg>* le_iso_events_, std::vector<uint16_t> conn_handles) {
81               LeIsoEventsMsg msg;
82 
83               msg.set_message_type(IsoMsgType::ISO_PARAMETERS_SET_COMPLETE);
84               for (const uint16_t conn_handle : conn_handles) {
85                 msg.add_cis_handle(conn_handle);
86               }
87               le_iso_events_->OnIncomingEvent(msg);
88             },
89             &le_iso_events_));
90     return ::grpc::Status::OK;
91   }
92 
LeSetCigParametersTest(::grpc::ServerContext * context,const::bluetooth::iso::LeSetCigParametersTestRequest * request,::google::protobuf::Empty * response)93   ::grpc::Status LeSetCigParametersTest(
94       ::grpc::ServerContext* context,
95       const ::bluetooth::iso::LeSetCigParametersTestRequest* request,
96       ::google::protobuf::Empty* response) override {
97     std::vector<hci::LeCisParametersTestConfig> cis_config;
98 
99     for (const auto& cc : request->cis_configs()) {
100       hci::LeCisParametersTestConfig cfg;
101       cfg.cis_id_ = cc.cis_id();
102       cfg.nse_ = cc.nse();
103       cfg.max_sdu_m_to_s_ = cc.max_sdu_m_to_s();
104       cfg.max_sdu_s_to_m_ = cc.max_sdu_s_to_m();
105       cfg.max_pdu_m_to_s_ = cc.max_pdu_m_to_s();
106       cfg.max_pdu_s_to_m_ = cc.max_pdu_s_to_m();
107       cfg.phy_m_to_s_ = cc.phy_m_to_s();
108       cfg.phy_s_to_m_ = cc.phy_s_to_m();
109       cfg.bn_m_to_s_ = cc.bn_m_to_s();
110       cfg.bn_s_to_m_ = cc.bn_s_to_m();
111       cis_config.push_back(cfg);
112     }
113     iso_module_->GetIsoManager()->SetCigParametersTest(
114         request->cig_id(),
115         request->sdu_interval_m_to_s(),
116         request->sdu_interval_s_to_m(),
117         request->ft_m_to_s(),
118         request->ft_s_to_m(),
119         request->iso_interval(),
120         static_cast<hci::ClockAccuracy>(request->peripherals_clock_accuracy()),
121         static_cast<hci::Packing>(request->packing()),
122         static_cast<hci::Enable>(request->framing()),
123         request->max_transport_latency_m_to_s(),
124         request->max_transport_latency_s_to_m(),
125         cis_config,
126         iso_handler_->BindOnce(
127             [](::bluetooth::grpc::GrpcEventQueue<LeIsoEventsMsg>* le_iso_events_, std::vector<uint16_t> conn_handles) {
128               LeIsoEventsMsg msg;
129 
130               msg.set_message_type(IsoMsgType::ISO_PARAMETERS_SET_COMPLETE);
131               for (const uint16_t conn_handle : conn_handles) {
132                 msg.add_cis_handle(conn_handle);
133               }
134               le_iso_events_->OnIncomingEvent(msg);
135             },
136             &le_iso_events_));
137     return ::grpc::Status::OK;
138   }
139 
LeCreateCis(::grpc::ServerContext * context,const::bluetooth::iso::LeCreateCisRequest * request,::google::protobuf::Empty * response)140   ::grpc::Status LeCreateCis(
141       ::grpc::ServerContext* context,
142       const ::bluetooth::iso::LeCreateCisRequest* request,
143       ::google::protobuf::Empty* response) override {
144     std::vector<std::pair<uint16_t, uint16_t>> create_cis_params;
145     for (const auto& handle_pair : request->handle_pair()) {
146       create_cis_params.push_back(
147           std::make_pair<uint16_t, uint16_t>(handle_pair.cis_handle(), handle_pair.acl_handle()));
148     }
149     iso_module_->GetIsoManager()->LeCreateCis(create_cis_params);
150 
151     return ::grpc::Status::OK;
152   }
153 
FetchIsoData(::grpc::ServerContext * context,const LeCisHandleMsg * request,::grpc::ServerWriter<IsoPacket> * writer)154   ::grpc::Status FetchIsoData(
155       ::grpc::ServerContext* context, const LeCisHandleMsg* request, ::grpc::ServerWriter<IsoPacket>* writer) override {
156     return le_iso_data_.RunLoop(context, writer);
157   }
158 
FetchIsoEvents(::grpc::ServerContext * context,const google::protobuf::Empty * request,::grpc::ServerWriter<LeIsoEventsMsg> * writer)159   ::grpc::Status FetchIsoEvents(
160       ::grpc::ServerContext* context,
161       const google::protobuf::Empty* request,
162       ::grpc::ServerWriter<LeIsoEventsMsg>* writer) override {
163     return le_iso_events_.RunLoop(context, writer);
164   }
165 
SendIsoPacket(::grpc::ServerContext * context,const::bluetooth::iso::IsoPacket * request,::google::protobuf::Empty * response)166   ::grpc::Status SendIsoPacket(
167       ::grpc::ServerContext* context,
168       const ::bluetooth::iso::IsoPacket* request,
169       ::google::protobuf::Empty* response) override {
170     std::vector<uint8_t> packet(request->payload().begin(), request->payload().end());
171     iso_module_->GetIsoManager()->SendIsoPacket(request->handle(), packet);
172     return ::grpc::Status::OK;
173   }
174 
OnIsoPacketReceived(std::unique_ptr<hci::IsoView> iso_view)175   void OnIsoPacketReceived(std::unique_ptr<hci::IsoView> iso_view) {
176     ASSERT(iso_view->IsValid());
177 
178     IsoPacket packet;
179     packet.set_handle(iso_view->GetConnectionHandle());
180 
181     if (iso_view->GetTsFlag() == hci::TimeStampFlag::NOT_PRESENT) {
182       hci::IsoWithoutTimestampView nts = hci::IsoWithoutTimestampView::Create(*iso_view);
183       ASSERT(nts.IsValid());
184 
185       auto data_vec = nts.GetPayload();
186       std::string data = std::string(data_vec.begin(), data_vec.end());
187       packet.set_payload(data);
188       le_iso_data_.OnIncomingEvent(packet);
189     } else {
190       hci::IsoWithTimestampView tsv = hci::IsoWithTimestampView::Create(*iso_view);
191       ASSERT(tsv.IsValid());
192 
193       auto data_vec = tsv.GetPayload();
194       std::string data = std::string(data_vec.begin(), data_vec.end());
195       packet.set_payload(data);
196       le_iso_data_.OnIncomingEvent(packet);
197     }
198   }
199 
200  private:
201   IsoModule* iso_module_;
202   ::bluetooth::grpc::GrpcEventQueue<LeIsoEventsMsg> le_iso_events_{"LE ISO events"};
203   ::bluetooth::grpc::GrpcEventQueue<IsoPacket> le_iso_data_{"LE ISO data"};
204   AclManager* acl_manager_ __attribute__((unused));
205   ::bluetooth::os::Handler* iso_handler_;
206 };
207 
ListDependencies(ModuleList * list)208 void IsoModuleFacadeModule::ListDependencies(ModuleList* list) {
209   ::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
210   list->add<IsoModule>();
211   list->add<AclManager>();
212 }
213 
Start()214 void IsoModuleFacadeModule::Start() {
215   ::bluetooth::grpc::GrpcFacadeModule::Start();
216   service_ = new IsoModuleFacadeService(GetDependency<IsoModule>(), GetDependency<AclManager>(), GetHandler());
217 }
218 
Stop()219 void IsoModuleFacadeModule::Stop() {
220   delete service_;
221   ::bluetooth::grpc::GrpcFacadeModule::Stop();
222 }
223 
GetService() const224 ::grpc::Service* IsoModuleFacadeModule::GetService() const {
225   return service_;
226 }
227 
228 const ModuleFactory IsoModuleFacadeModule::Factory =
__anon5bbe98140402() 229     ::bluetooth::ModuleFactory([]() { return new IsoModuleFacadeModule(); });
230 
231 }  // namespace iso
232 }  // namespace bluetooth
233