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 #define LOG_TAG "bt_shim_l2cap"
18
19 #include "main/shim/l2c_api.h"
20 #include "gd/l2cap/le/l2cap_le_module.h"
21 #include "gd/os/log.h"
22 #include "gd/os/queue.h"
23 #include "gd/packet/raw_builder.h"
24 #include "main/shim/btm.h"
25 #include "main/shim/entry.h"
26 #include "main/shim/helpers.h"
27 #include "main/shim/l2cap.h"
28
29 static bluetooth::shim::legacy::L2cap shim_l2cap;
30
31 /**
32 * Classic Service Registration APIs
33 */
L2CA_Register(uint16_t client_psm,tL2CAP_APPL_INFO * callbacks,bool enable_snoop,tL2CAP_ERTM_INFO * p_ertm_info,uint16_t required_mtu)34 uint16_t bluetooth::shim::L2CA_Register(uint16_t client_psm,
35 tL2CAP_APPL_INFO* callbacks,
36 bool enable_snoop,
37 tL2CAP_ERTM_INFO* p_ertm_info,
38 uint16_t required_mtu) {
39 CHECK(callbacks != nullptr);
40
41 if (L2C_INVALID_PSM(client_psm)) {
42 LOG_ERROR("%s Invalid classic psm:%hd", __func__, client_psm);
43 return 0;
44 }
45
46 if ((callbacks->pL2CA_ConfigCfm_Cb == nullptr) ||
47 (callbacks->pL2CA_ConfigInd_Cb == nullptr) ||
48 (callbacks->pL2CA_DataInd_Cb == nullptr) ||
49 (callbacks->pL2CA_DisconnectInd_Cb == nullptr)) {
50 LOG_ERROR("%s Invalid classic callbacks psm:%hd", __func__, client_psm);
51 return 0;
52 }
53
54 /**
55 * Check if this is a registration for an outgoing-only connection.
56 */
57 bool is_outgoing_connection_only = callbacks->pL2CA_ConnectInd_Cb == nullptr;
58 uint16_t psm = shim_l2cap.ConvertClientToRealPsm(client_psm,
59 is_outgoing_connection_only);
60
61 if (shim_l2cap.Classic().IsPsmRegistered(psm)) {
62 LOG_ERROR("%s Already registered classic client_psm:%hd psm:%hd", __func__,
63 client_psm, psm);
64 return 0;
65 }
66 LOG_INFO("%s classic client_psm:%hd psm:%hd", __func__, client_psm, psm);
67
68 return shim_l2cap.RegisterService(psm, callbacks, enable_snoop, p_ertm_info,
69 required_mtu);
70 }
71
L2CA_Deregister(uint16_t client_psm)72 void bluetooth::shim::L2CA_Deregister(uint16_t client_psm) {
73 if (L2C_INVALID_PSM(client_psm)) {
74 LOG_ERROR("%s Invalid classic client_psm:%hd", __func__, client_psm);
75 return;
76 }
77 uint16_t psm = shim_l2cap.ConvertClientToRealPsm(client_psm);
78
79 shim_l2cap.UnregisterService(psm);
80 shim_l2cap.RemoveClientPsm(psm);
81 }
82
L2CA_AllocatePSM(void)83 uint16_t bluetooth::shim::L2CA_AllocatePSM(void) {
84 return shim_l2cap.GetNextDynamicClassicPsm();
85 }
86
L2CA_AllocateLePSM(void)87 uint16_t bluetooth::shim::L2CA_AllocateLePSM(void) {
88 return shim_l2cap.GetNextDynamicLePsm();
89 }
90
L2CA_FreeLePSM(uint16_t psm)91 void bluetooth::shim::L2CA_FreeLePSM(uint16_t psm) {
92 if (!shim_l2cap.Le().IsPsmRegistered(psm)) {
93 LOG_ERROR("%s Not previously registered le psm:%hd", __func__, psm);
94 return;
95 }
96 shim_l2cap.Le().UnregisterPsm(psm);
97 }
98
99 /**
100 * Classic Connection Oriented Channel APIS
101 */
L2CA_ErtmConnectReq(uint16_t psm,const RawAddress & raw_address,tL2CAP_ERTM_INFO * p_ertm_info)102 uint16_t bluetooth::shim::L2CA_ErtmConnectReq(uint16_t psm,
103 const RawAddress& raw_address,
104 tL2CAP_ERTM_INFO* p_ertm_info) {
105 return shim_l2cap.CreateConnection(psm, raw_address);
106 }
107
L2CA_ConnectReq(uint16_t psm,const RawAddress & raw_address)108 uint16_t bluetooth::shim::L2CA_ConnectReq(uint16_t psm,
109 const RawAddress& raw_address) {
110 return shim_l2cap.CreateConnection(psm, raw_address);
111 }
112
L2CA_ErtmConnectRsp(const RawAddress & p_bd_addr,uint8_t id,uint16_t lcid,uint16_t result,uint16_t status,tL2CAP_ERTM_INFO * p_ertm_info)113 bool bluetooth::shim::L2CA_ErtmConnectRsp(const RawAddress& p_bd_addr,
114 uint8_t id, uint16_t lcid,
115 uint16_t result, uint16_t status,
116 tL2CAP_ERTM_INFO* p_ertm_info) {
117 return shim_l2cap.ConnectResponse(p_bd_addr, id, lcid, result, status,
118 p_ertm_info);
119 }
120
L2CA_ConnectRsp(const RawAddress & p_bd_addr,uint8_t id,uint16_t lcid,uint16_t result,uint16_t status)121 bool bluetooth::shim::L2CA_ConnectRsp(const RawAddress& p_bd_addr, uint8_t id,
122 uint16_t lcid, uint16_t result,
123 uint16_t status) {
124 return bluetooth::shim::L2CA_ErtmConnectRsp(p_bd_addr, id, lcid, result,
125 status, nullptr);
126 }
127
L2CA_ConfigReq(uint16_t cid,tL2CAP_CFG_INFO * cfg_info)128 bool bluetooth::shim::L2CA_ConfigReq(uint16_t cid, tL2CAP_CFG_INFO* cfg_info) {
129 return shim_l2cap.ConfigRequest(cid, cfg_info);
130 }
131
L2CA_ConfigRsp(uint16_t cid,tL2CAP_CFG_INFO * cfg_info)132 bool bluetooth::shim::L2CA_ConfigRsp(uint16_t cid, tL2CAP_CFG_INFO* cfg_info) {
133 return shim_l2cap.ConfigResponse(cid, cfg_info);
134 }
135
L2CA_DisconnectReq(uint16_t cid)136 bool bluetooth::shim::L2CA_DisconnectReq(uint16_t cid) {
137 return shim_l2cap.DisconnectRequest(cid);
138 }
139
L2CA_DisconnectRsp(uint16_t cid)140 bool bluetooth::shim::L2CA_DisconnectRsp(uint16_t cid) {
141 return shim_l2cap.DisconnectResponse(cid);
142 }
143
144 /**
145 * Le Connection Oriented Channel APIs
146 */
L2CA_RegisterLECoc(uint16_t psm,tL2CAP_APPL_INFO * callbacks)147 uint16_t bluetooth::shim::L2CA_RegisterLECoc(uint16_t psm,
148 tL2CAP_APPL_INFO* callbacks) {
149 LOG_INFO("UNIMPLEMENTED %s psm:%hd callbacks:%p", __func__, psm, callbacks);
150 return 0;
151 }
152
L2CA_DeregisterLECoc(uint16_t psm)153 void bluetooth::shim::L2CA_DeregisterLECoc(uint16_t psm) {
154 LOG_INFO("UNIMPLEMENTED %s psm:%hd", __func__, psm);
155 }
156
L2CA_ConnectLECocReq(uint16_t psm,const RawAddress & p_bd_addr,tL2CAP_LE_CFG_INFO * p_cfg)157 uint16_t bluetooth::shim::L2CA_ConnectLECocReq(uint16_t psm,
158 const RawAddress& p_bd_addr,
159 tL2CAP_LE_CFG_INFO* p_cfg) {
160 LOG_INFO("UNIMPLEMENTED %s psm:%hd addr:%s p_cfg:%p", __func__, psm,
161 p_bd_addr.ToString().c_str(), p_cfg);
162 return 0;
163 }
164
L2CA_ConnectLECocRsp(const RawAddress & p_bd_addr,uint8_t id,uint16_t lcid,uint16_t result,uint16_t status,tL2CAP_LE_CFG_INFO * p_cfg)165 bool bluetooth::shim::L2CA_ConnectLECocRsp(const RawAddress& p_bd_addr,
166 uint8_t id, uint16_t lcid,
167 uint16_t result, uint16_t status,
168 tL2CAP_LE_CFG_INFO* p_cfg) {
169 LOG_INFO(
170 "UNIMPLEMENTED %s addr:%s id:%hhd lcid:%hd result:%hd status:%hd "
171 "p_cfg:%p",
172 __func__, p_bd_addr.ToString().c_str(), id, lcid, result, status, p_cfg);
173 return false;
174 }
175
L2CA_GetPeerLECocConfig(uint16_t lcid,tL2CAP_LE_CFG_INFO * peer_cfg)176 bool bluetooth::shim::L2CA_GetPeerLECocConfig(uint16_t lcid,
177 tL2CAP_LE_CFG_INFO* peer_cfg) {
178 LOG_INFO("UNIMPLEMENTED %s lcid:%hd peer_cfg:%p", __func__, lcid, peer_cfg);
179 return false;
180 }
181
182 /**
183 * Channel Data Writes
184 */
L2CA_SetConnectionCallbacks(uint16_t cid,const tL2CAP_APPL_INFO * callbacks)185 bool bluetooth::shim::L2CA_SetConnectionCallbacks(
186 uint16_t cid, const tL2CAP_APPL_INFO* callbacks) {
187 LOG_INFO("Unsupported API %s", __func__);
188 return false;
189 }
190
L2CA_DataWrite(uint16_t cid,BT_HDR * p_data)191 uint8_t bluetooth::shim::L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) {
192 bool write_success = shim_l2cap.Write(cid, p_data);
193 return write_success ? L2CAP_DW_SUCCESS : L2CAP_DW_FAILED;
194 }
195
196 /**
197 * L2cap Layer APIs
198 */
L2CA_SetDesireRole(uint8_t new_role)199 uint8_t bluetooth::shim::L2CA_SetDesireRole(uint8_t new_role) {
200 LOG_INFO("UNIMPLEMENTED %s", __func__);
201 return 0;
202 }
203
204 /**
205 * Link APIs
206 */
L2CA_SetIdleTimeoutByBdAddr(const RawAddress & bd_addr,uint16_t timeout,tBT_TRANSPORT transport)207 bool bluetooth::shim::L2CA_SetIdleTimeoutByBdAddr(const RawAddress& bd_addr,
208 uint16_t timeout,
209 tBT_TRANSPORT transport) {
210 LOG_INFO("UNIMPLEMENTED %s", __func__);
211 return false;
212 }
213
L2CA_SetAclPriority(const RawAddress & bd_addr,uint8_t priority)214 bool bluetooth::shim::L2CA_SetAclPriority(const RawAddress& bd_addr,
215 uint8_t priority) {
216 LOG_INFO("UNIMPLEMENTED %s", __func__);
217 return false;
218 }
219
L2CA_SetFlushTimeout(const RawAddress & bd_addr,uint16_t flush_tout)220 bool bluetooth::shim::L2CA_SetFlushTimeout(const RawAddress& bd_addr,
221 uint16_t flush_tout) {
222 LOG_INFO("UNIMPLEMENTED %s", __func__);
223 return false;
224 }
225
L2CA_GetPeerFeatures(const RawAddress & bd_addr,uint32_t * p_ext_feat,uint8_t * p_chnl_mask)226 bool bluetooth::shim::L2CA_GetPeerFeatures(const RawAddress& bd_addr,
227 uint32_t* p_ext_feat,
228 uint8_t* p_chnl_mask) {
229 LOG_INFO("UNIMPLEMENTED %s", __func__);
230 return false;
231 }
232
233 using bluetooth::hci::AddressWithType;
234 using bluetooth::l2cap::le::FixedChannel;
235 using bluetooth::l2cap::le::FixedChannelManager;
236 using bluetooth::l2cap::le::FixedChannelService;
237
238 static constexpr uint16_t kAttCid = 4;
239
240 struct LeFixedChannelHelper {
LeFixedChannelHelperLeFixedChannelHelper241 LeFixedChannelHelper(uint16_t cid) : cid_(cid) {}
242
243 uint16_t cid_;
244
on_registration_completeLeFixedChannelHelper245 void on_registration_complete(FixedChannelManager::RegistrationResult result,
246 std::unique_ptr<FixedChannelService> service) {
247 if (result != FixedChannelManager::RegistrationResult::SUCCESS) {
248 LOG(ERROR) << "Channel is not registered. cid=" << +cid_;
249 return;
250 }
251 channel_service_ = std::move(service);
252 }
253
254 std::unique_ptr<FixedChannelService> channel_service_ = nullptr;
255
on_channel_closeLeFixedChannelHelper256 void on_channel_close(bluetooth::hci::AddressWithType device,
257 bluetooth::hci::ErrorCode error_code) {
258 auto address = bluetooth::ToRawAddress(device.GetAddress());
259 channel_enqueue_buffer_[device] = nullptr;
260 channels_[device]->GetQueueUpEnd()->UnregisterDequeue();
261 channels_[device] = nullptr;
262 (freg_.pL2CA_FixedConn_Cb)(cid_, address, true, 0, 2);
263 }
264
on_channel_openLeFixedChannelHelper265 void on_channel_open(std::unique_ptr<FixedChannel> channel) {
266 auto device = channel->GetDevice();
267 channel->RegisterOnCloseCallback(
268 bluetooth::shim::GetGdShimHandler(),
269 bluetooth::common::BindOnce(&LeFixedChannelHelper::on_channel_close,
270 bluetooth::common::Unretained(this),
271 device));
272 channel->Acquire();
273 channel_enqueue_buffer_[device] = std::make_unique<
274 bluetooth::os::EnqueueBuffer<bluetooth::packet::BasePacketBuilder>>(
275 channel->GetQueueUpEnd());
276 channel->GetQueueUpEnd()->RegisterDequeue(
277 bluetooth::shim::GetGdShimHandler(),
278 bluetooth::common::Bind(&LeFixedChannelHelper::on_incoming_data,
279 bluetooth::common::Unretained(this), device));
280 channels_[device] = std::move(channel);
281
282 auto address = bluetooth::ToRawAddress(device.GetAddress());
283
284 (freg_.pL2CA_FixedConn_Cb)(cid_, address, true, 0, BT_TRANSPORT_LE);
285 bluetooth::shim::Btm::StoreAddressType(
286 address, static_cast<uint8_t>(device.GetAddressType()));
287 }
288
on_incoming_dataLeFixedChannelHelper289 void on_incoming_data(bluetooth::hci::AddressWithType remote) {
290 auto channel = channels_.find(remote);
291 if (channel == channels_.end()) {
292 LOG_ERROR("Channel is not open");
293 return;
294 }
295 auto packet = channel->second->GetQueueUpEnd()->TryDequeue();
296 std::vector<uint8_t> packet_vector(packet->begin(), packet->end());
297 BT_HDR* buffer =
298 static_cast<BT_HDR*>(osi_calloc(packet_vector.size() + sizeof(BT_HDR)));
299 std::copy(packet_vector.begin(), packet_vector.end(), buffer->data);
300 buffer->len = packet_vector.size();
301 auto address = bluetooth::ToRawAddress(remote.GetAddress());
302 freg_.pL2CA_FixedData_Cb(cid_, address, buffer);
303 }
304
on_outgoing_connection_failLeFixedChannelHelper305 void on_outgoing_connection_fail(
306 RawAddress remote, FixedChannelManager::ConnectionResult result) {
307 LOG(ERROR) << "Outgoing connection failed";
308 freg_.pL2CA_FixedConn_Cb(cid_, remote, true, 0, BT_TRANSPORT_LE);
309 }
310
sendLeFixedChannelHelper311 bool send(AddressWithType remote,
312 std::unique_ptr<bluetooth::packet::BasePacketBuilder> packet) {
313 auto buffer = channel_enqueue_buffer_.find(remote);
314 if (buffer == channel_enqueue_buffer_.end() || buffer->second == nullptr) {
315 LOG(ERROR) << "Channel is not open";
316 return false;
317 }
318 buffer->second->Enqueue(std::move(packet),
319 bluetooth::shim::GetGdShimHandler());
320 return true;
321 }
322
323 std::unordered_map<AddressWithType, std::unique_ptr<FixedChannel>> channels_;
324 std::unordered_map<AddressWithType,
325 std::unique_ptr<bluetooth::os::EnqueueBuffer<
326 bluetooth::packet::BasePacketBuilder>>>
327 channel_enqueue_buffer_;
328 tL2CAP_FIXED_CHNL_REG freg_;
329 };
330
331 static LeFixedChannelHelper att_helper{4};
332 static std::unordered_map<uint16_t, LeFixedChannelHelper&>
333 le_fixed_channel_helper_{
334 {4, att_helper},
335 };
336
337 /**
338 * Fixed Channel APIs. Note: Classic fixed channel (connectionless and BR SMP)
339 * is not supported
340 */
L2CA_RegisterFixedChannel(uint16_t cid,tL2CAP_FIXED_CHNL_REG * p_freg)341 bool bluetooth::shim::L2CA_RegisterFixedChannel(uint16_t cid,
342 tL2CAP_FIXED_CHNL_REG* p_freg) {
343 if (cid != kAttCid) {
344 LOG(ERROR) << "Invalid cid: " << cid;
345 return false;
346 }
347 auto* helper = &le_fixed_channel_helper_.find(cid)->second;
348 if (helper == nullptr) {
349 LOG(ERROR) << "Can't register cid " << cid;
350 return false;
351 }
352 bluetooth::shim::GetL2capLeModule()
353 ->GetFixedChannelManager()
354 ->RegisterService(
355 cid,
356 common::BindOnce(&LeFixedChannelHelper::on_registration_complete,
357 common::Unretained(helper)),
358 common::Bind(&LeFixedChannelHelper::on_channel_open,
359 common::Unretained(helper)),
360 GetGdShimHandler());
361 helper->freg_ = *p_freg;
362 return true;
363 }
364
L2CA_ConnectFixedChnl(uint16_t cid,const RawAddress & rem_bda)365 bool bluetooth::shim::L2CA_ConnectFixedChnl(uint16_t cid,
366 const RawAddress& rem_bda) {
367 if (cid != kAttCid) {
368 LOG(ERROR) << "Invalid cid " << cid;
369 return false;
370 }
371
372 auto* helper = &le_fixed_channel_helper_.find(cid)->second;
373 auto remote = ToAddressWithType(rem_bda, Btm::GetAddressType(rem_bda));
374 auto manager = bluetooth::shim::GetL2capLeModule()->GetFixedChannelManager();
375 manager->ConnectServices(
376 remote,
377 common::BindOnce(&LeFixedChannelHelper::on_outgoing_connection_fail,
378 common::Unretained(helper), rem_bda),
379 GetGdShimHandler());
380 return true;
381 }
382
L2CA_ConnectFixedChnl(uint16_t cid,const RawAddress & rem_bda,uint8_t initiating_phys)383 bool bluetooth::shim::L2CA_ConnectFixedChnl(uint16_t cid,
384 const RawAddress& rem_bda,
385 uint8_t initiating_phys) {
386 return bluetooth::shim::L2CA_ConnectFixedChnl(cid, rem_bda);
387 }
388
MakeUniquePacket(const uint8_t * data,size_t len)389 static std::unique_ptr<bluetooth::packet::RawBuilder> MakeUniquePacket(
390 const uint8_t* data, size_t len) {
391 bluetooth::packet::RawBuilder builder;
392 std::vector<uint8_t> bytes(data, data + len);
393 auto payload = std::make_unique<bluetooth::packet::RawBuilder>();
394 payload->AddOctets(bytes);
395 return payload;
396 }
397
L2CA_SendFixedChnlData(uint16_t cid,const RawAddress & rem_bda,BT_HDR * p_buf)398 uint16_t bluetooth::shim::L2CA_SendFixedChnlData(uint16_t cid,
399 const RawAddress& rem_bda,
400 BT_HDR* p_buf) {
401 if (cid != kAttCid) {
402 LOG(ERROR) << "Invalid cid " << cid;
403 return false;
404 }
405 auto* helper = &le_fixed_channel_helper_.find(cid)->second;
406 auto remote = ToAddressWithType(rem_bda, Btm::GetAddressType(rem_bda));
407 auto len = p_buf->len;
408 auto* data = p_buf->data + p_buf->offset;
409 bool sent = helper->send(remote, MakeUniquePacket(data, len));
410 return sent ? len : 0;
411 }
412
L2CA_RemoveFixedChnl(uint16_t cid,const RawAddress & rem_bda)413 bool bluetooth::shim::L2CA_RemoveFixedChnl(uint16_t cid,
414 const RawAddress& rem_bda) {
415 if (cid != kAttCid) {
416 LOG(ERROR) << "Invalid cid " << cid;
417 return false;
418 }
419 auto* helper = &le_fixed_channel_helper_.find(cid)->second;
420 auto remote = ToAddressWithType(rem_bda, Btm::GetAddressType(rem_bda));
421 auto channel = helper->channels_.find(remote);
422 if (channel == helper->channels_.end() || channel->second == nullptr) {
423 LOG(ERROR) << "Channel is not open";
424 return false;
425 }
426 channel->second->Release();
427 return true;
428 }
429
430 /**
431 * Channel hygiene APIs
432 */
L2CA_GetRemoteCid(uint16_t lcid,uint16_t * rcid)433 bool bluetooth::shim::L2CA_GetRemoteCid(uint16_t lcid, uint16_t* rcid) {
434 return shim_l2cap.GetRemoteCid(lcid, rcid);
435 }
436
L2CA_SetIdleTimeout(uint16_t cid,uint16_t timeout,bool is_global)437 bool bluetooth::shim::L2CA_SetIdleTimeout(uint16_t cid, uint16_t timeout,
438 bool is_global) {
439 LOG_INFO("UNIMPLEMENTED %s", __func__);
440 return false;
441 }
442
L2CA_SetTxPriority(uint16_t cid,tL2CAP_CHNL_PRIORITY priority)443 bool bluetooth::shim::L2CA_SetTxPriority(uint16_t cid,
444 tL2CAP_CHNL_PRIORITY priority) {
445 LOG_INFO("UNIMPLEMENTED %s", __func__);
446 return false;
447 }
448
L2CA_SetFixedChannelTout(const RawAddress & rem_bda,uint16_t fixed_cid,uint16_t idle_tout)449 bool bluetooth::shim::L2CA_SetFixedChannelTout(const RawAddress& rem_bda,
450 uint16_t fixed_cid,
451 uint16_t idle_tout) {
452 LOG_INFO("UNIMPLEMENTED %s", __func__);
453 return false;
454 }
455
L2CA_SetChnlFlushability(uint16_t cid,bool is_flushable)456 bool bluetooth::shim::L2CA_SetChnlFlushability(uint16_t cid,
457 bool is_flushable) {
458 LOG_INFO("UNIMPLEMENTED %s", __func__);
459 return false;
460 }
461
L2CA_FlushChannel(uint16_t lcid,uint16_t num_to_flush)462 uint16_t bluetooth::shim::L2CA_FlushChannel(uint16_t lcid,
463 uint16_t num_to_flush) {
464 LOG_INFO("UNIMPLEMENTED %s", __func__);
465 return 0;
466 }
467
L2CA_IsLinkEstablished(const RawAddress & bd_addr,tBT_TRANSPORT transport)468 bool bluetooth::shim::L2CA_IsLinkEstablished(const RawAddress& bd_addr,
469 tBT_TRANSPORT transport) {
470 LOG_INFO("UNIMPLEMENTED %s", __func__);
471 return true;
472 }
473