clarify use of source_cid and dest_cid - use only for signal packets and use local_cid and remote_cid otherwise - fixes bug in incoming l2cap connection handling

This commit is contained in:
matthias.ringwald 2010-03-04 23:03:40 +00:00
parent 4e32e18a96
commit b35f641c7f
8 changed files with 69 additions and 63 deletions

View File

@ -26,7 +26,7 @@ rfcomm: rfcomm.c
@USE_LDID@ export CODESIGN_ALLOCATE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate ; ldid -S $@ @USE_LDID@ export CODESIGN_ALLOCATE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate ; ldid -S $@
clean: clean:
rm -f test mitm rfcomm inquiry rm -f test mitm rfcomm inquiry l2cap-server
install: install:
echo "nothing to be done" echo "nothing to be done"

View File

@ -82,12 +82,12 @@ void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint
bt_flip_addr(event_addr, &packet[2]); bt_flip_addr(event_addr, &packet[2]);
handle = READ_BT_16(packet, 8); handle = READ_BT_16(packet, 8);
psm = READ_BT_16(packet, 10); psm = READ_BT_16(packet, 10);
source_cid = READ_BT_16(packet, 12); local_cid = READ_BT_16(packet, 12);
dest_cid = READ_BT_16(packet, 14); remote_cid = READ_BT_16(packet, 14);
printf("L2CAP_EVENT_INCOMING_CONNECTION "); printf("L2CAP_EVENT_INCOMING_CONNECTION ");
print_bd_addr(event_addr); print_bd_addr(event_addr);
printf(", handle 0x%02x, psm 0x%02x, src cid 0x%02x, dest cid 0x%02x\n", printf(", handle 0x%02x, psm 0x%02x, local cid 0x%02x, remote cid 0x%02x\n",
handle, psm, source_cid, dest_cid); handle, psm, local_cid, remote_cid);
// accept // accept
bt_send_cmd(&l2cap_accept_connection, source_cid); bt_send_cmd(&l2cap_accept_connection, source_cid);
@ -97,13 +97,13 @@ void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint
// inform about new l2cap connection // inform about new l2cap connection
bt_flip_addr(event_addr, &packet[3]); bt_flip_addr(event_addr, &packet[3]);
psm = READ_BT_16(packet, 11); psm = READ_BT_16(packet, 11);
source_cid = READ_BT_16(packet, 13); local_cid = READ_BT_16(packet, 13);
handle = READ_BT_16(packet, 9); handle = READ_BT_16(packet, 9);
if (packet[2] == 0) { if (packet[2] == 0) {
printf("Channel successfully opened: "); printf("Channel successfully opened: ");
print_bd_addr(event_addr); print_bd_addr(event_addr);
printf(", handle 0x%02x, psm 0x%02x, source cid 0x%02x, dest cid 0x%02x\n", printf(", handle 0x%02x, psm 0x%02x, local cid 0x%02x, remote cid 0x%02x\n",
handle, psm, source_cid, READ_BT_16(packet, 15)); handle, psm, local_cid, READ_BT_16(packet, 15));
} else { } else {
printf("L2CAP connection to device "); printf("L2CAP connection to device ");
print_bd_addr(event_addr); print_bd_addr(event_addr);

View File

@ -74,4 +74,4 @@ btstack_packet_handler_t bt_register_packet_handler(btstack_packet_handler_t han
void bt_send_acl(uint8_t * data, uint16_t len); void bt_send_acl(uint8_t * data, uint16_t len);
void bt_send_l2cap(uint16_t source_cid, uint8_t *data, uint16_t len); void bt_send_l2cap(uint16_t local_cid, uint8_t *data, uint16_t len);

View File

@ -112,13 +112,13 @@
// data: system bluetooth on/off (bool) // data: system bluetooth on/off (bool)
#define BTSTACK_EVENT_SYSTEM_BLUETOOTH_ENABLED 0x64 #define BTSTACK_EVENT_SYSTEM_BLUETOOTH_ENABLED 0x64
// data: event (8), len(8), status (8), address(48), handle (16), psm (16), source_cid(16), dest_cid (16) // data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16)
#define L2CAP_EVENT_CHANNEL_OPENED 0x70 #define L2CAP_EVENT_CHANNEL_OPENED 0x70
// data: event (8), len(8), channel (16) // data: event (8), len(8), channel (16)
#define L2CAP_EVENT_CHANNEL_CLOSED 0x71 #define L2CAP_EVENT_CHANNEL_CLOSED 0x71
// data: event(8), len(8), address(48), handle (16), psm (16), source_cid(16), dest cid(16) // data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16)
#define L2CAP_EVENT_INCOMING_CONNECTION 0x72 #define L2CAP_EVENT_INCOMING_CONNECTION 0x72
// data: event(8), len(8), handle(16) // data: event(8), len(8), handle(16)

View File

@ -50,14 +50,14 @@
#define COMPLETE_L2CAP_HEADER 8 #define COMPLETE_L2CAP_HEADER 8
static void null_event_handler(uint8_t *packet, uint16_t size); static void null_event_handler(uint8_t *packet, uint16_t size);
static void null_data_handler(uint16_t source_cid, uint8_t *packet, uint16_t size); static void null_data_handler(uint16_t local_cid, uint8_t *packet, uint16_t size);
static uint8_t * sig_buffer = NULL; static uint8_t * sig_buffer = NULL;
static linked_list_t l2cap_channels = NULL; static linked_list_t l2cap_channels = NULL;
static linked_list_t l2cap_services = NULL; static linked_list_t l2cap_services = NULL;
static uint8_t * acl_buffer = NULL; static uint8_t * acl_buffer = NULL;
static void (*event_packet_handler) (uint8_t *packet, uint16_t size) = null_event_handler; static void (*event_packet_handler) (uint8_t *packet, uint16_t size) = null_event_handler;
static void (*data_packet_handler) (uint16_t source_cid, uint8_t *packet, uint16_t size) = null_data_handler; static void (*data_packet_handler) (uint16_t local_cid, uint8_t *packet, uint16_t size) = null_data_handler;
static connection_t * capture_connection = NULL; static connection_t * capture_connection = NULL;
static uint8_t config_options[] = { 1, 2, 150, 0}; // mtu = 48 static uint8_t config_options[] = { 1, 2, 150, 0}; // mtu = 48
@ -77,16 +77,17 @@ void l2cap_init(){
/** Register L2CAP packet handlers */ /** Register L2CAP packet handlers */
static void null_event_handler(uint8_t *packet, uint16_t size){ static void null_event_handler(uint8_t *packet, uint16_t size){
} }
static void null_data_handler(uint16_t source_cid, uint8_t *packet, uint16_t size){ static void null_data_handler(uint16_t local_cid, uint8_t *packet, uint16_t size){
} }
void l2cap_register_event_packet_handler(void (*handler)(uint8_t *packet, uint16_t size)){ void l2cap_register_event_packet_handler(void (*handler)(uint8_t *packet, uint16_t size)){
event_packet_handler = handler; event_packet_handler = handler;
} }
void l2cap_register_data_packet_handler (void (*handler)(uint16_t source_cid, uint8_t *packet, uint16_t size)){ void l2cap_register_data_packet_handler (void (*handler)(uint16_t local_cid, uint8_t *packet, uint16_t size)){
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, ...){ 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_list argptr;
va_start(argptr, identifier); va_start(argptr, identifier);
uint16_t len = l2cap_create_signaling_internal(sig_buffer, handle, cmd, identifier, argptr); uint16_t len = l2cap_create_signaling_internal(sig_buffer, handle, cmd, identifier, argptr);
@ -94,12 +95,12 @@ int l2cap_send_signaling_packet(hci_con_handle_t handle, L2CAP_SIGNALING_COMMAND
return hci_send_acl_packet(sig_buffer, len); return hci_send_acl_packet(sig_buffer, len);
} }
l2cap_channel_t * l2cap_get_channel_for_source_cid(uint16_t source_cid){ l2cap_channel_t * l2cap_get_channel_for_local_cid(uint16_t local_cid){
linked_item_t *it; linked_item_t *it;
l2cap_channel_t * channel; l2cap_channel_t * channel;
for (it = (linked_item_t *) l2cap_channels; it ; it = it->next){ for (it = (linked_item_t *) l2cap_channels; it ; it = it->next){
channel = (l2cap_channel_t *) it; channel = (l2cap_channel_t *) it;
if ( channel->source_cid == source_cid) { if ( channel->local_cid == local_cid) {
return channel; return channel;
} }
} }
@ -132,12 +133,12 @@ void l2cap_create_channel_internal(connection_t * connection, bd_addr_t address,
hci_send_cmd(&hci_create_connection, address, 0x18, 0, 0, 0, 0); hci_send_cmd(&hci_create_connection, address, 0x18, 0, 0, 0, 0);
} }
void l2cap_disconnect_internal(uint16_t source_cid, uint8_t reason){ void l2cap_disconnect_internal(uint16_t local_cid, uint8_t reason){
// find channel for source_cid // find channel for local_cid
l2cap_channel_t * channel = l2cap_get_channel_for_source_cid(source_cid); l2cap_channel_t * channel = l2cap_get_channel_for_local_cid(local_cid);
if (channel) { if (channel) {
channel->sig_id = l2cap_next_sig_id(); channel->sig_id = l2cap_next_sig_id();
l2cap_send_signaling_packet( channel->handle, DISCONNECTION_REQUEST, channel->sig_id, channel->dest_cid, channel->source_cid); l2cap_send_signaling_packet( channel->handle, DISCONNECTION_REQUEST, channel->sig_id, channel->remote_cid, channel->local_cid);
channel->state = L2CAP_STATE_WAIT_DISCONNECT; channel->state = L2CAP_STATE_WAIT_DISCONNECT;
} }
} }
@ -167,9 +168,9 @@ static void l2cap_handle_connection_success_for_addr(bd_addr_t address, hci_con_
// success, start l2cap handshake // success, start l2cap handshake
channel->handle = handle; channel->handle = handle;
channel->sig_id = l2cap_next_sig_id(); channel->sig_id = l2cap_next_sig_id();
channel->source_cid = l2cap_next_source_cid(); channel->local_cid = l2cap_next_local_cid();
channel->state = L2CAP_STATE_WAIT_CONNECT_RSP; channel->state = L2CAP_STATE_WAIT_CONNECT_RSP;
l2cap_send_signaling_packet( channel->handle, CONNECTION_REQUEST, channel->sig_id, channel->psm, channel->source_cid); l2cap_send_signaling_packet( channel->handle, CONNECTION_REQUEST, channel->sig_id, channel->psm, channel->local_cid);
} }
} }
} }
@ -245,13 +246,13 @@ void l2cap_event_handler( uint8_t *packet, uint16_t size ){
} }
static void l2cap_handle_disconnect_request(l2cap_channel_t *channel, uint16_t identifier){ static void l2cap_handle_disconnect_request(l2cap_channel_t *channel, uint16_t identifier){
l2cap_send_signaling_packet( channel->handle, DISCONNECTION_RESPONSE, identifier, channel->dest_cid, channel->source_cid); l2cap_send_signaling_packet( channel->handle, DISCONNECTION_RESPONSE, identifier, channel->remote_cid, channel->local_cid);
l2cap_finialize_channel_close(channel); l2cap_finialize_channel_close(channel);
} }
static void l2cap_handle_connection_request(hci_con_handle_t handle, uint8_t sig_id, uint16_t psm, uint16_t dest_cid){ static void l2cap_handle_connection_request(hci_con_handle_t handle, uint8_t sig_id, uint16_t psm, uint16_t source_cid){
// printf("l2cap_handle_connection_request for handle %u, psm %u cid %u\n", handle, psm, dest_cid); // printf("l2cap_handle_connection_request for handle %u, psm %u cid %u\n", handle, psm, source_cid);
l2cap_service_t *service = l2cap_get_service(psm); l2cap_service_t *service = l2cap_get_service(psm);
if (!service) { if (!service) {
// 0x0002 PSM not supported // 0x0002 PSM not supported
@ -277,8 +278,8 @@ static void l2cap_handle_connection_request(hci_con_handle_t handle, uint8_t sig
channel->psm = psm; channel->psm = psm;
channel->handle = handle; channel->handle = handle;
channel->connection = service->connection; channel->connection = service->connection;
channel->source_cid = l2cap_next_source_cid(); channel->local_cid = l2cap_next_local_cid();
channel->dest_cid = dest_cid; channel->remote_cid = source_cid;
// set initial state // set initial state
channel->state = L2CAP_STATE_WAIT_CLIENT_ACCEPT_OR_REJECT; channel->state = L2CAP_STATE_WAIT_CLIENT_ACCEPT_OR_REJECT;
@ -293,26 +294,28 @@ static void l2cap_handle_connection_request(hci_con_handle_t handle, uint8_t sig
l2cap_emit_connection_request(channel); l2cap_emit_connection_request(channel);
} }
void l2cap_accept_connection_internal(uint16_t source_cid){ void l2cap_accept_connection_internal(uint16_t local_cid){
l2cap_channel_t * channel = l2cap_get_channel_for_source_cid(source_cid); l2cap_channel_t * channel = l2cap_get_channel_for_local_cid(local_cid);
if (!channel) { if (!channel) {
fprintf(stderr, "l2cap_accept_connection_internal called but source_cid 0x%x not found", source_cid); fprintf(stderr, "l2cap_accept_connection_internal called but local_cid 0x%x not found", local_cid);
return; return;
} }
// accept connection // accept connection
l2cap_send_signaling_packet(channel->handle, CONNECTION_RESPONSE, channel->sig_id, channel->dest_cid, channel->source_cid, 0, 0); l2cap_send_signaling_packet(channel->handle, CONNECTION_RESPONSE, channel->sig_id, channel->local_cid, channel->remote_cid, 0, 0);
// set real sig and state and start config // set real sig and state and start config
channel->sig_id = l2cap_next_sig_id(); channel->sig_id = l2cap_next_sig_id();
channel->state = L2CAP_STATE_WAIT_CONFIG_REQ_RSP_OR_CONFIG_REQ; channel->state = L2CAP_STATE_WAIT_CONFIG_REQ_RSP_OR_CONFIG_REQ;
l2cap_send_signaling_packet(channel->handle, CONFIGURE_REQUEST, channel->sig_id, channel->dest_cid, 0, 4, &config_options); l2cap_send_signaling_packet(channel->handle, CONFIGURE_REQUEST, channel->sig_id, channel->remote_cid, 0, 4, &config_options);
// printf("new state %u\n", channel->state);
} }
void l2cap_decline_connection_internal(uint16_t source_cid, uint8_t reason){ void l2cap_decline_connection_internal(uint16_t local_cid, uint8_t reason){
l2cap_channel_t * channel = l2cap_get_channel_for_source_cid( source_cid); l2cap_channel_t * channel = l2cap_get_channel_for_local_cid( local_cid);
if (!channel) { if (!channel) {
fprintf(stderr, "l2cap_decline_connection_internal called but source_cid 0x%x not found", source_cid,reason); fprintf(stderr, "l2cap_decline_connection_internal called but local_cid 0x%x not found", local_cid,reason);
return; return;
} }
l2cap_send_signaling_packet(channel->handle, CONNECTION_RESPONSE, channel->sig_id, 0, 0, reason, 0); l2cap_send_signaling_packet(channel->handle, CONNECTION_RESPONSE, channel->sig_id, 0, 0, reason, 0);
@ -327,6 +330,8 @@ void l2cap_signaling_handler(l2cap_channel_t *channel, uint8_t *packet, uint16_t
uint8_t code = READ_L2CAP_SIGNALING_CODE( packet ); uint8_t code = READ_L2CAP_SIGNALING_CODE( packet );
uint8_t identifier = READ_L2CAP_SIGNALING_IDENTIFIER( packet ); uint8_t identifier = READ_L2CAP_SIGNALING_IDENTIFIER( packet );
uint16_t result = 0; uint16_t result = 0;
// printf("signaling handler code %u\n", code);
switch (channel->state) { switch (channel->state) {
@ -337,9 +342,9 @@ void l2cap_signaling_handler(l2cap_channel_t *channel, uint8_t *packet, uint16_t
switch (result) { switch (result) {
case 0: case 0:
// successful connection // successful connection
channel->dest_cid = READ_BT_16(packet, L2CAP_SIGNALING_DATA_OFFSET); channel->remote_cid = READ_BT_16(packet, L2CAP_SIGNALING_DATA_OFFSET);
channel->sig_id = l2cap_next_sig_id(); channel->sig_id = l2cap_next_sig_id();
l2cap_send_signaling_packet(channel->handle, CONFIGURE_REQUEST, channel->sig_id, channel->dest_cid, 0, 4, &config_options); l2cap_send_signaling_packet(channel->handle, CONFIGURE_REQUEST, channel->sig_id, channel->remote_cid, 0, 4, &config_options);
channel->state = L2CAP_STATE_WAIT_CONFIG_REQ_RSP_OR_CONFIG_REQ; channel->state = L2CAP_STATE_WAIT_CONFIG_REQ_RSP_OR_CONFIG_REQ;
break; break;
case 1: case 1:
@ -369,7 +374,7 @@ void l2cap_signaling_handler(l2cap_channel_t *channel, uint8_t *packet, uint16_t
break; break;
case CONFIGURE_REQUEST: case CONFIGURE_REQUEST:
// accept the other's configuration options // accept the other's configuration options
l2cap_send_signaling_packet(channel->handle, CONFIGURE_RESPONSE, identifier, channel->dest_cid, 0, 0, size - 16, &packet[16]); l2cap_send_signaling_packet(channel->handle, CONFIGURE_RESPONSE, identifier, channel->remote_cid, 0, 0, size - 16, &packet[16]);
channel->state = L2CAP_STATE_WAIT_CONFIG_REQ_RSP; channel->state = L2CAP_STATE_WAIT_CONFIG_REQ_RSP;
break; break;
case DISCONNECTION_REQUEST: case DISCONNECTION_REQUEST:
@ -385,7 +390,7 @@ void l2cap_signaling_handler(l2cap_channel_t *channel, uint8_t *packet, uint16_t
switch (code) { switch (code) {
case CONFIGURE_REQUEST: case CONFIGURE_REQUEST:
// accept the other's configuration options // accept the other's configuration options
l2cap_send_signaling_packet(channel->handle, CONFIGURE_RESPONSE, identifier, channel->dest_cid, 0, 0, size - 16, &packet[16]); l2cap_send_signaling_packet(channel->handle, CONFIGURE_RESPONSE, identifier, channel->remote_cid, 0, 0, size - 16, &packet[16]);
channel->state = L2CAP_STATE_OPEN; channel->state = L2CAP_STATE_OPEN;
l2cap_emit_channel_opened(channel, 0); // success l2cap_emit_channel_opened(channel, 0); // success
break; break;
@ -442,6 +447,7 @@ void l2cap_signaling_handler(l2cap_channel_t *channel, uint8_t *packet, uint16_t
} }
break; break;
} }
// printf("new state %u\n", channel->state);
} }
// finalize closed channel // finalize closed channel
@ -502,7 +508,7 @@ void l2cap_close_connection(connection_t *connection){
channel = (l2cap_channel_t *) it; channel = (l2cap_channel_t *) it;
if (channel->connection == connection) { if (channel->connection == connection) {
channel->sig_id = l2cap_next_sig_id(); channel->sig_id = l2cap_next_sig_id();
l2cap_send_signaling_packet( channel->handle, DISCONNECTION_REQUEST, channel->sig_id, channel->dest_cid, channel->source_cid); l2cap_send_signaling_packet( channel->handle, DISCONNECTION_REQUEST, channel->sig_id, channel->remote_cid, channel->local_cid);
channel->state = L2CAP_STATE_WAIT_DISCONNECT; channel->state = L2CAP_STATE_WAIT_DISCONNECT;
} }
} }
@ -527,8 +533,8 @@ void l2cap_emit_channel_opened(l2cap_channel_t *channel, uint8_t status) {
bt_flip_addr(&event[3], channel->address); bt_flip_addr(&event[3], channel->address);
bt_store_16(event, 9, channel->handle); bt_store_16(event, 9, channel->handle);
bt_store_16(event, 11, channel->psm); bt_store_16(event, 11, channel->psm);
bt_store_16(event, 13, channel->source_cid); bt_store_16(event, 13, channel->local_cid);
bt_store_16(event, 15, channel->dest_cid); bt_store_16(event, 15, channel->remote_cid);
hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event)); hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
socket_connection_send_packet(channel->connection, HCI_EVENT_PACKET, 0, event, sizeof(event)); socket_connection_send_packet(channel->connection, HCI_EVENT_PACKET, 0, event, sizeof(event));
} }
@ -537,7 +543,7 @@ void l2cap_emit_channel_closed(l2cap_channel_t *channel) {
uint8_t event[4]; uint8_t event[4];
event[0] = L2CAP_EVENT_CHANNEL_CLOSED; event[0] = L2CAP_EVENT_CHANNEL_CLOSED;
event[1] = sizeof(event) - 2; event[1] = sizeof(event) - 2;
bt_store_16(event, 2, channel->source_cid); bt_store_16(event, 2, channel->local_cid);
hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event)); hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
socket_connection_send_packet(channel->connection, HCI_EVENT_PACKET, 0, event, sizeof(event)); socket_connection_send_packet(channel->connection, HCI_EVENT_PACKET, 0, event, sizeof(event));
} }
@ -549,8 +555,8 @@ void l2cap_emit_connection_request(l2cap_channel_t *channel) {
bt_flip_addr(&event[2], channel->address); bt_flip_addr(&event[2], channel->address);
bt_store_16(event, 8, channel->handle); bt_store_16(event, 8, channel->handle);
bt_store_16(event, 10, channel->psm); bt_store_16(event, 10, channel->psm);
bt_store_16(event, 12, channel->source_cid); bt_store_16(event, 12, channel->local_cid);
bt_store_16(event, 14, channel->dest_cid); bt_store_16(event, 14, channel->remote_cid);
hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event)); hci_dump_packet( HCI_EVENT_PACKET, 0, event, sizeof(event));
socket_connection_send_packet(channel->connection, HCI_EVENT_PACKET, 0, event, sizeof(event)); socket_connection_send_packet(channel->connection, HCI_EVENT_PACKET, 0, event, sizeof(event));
} }
@ -589,8 +595,8 @@ void l2cap_acl_handler( uint8_t *packet, uint16_t size ){
// CONNECTION_REQUEST // CONNECTION_REQUEST
if (code == CONNECTION_REQUEST){ if (code == CONNECTION_REQUEST){
uint16_t psm = READ_BT_16(packet, L2CAP_SIGNALING_DATA_OFFSET); uint16_t psm = READ_BT_16(packet, L2CAP_SIGNALING_DATA_OFFSET);
uint16_t dest_cid = READ_BT_16(packet, L2CAP_SIGNALING_DATA_OFFSET+2); uint16_t source_cid = READ_BT_16(packet, L2CAP_SIGNALING_DATA_OFFSET+2);
l2cap_handle_connection_request(handle, sig_id, psm, dest_cid); l2cap_handle_connection_request(handle, sig_id, psm, source_cid);
return; return;
} }
@ -609,7 +615,7 @@ void l2cap_acl_handler( uint8_t *packet, uint16_t size ){
} }
} else { } else {
// match even commands by source channel id // match even commands by source channel id
if (channel->source_cid == dest_cid) { if (channel->local_cid == dest_cid) {
l2cap_signaling_handler( channel, packet, size); l2cap_signaling_handler( channel, packet, size);
} }
} }
@ -619,7 +625,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_source_cid(channel_id); l2cap_channel_t * channel = l2cap_get_channel_for_local_cid(channel_id);
if (channel) { if (channel) {
socket_connection_send_packet(channel->connection, L2CAP_DATA_PACKET, channel_id, socket_connection_send_packet(channel->connection, L2CAP_DATA_PACKET, channel_id,
&packet[COMPLETE_L2CAP_HEADER], size-COMPLETE_L2CAP_HEADER); &packet[COMPLETE_L2CAP_HEADER], size-COMPLETE_L2CAP_HEADER);
@ -627,9 +633,9 @@ void l2cap_acl_handler( uint8_t *packet, uint16_t size ){
} }
void l2cap_send_internal(uint16_t source_cid, uint8_t *data, uint16_t len){ void l2cap_send_internal(uint16_t local_cid, uint8_t *data, uint16_t len){
// find channel for source_cid, construct l2cap packet and send // find channel for local_cid, construct l2cap packet and send
l2cap_channel_t * channel = l2cap_get_channel_for_source_cid(source_cid); l2cap_channel_t * channel = l2cap_get_channel_for_local_cid(local_cid);
if (channel) { if (channel) {
// 0 - Connection handle : PB=10 : BC=00 // 0 - Connection handle : PB=10 : BC=00
bt_store_16(acl_buffer, 0, channel->handle | (2 << 12) | (0 << 14)); bt_store_16(acl_buffer, 0, channel->handle | (2 << 12) | (0 << 14));
@ -638,7 +644,7 @@ void l2cap_send_internal(uint16_t source_cid, uint8_t *data, uint16_t len){
// 4 - L2CAP packet length // 4 - L2CAP packet length
bt_store_16(acl_buffer, 4, len + 0); bt_store_16(acl_buffer, 4, len + 0);
// 6 - L2CAP channel DEST // 6 - L2CAP channel DEST
bt_store_16(acl_buffer, 6, channel->dest_cid); bt_store_16(acl_buffer, 6, channel->remote_cid);
// 8 - data // 8 - data
memcpy(&acl_buffer[8], data, len); memcpy(&acl_buffer[8], data, len);
// send // send

View File

@ -47,7 +47,7 @@
#define L2CAP_SIG_ID_INVALID 0 #define L2CAP_SIG_ID_INVALID 0
typedef enum { typedef enum {
L2CAP_STATE_CLOSED, // no baseband L2CAP_STATE_CLOSED = 1, // no baseband
L2CAP_STATE_WAIT_CLIENT_ACCEPT_OR_REJECT, L2CAP_STATE_WAIT_CLIENT_ACCEPT_OR_REJECT,
L2CAP_STATE_WAIT_CONNECT_RSP, // from peer L2CAP_STATE_WAIT_CONNECT_RSP, // from peer
L2CAP_STATE_WAIT_CONFIG_REQ_RSP_OR_CONFIG_REQ, L2CAP_STATE_WAIT_CONFIG_REQ_RSP_OR_CONFIG_REQ,
@ -64,8 +64,8 @@ typedef struct {
L2CAP_STATE state; L2CAP_STATE state;
uint8_t sig_id; // other sig for conn requests uint8_t sig_id; // other sig for conn requests
uint16_t source_cid; uint16_t local_cid;
uint16_t dest_cid; uint16_t remote_cid;
bd_addr_t address; bd_addr_t address;
uint16_t psm; uint16_t psm;
hci_con_handle_t handle; hci_con_handle_t handle;
@ -94,8 +94,8 @@ typedef struct {
void l2cap_init(); void l2cap_init();
void l2cap_register_event_packet_handler(void (*handler)(uint8_t *packet, uint16_t size)); void l2cap_register_event_packet_handler(void (*handler)(uint8_t *packet, uint16_t size));
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);
void l2cap_disconnect_internal(uint16_t source_cid, uint8_t reason); void l2cap_disconnect_internal(uint16_t local_cid, uint8_t reason);
void l2cap_send_internal(uint16_t source_cid, uint8_t *data, uint16_t len); void l2cap_send_internal(uint16_t local_cid, uint8_t *data, uint16_t len);
void l2cap_acl_handler( uint8_t *packet, uint16_t size ); void l2cap_acl_handler( uint8_t *packet, uint16_t size );
void l2cap_event_handler( uint8_t *packet, uint16_t size ); void l2cap_event_handler( uint8_t *packet, uint16_t size );
@ -108,8 +108,8 @@ l2cap_service_t * l2cap_get_service(uint16_t psm);
void l2cap_register_service_internal(connection_t *connection, uint16_t psm, uint16_t); void l2cap_register_service_internal(connection_t *connection, uint16_t psm, uint16_t);
void l2cap_unregister_service_internal(connection_t *connection, uint16_t psm); void l2cap_unregister_service_internal(connection_t *connection, uint16_t psm);
void l2cap_accept_connection_internal(uint16_t source_cid); void l2cap_accept_connection_internal(uint16_t local_cid);
void l2cap_decline_connection_internal(uint16_t source_cid, uint8_t reason); void l2cap_decline_connection_internal(uint16_t local_cid, uint8_t reason);
void l2cap_emit_channel_opened(l2cap_channel_t *channel, uint8_t status); void l2cap_emit_channel_opened(l2cap_channel_t *channel, uint8_t status);
void l2cap_emit_channel_closed(l2cap_channel_t *channel); void l2cap_emit_channel_closed(l2cap_channel_t *channel);

View File

@ -65,7 +65,7 @@ uint8_t l2cap_next_sig_id(void){
return sig_seq_nr; return sig_seq_nr;
} }
uint16_t l2cap_next_source_cid(void){ uint16_t l2cap_next_local_cid(void){
return source_cid++; return source_cid++;
} }

View File

@ -58,5 +58,5 @@ typedef enum {
uint16_t l2cap_create_signaling_internal(uint8_t * acl_buffer,hci_con_handle_t handle, L2CAP_SIGNALING_COMMANDS cmd, uint8_t identifier, va_list argptr); uint16_t l2cap_create_signaling_internal(uint8_t * acl_buffer,hci_con_handle_t handle, L2CAP_SIGNALING_COMMANDS cmd, uint8_t identifier, va_list argptr);
uint8_t l2cap_next_sig_id(); uint8_t l2cap_next_sig_id();
uint16_t l2cap_next_source_cid(); uint16_t l2cap_next_local_cid();