diff --git a/TODO.txt b/TODO.txt index d15a8388a..a64926767 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,13 +1,11 @@ /* new todo file for BTstack */ +Last milestone reached: Restart client app without restarting BTdaemon possible + NEXT: -- implement HCI disconnection -=== Restart client app without restarting BTdaemon possible -- handle HCI link disconnect - - broadcast l2cap disconnects,too - implement timers for POSIX run loop - automatic HCI link disconnect - - periodically close HCI connections without active L2CAP channel + - periodically (e.g., 5 seconds) close HCI connections without active L2CAP channel === BTdaemon can run always - implement rest of L2CAP state machine - incoming connections diff --git a/example/test.c b/example/test.c index f976d316d..9f260aa12 100644 --- a/example/test.c +++ b/example/test.c @@ -16,6 +16,7 @@ // bd_addr_t addr = {0x00, 0x03, 0xc9, 0x3d, 0x77, 0x43 }; // Think Outside Keyboard bd_addr_t addr = {0x00, 0x19, 0x1d, 0x90, 0x44, 0x68 }; // WiiMote +hci_con_handle_t con_handle; uint16_t source_cid_interrupt; uint16_t source_cid_control; @@ -23,10 +24,14 @@ void data_handler(uint8_t *packet, uint16_t size){ // just dump data for now hexdump( packet, size ); - // HOME => disconnect L2CAP - if (packet[11] == 0x080){ - printf("Closing interrupt channel\n"); - bt_send_cmd(&l2cap_disconnect, source_cid_interrupt); + // 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 + printf("Disconnect baseband\n"); + bt_send_cmd(&hci_disconnect, con_handle, 0x13); // remote closed connection + } + } } } @@ -45,6 +50,7 @@ void event_handler(uint8_t *packet, uint16_t size){ // connect to HID device (PSM 0x13) at addr if ( COMMAND_COMPLETE_EVENT(packet, hci_write_authentication_enable) ) { bt_send_cmd(&l2cap_create_channel, addr, 0x13); + printf("Press 1+2 on WiiMote to make it discoverable - Press HOME to disconnect later :)\n"); } @@ -59,10 +65,11 @@ void event_handler(uint8_t *packet, uint16_t size){ bt_flip_addr(addr, &packet[2]); uint16_t psm = READ_BT_16(packet, 10); uint16_t source_cid = READ_BT_16(packet, 12); + con_handle = 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)); + con_handle, psm, source_cid, READ_BT_16(packet, 14)); if (psm == 0x13) { source_cid_interrupt = source_cid; @@ -72,22 +79,14 @@ void event_handler(uint8_t *packet, uint16_t size){ source_cid_control = source_cid; // request acceleration data.. uint8_t setMode31[] = { 0x52, 0x12, 0x00, 0x31 }; - // l2cap_send( source_cid, setMode31, sizeof(setMode31)); + l2cap_send( source_cid, setMode31, sizeof(setMode31)); } } - if (packet[0] == HCI_EVENT_L2CAP_CHANNEL_CLOSED) { - uint16_t source_cid = READ_BT_16(packet, 2); - if (source_cid == source_cid_interrupt){ - printf("Interrupt channel closed, closing control channel\n"); - bt_send_cmd(&l2cap_disconnect, source_cid_control); - } - if (source_cid == source_cid_control){ - printf("Control channel closed, closing baseband connection\n"); - printf("To be implemented..\n"); - exit(0); - // bt_send_cmd(&l2cap_disconnect, source_cid_control); - } + // connection closed -> quit tes app + if (packet[0] == HCI_EVENT_DISCONNECTION_COMPLETE) { + printf("Basebank connection closed, exit.\n"); + exit(0); } } diff --git a/src/hci_cmds.c b/src/hci_cmds.c index 33dac642c..a8f8ddd36 100644 --- a/src/hci_cmds.c +++ b/src/hci_cmds.c @@ -37,7 +37,9 @@ uint16_t hci_create_cmd_internal(uint8_t *hci_cmd_buffer, hci_cmd_t *cmd, va_lis if (*format == '2') { hci_cmd_buffer[pos++] = word >> 8; } else if (*format == 'H') { - // TODO + // TODO implement opaque client connection handles + // pass module handle for now + hci_cmd_buffer[pos++] = word >> 8; } break; case '3': @@ -114,12 +116,19 @@ OPCODE(OGF_LINK_CONTROL, 0x05), "B21121" // BD_ADDR, Packet_Type, Page_Scan_Repetition_Mode, Reserved, Clock_Offset, Allow_Role_Switch }; +hci_cmd_t hci_disconnect = { +OPCODE(OGF_LINK_CONTROL, 0x06), "H1" +// Handle, Reason: 0x05, 0x13-0x15, 0x1a, 0x29 +// see Errors Codes in BT Spec Part D +}; + hci_cmd_t hci_accept_connection_request = { OPCODE(OGF_LINK_CONTROL, 0x09), "B1" // BD_ADDR, Role: become master, stay slave }; hci_cmd_t hci_link_key_request_negative_reply = { OPCODE(OGF_LINK_CONTROL, 0x0c), "B" +// BD_ADDR }; hci_cmd_t hci_pin_code_request_reply = { OPCODE(OGF_LINK_CONTROL, 0x0d), "B1P" diff --git a/src/hci_cmds.h b/src/hci_cmds.h index 16df8a30d..9f68dd888 100644 --- a/src/hci_cmds.h +++ b/src/hci_cmds.h @@ -132,6 +132,7 @@ extern hci_cmd_t hci_pin_code_request_reply; extern hci_cmd_t hci_set_event_mask; extern hci_cmd_t hci_reset; extern hci_cmd_t hci_create_connection; +extern hci_cmd_t hci_disconnect; extern hci_cmd_t hci_host_buffer_size; extern hci_cmd_t hci_write_authentication_enable; extern hci_cmd_t hci_write_local_name;