mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-28 08:37:22 +00:00
require hci connection for l2cap le data channels
This commit is contained in:
parent
e5b5b3745f
commit
7dafa7502d
96
src/l2cap.c
96
src/l2cap.c
@ -268,18 +268,6 @@ static l2cap_channel_t * l2cap_le_get_channel_for_local_cid(uint16_t local_cid){
|
||||
}
|
||||
#endif
|
||||
|
||||
static l2cap_channel_t * l2cap_get_le_channel_for_address_and_addr_type(bd_addr_t address, bd_addr_type_t address_type){
|
||||
btstack_linked_list_iterator_t it;
|
||||
btstack_linked_list_iterator_init(&it, &l2cap_le_channels);
|
||||
while (btstack_linked_list_iterator_has_next(&it)){
|
||||
l2cap_channel_t * channel = (l2cap_channel_t *) btstack_linked_list_iterator_next(&it);
|
||||
if (channel->address_type != address_type) continue;
|
||||
if (bd_addr_cmp(channel->address, address)) continue;
|
||||
return channel;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
void l2cap_request_can_send_now_event(uint16_t local_cid){
|
||||
@ -883,20 +871,6 @@ static void l2cap_handle_connection_complete(hci_con_handle_t con_handle, l2cap_
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_BLE
|
||||
static void l2cap_handle_le_connection_complete(l2cap_channel_t * channel, uint8_t status, hci_con_handle_t con_handle){
|
||||
if (channel->state == L2CAP_STATE_WAIT_CONNECTION_COMPLETE || channel->state == L2CAP_STATE_WILL_SEND_CREATE_CONNECTION) {
|
||||
log_info("l2cap_le_handle_connection_complete expected state");
|
||||
// TODO: bail if status != 0
|
||||
|
||||
// success, start l2cap handshake
|
||||
channel->con_handle = con_handle;
|
||||
channel->state = L2CAP_STATE_WILL_SEND_LE_CONNECTION_REQUEST;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void l2cap_handle_remote_supported_features_received(l2cap_channel_t * channel){
|
||||
if (channel->state != L2CAP_STATE_WAIT_REMOTE_SUPPORTED_FEATURES) return;
|
||||
|
||||
@ -1161,28 +1135,6 @@ static void l2cap_hci_event_handler(uint8_t packet_type, uint16_t cid, uint8_t *
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef ENABLE_BLE
|
||||
case HCI_EVENT_LE_META:
|
||||
switch (packet[2]){
|
||||
int addr_type;
|
||||
l2cap_channel_t * channel;
|
||||
case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
|
||||
// Connection management
|
||||
reverse_bd_addr(&packet[8], address);
|
||||
addr_type = (bd_addr_type_t)packet[7];
|
||||
log_info("L2CAP - LE Connection_complete (status=%u) type %u, %s", packet[3], addr_type, bd_addr_to_str(address));
|
||||
// get l2cap_channel
|
||||
// also pass in status
|
||||
channel = l2cap_get_le_channel_for_address_and_addr_type(address, addr_type);
|
||||
if (!channel) break;
|
||||
l2cap_handle_le_connection_complete(channel, packet[3], little_endian_read_16(packet, 4));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case GAP_EVENT_SECURITY_LEVEL:
|
||||
handle = little_endian_read_16(packet, 2);
|
||||
log_info("l2cap - security level update");
|
||||
@ -2081,13 +2033,20 @@ uint8_t l2cap_le_decline_connection(uint16_t local_cid){
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t l2cap_le_create_channel(btstack_packet_handler_t packet_handler, bd_addr_t address, bd_addr_type_t address_type,
|
||||
uint8_t l2cap_le_create_channel(btstack_packet_handler_t packet_handler, hci_con_handle_t con_handle,
|
||||
uint16_t psm, uint8_t * receive_sdu_buffer, uint16_t mtu, uint16_t initial_credits, gap_security_level_t security_level,
|
||||
uint16_t * out_local_cid) {
|
||||
|
||||
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, security_level);
|
||||
log_info("L2CAP_LE_CREATE_CHANNEL handle 0x%04x psm 0x%x mtu %u", con_handle, psm, mtu);
|
||||
|
||||
|
||||
hci_connection_t * connection = hci_connection_for_handle(con_handle);
|
||||
if (!connection) {
|
||||
log_error("no hci_connection for handle 0x%04x", con_handle);
|
||||
return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
|
||||
}
|
||||
|
||||
l2cap_channel_t * channel = l2cap_create_channel_entry(packet_handler, connection->address, connection->address_type, psm, mtu, security_level);
|
||||
if (!channel) {
|
||||
return BTSTACK_MEMORY_ALLOC_FAILED;
|
||||
}
|
||||
@ -2098,41 +2057,18 @@ uint8_t l2cap_le_create_channel(btstack_packet_handler_t packet_handler, bd_addr
|
||||
*out_local_cid = channel->local_cid;
|
||||
}
|
||||
|
||||
// provdide buffer
|
||||
// provide buffer
|
||||
channel->con_handle = con_handle;
|
||||
channel->receive_sdu_buffer = receive_sdu_buffer;
|
||||
channel->state = L2CAP_STATE_WAIT_CONNECTION_COMPLETE;
|
||||
channel->state = L2CAP_STATE_WILL_SEND_LE_CONNECTION_REQUEST;
|
||||
channel->new_credits_incoming = initial_credits;
|
||||
channel->automatic_credits = initial_credits == L2CAP_LE_AUTOMATIC_CREDITS;
|
||||
|
||||
// test
|
||||
// channel->new_credits_incoming = 1;
|
||||
|
||||
// add to connections list
|
||||
btstack_linked_list_add(&l2cap_le_channels, (btstack_linked_item_t *) channel);
|
||||
|
||||
// check if hci connection is already usable
|
||||
hci_connection_t * conn = hci_connection_for_bd_addr_and_type(address, address_type);
|
||||
|
||||
if (conn){
|
||||
log_info("l2cap_le_create_channel, hci connection already exists");
|
||||
l2cap_handle_le_connection_complete(channel, 0, conn->con_handle);
|
||||
l2cap_run();
|
||||
} else {
|
||||
|
||||
//
|
||||
// TODO: start timer
|
||||
// ..
|
||||
|
||||
// start connection
|
||||
uint8_t res = gap_auto_connection_start(address_type, address);
|
||||
if (res){
|
||||
// discard channel object
|
||||
log_info("gap_auto_connection_start failed! 0x%02x", res);
|
||||
btstack_linked_list_remove(&l2cap_le_channels, (btstack_linked_item_t *) channel);
|
||||
btstack_memory_l2cap_channel_free(channel);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
// go
|
||||
l2cap_run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -354,8 +354,7 @@ uint8_t l2cap_le_decline_connection(uint16_t local_cid);
|
||||
/**
|
||||
* @brief Create LE Data Channel
|
||||
* @param packet_handler Packet handler for this connection
|
||||
* @param address Peer address
|
||||
* @param address_type Peer address type
|
||||
* @param con_handle ACL-LE HCI Connction Handle
|
||||
* @param psm Service PSM to connect to
|
||||
* @param receive_buffer buffer used for reassembly of L2CAP LE Information Frames into service data unit (SDU) with given MTU
|
||||
* @param receive_buffer_size buffer size equals MTU
|
||||
@ -363,7 +362,7 @@ uint8_t l2cap_le_decline_connection(uint16_t local_cid);
|
||||
* @param security_level Minimum required security level
|
||||
* @param out_local_cid L2CAP LE Channel Identifier is stored here
|
||||
*/
|
||||
uint8_t l2cap_le_create_channel(btstack_packet_handler_t packet_handler, bd_addr_t address, bd_addr_type_t address_type,
|
||||
uint8_t l2cap_le_create_channel(btstack_packet_handler_t packet_handler, hci_con_handle_t con_handle,
|
||||
uint16_t psm, uint8_t * receive_sdu_buffer, uint16_t mtu, uint16_t initial_credits, gap_security_level_t security_level,
|
||||
uint16_t * out_local_cid);
|
||||
|
||||
|
@ -66,10 +66,13 @@
|
||||
static btstack_packet_callback_registration_t hci_event_callback_registration;
|
||||
static btstack_packet_callback_registration_t sm_event_callback_registration;
|
||||
|
||||
static bd_addr_t pts_address = { 0x00, 0x1a, 0x7d, 0xda, 0x71, 0x0a};
|
||||
// static bd_addr_t pts_address = { 0x00, 0x1a, 0x7d, 0xda, 0x71, 0x0a};
|
||||
static bd_addr_t pts_address = { 0x00, 0x1b, 0xdc, 0x08, 0x0a, 0xa5};
|
||||
|
||||
static int pts_address_type = 0;
|
||||
static int master_addr_type = 0;
|
||||
static hci_con_handle_t handle;
|
||||
static hci_con_handle_t handle_le;
|
||||
static hci_con_handle_t handle_classic;
|
||||
static uint32_t ui_passkey;
|
||||
static int ui_digits_for_passkey;
|
||||
static uint16_t local_cid;
|
||||
@ -100,6 +103,7 @@ static void app_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *
|
||||
bd_addr_t event_address;
|
||||
uint16_t psm;
|
||||
uint16_t cid;
|
||||
hci_con_handle_t handle;
|
||||
|
||||
switch (packet_type) {
|
||||
|
||||
@ -121,8 +125,8 @@ static void app_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *
|
||||
case HCI_EVENT_LE_META:
|
||||
switch (hci_event_le_meta_get_subevent_code(packet)) {
|
||||
case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
|
||||
handle = little_endian_read_16(packet, 4);
|
||||
printf("HCI: LE Connection Complete, connection handle 0x%04x\n", handle);
|
||||
handle_le = little_endian_read_16(packet, 4);
|
||||
printf("HCI: LE Connection Complete, connection handle 0x%04x\n", handle_le);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -131,8 +135,8 @@ static void app_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *
|
||||
break;
|
||||
|
||||
case HCI_EVENT_CONNECTION_COMPLETE:
|
||||
handle = little_endian_read_16(packet, 3);
|
||||
printf("HCI: ACL Connection Complete, connection handle 0x%04x\n", handle);
|
||||
handle_classic = little_endian_read_16(packet, 3);
|
||||
printf("HCI: ACL Connection Complete, connection handle 0x%04x\n", handle_classic);
|
||||
break;
|
||||
|
||||
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
||||
@ -228,13 +232,14 @@ void show_usage(void){
|
||||
gap_advertisements_get_address(&uit_addr_type, iut_address);
|
||||
|
||||
printf("\n--- CLI for LE Data Channel %s ---\n", bd_addr_to_str(iut_address));
|
||||
printf("a - connect to type %u address %s PSM 0x%02x (TSPX_le_psm - LE)\n", pts_address_type, bd_addr_to_str(pts_address), TSPX_le_psm);
|
||||
printf("A - connect to type %u address %s PSM 0x%02x (TSPX_psm_unsupported - LE)\n", pts_address_type, bd_addr_to_str(pts_address), TSPX_psm_unsupported);
|
||||
printf("b - connect to type %u address %s PSM 0x%02x (TSPX_psm - Classic)\n", pts_address_type, bd_addr_to_str(pts_address), TSPX_psm);
|
||||
printf("a - create HCI connection to type %u address %s\n", pts_address_type, bd_addr_to_str(pts_address));
|
||||
printf("b - connect to PSM 0x%02x (TSPX_le_psm - LE)\n", TSPX_le_psm);
|
||||
printf("B - connect to PSM 0x%02x (TSPX_psm_unsupported - LE)\n", TSPX_psm_unsupported);
|
||||
printf("c - send 10 credits\n");
|
||||
printf("m - enable manual credit managment (incoming connections only)\n");
|
||||
printf("s - send short data %s\n", data_short);
|
||||
printf("S - send long data %s\n", data_long);
|
||||
printf("y - connect to address %s PSM 0x%02x (TSPX_psm - Classic)\n", bd_addr_to_str(pts_address), TSPX_psm);
|
||||
printf("z - send classic data Classic %s\n", data_classic);
|
||||
printf("t - disconnect channel\n");
|
||||
printf("---\n");
|
||||
@ -255,31 +260,29 @@ static void stdin_process(btstack_data_source_t *ds, btstack_data_source_callbac
|
||||
ui_digits_for_passkey--;
|
||||
if (ui_digits_for_passkey == 0){
|
||||
printf("\nSending Passkey '%06x'\n", ui_passkey);
|
||||
sm_passkey_input(handle, ui_passkey);
|
||||
sm_passkey_input(handle_le, ui_passkey);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch (buffer){
|
||||
case 'a':
|
||||
printf("Creating connection to %s 0x%02x - LE\n", bd_addr_to_str(pts_address), TSPX_le_psm);
|
||||
gap_advertisements_enable(0);
|
||||
l2cap_le_create_channel(&app_packet_handler,pts_address, pts_address_type, TSPX_le_psm, buffer_x,
|
||||
printf("Direct Connection Establishment to type %u, addr %s\n", pts_address_type, bd_addr_to_str(pts_address));
|
||||
gap_connect(pts_address, pts_address_type);
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf("Connect to PSM 0x%02x - LE\n", TSPX_le_psm);
|
||||
l2cap_le_create_channel(&app_packet_handler, handle_le, TSPX_le_psm, buffer_x,
|
||||
sizeof(buffer_x), L2CAP_LE_AUTOMATIC_CREDITS, LEVEL_0, &cid_le);
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
printf("Creating connection to %s 0x%02x - LE\n", bd_addr_to_str(pts_address), TSPX_psm_unsupported);
|
||||
gap_advertisements_enable(0);
|
||||
l2cap_le_create_channel(&app_packet_handler,pts_address, pts_address_type, TSPX_psm_unsupported, buffer_x,
|
||||
l2cap_le_create_channel(&app_packet_handler, handle_le, TSPX_psm_unsupported, buffer_x,
|
||||
sizeof(buffer_x), L2CAP_LE_AUTOMATIC_CREDITS, LEVEL_0, &cid_le);
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf("Creating connection to %s 0x%02x - Classic\n", bd_addr_to_str(pts_address), TSPX_psm);
|
||||
l2cap_create_channel(&app_packet_handler, pts_address, TSPX_psm, 100, &cid_classic);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf("Provide 10 credits\n");
|
||||
l2cap_le_provide_credits(cid_le, 10);
|
||||
@ -300,6 +303,11 @@ static void stdin_process(btstack_data_source_t *ds, btstack_data_source_callbac
|
||||
l2cap_le_send_data(cid_le, (uint8_t *) data_long, strlen(data_long));
|
||||
break;
|
||||
|
||||
case 'y':
|
||||
printf("Creating connection to %s 0x%02x - Classic\n", bd_addr_to_str(pts_address), TSPX_psm);
|
||||
l2cap_create_channel(&app_packet_handler, pts_address, TSPX_psm, 100, &cid_classic);
|
||||
break;
|
||||
|
||||
case 'z':
|
||||
printf("Send L2CAP Data Classic %s\n", data_classic);
|
||||
l2cap_send(cid_classic, (uint8_t *) data_classic, strlen(data_classic));
|
||||
|
Loading…
x
Reference in New Issue
Block a user