mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-11 18:40:22 +00:00
fix l2cap signaling command dispatching
This commit is contained in:
parent
ed21c97dcd
commit
bb53b2914c
@ -62,9 +62,9 @@ void l2cap_event_handler( uint8_t *packet, uint16_t size ){
|
||||
if (chan->state == L2CAP_STATE_CLOSED) {
|
||||
chan->handle = READ_BT_16(packet, 3);
|
||||
chan->sig_id = l2cap_next_sig_id();
|
||||
chan->local_cid = l2cap_next_local_cid();
|
||||
chan->source_cid = l2cap_next_source_cid();
|
||||
|
||||
bt_send_l2cap_signaling_packet( chan->handle, CONNECTION_REQUEST, chan->sig_id, chan->psm, chan->local_cid);
|
||||
bt_send_l2cap_signaling_packet( chan->handle, CONNECTION_REQUEST, chan->sig_id, chan->psm, chan->source_cid);
|
||||
|
||||
chan->state = L2CAP_STATE_WAIT_CONNECT_RSP;
|
||||
}
|
||||
@ -123,7 +123,7 @@ void l2cap_signaling_handler(l2cap_channel_t *channel, uint8_t *packet, uint16_t
|
||||
event[0] = HCI_EVENT_L2CAP_CHANNEL_OPENED;
|
||||
event[1] = 4;
|
||||
bt_store_16(event, 2, channel->handle);
|
||||
bt_store_16(event, 4, channel->local_cid);
|
||||
bt_store_16(event, 4, channel->source_cid);
|
||||
(*channel->event_callback)(event, sizeof(event));
|
||||
break;
|
||||
}
|
||||
@ -133,32 +133,51 @@ void l2cap_signaling_handler(l2cap_channel_t *channel, uint8_t *packet, uint16_t
|
||||
|
||||
void l2cap_data_handler( uint8_t *packet, uint16_t size ){
|
||||
|
||||
// Get Channel ID
|
||||
// Get Channel ID and command code
|
||||
uint16_t channel_id = READ_L2CAP_CHANNEL_ID(packet);
|
||||
uint8_t code = READ_L2CAP_SIGNALING_CODE( packet );
|
||||
|
||||
// Get Connection
|
||||
hci_con_handle_t handle = READ_ACL_CONNECTION_HANDLE(packet);
|
||||
|
||||
// Signaling Packet?
|
||||
if (channel_id == 1) {
|
||||
// Get Signaling Identifier
|
||||
uint8_t sig_id = READ_L2CAP_SIGNALING_IDENTIFIER(packet);
|
||||
|
||||
if (code < 1 || code == 2 || code >= 8){
|
||||
// not for a particular channel
|
||||
return;
|
||||
}
|
||||
|
||||
// Get Signaling Identifier and potential destination CID
|
||||
uint8_t sig_id = READ_L2CAP_SIGNALING_IDENTIFIER(packet);
|
||||
uint16_t dest_cid = READ_BT_16(packet, L2CAP_SIGNALING_DATA_OFFSET);
|
||||
|
||||
// Find channel for this sig_id and connection handle
|
||||
linked_item_t *it;
|
||||
for (it = (linked_item_t *) l2cap_channels; it ; it = it->next){
|
||||
l2cap_channel_t * chan = (l2cap_channel_t *) it;
|
||||
if ( chan->sig_id == sig_id && chan->handle == handle) {
|
||||
l2cap_signaling_handler( chan, packet, size);
|
||||
if (chan->handle == handle) {
|
||||
if (code & 1) {
|
||||
// match odd commands by previous signaling identifier
|
||||
if (chan->sig_id == sig_id) {
|
||||
l2cap_signaling_handler( chan, packet, size);
|
||||
}
|
||||
} else {
|
||||
// match even commands by source channel id
|
||||
if (chan->source_cid == dest_cid) {
|
||||
l2cap_signaling_handler( chan, packet, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Find channel for this channel_id and connection handle
|
||||
linked_item_t *it;
|
||||
for (it = (linked_item_t *) l2cap_channels; it ; it = it->next){
|
||||
l2cap_channel_t * channel = (l2cap_channel_t *) it;
|
||||
if ( channel->local_cid == channel_id && channel->handle == handle) {
|
||||
if ( channel->source_cid == channel_id && channel->handle == handle) {
|
||||
(*channel->data_callback)(packet, size);
|
||||
}
|
||||
}
|
||||
|
@ -75,8 +75,8 @@ int main (int argc, const char * argv[]){
|
||||
// @TODO allow configuration per HCI CMD
|
||||
|
||||
// use logger: format HCI_DUMP_PACKETLOGGER, HCI_DUMP_BLUEZ or HCI_DUMP_STDOUT
|
||||
// hci_dump_open("/tmp/hci_dump.pklg", HCI_DUMP_PACKETLOGGER);
|
||||
hci_dump_open(NULL, HCI_DUMP_STDOUT);
|
||||
hci_dump_open("/tmp/hci_dump.pklg", HCI_DUMP_PACKETLOGGER);
|
||||
// hci_dump_open(NULL, HCI_DUMP_STDOUT);
|
||||
|
||||
// init HCI
|
||||
hci_init(transport, &config, control);
|
||||
|
@ -30,7 +30,7 @@ typedef struct {
|
||||
|
||||
L2CAP_STATE state;
|
||||
uint8_t sig_id;
|
||||
uint16_t local_cid;
|
||||
uint16_t source_cid;
|
||||
uint16_t dest_cid;
|
||||
bd_addr_t address;
|
||||
uint16_t psm;
|
||||
|
@ -23,7 +23,7 @@ static char *l2cap_signaling_commands_format[] = {
|
||||
};
|
||||
|
||||
uint8_t sig_seq_nr = 0xff;
|
||||
uint16_t local_cid = 0x40;
|
||||
uint16_t source_cid = 0x40;
|
||||
|
||||
uint8_t l2cap_next_sig_id(void){
|
||||
if (sig_seq_nr == 0xff) {
|
||||
@ -34,8 +34,8 @@ uint8_t l2cap_next_sig_id(void){
|
||||
return sig_seq_nr;
|
||||
}
|
||||
|
||||
uint16_t l2cap_next_local_cid(void){
|
||||
return local_cid++;
|
||||
uint16_t l2cap_next_source_cid(void){
|
||||
return source_cid++;
|
||||
}
|
||||
|
||||
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){
|
||||
|
@ -27,5 +27,5 @@ typedef enum {
|
||||
uint16_t l2cap_create_signaling_packet(uint8_t *acl_buffer, hci_con_handle_t handle, L2CAP_SIGNALING_COMMANDS cmd, uint8_t identifier, ...);
|
||||
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();
|
||||
uint16_t l2cap_next_local_cid();
|
||||
uint16_t l2cap_next_source_cid();
|
||||
|
||||
|
@ -44,7 +44,7 @@ typedef uint8_t link_key_t[LINK_KEY_LEN];
|
||||
// L2CAP Signaling Packet
|
||||
#define READ_L2CAP_SIGNALING_CODE( buffer ) (buffer[ 8])
|
||||
#define READ_L2CAP_SIGNALING_IDENTIFIER( buffer ) (buffer[ 9])
|
||||
#define READ_L2CAP_SIGNALING_LENGTH( buffer ) (buffer[10])
|
||||
#define READ_L2CAP_SIGNALING_LENGTH( buffer ) (READ_BT_16(buffer, 10))
|
||||
|
||||
#define L2CAP_SIGNALING_DATA_OFFSET 12
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user