mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-01-25 09:35:42 +00:00
l2cap: send/receive le data channel SDUs that fit into single packet
This commit is contained in:
parent
991fea48d1
commit
64e11ca9ae
46
src/l2cap.c
46
src/l2cap.c
@ -756,6 +756,8 @@ static void l2cap_run(void){
|
||||
// TODO: support larger MPS
|
||||
channel->state = L2CAP_STATE_OPEN;
|
||||
l2cap_send_le_signaling_packet(channel->con_handle, LE_CREDIT_BASED_CONNECTION_RESPONSE, channel->remote_sig_id, channel->remote_cid, channel->local_mtu, 23, channel->credits_incoming, 0);
|
||||
// notify client
|
||||
l2cap_emit_channel_opened(channel, 0);
|
||||
break;
|
||||
case L2CAP_STATE_WILL_SEND_LE_CONNECTION_RESPONSE_DECLINE:
|
||||
if (!hci_can_send_acl_packet_now(channel->con_handle)) break;
|
||||
@ -1729,10 +1731,17 @@ static void l2cap_acl_handler(uint8_t packet_type, uint16_t channel, uint8_t *pa
|
||||
|
||||
default: {
|
||||
// Find channel for this channel_id and connection handle
|
||||
l2cap_channel_t * l2cap_channel = l2cap_get_channel_for_local_cid(channel_id);
|
||||
l2cap_channel_t * l2cap_channel;
|
||||
l2cap_channel = l2cap_get_channel_for_local_cid(channel_id);
|
||||
if (l2cap_channel) {
|
||||
l2cap_dispatch_to_channel(l2cap_channel, L2CAP_DATA_PACKET, &packet[COMPLETE_L2CAP_HEADER], size-COMPLETE_L2CAP_HEADER);
|
||||
}
|
||||
#ifdef ENABLE_BLE
|
||||
l2cap_channel = l2cap_le_get_channel_for_local_cid(channel_id);
|
||||
if (l2cap_channel) {
|
||||
l2cap_dispatch_to_channel(l2cap_channel, L2CAP_DATA_PACKET, &packet[COMPLETE_L2CAP_HEADER], size-COMPLETE_L2CAP_HEADER);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1964,7 +1973,7 @@ l2cap_channel_t * channel = l2cap_create_channel_entry(packet_handler, address,
|
||||
* @param local_cid L2CAP LE Data Channel Identifier
|
||||
* @param credits Number additional credits for peer
|
||||
*/
|
||||
uint8_t l2cap_le_provide_credits(uint16_t cid, uint16_t credits){
|
||||
uint8_t l2cap_le_provide_credits(uint16_t local_cid, uint16_t credits){
|
||||
// get channel
|
||||
// bail if missing
|
||||
// check state
|
||||
@ -1978,7 +1987,7 @@ uint8_t l2cap_le_provide_credits(uint16_t cid, uint16_t credits){
|
||||
* @brief Check if outgoing buffer is available and that there's space on the Bluetooth module
|
||||
* @param local_cid L2CAP LE Data Channel Identifier
|
||||
*/
|
||||
int l2cap_le_can_send_now(uint16_t cid){
|
||||
int l2cap_le_can_send_now(uint16_t local_cid){
|
||||
// check if data can be sent via le at all
|
||||
return 0;
|
||||
}
|
||||
@ -1989,7 +1998,7 @@ int l2cap_le_can_send_now(uint16_t cid){
|
||||
* so packet handler should be ready to handle it
|
||||
* @param local_cid L2CAP LE Data Channel Identifier
|
||||
*/
|
||||
uint8_t l2cap_le_request_can_send_now_event(uint16_t cid){
|
||||
uint8_t l2cap_le_request_can_send_now_event(uint16_t local_cid){
|
||||
// same as for non-le
|
||||
return 0;
|
||||
}
|
||||
@ -2001,11 +2010,30 @@ uint8_t l2cap_le_request_can_send_now_event(uint16_t cid){
|
||||
* @param data data to send
|
||||
* @param size data size
|
||||
*/
|
||||
uint8_t l2cap_le_send_data(uint16_t cid, uint8_t * data, uint16_t size){
|
||||
// check if no outgoing data is pending
|
||||
// store info
|
||||
// l2cap_le_run()
|
||||
return 0;
|
||||
uint8_t l2cap_le_send_data(uint16_t local_cid, uint8_t * data, uint16_t len){
|
||||
|
||||
l2cap_channel_t * channel = l2cap_le_get_channel_for_local_cid(local_cid);
|
||||
if (!channel) {
|
||||
log_error("l2cap_send no channel for cid 0x%02x", local_cid);
|
||||
return -1; // TODO: define error
|
||||
}
|
||||
|
||||
if (len > channel->remote_mtu){
|
||||
log_error("l2cap_send cid 0x%02x, data length exceeds remote MTU.", local_cid);
|
||||
return L2CAP_DATA_LEN_EXCEEDS_REMOTE_MTU;
|
||||
}
|
||||
|
||||
if (!hci_can_send_acl_packet_now(channel->con_handle)){
|
||||
log_info("l2cap_send cid 0x%02x, cannot send", local_cid);
|
||||
return BTSTACK_ACL_BUFFERS_FULL;
|
||||
}
|
||||
|
||||
hci_reserve_packet_buffer();
|
||||
uint8_t *acl_buffer = hci_get_outgoing_packet_buffer();
|
||||
|
||||
memcpy(&acl_buffer[8], data, len);
|
||||
|
||||
return l2cap_send_prepared_connectionless(channel->con_handle, local_cid, len);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,6 +73,7 @@ static int master_addr_type = 0;
|
||||
static hci_con_handle_t handle;
|
||||
static uint32_t ui_passkey;
|
||||
static int ui_digits_for_passkey;
|
||||
static uint16_t local_cid;
|
||||
|
||||
// general discoverable flags
|
||||
static uint8_t adv_general_discoverable[] = { 2, 01, 02 };
|
||||
@ -87,10 +88,15 @@ static void gap_run(void){
|
||||
static void app_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
bd_addr_t event_address;
|
||||
uint16_t psm;
|
||||
uint16_t local_cid;
|
||||
uint16_t cid;
|
||||
|
||||
switch (packet_type) {
|
||||
|
||||
|
||||
case L2CAP_DATA_PACKET:
|
||||
printf("L2CAP data cid 0x%02x: ", channel);
|
||||
printf_hexdump(packet, size);
|
||||
break;
|
||||
|
||||
case HCI_EVENT_PACKET:
|
||||
switch (packet[0]) {
|
||||
|
||||
@ -116,17 +122,11 @@ static void app_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *
|
||||
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
||||
break;
|
||||
|
||||
case L2CAP_EVENT_INCOMING_CONNECTION: {
|
||||
local_cid = little_endian_read_16(packet, 12);
|
||||
#if 1
|
||||
printf("L2CAP: Accepting incoming connection request for 0x%02x\n", local_cid);
|
||||
l2cap_le_accept_connection(local_cid, receive_buffer_X, sizeof(receive_buffer_X), 1);
|
||||
#else
|
||||
printf("L2CAP Decline incoming connection request\n");
|
||||
l2cap_le_decline_connection(local_cid);
|
||||
#endif
|
||||
case L2CAP_EVENT_INCOMING_CONNECTION:
|
||||
cid = little_endian_read_16(packet, 12);
|
||||
printf("L2CAP: Accepting incoming connection request for 0x%02x\n", cid);
|
||||
l2cap_le_accept_connection(cid, receive_buffer_X, sizeof(receive_buffer_X), 1);
|
||||
break;
|
||||
}
|
||||
|
||||
case L2CAP_EVENT_CHANNEL_OPENED:
|
||||
// inform about new l2cap connection
|
||||
@ -142,8 +142,8 @@ static void app_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *
|
||||
}
|
||||
break;
|
||||
case L2CAP_EVENT_CHANNEL_CLOSED:
|
||||
local_cid = l2cap_event_channel_closed_get_local_cid(packet);
|
||||
printf("L2CAP: Channel closed 0x%02x\n", local_cid);
|
||||
cid = l2cap_event_channel_closed_get_local_cid(packet);
|
||||
printf("L2CAP: Channel closed 0x%02x\n", cid);
|
||||
break;
|
||||
|
||||
case SM_EVENT_JUST_WORKS_REQUEST:
|
||||
@ -191,6 +191,7 @@ void show_usage(void){
|
||||
|
||||
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\n", pts_address_type, bd_addr_to_str(pts_address), psm_x);
|
||||
printf("s - send data\n");
|
||||
printf("---\n");
|
||||
printf("Ctrl-c - exit\n");
|
||||
printf("---\n");
|
||||
@ -223,6 +224,11 @@ static void stdin_process(btstack_data_source_t *ds, btstack_data_source_callbac
|
||||
l2cap_le_create_channel(&app_packet_handler,pts_address, pts_address_type, psm_x, buffer_x, sizeof(buffer_x), 1, LEVEL_0, &cid_x);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
printf("Send L2CAP Data\n");
|
||||
l2cap_le_send_data(local_cid, (uint8_t *) "0123456789", 10);
|
||||
break;
|
||||
|
||||
default:
|
||||
show_usage();
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user