mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-30 07:21:20 +00:00
also dispatch L2CAP DATA packets
This commit is contained in:
parent
f8dd2f72bd
commit
58de561001
153
src/l2cap.c
153
src/l2cap.c
@ -92,13 +92,59 @@ void l2cap_register_data_packet_handler (void (*handler)(connection_t * connect
|
|||||||
data_packet_handler = handler;
|
data_packet_handler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
int l2cap_send_signaling_packet(hci_con_handle_t handle, L2CAP_SIGNALING_COMMANDS cmd, uint8_t identifier, ...){
|
// notify client/protocol handler
|
||||||
// printf("l2cap_send_signaling_packet type %u\n", cmd);
|
void l2cap_dispatch(l2cap_channel_t *channel, uint8_t type, uint8_t * data, uint16_t size){
|
||||||
va_list argptr;
|
if (channel->packet_handler) {
|
||||||
va_start(argptr, identifier);
|
(* (channel->packet_handler))(type, channel->local_cid, data, size);
|
||||||
uint16_t len = l2cap_create_signaling_internal(sig_buffer, handle, cmd, identifier, argptr);
|
} else {
|
||||||
va_end(argptr);
|
switch (type){
|
||||||
return hci_send_acl_packet(sig_buffer, len);
|
case HCI_EVENT_PACKET:
|
||||||
|
(*event_packet_handler)(channel->connection, data, size);
|
||||||
|
break;
|
||||||
|
case L2CAP_DATA_PACKET:
|
||||||
|
(*data_packet_handler)(channel->connection, channel->local_cid, data, size);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// ??
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void l2cap_emit_channel_opened(l2cap_channel_t *channel, uint8_t status) {
|
||||||
|
uint8_t event[17];
|
||||||
|
event[0] = L2CAP_EVENT_CHANNEL_OPENED;
|
||||||
|
event[1] = sizeof(event) - 2;
|
||||||
|
event[2] = status;
|
||||||
|
bt_flip_addr(&event[3], channel->address);
|
||||||
|
bt_store_16(event, 9, channel->handle);
|
||||||
|
bt_store_16(event, 11, channel->psm);
|
||||||
|
bt_store_16(event, 13, channel->local_cid);
|
||||||
|
bt_store_16(event, 15, channel->remote_cid);
|
||||||
|
hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||||
|
l2cap_dispatch(channel, HCI_EVENT_PACKET, event, sizeof(event));
|
||||||
|
}
|
||||||
|
|
||||||
|
void l2cap_emit_channel_closed(l2cap_channel_t *channel) {
|
||||||
|
uint8_t event[4];
|
||||||
|
event[0] = L2CAP_EVENT_CHANNEL_CLOSED;
|
||||||
|
event[1] = sizeof(event) - 2;
|
||||||
|
bt_store_16(event, 2, channel->local_cid);
|
||||||
|
hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||||
|
l2cap_dispatch(channel, HCI_EVENT_PACKET, event, sizeof(event));
|
||||||
|
}
|
||||||
|
|
||||||
|
void l2cap_emit_connection_request(l2cap_channel_t *channel) {
|
||||||
|
uint8_t event[16];
|
||||||
|
event[0] = L2CAP_EVENT_INCOMING_CONNECTION;
|
||||||
|
event[1] = sizeof(event) - 2;
|
||||||
|
bt_flip_addr(&event[2], channel->address);
|
||||||
|
bt_store_16(event, 8, channel->handle);
|
||||||
|
bt_store_16(event, 10, channel->psm);
|
||||||
|
bt_store_16(event, 12, channel->local_cid);
|
||||||
|
bt_store_16(event, 14, channel->remote_cid);
|
||||||
|
hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||||
|
l2cap_dispatch(channel, HCI_EVENT_PACKET, event, sizeof(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
l2cap_channel_t * l2cap_get_channel_for_local_cid(uint16_t local_cid){
|
l2cap_channel_t * l2cap_get_channel_for_local_cid(uint16_t local_cid){
|
||||||
@ -112,6 +158,34 @@ l2cap_channel_t * l2cap_get_channel_for_local_cid(uint16_t local_cid){
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int l2cap_send_signaling_packet(hci_con_handle_t handle, L2CAP_SIGNALING_COMMANDS cmd, uint8_t identifier, ...){
|
||||||
|
// printf("l2cap_send_signaling_packet type %u\n", cmd);
|
||||||
|
va_list argptr;
|
||||||
|
va_start(argptr, identifier);
|
||||||
|
uint16_t len = l2cap_create_signaling_internal(sig_buffer, handle, cmd, identifier, argptr);
|
||||||
|
va_end(argptr);
|
||||||
|
return hci_send_acl_packet(sig_buffer, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void l2cap_send_internal(uint16_t local_cid, uint8_t *data, uint16_t len){
|
||||||
|
// find channel for local_cid, construct l2cap packet and send
|
||||||
|
l2cap_channel_t * channel = l2cap_get_channel_for_local_cid(local_cid);
|
||||||
|
if (channel) {
|
||||||
|
// 0 - Connection handle : PB=10 : BC=00
|
||||||
|
bt_store_16(acl_buffer, 0, channel->handle | (2 << 12) | (0 << 14));
|
||||||
|
// 2 - ACL length
|
||||||
|
bt_store_16(acl_buffer, 2, len + 4);
|
||||||
|
// 4 - L2CAP packet length
|
||||||
|
bt_store_16(acl_buffer, 4, len + 0);
|
||||||
|
// 6 - L2CAP channel DEST
|
||||||
|
bt_store_16(acl_buffer, 6, channel->remote_cid);
|
||||||
|
// 8 - data
|
||||||
|
memcpy(&acl_buffer[8], data, len);
|
||||||
|
// send
|
||||||
|
hci_send_acl_packet(acl_buffer, len+8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// open outgoing L2CAP channel
|
// open outgoing L2CAP channel
|
||||||
void l2cap_create_channel_internal(connection_t * connection, bd_addr_t address, uint16_t psm){
|
void l2cap_create_channel_internal(connection_t * connection, bd_addr_t address, uint16_t psm){
|
||||||
@ -562,7 +636,7 @@ void l2cap_acl_handler( uint8_t *packet, uint16_t size ){
|
|||||||
// Find channel for this channel_id and connection handle
|
// Find channel for this channel_id and connection handle
|
||||||
l2cap_channel_t * channel = l2cap_get_channel_for_local_cid(channel_id);
|
l2cap_channel_t * channel = l2cap_get_channel_for_local_cid(channel_id);
|
||||||
if (channel) {
|
if (channel) {
|
||||||
(*data_packet_handler)(channel->connection, channel_id, &packet[COMPLETE_L2CAP_HEADER], size-COMPLETE_L2CAP_HEADER);
|
l2cap_dispatch(channel, L2CAP_DATA_PACKET, &packet[COMPLETE_L2CAP_HEADER], size-COMPLETE_L2CAP_HEADER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -644,69 +718,6 @@ void l2cap_close_connection(connection_t *connection){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// notify client/protocol handler
|
|
||||||
void l2cap_dispatch(l2cap_channel_t *channel, uint8_t type, uint8_t * data, uint16_t size){
|
|
||||||
if (channel->packet_handler) {
|
|
||||||
(* (channel->packet_handler))(type, channel->local_cid, data, size);
|
|
||||||
} else {
|
|
||||||
(*event_packet_handler)(channel->connection, data, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void l2cap_emit_channel_opened(l2cap_channel_t *channel, uint8_t status) {
|
|
||||||
uint8_t event[17];
|
|
||||||
event[0] = L2CAP_EVENT_CHANNEL_OPENED;
|
|
||||||
event[1] = sizeof(event) - 2;
|
|
||||||
event[2] = status;
|
|
||||||
bt_flip_addr(&event[3], channel->address);
|
|
||||||
bt_store_16(event, 9, channel->handle);
|
|
||||||
bt_store_16(event, 11, channel->psm);
|
|
||||||
bt_store_16(event, 13, channel->local_cid);
|
|
||||||
bt_store_16(event, 15, channel->remote_cid);
|
|
||||||
hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
|
|
||||||
l2cap_dispatch(channel, HCI_EVENT_PACKET, event, sizeof(event));
|
|
||||||
}
|
|
||||||
|
|
||||||
void l2cap_emit_channel_closed(l2cap_channel_t *channel) {
|
|
||||||
uint8_t event[4];
|
|
||||||
event[0] = L2CAP_EVENT_CHANNEL_CLOSED;
|
|
||||||
event[1] = sizeof(event) - 2;
|
|
||||||
bt_store_16(event, 2, channel->local_cid);
|
|
||||||
hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
|
|
||||||
l2cap_dispatch(channel, HCI_EVENT_PACKET, event, sizeof(event));
|
|
||||||
}
|
|
||||||
|
|
||||||
void l2cap_emit_connection_request(l2cap_channel_t *channel) {
|
|
||||||
uint8_t event[16];
|
|
||||||
event[0] = L2CAP_EVENT_INCOMING_CONNECTION;
|
|
||||||
event[1] = sizeof(event) - 2;
|
|
||||||
bt_flip_addr(&event[2], channel->address);
|
|
||||||
bt_store_16(event, 8, channel->handle);
|
|
||||||
bt_store_16(event, 10, channel->psm);
|
|
||||||
bt_store_16(event, 12, channel->local_cid);
|
|
||||||
bt_store_16(event, 14, channel->remote_cid);
|
|
||||||
hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
|
|
||||||
l2cap_dispatch(channel, HCI_EVENT_PACKET, event, sizeof(event));
|
|
||||||
}
|
|
||||||
|
|
||||||
void l2cap_send_internal(uint16_t local_cid, uint8_t *data, uint16_t len){
|
|
||||||
// find channel for local_cid, construct l2cap packet and send
|
|
||||||
l2cap_channel_t * channel = l2cap_get_channel_for_local_cid(local_cid);
|
|
||||||
if (channel) {
|
|
||||||
// 0 - Connection handle : PB=10 : BC=00
|
|
||||||
bt_store_16(acl_buffer, 0, channel->handle | (2 << 12) | (0 << 14));
|
|
||||||
// 2 - ACL length
|
|
||||||
bt_store_16(acl_buffer, 2, len + 4);
|
|
||||||
// 4 - L2CAP packet length
|
|
||||||
bt_store_16(acl_buffer, 4, len + 0);
|
|
||||||
// 6 - L2CAP channel DEST
|
|
||||||
bt_store_16(acl_buffer, 6, channel->remote_cid);
|
|
||||||
// 8 - data
|
|
||||||
memcpy(&acl_buffer[8], data, len);
|
|
||||||
// send
|
|
||||||
hci_send_acl_packet(acl_buffer, len+8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void l2cap_set_capture_connection(connection_t * connection){
|
void l2cap_set_capture_connection(connection_t * connection){
|
||||||
capture_connection = connection;
|
capture_connection = connection;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user