mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-29 04:20:20 +00:00
l2cap: send and handle le connection decline
This commit is contained in:
parent
fcea67036c
commit
1b8b8d056f
58
src/l2cap.c
58
src/l2cap.c
@ -748,6 +748,7 @@ static void l2cap_run(void){
|
|||||||
if (!hci_can_send_acl_packet_now(channel->con_handle)) break;
|
if (!hci_can_send_acl_packet_now(channel->con_handle)) break;
|
||||||
channel->state = L2CAP_STATE_WAIT_LE_CONNECTION_RESPONSE;
|
channel->state = L2CAP_STATE_WAIT_LE_CONNECTION_RESPONSE;
|
||||||
// le psm, source cid, mtu, mps, initial credits
|
// le psm, source cid, mtu, mps, initial credits
|
||||||
|
channel->local_sig_id = l2cap_next_sig_id();
|
||||||
l2cap_send_le_signaling_packet( channel->con_handle, LE_CREDIT_BASED_CONNECTION_REQUEST, channel->local_sig_id, channel->psm, channel->local_cid, 23, 23, 1);
|
l2cap_send_le_signaling_packet( channel->con_handle, LE_CREDIT_BASED_CONNECTION_REQUEST, channel->local_sig_id, channel->psm, channel->local_cid, 23, 23, 1);
|
||||||
break;
|
break;
|
||||||
case L2CAP_STATE_WILL_SEND_LE_CONNECTION_RESPONSE_DECLINE:
|
case L2CAP_STATE_WILL_SEND_LE_CONNECTION_RESPONSE_DECLINE:
|
||||||
@ -1494,8 +1495,13 @@ static int l2cap_le_signaling_handler_dispatch(hci_con_handle_t handle, uint8_t
|
|||||||
uint8_t event[10];
|
uint8_t event[10];
|
||||||
uint16_t le_psm;
|
uint16_t le_psm;
|
||||||
l2cap_service_t * service;
|
l2cap_service_t * service;
|
||||||
|
l2cap_channel_t * channel;
|
||||||
|
btstack_linked_list_iterator_t it;
|
||||||
|
|
||||||
switch (command[0]){
|
uint8_t code = command[L2CAP_SIGNALING_COMMAND_CODE_OFFSET];
|
||||||
|
printf("l2cap_le_signaling_handler_dispatch: command 0x%02x, sig id %u\n", code, sig_id);
|
||||||
|
|
||||||
|
switch (code){
|
||||||
|
|
||||||
case CONNECTION_PARAMETER_UPDATE_RESPONSE:
|
case CONNECTION_PARAMETER_UPDATE_RESPONSE:
|
||||||
result = little_endian_read_16(command, 4);
|
result = little_endian_read_16(command, 4);
|
||||||
@ -1567,12 +1573,11 @@ static int l2cap_le_signaling_handler_dispatch(hci_con_handle_t handle, uint8_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
// go through list of channels for this ACL connection and check if we get a match
|
// go through list of channels for this ACL connection and check if we get a match
|
||||||
btstack_linked_list_iterator_t it;
|
|
||||||
btstack_linked_list_iterator_init(&it, &l2cap_le_channels);
|
btstack_linked_list_iterator_init(&it, &l2cap_le_channels);
|
||||||
while (btstack_linked_list_iterator_has_next(&it)){
|
while (btstack_linked_list_iterator_has_next(&it)){
|
||||||
l2cap_channel_t * channel = (l2cap_channel_t *) btstack_linked_list_iterator_next(&it);
|
l2cap_channel_t * a_channel = (l2cap_channel_t *) btstack_linked_list_iterator_next(&it);
|
||||||
if (channel->con_handle != handle) continue;
|
if (a_channel->con_handle != handle) continue;
|
||||||
if (channel->remote_cid != source_cid) continue;
|
if (a_channel->remote_cid != source_cid) continue;
|
||||||
// 0x000a Connection refused - Source CID already allocated
|
// 0x000a Connection refused - Source CID already allocated
|
||||||
l2cap_register_signaling_response(handle, LE_CREDIT_BASED_CONNECTION_REQUEST, sig_id, 0x000a);
|
l2cap_register_signaling_response(handle, LE_CREDIT_BASED_CONNECTION_REQUEST, sig_id, 0x000a);
|
||||||
return 1;
|
return 1;
|
||||||
@ -1581,7 +1586,7 @@ static int l2cap_le_signaling_handler_dispatch(hci_con_handle_t handle, uint8_t
|
|||||||
// TODO: deal with authentication requirements, errors 0x005 - 000x8
|
// TODO: deal with authentication requirements, errors 0x005 - 000x8
|
||||||
|
|
||||||
// allocate channel
|
// allocate channel
|
||||||
l2cap_channel_t * channel = l2cap_create_channel_entry(service->packet_handler, connection->address,
|
channel = l2cap_create_channel_entry(service->packet_handler, connection->address,
|
||||||
BD_ADDR_TYPE_LE_RANDOM, le_psm, service->mtu, service->required_security_level);
|
BD_ADDR_TYPE_LE_RANDOM, le_psm, service->mtu, service->required_security_level);
|
||||||
if (!channel){
|
if (!channel){
|
||||||
// 0x0004 Connection refused – no resources available
|
// 0x0004 Connection refused – no resources available
|
||||||
@ -1608,11 +1613,48 @@ static int l2cap_le_signaling_handler_dispatch(hci_con_handle_t handle, uint8_t
|
|||||||
l2cap_emit_connection_request(channel);
|
l2cap_emit_connection_request(channel);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Connection refused – LE_PSM not supported
|
// Connection refused – LE_PSM not supported
|
||||||
l2cap_register_signaling_response(handle, LE_CREDIT_BASED_CONNECTION_REQUEST, sig_id, 0x0002);
|
l2cap_register_signaling_response(handle, LE_CREDIT_BASED_CONNECTION_REQUEST, sig_id, 0x0002);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LE_CREDIT_BASED_CONNECTION_RESPONSE:
|
||||||
|
// Find channel for this sig_id and connection handle
|
||||||
|
channel = NULL;
|
||||||
|
btstack_linked_list_iterator_init(&it, &l2cap_le_channels);
|
||||||
|
while (btstack_linked_list_iterator_has_next(&it)){
|
||||||
|
l2cap_channel_t * a_channel = (l2cap_channel_t *) btstack_linked_list_iterator_next(&it);
|
||||||
|
if (a_channel->con_handle != handle) continue;
|
||||||
|
if (a_channel->local_sig_id != sig_id) continue;
|
||||||
|
channel = a_channel;
|
||||||
|
printf("channel %p\n", channel);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// TODO: send error
|
||||||
|
if (!channel) break;
|
||||||
|
|
||||||
|
// cid + 0
|
||||||
|
result = little_endian_read_16 (command, L2CAP_SIGNALING_COMMAND_DATA_OFFSET+8);
|
||||||
|
if (result){
|
||||||
|
channel->state = L2CAP_STATE_CLOSED;
|
||||||
|
// map l2cap connection response result to BTstack status enumeration
|
||||||
|
l2cap_emit_channel_opened(channel, result);
|
||||||
|
|
||||||
|
// discard channel
|
||||||
|
btstack_linked_list_remove(&l2cap_channels, (btstack_linked_item_t *) channel);
|
||||||
|
btstack_memory_l2cap_channel_free(channel);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// success
|
||||||
|
channel->remote_cid = little_endian_read_16(command, L2CAP_SIGNALING_COMMAND_DATA_OFFSET + 0);
|
||||||
|
channel->remote_mtu = little_endian_read_16(command, L2CAP_SIGNALING_COMMAND_DATA_OFFSET + 2);
|
||||||
|
channel->remote_mps = little_endian_read_16(command, L2CAP_SIGNALING_COMMAND_DATA_OFFSET + 4);
|
||||||
|
channel->credits_outgoing = little_endian_read_16(command, L2CAP_SIGNALING_COMMAND_DATA_OFFSET + 6);
|
||||||
|
channel->state = L2CAP_STATE_OPEN;
|
||||||
|
l2cap_emit_channel_opened(channel, result);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// command unknown -> reject command
|
// command unknown -> reject command
|
||||||
return 0;
|
return 0;
|
||||||
@ -1860,7 +1902,7 @@ uint8_t l2cap_le_create_channel(btstack_packet_handler_t packet_handler, bd_addr
|
|||||||
|
|
||||||
log_info("L2CAP_LE_CREATE_CHANNEL addr %s psm 0x%x mtu %u", bd_addr_to_str(address), psm, mtu);
|
log_info("L2CAP_LE_CREATE_CHANNEL addr %s psm 0x%x mtu %u", bd_addr_to_str(address), psm, mtu);
|
||||||
|
|
||||||
l2cap_channel_t * channel = l2cap_create_channel_entry(packet_handler, address, address_type, psm, mtu, LEVEL_0);
|
l2cap_channel_t * channel = l2cap_create_channel_entry(packet_handler, address, address_type, psm, mtu, LEVEL_0);
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
return BTSTACK_MEMORY_ALLOC_FAILED;
|
return BTSTACK_MEMORY_ALLOC_FAILED;
|
||||||
}
|
}
|
||||||
|
@ -66,9 +66,9 @@
|
|||||||
static btstack_packet_callback_registration_t hci_event_callback_registration;
|
static btstack_packet_callback_registration_t hci_event_callback_registration;
|
||||||
static btstack_packet_callback_registration_t sm_event_callback_registration;
|
static btstack_packet_callback_registration_t sm_event_callback_registration;
|
||||||
|
|
||||||
static bd_addr_t pts_address = {0x00, 0x1B, 0xDC, 0x07, 0x32, 0xef};
|
static bd_addr_t pts_address = { 0x00, 0x02, 0x72, 0xDC, 0x31, 0xC1};
|
||||||
static int pts_address_type = 0;
|
static int pts_address_type = 0;
|
||||||
static bd_addr_t master_address = {0x00, 0x1B, 0xDC, 0x07, 0x32, 0xef};
|
static bd_addr_t master_address = { 0x00, 0x02, 0x72, 0xDC, 0x31, 0xC1};
|
||||||
static int master_addr_type = 0;
|
static int master_addr_type = 0;
|
||||||
static hci_con_handle_t handle;
|
static hci_con_handle_t handle;
|
||||||
static uint32_t ui_passkey;
|
static uint32_t ui_passkey;
|
||||||
@ -86,6 +86,9 @@ static void gap_run(void){
|
|||||||
|
|
||||||
static void app_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
static void app_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||||
bd_addr_t event_address;
|
bd_addr_t event_address;
|
||||||
|
uint16_t psm;
|
||||||
|
uint16_t local_cid;
|
||||||
|
|
||||||
switch (packet_type) {
|
switch (packet_type) {
|
||||||
|
|
||||||
case HCI_EVENT_PACKET:
|
case HCI_EVENT_PACKET:
|
||||||
@ -125,6 +128,20 @@ static void app_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case L2CAP_EVENT_CHANNEL_OPENED:
|
||||||
|
// inform about new l2cap connection
|
||||||
|
reverse_bd_addr(&packet[3], event_address);
|
||||||
|
psm = little_endian_read_16(packet, 11);
|
||||||
|
local_cid = little_endian_read_16(packet, 13);
|
||||||
|
handle = little_endian_read_16(packet, 9);
|
||||||
|
if (packet[2] == 0) {
|
||||||
|
printf("Channel successfully opened: %s, handle 0x%02x, psm 0x%02x, local cid 0x%02x, remote cid 0x%02x\n",
|
||||||
|
bd_addr_to_str(event_address), handle, psm, local_cid, little_endian_read_16(packet, 15));
|
||||||
|
} else {
|
||||||
|
printf("L2CAP connection to device %s failed. status code %u\n", bd_addr_to_str(event_address), packet[2]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case SM_EVENT_JUST_WORKS_REQUEST:
|
case SM_EVENT_JUST_WORKS_REQUEST:
|
||||||
printf("SM_EVENT_JUST_WORKS_REQUEST\n");
|
printf("SM_EVENT_JUST_WORKS_REQUEST\n");
|
||||||
sm_just_works_confirm(little_endian_read_16(packet, 2));
|
sm_just_works_confirm(little_endian_read_16(packet, 2));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user