From ebb333de9a8fb25dca34d0ca6b6ca76b8340a820 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 7 Oct 2012 14:50:51 +0200 Subject: [PATCH 1/9] Now able to pair with Wiimote --- BTD.cpp | 101 ++++++++++++++++++++++++++++++++------------------- BTD.h | 10 +++-- Wii.cpp | 98 ++++++++++++++++++++++++++++++++++++++++--------- Wii.h | 41 ++++++++++++++------- keywords.txt | 3 +- 5 files changed, 180 insertions(+), 73 deletions(-) diff --git a/BTD.cpp b/BTD.cpp index 85a75183..f6530db4 100644 --- a/BTD.cpp +++ b/BTD.cpp @@ -427,12 +427,18 @@ void BTD::HCI_event_task() { break; case EV_PIN_CODE_REQUEST: - if(btdPin != NULL) { + if(pairWithWii) { +#ifdef DEBUG + Notify(PSTR("\r\nPairing with wiimote")); +#endif + hci_pin_code_request_reply(); + } + else if(btdPin != NULL) { #ifdef DEBUG Notify(PSTR("\r\nBluetooth pin is set too: ")); Serial.print(btdPin); #endif - hci_pin_code_request_reply(btdPin); + hci_pin_code_request_reply(); } else { #ifdef DEBUG @@ -449,14 +455,21 @@ void BTD::HCI_event_task() { hci_link_key_request_negative_reply(); break; - /* We will just ignore the following events */ + case EV_AUTHENTICATION_COMPLETE: + if(pairWithWii) { +#ifdef DEBUG + Notify(PSTR("\r\nPairing successful")); +#endif + connectToWii = true; // Only send the ACL data to the Wii service + } + break; + /* We will just ignore the following events */ case EV_NUM_COMPLETE_PKT: case EV_ROLE_CHANGED: case EV_PAGE_SCAN_REP_MODE: case EV_LOOPBACK_COMMAND: - case EV_DATA_BUFFER_OVERFLOW: - case EV_CHANGE_CONNECTION_LINK: - case EV_AUTHENTICATION_COMPLETE: + case EV_DATA_BUFFER_OVERFLOW: + case EV_CHANGE_CONNECTION_LINK: case EV_MAX_SLOTS_CHANGE: case EV_QOS_SETUP_COMPLETE: case EV_LINK_KEY_NOTIFICATION: @@ -552,16 +565,12 @@ void BTD::HCI_task() { break; case HCI_CHECK_WII_SERVICE: - if(wiiServiceID != -1) { // Check if it should try to connect to a wiimote - if(disc_bdaddr[5] == 0 && disc_bdaddr[4] == 0 && disc_bdaddr[3] == 0 && disc_bdaddr[2] == 0 && disc_bdaddr[1] == 0 && disc_bdaddr[0] == 0) { + if(pairWithWii) { // Check if it should try to connect to a wiimote #ifdef DEBUG - Notify(PSTR("\r\nStarting inquiry\r\nPress 1 & 2 on the Wiimote")); + Notify(PSTR("\r\nStarting inquiry\r\nPress 1 & 2 on the Wiimote")); #endif - hci_inquiry(); - hci_state = HCI_INQUIRY_STATE; - } - else - hci_state = HCI_CONNECT_WII_STATE; + hci_inquiry(); + hci_state = HCI_INQUIRY_STATE; } else hci_state = HCI_SCANNING_STATE; // Don't try to connect to a Wiimote @@ -572,23 +581,16 @@ void BTD::HCI_task() { hci_inquiry_cancel(); // Stop inquiry #ifdef DEBUG Notify(PSTR("\r\nWiimote found")); - Notify(PSTR("\r\nCreate the instance like so to connect automatically:")); - Notify(PSTR("\r\nWII Wii(&Btd,")); - for(int8_t i = 5; i>0;i--) { - Notify(PSTR("0x")); - PrintHex(disc_bdaddr[i]); - Notify(PSTR(",")); - } - Notify(PSTR("0x")); - PrintHex(disc_bdaddr[0]); - Notify(PSTR(");")); + Notify(PSTR("\r\nNow just create the instance like so:")); + Notify(PSTR("\r\nWII Wii(&Btd);")); + Notify(PSTR("\r\nAnd then press any button on the Wiimote")); #endif hci_state = HCI_CONNECT_WII_STATE; } break; case HCI_CONNECT_WII_STATE: - if(!hci_wii_found || hci_cmd_complete) { + if(hci_cmd_complete) { #ifdef DEBUG Notify(PSTR("\r\nConnecting to Wiimote")); #endif @@ -602,8 +604,9 @@ void BTD::HCI_task() { if(hci_connect_complete) { #ifdef DEBUG Notify(PSTR("\r\nConnected to Wiimote")); -#endif - connectToWii = true; // Only send the ACL data to the Wii service +#endif + hci_authentication_request(); // This will start the pairing with the wiimote + //connectToWii = true; hci_state = HCI_SCANNING_STATE; } else { #ifdef DEBUG @@ -615,7 +618,7 @@ void BTD::HCI_task() { break; case HCI_SCANNING_STATE: - if(!connectToWii) { + if(!connectToWii && !pairWithWii) { #ifdef DEBUG Notify(PSTR("\r\nWait For Incoming Connection Request")); #endif @@ -663,6 +666,10 @@ void BTD::HCI_task() { PrintHex(disc_bdaddr[0]); #endif l2capConnectionClaimed = false; + if(strncmp((const char *)remote_name, "Nintendo", 8) == 0) { + Serial.print("\r\nWiimote is connecting"); + incomingWii = true; + } hci_event_flag = 0; hci_state = HCI_DONE_STATE; } @@ -849,7 +856,7 @@ void BTD::hci_connect() { HCI_Command(hcibuf, 16); } -void BTD::hci_pin_code_request_reply(const char* key) { +void BTD::hci_pin_code_request_reply() { hcibuf[0] = 0x0D; // HCI OCF = 0D hcibuf[1] = 0x01 << 2; // HCI OGF = 1 hcibuf[2] = 0x17; // parameter length 23 @@ -858,14 +865,25 @@ void BTD::hci_pin_code_request_reply(const char* key) { hcibuf[5] = disc_bdaddr[2]; hcibuf[6] = disc_bdaddr[3]; hcibuf[7] = disc_bdaddr[4]; - hcibuf[8] = disc_bdaddr[5]; - hcibuf[9] = strlen(key); // Length of key - uint8_t i; - for(i = 0; i < strlen(key); i++) // The maximum size of the key is 16 - hcibuf[i+10] = key[i]; - for(;i < 16; i++) - hcibuf[i+10] = 0x00; // The rest should be 0 - + hcibuf[8] = disc_bdaddr[5]; + if(pairWithWii) { + hcibuf[9] = 6; // Pin length is the length of the bt address + hcibuf[10] = disc_bdaddr[5]; // The pin is the Wiimotes bt address backwards + hcibuf[11] = disc_bdaddr[4]; + hcibuf[12] = disc_bdaddr[3]; + hcibuf[13] = disc_bdaddr[2]; + hcibuf[14] = disc_bdaddr[1]; + hcibuf[15] = disc_bdaddr[0]; + for(uint8_t i = 16; i < 26; i++) + hcibuf[i] = 0x00; // The rest should be 0 + } else { + hcibuf[9] = strlen(btdPin); // Length of key + uint8_t i; + for(i = 0; i < strlen(btdPin); i++) // The maximum size of the key is 16 + hcibuf[i+10] = btdPin[i]; + for(;i < 16; i++) + hcibuf[i+10] = 0x00; // The rest should be 0 + } HCI_Command(hcibuf, 26); } void BTD::hci_pin_code_negative_request_reply() { @@ -894,6 +912,15 @@ void BTD::hci_link_key_request_negative_reply() { HCI_Command(hcibuf, 9); } +void BTD::hci_authentication_request() { + hcibuf[0] = 0x11; // HCI OCF = 11 + hcibuf[1] = 0x01 << 2; // HCI OGF = 1 + hcibuf[2] = 0x02; // parameter length = 2 + hcibuf[3] = (uint8_t)(hci_handle & 0xFF);//connection handle - low byte + hcibuf[4] = (uint8_t)((hci_handle >> 8) & 0x0F);//connection handle - high byte + + HCI_Command(hcibuf, 5); +} void BTD::hci_disconnect(uint16_t handle) { // This is called by the different services hci_event_flag &= ~HCI_FLAG_DISCONN_COMPLETE; hcibuf[0] = 0x06; // HCI OCF = 6 diff --git a/BTD.h b/BTD.h index 168b742d..5858eefb 100644 --- a/BTD.h +++ b/BTD.h @@ -44,7 +44,7 @@ #define HCI_SET_NAME_STATE 4 #define HCI_CHECK_WII_SERVICE 5 -#define HCI_INQUIRY_STATE 6 // These three states are only used if it should connect to a Wii controller +#define HCI_INQUIRY_STATE 6 // These three states are only used if it should pair and connect to a Wii controller #define HCI_CONNECT_WII_STATE 7 #define HCI_CONNECTED_WII_STATE 8 @@ -180,9 +180,12 @@ public: uint8_t disc_bdaddr[6]; // Last incoming devices Bluetooth address uint8_t remote_name[30]; // First 30 chars of last remote name uint8_t hci_version; - + int8_t wiiServiceID; // Stores the service ID of the Wii service + bool connectToWii; // Used to only send the ACL data to the wiimote + bool incomingWii; + bool pairWithWii; /* HCI Commands */ void HCI_Command(uint8_t* data, uint16_t nbytes); @@ -195,9 +198,10 @@ public: void hci_accept_connection(); void hci_write_scan_disable(); void hci_disconnect(uint16_t handle); - void hci_pin_code_request_reply(const char* key); + void hci_pin_code_request_reply(); void hci_pin_code_negative_request_reply(); void hci_link_key_request_negative_reply(); + void hci_authentication_request(); void hci_inquiry(); void hci_inquiry_cancel(); void hci_connect(); diff --git a/Wii.cpp b/Wii.cpp index e24af56d..2bd9caa1 100644 --- a/Wii.cpp +++ b/Wii.cpp @@ -20,18 +20,13 @@ //#define EXTRADEBUG // Uncomment to get even more debugging data //#define PRINTREPORT // Uncomment to print the report send by the Wii controllers -WII::WII(BTD *p, uint8_t btadr5, uint8_t btadr4, uint8_t btadr3, uint8_t btadr2, uint8_t btadr1, uint8_t btadr0): +WII::WII(BTD *p, bool pair): pBtd(p) // pointer to USB class instance - mandatory { if (pBtd) pBtd->wiiServiceID = pBtd->registerServiceClass(this); // Register it as a Bluetooth service - pBtd->disc_bdaddr[5] = btadr5; // Change to your dongle's Bluetooth address instead - pBtd->disc_bdaddr[4] = btadr4; - pBtd->disc_bdaddr[3] = btadr3; - pBtd->disc_bdaddr[2] = btadr2; - pBtd->disc_bdaddr[1] = btadr1; - pBtd->disc_bdaddr[0] = btadr0; + pBtd->pairWithWii = pair; HIDBuffer[0] = 0xA2;// HID BT DATA_request (0x50) | Report Type (Output 0x02) @@ -47,6 +42,7 @@ void WII::Reset() { wiimoteConnected = false; nunchuckConnected = false; motionPlusConnected = false; + activateNunchuck = false; l2cap_event_flag = 0; // Reset flags l2cap_state = L2CAP_WAIT; } @@ -59,7 +55,7 @@ void WII::disconnect() { // Use this void to disconnect any of the controllers } void WII::ACLData(uint8_t* l2capinbuf) { - if (((l2capinbuf[0] | (l2capinbuf[1] << 8)) == (hci_handle | 0x2000))) { //acl_handle_ok + if (((l2capinbuf[0] | (l2capinbuf[1] << 8)) == (hci_handle | 0x2000)) || pBtd->incomingWii) { // acl_handle_ok or it's a new connection if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001) { //l2cap_control - Channel ID for ACL-U if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) { #ifdef DEBUG @@ -76,7 +72,7 @@ void WII::ACLData(uint8_t* l2capinbuf) { Notify(PSTR(" ")); PrintHex(l2capinbuf[14]); #endif - } + } else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_RESPONSE) { if (((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) && ((l2capinbuf[18] | (l2capinbuf[19] << 8)) == SUCCESSFUL)) { // Success if (l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) { // Success @@ -94,6 +90,32 @@ void WII::ACLData(uint8_t* l2capinbuf) { l2cap_event_flag |= L2CAP_FLAG_INTERRUPT_CONNECTED; } } + } + else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) { +#ifdef EXTRADEBUG + Notify(PSTR("\r\nL2CAP Connection Request - PSM: ")); + PrintHex(l2capinbuf[13]); + Notify(PSTR(" ")); + PrintHex(l2capinbuf[12]); + Notify(PSTR(" SCID: ")); + PrintHex(l2capinbuf[15]); + Notify(PSTR(" ")); + PrintHex(l2capinbuf[14]); + Notify(PSTR(" Identifier: ")); + PrintHex(l2capinbuf[9]); +#endif + if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) { + identifier = l2capinbuf[9]; + control_scid[0] = l2capinbuf[14]; + control_scid[1] = l2capinbuf[15]; + l2cap_event_flag |= L2CAP_FLAG_CONNECTION_CONTROL_REQUEST; + } + else if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_INTR_PSM) { + identifier = l2capinbuf[9]; + interrupt_scid[0] = l2capinbuf[14]; + interrupt_scid[1] = l2capinbuf[15]; + l2cap_event_flag |= L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST; + } } else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_RESPONSE) { if ((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) { // Success @@ -410,6 +432,33 @@ void WII::ACLData(uint8_t* l2capinbuf) { } void WII::L2CAP_task() { switch (l2cap_state) { + /* These states are used if the Wiimote is the host */ + case L2CAP_CONTROL_SUCCESS: + if (l2cap_config_success_control_flag) { +#ifdef DEBUG + Notify(PSTR("\r\nHID Control Successfully Configured")); +#endif + l2cap_state = L2CAP_INTERRUPT_SETUP; + } + break; + + case L2CAP_INTERRUPT_SETUP: + if (l2cap_connection_request_interrupt_flag) { +#ifdef DEBUG + Notify(PSTR("\r\nHID Interrupt Incoming Connection Request")); +#endif + pBtd->l2cap_connection_response(hci_handle,identifier, interrupt_dcid, interrupt_scid, PENDING); + delay(1); + pBtd->l2cap_connection_response(hci_handle,identifier, interrupt_dcid, interrupt_scid, SUCCESSFUL); + identifier++; + delay(1); + pBtd->l2cap_config_request(hci_handle,identifier, interrupt_scid); + + l2cap_state = L2CAP_INTERRUPT_CONFIG_REQUEST; + } + break; + + /* These states are used if the Arduino is the host */ case L2CAP_CONTROL_CONNECT_REQUEST: if (l2cap_connected_control_flag) { #ifdef DEBUG @@ -443,18 +492,18 @@ void WII::L2CAP_task() { } break; - case L2CAP_INTERRUPT_CONFIG_REQUEST: - if(l2cap_config_success_interrupt_flag) { + if(l2cap_config_success_interrupt_flag) { // Now the HID channels is established #ifdef DEBUG Notify(PSTR("\r\nHID Channels Established")); #endif pBtd->connectToWii = false; + pBtd->pairWithWii = false; wiimoteConnected = true; stateCounter = 0; l2cap_state = L2CAP_CHECK_MOTION_PLUS_STATE; } - break; + break; /* The next states are in run() */ @@ -493,10 +542,21 @@ void WII::Run() { identifier = 0; pBtd->l2cap_connection_request(hci_handle,identifier,control_dcid,HID_CTRL_PSM); l2cap_state = L2CAP_CONTROL_CONNECT_REQUEST; + } else if (l2cap_connection_request_control_flag) { + hci_handle = pBtd->hci_handle; + pBtd->incomingWii = false; +#ifdef DEBUG + Notify(PSTR("\r\nHID Control Incoming Connection Request")); +#endif + pBtd->l2cap_connection_response(hci_handle,identifier, control_dcid, control_scid, PENDING); + delay(1); + pBtd->l2cap_connection_response(hci_handle,identifier, control_dcid, control_scid, SUCCESSFUL); + identifier++; + delay(1); + pBtd->l2cap_config_request(hci_handle,identifier, control_scid); + l2cap_state = L2CAP_CONTROL_SUCCESS; } - break; - - + break; case L2CAP_CHECK_MOTION_PLUS_STATE: #ifdef DEBUG @@ -552,7 +612,7 @@ void WII::Run() { } break; - case L2CAP_INIT_MOTION_PLUS_STATE: + case L2CAP_INIT_MOTION_PLUS_STATE: { stateCounter++; if(stateCounter == 1) initMotionPlus(); @@ -566,14 +626,16 @@ void WII::Run() { l2cap_state = L2CAP_LED_STATE; } break; + } - case L2CAP_LED_STATE: + case L2CAP_LED_STATE: { if(nunchuck_connected_flag) nunchuckConnected = true; setLedStatus(); l2cap_state = L2CAP_DONE; break; - + } + case L2CAP_DONE: if(unknownExtensionConnected) { #ifdef DEBUG diff --git a/Wii.h b/Wii.h index aa9502c0..e8acd2d7 100644 --- a/Wii.h +++ b/Wii.h @@ -22,19 +22,26 @@ /* Bluetooth L2CAP states for L2CAP_task() */ #define L2CAP_WAIT 0 -#define L2CAP_CONTROL_CONNECT_REQUEST 1 -#define L2CAP_CONTROL_CONFIG_REQUEST 2 -#define L2CAP_INTERRUPT_CONNECT_REQUEST 3 -#define L2CAP_INTERRUPT_CONFIG_REQUEST 4 -#define L2CAP_CHECK_MOTION_PLUS_STATE 5 -#define L2CAP_CHECK_EXTENSION_STATE 6 -#define L2CAP_INIT_MOTION_PLUS_STATE 7 +// These states are used if the Wiimote is the host +#define L2CAP_CONTROL_SUCCESS 1 +#define L2CAP_INTERRUPT_SETUP 2 -#define L2CAP_LED_STATE 8 -#define L2CAP_DONE 9 -#define L2CAP_INTERRUPT_DISCONNECT 10 -#define L2CAP_CONTROL_DISCONNECT 11 +// These states are used if the Arduino is the host +#define L2CAP_CONTROL_CONNECT_REQUEST 3 +#define L2CAP_CONTROL_CONFIG_REQUEST 4 +#define L2CAP_INTERRUPT_CONNECT_REQUEST 5 + +#define L2CAP_INTERRUPT_CONFIG_REQUEST 6 + +#define L2CAP_CHECK_MOTION_PLUS_STATE 7 +#define L2CAP_CHECK_EXTENSION_STATE 8 +#define L2CAP_INIT_MOTION_PLUS_STATE 9 +#define L2CAP_LED_STATE 10 +#define L2CAP_DONE 11 + +#define L2CAP_INTERRUPT_DISCONNECT 12 +#define L2CAP_CONTROL_DISCONNECT 13 /* L2CAP event flags */ #define L2CAP_FLAG_CONTROL_CONNECTED 0x001 @@ -43,6 +50,8 @@ #define L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS 0x008 #define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE 0x040 #define L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE 0x080 +#define L2CAP_FLAG_CONNECTION_CONTROL_REQUEST 0x100 +#define L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST 0x200 /* Macros for L2CAP event flag tests */ #define l2cap_connected_control_flag (l2cap_event_flag & L2CAP_FLAG_CONTROL_CONNECTED) @@ -51,14 +60,18 @@ #define l2cap_config_success_interrupt_flag (l2cap_event_flag & L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS) #define l2cap_disconnect_response_control_flag (l2cap_event_flag & L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE) #define l2cap_disconnect_response_interrupt_flag (l2cap_event_flag & L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE) +#define l2cap_connection_request_control_flag (l2cap_event_flag & L2CAP_FLAG_CONNECTION_CONTROL_REQUEST) +#define l2cap_connection_request_interrupt_flag (l2cap_event_flag & L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST) /* Wii event flags */ -#define WII_FLAG_MOTION_PLUS_CONNECTED 0x100 -#define WII_FLAG_NUNCHUCK_CONNECTED 0x200 +#define WII_FLAG_MOTION_PLUS_CONNECTED 0x400 +#define WII_FLAG_NUNCHUCK_CONNECTED 0x800 #define motion_plus_connected_flag (l2cap_event_flag & WII_FLAG_MOTION_PLUS_CONNECTED) #define nunchuck_connected_flag (l2cap_event_flag & WII_FLAG_NUNCHUCK_CONNECTED) +#define PAIR 1 + enum LED { LED1 = 0x10, LED2 = 0x20, @@ -97,7 +110,7 @@ enum AnalogHat { class WII : public BluetoothService { public: - WII(BTD *pBtd, uint8_t btadr5=0, uint8_t btadr4=0, uint8_t btadr3=0, uint8_t btadr2=0, uint8_t btadr1=0, uint8_t btadr0=0); + WII(BTD *p, bool pair=false); // BluetoothService implementation virtual void ACLData(uint8_t* ACLData); // Used to pass acldata to the services diff --git a/keywords.txt b/keywords.txt index 187cef9c..fb64769a 100644 --- a/keywords.txt +++ b/keywords.txt @@ -222,4 +222,5 @@ motionPlusConnected KEYWORD2 setRumbleToggle KEYWORD2 getPitch KEYWORD2 getRoll KEYWORD2 -getYaw KEYWORD2 \ No newline at end of file +getYaw KEYWORD2 +PAIR KEYWORD2 \ No newline at end of file From a6d77dce92a22c7e8b05be9d5a6bba23783d58ec Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 7 Oct 2012 15:22:29 +0200 Subject: [PATCH 2/9] Added DEBUG around string --- BTD.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/BTD.cpp b/BTD.cpp index f6530db4..6a220925 100644 --- a/BTD.cpp +++ b/BTD.cpp @@ -476,7 +476,7 @@ void BTD::HCI_event_task() { case EV_ENCRYPTION_CHANGE: case EV_READ_REMOTE_VERSION_INFORMATION_COMPLETE: break; -#ifdef EXTRADEBUG +#ifdef EXTRADEBUG default: if(hcibuf[0] != 0x00) { Notify(PSTR("\r\nUnmanaged HCI Event: ")); @@ -667,7 +667,9 @@ void BTD::HCI_task() { #endif l2capConnectionClaimed = false; if(strncmp((const char *)remote_name, "Nintendo", 8) == 0) { - Serial.print("\r\nWiimote is connecting"); +#ifdef DEBUG + Notify(PSTR("\r\nWiimote is connecting")); +#endif incomingWii = true; } hci_event_flag = 0; From 940b8e185b4627bf760954929404fd70e727ad09 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 7 Oct 2012 16:24:12 +0200 Subject: [PATCH 3/9] Minor edit --- BTD.cpp | 3 +-- Wii.cpp | 8 +++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/BTD.cpp b/BTD.cpp index 6a220925..ab55885b 100644 --- a/BTD.cpp +++ b/BTD.cpp @@ -606,7 +606,6 @@ void BTD::HCI_task() { Notify(PSTR("\r\nConnected to Wiimote")); #endif hci_authentication_request(); // This will start the pairing with the wiimote - //connectToWii = true; hci_state = HCI_SCANNING_STATE; } else { #ifdef DEBUG @@ -666,7 +665,7 @@ void BTD::HCI_task() { PrintHex(disc_bdaddr[0]); #endif l2capConnectionClaimed = false; - if(strncmp((const char *)remote_name, "Nintendo", 8) == 0) { + if(strncmp((const char*)remote_name, "Nintendo", 8) == 0) { #ifdef DEBUG Notify(PSTR("\r\nWiimote is connecting")); #endif diff --git a/Wii.cpp b/Wii.cpp index 2bd9caa1..27f41727 100644 --- a/Wii.cpp +++ b/Wii.cpp @@ -612,7 +612,7 @@ void WII::Run() { } break; - case L2CAP_INIT_MOTION_PLUS_STATE: { + case L2CAP_INIT_MOTION_PLUS_STATE: stateCounter++; if(stateCounter == 1) initMotionPlus(); @@ -626,15 +626,13 @@ void WII::Run() { l2cap_state = L2CAP_LED_STATE; } break; - } - case L2CAP_LED_STATE: { + case L2CAP_LED_STATE: if(nunchuck_connected_flag) nunchuckConnected = true; setLedStatus(); l2cap_state = L2CAP_DONE; - break; - } + break; case L2CAP_DONE: if(unknownExtensionConnected) { From 2a6fa135e57ecf5c47434c1488de3590491d0624 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 7 Oct 2012 19:12:26 +0200 Subject: [PATCH 4/9] Fixed comment --- BTD.cpp | 5 +++-- Wii.cpp | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/BTD.cpp b/BTD.cpp index ab55885b..a7a9f986 100644 --- a/BTD.cpp +++ b/BTD.cpp @@ -878,13 +878,14 @@ void BTD::hci_pin_code_request_reply() { for(uint8_t i = 16; i < 26; i++) hcibuf[i] = 0x00; // The rest should be 0 } else { - hcibuf[9] = strlen(btdPin); // Length of key + hcibuf[9] = strlen(btdPin); // Length of pin uint8_t i; - for(i = 0; i < strlen(btdPin); i++) // The maximum size of the key is 16 + for(i = 0; i < strlen(btdPin); i++) // The maximum size of the pin is 16 hcibuf[i+10] = btdPin[i]; for(;i < 16; i++) hcibuf[i+10] = 0x00; // The rest should be 0 } + HCI_Command(hcibuf, 26); } void BTD::hci_pin_code_negative_request_reply() { diff --git a/Wii.cpp b/Wii.cpp index 27f41727..37fc806e 100644 --- a/Wii.cpp +++ b/Wii.cpp @@ -43,6 +43,7 @@ void WII::Reset() { nunchuckConnected = false; motionPlusConnected = false; activateNunchuck = false; + motionValuesReset = false; l2cap_event_flag = 0; // Reset flags l2cap_state = L2CAP_WAIT; } @@ -72,7 +73,7 @@ void WII::ACLData(uint8_t* l2capinbuf) { Notify(PSTR(" ")); PrintHex(l2capinbuf[14]); #endif - } + } else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_RESPONSE) { if (((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) && ((l2capinbuf[18] | (l2capinbuf[19] << 8)) == SUCCESSFUL)) { // Success if (l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) { // Success From d445689813810721cd85adc4126fa1fb46d0e5c0 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 7 Oct 2012 19:44:27 +0200 Subject: [PATCH 5/9] Fixed bug when pairing --- BTD.cpp | 12 ++++++------ BTD.h | 0 Wii.cpp | 0 Wii.h | 0 4 files changed, 6 insertions(+), 6 deletions(-) mode change 100644 => 100755 BTD.cpp mode change 100644 => 100755 BTD.h mode change 100644 => 100755 Wii.cpp mode change 100644 => 100755 Wii.h diff --git a/BTD.cpp b/BTD.cpp old mode 100644 new mode 100755 index a7a9f986..96d6d4aa --- a/BTD.cpp +++ b/BTD.cpp @@ -869,12 +869,12 @@ void BTD::hci_pin_code_request_reply() { hcibuf[8] = disc_bdaddr[5]; if(pairWithWii) { hcibuf[9] = 6; // Pin length is the length of the bt address - hcibuf[10] = disc_bdaddr[5]; // The pin is the Wiimotes bt address backwards - hcibuf[11] = disc_bdaddr[4]; - hcibuf[12] = disc_bdaddr[3]; - hcibuf[13] = disc_bdaddr[2]; - hcibuf[14] = disc_bdaddr[1]; - hcibuf[15] = disc_bdaddr[0]; + hcibuf[10] = disc_bdaddr[0]; // The pin is the Wiimotes bt address backwards + hcibuf[11] = disc_bdaddr[1]; + hcibuf[12] = disc_bdaddr[2]; + hcibuf[13] = disc_bdaddr[3]; + hcibuf[14] = disc_bdaddr[4]; + hcibuf[15] = disc_bdaddr[5]; for(uint8_t i = 16; i < 26; i++) hcibuf[i] = 0x00; // The rest should be 0 } else { diff --git a/BTD.h b/BTD.h old mode 100644 new mode 100755 diff --git a/Wii.cpp b/Wii.cpp old mode 100644 new mode 100755 diff --git a/Wii.h b/Wii.h old mode 100644 new mode 100755 From f8b5c46f60453804caca7ea18bd09dcd1642fd70 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 7 Oct 2012 20:07:48 +0200 Subject: [PATCH 6/9] Added debug about inactive Motion Plus --- Wii.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Wii.cpp b/Wii.cpp index 37fc806e..8c08ac5e 100755 --- a/Wii.cpp +++ b/Wii.cpp @@ -274,6 +274,12 @@ void WII::ACLData(uint8_t* l2capinbuf) { activateNunchuck = false; motionPlusConnected = true; nunchuckConnected = true; + } else if(l2capinbuf[15] == 0x00 && l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA6 && l2capinbuf[18] == 0x20 && (l2capinbuf[19] == 0x00 || l2capinbuf[19] == 0x04 || l2capinbuf[19] == 0x05 || l2capinbuf[19] == 0x07) && l2capinbuf[20] == 0x05) { +#ifdef DEBUG + Notify(PSTR("\r\nInactive Wii Motion Plus")); + Notify(PSTR("\r\nPlease unplug the Motion Plus, disconnect the Wiimote and then replug the Motion Plus Extension")); +#endif + stateCounter = 300; // Skip the rest in "L2CAP_CHECK_MOTION_PLUS_STATE" } #ifdef DEBUG else { From 48f3153c3b142a49595f4d034ff2e0c78a3f885a Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 7 Oct 2012 20:16:09 +0200 Subject: [PATCH 7/9] Updated example sketch to work with pairing --- examples/Bluetooth/Wii/Wii.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/Bluetooth/Wii/Wii.ino b/examples/Bluetooth/Wii/Wii.ino index 2fdd15b7..d320e666 100644 --- a/examples/Bluetooth/Wii/Wii.ino +++ b/examples/Bluetooth/Wii/Wii.ino @@ -8,8 +8,8 @@ USB Usb; BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so /* You can create the instance of the class in two ways */ -WII Wii(&Btd); // This will start inquiry which will connect to any Wiimote -//WII Wii(&Btd,0x00,0x26,0x59,0x48,0xFF,0xFB); // This will connect to the Wiimote with that specific Bluetooth Address +WII Wii(&Btd,PAIR); // This will start an inquiry and then pair with your Wiimote - you only have to do this once +//WII Wii(&Btd); // After that you can simply create the instance like so and then press any button on the Wiimote bool printAngle; From 90ae685010fcc748bbb0964d148d58c351886320 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 7 Oct 2012 20:34:52 +0200 Subject: [PATCH 8/9] Minor edit --- BTD.h | 2 +- Wii.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BTD.h b/BTD.h index 5858eefb..8b079762 100755 --- a/BTD.h +++ b/BTD.h @@ -180,7 +180,7 @@ public: uint8_t disc_bdaddr[6]; // Last incoming devices Bluetooth address uint8_t remote_name[30]; // First 30 chars of last remote name uint8_t hci_version; - + int8_t wiiServiceID; // Stores the service ID of the Wii service bool connectToWii; // Used to only send the ACL data to the wiimote diff --git a/Wii.cpp b/Wii.cpp index 8c08ac5e..10650329 100755 --- a/Wii.cpp +++ b/Wii.cpp @@ -28,7 +28,7 @@ pBtd(p) // pointer to USB class instance - mandatory pBtd->pairWithWii = pair; - HIDBuffer[0] = 0xA2;// HID BT DATA_request (0x50) | Report Type (Output 0x02) + HIDBuffer[0] = 0xA2;// HID BT DATA_request (0xA0) | Report Type (Output 0x02) /* Set device cid for the control and intterrupt channelse - LSB */ control_dcid[0] = 0x60;//0x0060 From 3441f6c3c4c578de14d93fdb851d687fa5190889 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 7 Oct 2012 22:31:28 +0200 Subject: [PATCH 9/9] Prevent it from printing "Pairing successful" multiple times --- BTD.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BTD.cpp b/BTD.cpp index 96d6d4aa..8151e9d7 100755 --- a/BTD.cpp +++ b/BTD.cpp @@ -456,7 +456,7 @@ void BTD::HCI_event_task() { break; case EV_AUTHENTICATION_COMPLETE: - if(pairWithWii) { + if(pairWithWii && !connectToWii) { #ifdef DEBUG Notify(PSTR("\r\nPairing successful")); #endif