mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-23 19:20:51 +00:00
improve hci connection handling -> suppress create connection requests for connections already open and just emit connection complete event
This commit is contained in:
parent
9dbf9f9329
commit
c8e4258af8
@ -46,12 +46,23 @@ void event_handler(uint8_t *packet, uint16_t size){
|
||||
|
||||
// inform about new l2cap connection
|
||||
if (packet[0] == HCI_EVENT_L2CAP_CHANNEL_OPENED){
|
||||
uint16_t source_cid = READ_BT_16(packet, 4);
|
||||
printf("Channel successfully opened, handle 0x%02x, source cid 0x%02x, dest cid 0x%02x\n", READ_BT_16(packet, 2), source_cid, READ_BT_16(packet, 6));;
|
||||
bd_addr_t addr;
|
||||
bt_flip_addr(addr, &packet[2]);
|
||||
uint16_t psm = READ_BT_16(packet, 10);
|
||||
uint16_t source_cid = READ_BT_16(packet, 8);
|
||||
printf("Channel successfully opened: ");
|
||||
print_bd_addr(addr);
|
||||
printf(", handle 0x%02x, psm 0x%02x, source cid 0x%02x, dest cid 0x%02x\n",
|
||||
READ_BT_16(packet, 8), psm, source_cid, READ_BT_16(packet, 14));
|
||||
|
||||
// request acceleration data.. probably has to be sent to control channel 0x11 instead of 0x13
|
||||
// uint8_t setMode33[] = { 0x52, 0x12, 0x00, 0x33 };
|
||||
// l2cap_send( source_cid, setMode33, sizeof(setMode33));
|
||||
if (psm == 0x13) {
|
||||
// interupt channel openedn succesfully, now open control channel, too.
|
||||
bt_send_cmd(&l2cap_create_channel, addr, 0x11);
|
||||
} else {
|
||||
// request acceleration data.. probably has to be sent to control channel 0x11 instead of 0x13
|
||||
uint8_t setMode33[] = { 0x52, 0x12, 0x00, 0x33 };
|
||||
l2cap_send( source_cid, setMode33, sizeof(setMode33));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,27 +12,22 @@
|
||||
9C00F7D81019082F008DAB17 /* hci_cmds.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C00F7D61019082F008DAB17 /* hci_cmds.c */; };
|
||||
9C00F86410191097008DAB17 /* utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C00F86210191097008DAB17 /* utils.c */; };
|
||||
9C00F86510191097008DAB17 /* utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C00F86210191097008DAB17 /* utils.c */; };
|
||||
9C00F87310191130008DAB17 /* l2cap_signaling.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C00F87210191130008DAB17 /* l2cap_signaling.c */; };
|
||||
9C00F87410191130008DAB17 /* l2cap_signaling.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C00F87210191130008DAB17 /* l2cap_signaling.c */; };
|
||||
9C05FC971020D3F300255261 /* socket_connection.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C00F7301017ACC3008DAB17 /* socket_connection.c */; };
|
||||
9C1F0E9A0FDAE023008F472F /* run_loop.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C1F0E980FDAE023008F472F /* run_loop.c */; };
|
||||
9C2071F310014D3200A07EA4 /* hci_transport_usb.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C2071F210014D3200A07EA4 /* hci_transport_usb.c */; };
|
||||
9C46FC390FA906F700ABEF05 /* hci.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C46FC340FA906F700ABEF05 /* hci.c */; };
|
||||
9C46FC3A0FA906F700ABEF05 /* hci_transport_h4.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C46FC360FA906F700ABEF05 /* hci_transport_h4.c */; };
|
||||
9C7B5AC0100BD3340065D87E /* linked_list.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C7B5ABF100BD3340065D87E /* linked_list.c */; };
|
||||
9C7B5D00100FC9AA0065D87E /* bt_control_iphone.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C7ECB820FCC85650085DAC5 /* bt_control_iphone.c */; };
|
||||
9C7B5D01100FC9AE0065D87E /* btstack.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CC813A10FFC0774002816F9 /* btstack.c */; };
|
||||
9C7B5D02100FC9B50065D87E /* hci.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C46FC340FA906F700ABEF05 /* hci.c */; };
|
||||
9C7B5D03100FC9BB0065D87E /* test.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C7B5B7E100D04450065D87E /* test.c */; };
|
||||
9C7B5D04100FC9C20065D87E /* hci_dump.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C7ECBB40FCC95DD0085DAC5 /* hci_dump.c */; };
|
||||
9C7B5D0D100FC9CE0065D87E /* linked_list.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C7B5ABF100BD3340065D87E /* linked_list.c */; };
|
||||
9C7B5D0E100FC9D00065D87E /* run_loop.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C1F0E980FDAE023008F472F /* run_loop.c */; };
|
||||
9C7B5D12100FC9F00065D87E /* l2cap.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C88500C0FBF6702004980E4 /* l2cap.c */; };
|
||||
9C7ECB840FCC85650085DAC5 /* bt_control_iphone.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C7ECB820FCC85650085DAC5 /* bt_control_iphone.c */; };
|
||||
9C7ECBB50FCC95DD0085DAC5 /* hci_dump.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C7ECBB40FCC95DD0085DAC5 /* hci_dump.c */; };
|
||||
9C88500E0FBF6702004980E4 /* l2cap.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C88500C0FBF6702004980E4 /* l2cap.c */; };
|
||||
9CC813A20FFC0774002816F9 /* btstack.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CC813A10FFC0774002816F9 /* btstack.c */; };
|
||||
9CC813A50FFC0A51002816F9 /* daemon.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CC813A40FFC0A51002816F9 /* daemon.c */; };
|
||||
9CCE6CEA1025BD0000FCE9F4 /* hci.c in Sources */ = {isa = PBXBuildFile; fileRef = 9C46FC340FA906F700ABEF05 /* hci.c */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
@ -236,7 +231,6 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9C46FC390FA906F700ABEF05 /* hci.c in Sources */,
|
||||
9C46FC3A0FA906F700ABEF05 /* hci_transport_h4.c in Sources */,
|
||||
9C88500E0FBF6702004980E4 /* l2cap.c in Sources */,
|
||||
9C7ECB840FCC85650085DAC5 /* bt_control_iphone.c in Sources */,
|
||||
@ -250,6 +244,7 @@
|
||||
9C00F7D71019082F008DAB17 /* hci_cmds.c in Sources */,
|
||||
9C00F86510191097008DAB17 /* utils.c in Sources */,
|
||||
9C00F87410191130008DAB17 /* l2cap_signaling.c in Sources */,
|
||||
9CCE6CEA1025BD0000FCE9F4 /* hci.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -257,17 +252,12 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9C7B5D00100FC9AA0065D87E /* bt_control_iphone.c in Sources */,
|
||||
9C7B5D01100FC9AE0065D87E /* btstack.c in Sources */,
|
||||
9C7B5D02100FC9B50065D87E /* hci.c in Sources */,
|
||||
9C7B5D03100FC9BB0065D87E /* test.c in Sources */,
|
||||
9C7B5D04100FC9C20065D87E /* hci_dump.c in Sources */,
|
||||
9C7B5D0D100FC9CE0065D87E /* linked_list.c in Sources */,
|
||||
9C7B5D0E100FC9D00065D87E /* run_loop.c in Sources */,
|
||||
9C7B5D12100FC9F00065D87E /* l2cap.c in Sources */,
|
||||
9C00F7D81019082F008DAB17 /* hci_cmds.c in Sources */,
|
||||
9C00F86410191097008DAB17 /* utils.c in Sources */,
|
||||
9C00F87310191130008DAB17 /* l2cap_signaling.c in Sources */,
|
||||
9C05FC971020D3F300255261 /* socket_connection.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -112,8 +112,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);
|
||||
|
100
src/hci.c
100
src/hci.c
@ -18,6 +18,21 @@
|
||||
// the STACK is here
|
||||
static hci_stack_t hci_stack;
|
||||
|
||||
/**
|
||||
* create connection for given address
|
||||
*
|
||||
* @return connection OR NULL, if not found
|
||||
*/
|
||||
static hci_connection_t * create_connection_for_addr(bd_addr_t addr){
|
||||
hci_connection_t * conn = malloc( sizeof(hci_connection_t) );
|
||||
if (!conn) return NULL;
|
||||
BD_ADDR_COPY(conn->address, addr);
|
||||
conn->con_handle = 0xffff;
|
||||
conn->flags = 0;
|
||||
linked_list_add(&hci_stack.connections, (linked_item_t *) conn);
|
||||
return conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* get connection for given address
|
||||
*
|
||||
@ -48,6 +63,7 @@ static hci_connection_t * connection_for_handle(hci_con_handle_t con_handle){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dummy handler called by HCI
|
||||
*/
|
||||
@ -70,6 +86,7 @@ static bt_control_t null_control = {
|
||||
null_control_name
|
||||
};
|
||||
|
||||
|
||||
static void acl_handler(uint8_t *packet, int size){
|
||||
hci_stack.acl_packet_handler(packet, size);
|
||||
|
||||
@ -91,15 +108,10 @@ static void event_handler(uint8_t *packet, int size){
|
||||
if (packet[0] == HCI_EVENT_CONNECTION_COMPLETE) {
|
||||
if (!packet[2]){
|
||||
bt_flip_addr(addr, &packet[5]);
|
||||
printf("Connection_complete "); print_bd_addr(addr); printf("\n");
|
||||
hci_connection_t * conn = connection_for_address(addr);
|
||||
if (!conn) {
|
||||
conn = malloc( sizeof(hci_connection_t) );
|
||||
if (conn) {
|
||||
linked_list_add(&hci_stack.connections, (linked_item_t *) conn);
|
||||
}
|
||||
}
|
||||
if (conn) {
|
||||
BD_ADDR_COPY(conn->address, addr);
|
||||
conn->state = OPEN;
|
||||
conn->con_handle = READ_BT_16(packet, 3);
|
||||
conn->flags = 0;
|
||||
printf("New connection: handle %u, ", conn->con_handle);
|
||||
@ -195,15 +207,6 @@ void hci_init(hci_transport_t *transport, void *config, bt_control_t *control){
|
||||
transport->register_acl_packet_handler( acl_handler);
|
||||
}
|
||||
|
||||
void hci_emit_state(){
|
||||
uint8_t event[3];
|
||||
event[0] = HCI_EVENT_BTSTACK_STATE;
|
||||
event[1] = 1;
|
||||
event[2] = hci_stack.state;
|
||||
hci_dump_packet( HCI_EVENT_PACKET, 0, event, 3);
|
||||
hci_stack.event_packet_handler(event, 3);
|
||||
}
|
||||
|
||||
int hci_power_control(HCI_POWER_MODE power_mode){
|
||||
if (power_mode == HCI_POWER_ON) {
|
||||
|
||||
@ -285,11 +288,42 @@ int hci_send_acl_packet(uint8_t *packet, int size){
|
||||
}
|
||||
|
||||
int hci_send_cmd_packet(uint8_t *packet, int size){
|
||||
if (READ_CMD_OGF(packet) != OGF_BTSTACK) {
|
||||
hci_stack.num_cmd_packets--;
|
||||
return hci_stack.hci_transport->send_cmd_packet(packet, size);
|
||||
bd_addr_t addr;
|
||||
hci_connection_t * conn;
|
||||
// house-keeping
|
||||
|
||||
// create_connection?
|
||||
if (IS_COMMAND(packet, hci_create_connection)){
|
||||
bt_flip_addr(addr, &packet[3]);
|
||||
printf("Create_connection to "); print_bd_addr(addr); printf("\n");
|
||||
conn = connection_for_address(addr);
|
||||
if (conn) {
|
||||
// if connection exists
|
||||
if (conn->state == OPEN) {
|
||||
// if OPEN, emit connection complete command
|
||||
hci_emit_connection_complete(conn);
|
||||
}
|
||||
// otherwise, just ignore
|
||||
return 0; // don't sent packet to controller
|
||||
|
||||
} else{
|
||||
conn = create_connection_for_addr(addr);
|
||||
if (conn){
|
||||
// create connection struct and register, state = SENT_CREATE_CONNECTION
|
||||
conn->state = SENT_CREATE_CONNECTION;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
// accept connection
|
||||
|
||||
// reject connection
|
||||
|
||||
// close_connection?
|
||||
// set state = SENT_DISCONNECT
|
||||
|
||||
hci_stack.num_cmd_packets--;
|
||||
return hci_stack.hci_transport->send_cmd_packet(packet, size);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -302,4 +336,28 @@ int hci_send_cmd(hci_cmd_t *cmd, ...){
|
||||
uint16_t size = hci_create_cmd_internal(hci_stack.hci_cmd_buffer, cmd, argptr);
|
||||
va_end(argptr);
|
||||
return hci_send_cmd_packet(hci_cmd_buffer, size);
|
||||
}
|
||||
}
|
||||
|
||||
void hci_emit_state(){
|
||||
uint8_t len = 3;
|
||||
uint8_t event[len];
|
||||
event[0] = HCI_EVENT_BTSTACK_STATE;
|
||||
event[1] = 1;
|
||||
event[2] = hci_stack.state;
|
||||
hci_dump_packet( HCI_EVENT_PACKET, 0, event, len);
|
||||
hci_stack.event_packet_handler(event, len);
|
||||
}
|
||||
|
||||
void hci_emit_connection_complete(hci_connection_t *conn){
|
||||
uint8_t len = 13;
|
||||
uint8_t event[len];
|
||||
event[0] = HCI_EVENT_CONNECTION_COMPLETE;
|
||||
event[2] = 0; // status = OK
|
||||
bt_store_16(event, 3, conn->con_handle);
|
||||
bt_flip_addr(&event[5], conn->address);
|
||||
event[11] = 1; // ACL connection
|
||||
event[12] = 0; // encryption disabled
|
||||
hci_dump_packet( HCI_EVENT_PACKET, 0, event, len);
|
||||
hci_stack.event_packet_handler(event, len);
|
||||
}
|
||||
|
||||
|
18
src/hci.h
18
src/hci.h
@ -24,7 +24,16 @@ typedef enum {
|
||||
SEND_PIN_CODE_RESPONSE = 1 << 1
|
||||
} hci_connection_flags_t;
|
||||
|
||||
typedef struct hci_connection {
|
||||
typedef enum {
|
||||
SENT_CREATE_CONNECTION = 1,
|
||||
RECEIVED_CONNECTION_REQUEST,
|
||||
ACCEPTED_CONNECTION_REQUEST,
|
||||
REJECTED_CONNECTION_REQUEST,
|
||||
OPEN,
|
||||
SENT_DISCONNECT
|
||||
} CONNECTION_STATE;
|
||||
|
||||
typedef struct {
|
||||
// linked list - assert: first field
|
||||
linked_item_t item;
|
||||
|
||||
@ -33,9 +42,13 @@ typedef struct hci_connection {
|
||||
|
||||
// module handle
|
||||
hci_con_handle_t con_handle;
|
||||
|
||||
// state
|
||||
CONNECTION_STATE state;
|
||||
|
||||
// errands
|
||||
hci_connection_flags_t flags;
|
||||
|
||||
} hci_connection_t;
|
||||
|
||||
/**
|
||||
@ -81,7 +94,7 @@ void hci_register_acl_packet_handler (void (*handler)(uint8_t *packet, uint16_t
|
||||
int hci_power_control(HCI_POWER_MODE mode);
|
||||
|
||||
/**
|
||||
* run the hci daemon loop once
|
||||
* run the hci control loop once
|
||||
*/
|
||||
void hci_run();
|
||||
|
||||
@ -96,3 +109,4 @@ int hci_send_acl_packet(uint8_t *packet, int size);
|
||||
|
||||
//
|
||||
void hci_emit_state();
|
||||
void hci_emit_connection_complete(hci_connection_t *conn);
|
||||
|
@ -85,6 +85,8 @@
|
||||
|
||||
#define COMMAND_COMPLETE_EVENT(event,cmd) ( event[0] == HCI_EVENT_COMMAND_COMPLETE && READ_BT_16(event,3) == cmd.opcode)
|
||||
|
||||
#define IS_COMMAND(packet, command) (READ_BT_16(packet,0) == command.opcode)
|
||||
|
||||
/**
|
||||
* Default INQ Mode
|
||||
*/
|
||||
|
23
src/l2cap.c
23
src/l2cap.c
@ -160,21 +160,26 @@ void l2cap_signaling_handler(l2cap_channel_t *channel, uint8_t *packet, uint16_t
|
||||
l2cap_send_signaling_packet(channel->handle, CONFIGURE_RESPONSE, identifier, channel->dest_cid, 0, 0, size - 16, &packet[16]);
|
||||
|
||||
channel->state = L2CAP_STATE_OPEN;
|
||||
|
||||
// notify client
|
||||
uint8_t event[8];
|
||||
event[0] = HCI_EVENT_L2CAP_CHANNEL_OPENED;
|
||||
event[1] = 6;
|
||||
bt_store_16(event, 2, channel->handle);
|
||||
bt_store_16(event, 4, channel->source_cid);
|
||||
bt_store_16(event, 6, channel->dest_cid);
|
||||
socket_connection_send_packet(channel->connection, HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
l2cap_emit_channel_opened(channel);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// notify client
|
||||
void l2cap_emit_channel_opened(l2cap_channel_t *channel) {
|
||||
uint8_t event[16];
|
||||
event[0] = HCI_EVENT_L2CAP_CHANNEL_OPENED;
|
||||
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->source_cid);
|
||||
bt_store_16(event, 14, channel->dest_cid);
|
||||
socket_connection_send_packet(channel->connection, HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
void l2cap_acl_handler( uint8_t *packet, uint16_t size ){
|
||||
|
||||
// Get Channel ID and command code
|
||||
|
@ -55,3 +55,4 @@ void l2cap_acl_handler( uint8_t *packet, uint16_t size );
|
||||
void l2cap_event_handler( uint8_t *packet, uint16_t size );
|
||||
|
||||
|
||||
void l2cap_emit_channel_opened(l2cap_channel_t *channel);
|
||||
|
Loading…
x
Reference in New Issue
Block a user