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