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