diff --git a/TODO.txt b/TODO.txt index 6e36e1412..d15751567 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,11 +1,7 @@ /* new todo file for BTstack */ NEXT: -- forward channel ID to client packet handler - - change BTstack.h, BTstack.c and all example apps - map l2cap errors to general status code starting from 0x80 -- create -- add timeouts to cocoa run loop - CocoaTouch User Interface Components - move all inquiry related code from BTstackCocoaAppDelegate into BTInquiryViewController - figure out why stack doesn't shut Bluetooth off when in sleep for a while/after wakeup @@ -17,6 +13,8 @@ NEXT: == Release Version 0.1 +- create +- add timeouts to cocoa run loop - implement rest of L2CAP state machine - incoming connections - list of supported PSM diff --git a/example/WiiMoteOpenGLDemo/BTWiiMote.c b/example/WiiMoteOpenGLDemo/BTWiiMote.c index b703ff4bb..6ce0b8b6a 100644 --- a/example/WiiMoteOpenGLDemo/BTWiiMote.c +++ b/example/WiiMoteOpenGLDemo/BTWiiMote.c @@ -20,16 +20,14 @@ bd_addr_t addr = {0x00, 0x19, 0x1d, 0x90, 0x44, 0x68 }; // WiiMote static void (*data_cb)(uint8_t x, uint8_t y, uint8_t z); static void (*state_cb)(char *text); -void packet_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){ +void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ bd_addr_t event_addr; switch (packet_type) { case L2CAP_DATA_PACKET: - // just dump data for now - // hexdump( packet, size ); - if (packet[8] == 0xa1 && packet[9] == 0x31){ - (*data_cb)(packet[12], packet[13], packet[14]); + if (packet[0] == 0xa1 && packet[1] == 0x31){ + (*data_cb)(packet[4], packet[5], packet[6]); } break; @@ -52,14 +50,13 @@ void packet_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){ case L2CAP_EVENT_CHANNEL_OPENED: // inform about new l2cap connection - bt_flip_addr(event_addr, &packet[2]); - uint16_t psm = READ_BT_16(packet, 10); - uint16_t source_cid = READ_BT_16(packet, 12); + bt_flip_addr(event_addr, &packet[3]); + uint16_t psm = READ_BT_16(packet, 11); + uint16_t source_cid = READ_BT_16(packet, 13); printf("Channel successfully opened: "); print_bd_addr(event_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)); - + READ_BT_16(packet, 9), psm, source_cid, READ_BT_16(packet, 15)); if (psm == 0x13) { // interupt channel openedn succesfully, now open control channel, too. bt_send_cmd(&l2cap_create_channel, event_addr, 0x11); diff --git a/example/rfcomm.c b/example/rfcomm.c index 9fbcd97b9..fbd8e113d 100644 --- a/example/rfcomm.c +++ b/example/rfcomm.c @@ -134,7 +134,7 @@ void _bt_rfcomm_send_uih_pn_command(uint16_t source_cid, uint8_t initiator, uint rfcomm_send_packet(source_cid, address, BT_RFCOMM_UIH, 0, (uint8_t *) payload, pos); } -void packet_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){ +void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ bd_addr_t event_addr; static uint8_t msc_resp_send = 0; @@ -142,6 +142,7 @@ void packet_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){ static uint8_t credits_used = 0; static uint8_t credits_free = 0; uint8_t packet_processed = 0; + switch (packet_type) { case L2CAP_DATA_PACKET: @@ -149,7 +150,7 @@ void packet_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){ // rfcomm: data[9] = command // received 1. message BT_RF_COMM_UA - if (size == 12 && packet[9] == BT_RFCOMM_UA && packet[8] == 0x03){ + if (size == 4 && packet[1] == BT_RFCOMM_UA && packet[0] == 0x03){ packet_processed++; printf("Received RFCOMM unnumbered acknowledgement for channel 0 - multiplexer working\n"); printf("Sending UIH Parameter Negotiation Command\n"); @@ -157,7 +158,7 @@ void packet_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){ } // received UIH Parameter Negotiation Response - if (size == 22 && packet[9] == BT_RFCOMM_UIH && packet[11] == BT_RFCOMM_PN_RSP){ + if (size == 14 && packet[1] == BT_RFCOMM_UIH && packet[3] == BT_RFCOMM_PN_RSP){ packet_processed++; printf("UIH Parameter Negotiation Response\n"); printf("Sending SABM #1\n"); @@ -165,7 +166,7 @@ void packet_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){ } // received 2. message BT_RF_COMM_UA - if (size == 12 && packet[9] == BT_RFCOMM_UA && packet[8] == ((RFCOMM_CHANNEL_ID << 3) | 3) ){ + if (size == 4 && packet[1] == BT_RFCOMM_UA && packet[0] == ((RFCOMM_CHANNEL_ID << 3) | 3) ){ packet_processed++; printf("Received RFCOMM unnumbered acknowledgement for channel 1 - channel opened\n"); printf("Sending MSC 'I'm ready'\n"); @@ -173,33 +174,32 @@ void packet_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){ } // received BT_RFCOMM_MSC_CMD - if (size == 16 && packet[9] == BT_RFCOMM_UIH && packet[11] == BT_RFCOMM_MSC_CMD){ + if (size == 8 && packet[1] == BT_RFCOMM_UIH && packet[3] == BT_RFCOMM_MSC_CMD){ packet_processed++; printf("Received BT_RFCOMM_MSC_CMD\n"); printf("Responding to 'I'm ready'\n"); // fine with this - uint8_t * payload = &packet[8]; - uint8_t address = payload[0] | 2; // set response - payload[3] = BT_RFCOMM_MSC_RSP; // " " - rfcomm_send_packet(source_cid, address, BT_RFCOMM_UIH_PF, 0x30, payload, 8); + uint8_t address = packet[0] | 2; // set response + packet[3] = BT_RFCOMM_MSC_RSP; // " " + rfcomm_send_packet(source_cid, address, BT_RFCOMM_UIH_PF, 0x30, packet, 8); msc_resp_send = 1; } // received BT_RFCOMM_MSC_RSP - if (size == 16 && packet[9] == BT_RFCOMM_UIH && packet[11] == BT_RFCOMM_MSC_RSP){ + if (size == 8 && packet[1] == BT_RFCOMM_UIH && packet[3] == BT_RFCOMM_MSC_RSP){ packet_processed++; msc_resp_received = 1; } - if (packet[9] == BT_RFCOMM_UIH && packet[8] == ((RFCOMM_CHANNEL_ID<<3)|1)){ + if (packet[1] == BT_RFCOMM_UIH && packet[0] == ((RFCOMM_CHANNEL_ID<<3)|1)){ credits_used++; } - if (packet[9] == BT_RFCOMM_UIH_PF && packet[8] == ((RFCOMM_CHANNEL_ID<<3)|1)){ + if (packet[1] == BT_RFCOMM_UIH_PF && packet[0] == ((RFCOMM_CHANNEL_ID<<3)|1)){ if (!credits_free) { - printf("Got %u credits, can send!\n", packet[10]); + printf("Got %u credits, can send!\n", packet[2]); } - credits_free = packet[10]; + credits_free = packet[2]; } uint8_t send_credits_packet = 0; diff --git a/example/test.c b/example/test.c index a0686ee06..bfc704fbe 100644 --- a/example/test.c +++ b/example/test.c @@ -18,19 +18,20 @@ hci_con_handle_t con_handle; uint16_t source_cid_interrupt; uint16_t source_cid_control; -void packet_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){ +void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ bd_addr_t event_addr; switch (packet_type) { case L2CAP_DATA_PACKET: // just dump data for now + printf("source cid %x -- ", channel); hexdump( packet, size ); // HOME => disconnect - if (packet[8] == 0xA1) { // Status report - if (packet[9] == 0x30 || packet[9] == 0x31) { // type 0x30 or 0x31 - if (packet[11] & 0x080) { // homne button pressed + if (packet[0] == 0xA1) { // Status report + if (packet[1] == 0x30 || packet[1] == 0x31) { // type 0x30 or 0x31 + if (packet[3] & 0x080) { // homne button pressed printf("Disconnect baseband\n"); bt_send_cmd(&hci_disconnect, con_handle, 0x13); // remote closed connection } diff --git a/include/btstack/btstack.h b/include/btstack/btstack.h index 42ae5f149..4d37436c7 100644 --- a/include/btstack/btstack.h +++ b/include/btstack/btstack.h @@ -24,8 +24,8 @@ int bt_close(); // send hci cmd packet int bt_send_cmd(hci_cmd_t *cmd, ...); -// register packet handler -void bt_register_packet_handler (void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)); +// register packet handler -- channel only valid for l2cap and rfcomm packets +void bt_register_packet_handler (void (*handler)(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)); void bt_send_acl(uint8_t * data, uint16_t len); diff --git a/src/btstack.c b/src/btstack.c index 9dac9852e..7b386d28f 100644 --- a/src/btstack.c +++ b/src/btstack.c @@ -22,11 +22,11 @@ static uint8_t hci_cmd_buffer[3+255]; static connection_t *btstack_connection = NULL; /** prototypes & dummy functions */ -static void dummy_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){}; +static void dummy_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){}; static int btstack_packet_handler(connection_t *connection, uint16_t packet_type, uint16_t channel, uint8_t *data, uint16_t size); /** local globals :) */ -static void (*client_packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size) = dummy_handler; +static void (*client_packet_handler)(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) = dummy_handler; // init BTstack library @@ -57,12 +57,12 @@ int bt_send_cmd(hci_cmd_t *cmd, ...){ int btstack_packet_handler(connection_t *connection, uint16_t packet_type, uint16_t channel, uint8_t *data, uint16_t size){ // printf("BTstack client handler: packet type %u, data[0] %x\n", packet_type, data[0]); - (*client_packet_handler)(packet_type, data, size); + (*client_packet_handler)(packet_type, channel, data, size); return 0; } // register packet handler -void bt_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){ +void bt_register_packet_handler(void (*handler)(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)){ client_packet_handler = handler; } diff --git a/src/l2cap.c b/src/l2cap.c index d32f60402..da47036d7 100644 --- a/src/l2cap.c +++ b/src/l2cap.c @@ -13,6 +13,9 @@ #include +// size of HCI ACL + L2CAP Header for regular data packets +#define COMPLETE_L2CAP_HEADER 8 + 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); @@ -321,7 +324,8 @@ void l2cap_acl_handler( uint8_t *packet, uint16_t size ){ // Find channel for this channel_id and connection handle l2cap_channel_t * channel = l2cap_get_channel_for_source_cid(channel_id); if (channel) { - socket_connection_send_packet(channel->connection, L2CAP_DATA_PACKET, 0, packet, size); + socket_connection_send_packet(channel->connection, L2CAP_DATA_PACKET, channel_id, + &packet[COMPLETE_L2CAP_HEADER], size-COMPLETE_L2CAP_HEADER); } }