mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-30 16:20:24 +00:00
l2cap: use connection handle for channel lookup
This commit is contained in:
parent
e04eae2275
commit
7d5c2f20da
@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
- L2CAP: use connection handle for channel lookups
|
||||
### Added
|
||||
### Changed
|
||||
|
||||
|
32
src/l2cap.c
32
src/l2cap.c
@ -1125,6 +1125,14 @@ static l2cap_channel_t * l2cap_get_channel_for_local_cid(uint16_t local_cid){
|
||||
return (l2cap_channel_t*) l2cap_channel_item_by_cid(local_cid);
|
||||
}
|
||||
|
||||
static l2cap_channel_t * l2cap_get_channel_for_local_cid_and_handle(uint16_t local_cid, hci_con_handle_t con_handle){
|
||||
if (local_cid < 0x40u) return NULL;
|
||||
l2cap_channel_t * l2cap_channel = (l2cap_channel_t*) l2cap_channel_item_by_cid(local_cid);
|
||||
if (l2cap_channel == NULL) return NULL;
|
||||
if (l2cap_channel->con_handle != con_handle) return NULL;
|
||||
return l2cap_channel;
|
||||
}
|
||||
|
||||
void l2cap_request_can_send_now_event(uint16_t local_cid){
|
||||
l2cap_channel_t *channel = l2cap_get_channel_for_local_cid(local_cid);
|
||||
if (!channel) return;
|
||||
@ -3279,7 +3287,7 @@ static int l2cap_le_signaling_handler_dispatch(hci_con_handle_t handle, uint8_t
|
||||
|
||||
// find channel
|
||||
local_cid = little_endian_read_16(command, L2CAP_SIGNALING_COMMAND_DATA_OFFSET + 0);
|
||||
channel = l2cap_get_channel_for_local_cid(local_cid);
|
||||
channel = l2cap_get_channel_for_local_cid_and_handle(local_cid, handle);
|
||||
if (!channel) {
|
||||
log_error("l2cap: no channel for cid 0x%02x", local_cid);
|
||||
break;
|
||||
@ -3303,7 +3311,7 @@ static int l2cap_le_signaling_handler_dispatch(hci_con_handle_t handle, uint8_t
|
||||
|
||||
// find channel
|
||||
local_cid = little_endian_read_16(command, L2CAP_SIGNALING_COMMAND_DATA_OFFSET + 0);
|
||||
channel = l2cap_get_channel_for_local_cid(local_cid);
|
||||
channel = l2cap_get_channel_for_local_cid_and_handle(local_cid, handle);
|
||||
if (!channel) {
|
||||
log_error("l2cap: no channel for cid 0x%02x", local_cid);
|
||||
break;
|
||||
@ -3534,10 +3542,12 @@ static void l2cap_acl_classic_handler(hci_con_handle_t handle, uint8_t *packet,
|
||||
l2cap_channel_t * l2cap_channel;
|
||||
l2cap_fixed_channel_t * l2cap_fixed_channel;
|
||||
|
||||
uint16_t channel_id = READ_L2CAP_CHANNEL_ID(packet);
|
||||
uint16_t channel_id = READ_L2CAP_CHANNEL_ID(packet);
|
||||
uint8_t broadcast_flag = READ_ACL_FLAGS(packet) >> 2;
|
||||
switch (channel_id) {
|
||||
|
||||
case L2CAP_CID_SIGNALING: {
|
||||
if (broadcast_flag != 0) break;
|
||||
uint32_t command_offset = 8;
|
||||
while ((command_offset + L2CAP_SIGNALING_COMMAND_DATA_OFFSET) < size) {
|
||||
// assert signaling command is fully inside packet
|
||||
@ -3555,16 +3565,18 @@ static void l2cap_acl_classic_handler(hci_con_handle_t handle, uint8_t *packet,
|
||||
break;
|
||||
}
|
||||
case L2CAP_CID_CONNECTIONLESS_CHANNEL:
|
||||
if (broadcast_flag == 0) break;
|
||||
l2cap_fixed_channel = l2cap_fixed_channel_for_channel_id(L2CAP_CID_CONNECTIONLESS_CHANNEL);
|
||||
if (!l2cap_fixed_channel) break;
|
||||
if (!l2cap_fixed_channel->packet_handler) break;
|
||||
(*l2cap_fixed_channel->packet_handler)(UCD_DATA_PACKET, handle, &packet[COMPLETE_L2CAP_HEADER], size-COMPLETE_L2CAP_HEADER);
|
||||
break;
|
||||
|
||||
default:
|
||||
default:
|
||||
if (broadcast_flag != 0) break;
|
||||
// Find channel for this channel_id and connection handle
|
||||
l2cap_channel = l2cap_get_channel_for_local_cid(channel_id);
|
||||
if (l2cap_channel) {
|
||||
l2cap_channel = l2cap_get_channel_for_local_cid_and_handle(channel_id, handle);
|
||||
if (l2cap_channel != NULL){
|
||||
l2cap_acl_classic_handler_for_channel(l2cap_channel, packet, size);
|
||||
}
|
||||
break;
|
||||
@ -3615,11 +3627,11 @@ static void l2cap_acl_le_handler(hci_con_handle_t handle, uint8_t *packet, uint1
|
||||
default:
|
||||
|
||||
#ifdef ENABLE_LE_DATA_CHANNELS
|
||||
l2cap_channel = l2cap_get_channel_for_local_cid(channel_id);
|
||||
if (l2cap_channel) {
|
||||
l2cap_channel = l2cap_get_channel_for_local_cid_and_handle(channel_id, handle);
|
||||
if (l2cap_channel != NULL) {
|
||||
// credit counting
|
||||
if (l2cap_channel->credits_incoming == 0u){
|
||||
log_error("LE Data Channel packet received but no incoming credits");
|
||||
log_info("LE Data Channel packet received but no incoming credits");
|
||||
l2cap_channel->state = L2CAP_STATE_WILL_SEND_DISCONNECT_REQUEST;
|
||||
break;
|
||||
}
|
||||
@ -3653,8 +3665,6 @@ static void l2cap_acl_le_handler(hci_con_handle_t handle, uint8_t *packet, uint1
|
||||
l2cap_dispatch_to_channel(l2cap_channel, L2CAP_DATA_PACKET, l2cap_channel->receive_sdu_buffer, l2cap_channel->receive_sdu_len);
|
||||
l2cap_channel->receive_sdu_len = 0;
|
||||
}
|
||||
} else {
|
||||
log_error("LE Data Channel packet received but no channel found for cid 0x%02x", channel_id);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user