Example #1
1
/*
 * command_complete():
 *
 * Called by HCI when an issued command has completed during the initialization of the
 * host controller. Waits for a connection from remote device once connected.
 *
 * Event Sequence:
 * HCI Reset -> Read Buf Size -> Read BDAddr -> Set Ev Filter -+
 * +-----------------------------------------------------------+
 * |_/-> Write CoD -> Cng Local Name -> Write Pg Timeout -> Inq -> Complete
 *   \-> Scan Enable -> Complete
 */
err_t command_complete(void *arg, struct hci_pcb *pcb, u8_t ogf, u8_t ocf, u8_t result)
{
	u8_t cod_spp[] = {0x80,0x08,0x04};
	u8_t devname[] = "PIC24F------";
	u8_t n1, n2, n3;
	u8_t flag = HCI_SET_EV_FILTER_AUTOACC_ROLESW;

	switch(ogf) {
		case HCI_INFO_PARAM:
			switch(ocf) {
				case HCI_READ_BUFFER_SIZE:
					if(result == HCI_SUCCESS) {
						LWIP_DEBUGF(BT_SPP_DEBUG, ("successful HCI_READ_BUFFER_SIZE.\n"));
						hci_read_bd_addr(read_bdaddr_complete);
					} else {
						LWIP_DEBUGF(BT_SPP_DEBUG, ("Unsuccessful HCI_READ_BUFFER_SIZE.\n"));
						return ERR_CONN;
					}
					break;
				case HCI_READ_BD_ADDR:
					if(result == HCI_SUCCESS) {
						LWIP_DEBUGF(BT_SPP_DEBUG, ("successful HCI_READ_BD_ADDR.\n"));
						/* Make discoverable */
						hci_set_event_filter(HCI_SET_EV_FILTER_CONNECTION,
								HCI_SET_EV_FILTER_ALLDEV, &flag);

					} else {
						LWIP_DEBUGF(BT_SPP_DEBUG, ("Unsuccessful HCI_READ_BD_ADDR.\n"));
						return ERR_CONN;
					}
					break;
				default:
					LWIP_DEBUGF(BT_SPP_DEBUG, ("Unknown HCI_INFO_PARAM command complete event\n"));
					break;
			}
			break;
		case HCI_HC_BB_OGF:
			switch(ocf) {
				case HCI_RESET:
					if(result == HCI_SUCCESS) {
						LWIP_DEBUGF(BT_SPP_DEBUG, ("successful HCI_RESET.\n")); 
						hci_read_buffer_size();
					} else {
						LWIP_DEBUGF(BT_SPP_DEBUG, ("Unsuccessful HCI_RESET.\n"));
						return ERR_CONN;
					}
					break;
				case HCI_WRITE_SCAN_ENABLE:
					if(result == HCI_SUCCESS) {
						LWIP_DEBUGF(BT_SPP_DEBUG, ("successful HCI_WRITE_SCAN_ENABLE.\n")); 
						hci_write_page_timeout(0x4000); /* 10.24s */
						//hci_cmd_complete(NULL); /* Initialization done, don't come back */
					} else {
						LWIP_DEBUGF(BT_SPP_DEBUG, ("Unsuccessful HCI_WRITE_SCAN_ENABLE.\n"));
						return ERR_CONN;
					}
					break;
				case HCI_SET_EVENT_FILTER:
					if(result == HCI_SUCCESS) {
						LWIP_DEBUGF(BT_SPP_DEBUG, ("successful HCI_SET_EVENT_FILTER.\n"));
							hci_write_cod(cod_spp);
					} else {
						LWIP_DEBUGF(BT_SPP_DEBUG, ("Unsuccessful HCI_SET_EVENT_FILTER.\n"));
						return ERR_CONN;
					}
					break;
				case HCI_CHANGE_LOCAL_NAME:
					if(result == HCI_SUCCESS) {
						LWIP_DEBUGF(BT_SPP_DEBUG, ("Successful HCI_CHANGE_LOCAL_NAME.\n"));
						hci_write_scan_enable(HCI_SCAN_EN_INQUIRY | HCI_SCAN_EN_PAGE);
					} else {
						LWIP_DEBUGF(BT_SPP_DEBUG, ("Unsuccessful HCI_CHANGE_LOCAL_NAME.\n"));
						return ERR_CONN;
					}
					break;
				case HCI_WRITE_COD:
					if(result == HCI_SUCCESS) {
						LWIP_DEBUGF(BT_SPP_DEBUG, ("Successful HCI_WRITE_COD.\n"));
						n1 = (u8_t)(bt_spp_state.bdaddr.addr[0] / 100);
						n2 = (u8_t)(bt_spp_state.bdaddr.addr[0] / 10) - n1 * 10;
						n3 = bt_spp_state.bdaddr.addr[0] - n1 * 100 - n2 * 10;
						devname[9] = '0' + n1;
						devname[10] = '0' + n2;
						devname[11] = '0' + n3;
						hci_change_local_name(devname, sizeof(devname));
					} else {
						LWIP_DEBUGF(BT_SPP_DEBUG, ("Unsuccessful HCI_WRITE_COD.\n"));
						return ERR_CONN;
					}
					break;
				case HCI_WRITE_PAGE_TIMEOUT:
					if(result == HCI_SUCCESS) {
						LWIP_DEBUGF(BT_SPP_DEBUG, ("successful HCI_WRITE_PAGE_TIMEOUT.\n"));
						//hci_cmd_complete(NULL); /* Initialization done, don't come back */
						hci_connection_complete(acl_conn_complete);
						LWIP_DEBUGF(BT_SPP_DEBUG, ("Initialization done.\n"));
						//LWIP_DEBUGF(BT_SPP_DEBUG, ("Discover other Bluetooth devices.\n"));
						//hci_inquiry(0x009E8B33, 0x04, 0x01, inquiry_complete); //FAILED????
					} else {
						LWIP_DEBUGF(BT_SPP_DEBUG, ("Unsuccessful HCI_WRITE_PAGE_TIMEOUT.\n"));
						return ERR_CONN;
					}
					break;
				default:
					LWIP_DEBUGF(BT_SPP_DEBUG, ("Unknown HCI_HC_BB_OGF command complete event\n"));
					break;
			}
			break;
		default:
			LWIP_DEBUGF(BT_SPP_DEBUG, ("Unknown command complete event. OGF = 0x%x OCF = 0x%x\n", ogf, ocf));
			break;
	}
	return ERR_OK;
}
Example #2
1
/* Poll Bluetooth and print result */
void BTD::HCI_task() {
        switch(hci_state) {
                case HCI_INIT_STATE:
                        hci_counter++;
                        if(hci_counter > hci_num_reset_loops) { // wait until we have looped x times to clear any old events
                                hci_reset();
                                hci_state = HCI_RESET_STATE;
                                hci_counter = 0;
                        }
                        break;

                case HCI_RESET_STATE:
                        hci_counter++;
                        if(hci_check_flag(HCI_FLAG_CMD_COMPLETE)) {
                                hci_counter = 0;
#ifdef DEBUG_USB_HOST
                                Notify(PSTR("\r\nHCI Reset complete"), 0x80);
#endif
                                hci_state = HCI_CLASS_STATE;
                                hci_write_class_of_device();
                        } else if(hci_counter > hci_num_reset_loops) {
                                hci_num_reset_loops *= 10;
                                if(hci_num_reset_loops > 2000)
                                        hci_num_reset_loops = 2000;
#ifdef DEBUG_USB_HOST
                                Notify(PSTR("\r\nNo response to HCI Reset"), 0x80);
#endif
                                hci_state = HCI_INIT_STATE;
                                hci_counter = 0;
                        }
                        break;

                case HCI_CLASS_STATE:
                        if(hci_check_flag(HCI_FLAG_CMD_COMPLETE)) {
#ifdef DEBUG_USB_HOST
                                Notify(PSTR("\r\nWrite class of device"), 0x80);
#endif
                                hci_state = HCI_BDADDR_STATE;
                                hci_read_bdaddr();
                        }
                        break;

                case HCI_BDADDR_STATE:
                        if(hci_check_flag(HCI_FLAG_READ_BDADDR)) {
#ifdef DEBUG_USB_HOST
                                Notify(PSTR("\r\nLocal Bluetooth Address: "), 0x80);
                                for(int8_t i = 5; i > 0; i--) {
                                        D_PrintHex<uint8_t > (my_bdaddr[i], 0x80);
                                        Notify(PSTR(":"), 0x80);
                                }
                                D_PrintHex<uint8_t > (my_bdaddr[0], 0x80);
#endif
                                hci_read_local_version_information();
                                hci_state = HCI_LOCAL_VERSION_STATE;
                        }
                        break;

                case HCI_LOCAL_VERSION_STATE: // The local version is used by the PS3BT class
                        if(hci_check_flag(HCI_FLAG_READ_VERSION)) {
                                if(btdName != NULL) {
                                        hci_set_local_name(btdName);
                                        hci_state = HCI_SET_NAME_STATE;
                                } else
                                        hci_state = HCI_CHECK_DEVICE_SERVICE;
                        }
                        break;

                case HCI_SET_NAME_STATE:
                        if(hci_check_flag(HCI_FLAG_CMD_COMPLETE)) {
#ifdef DEBUG_USB_HOST
                                Notify(PSTR("\r\nThe name is set to: "), 0x80);
                                NotifyStr(btdName, 0x80);
#endif
                                hci_state = HCI_CHECK_DEVICE_SERVICE;
                        }
                        break;

                case HCI_CHECK_DEVICE_SERVICE:
                        if(pairWithHIDDevice || pairWithWii) { // Check if it should try to connect to a Wiimote
#ifdef DEBUG_USB_HOST
                                if(pairWithWii)
                                        Notify(PSTR("\r\nStarting inquiry\r\nPress 1 & 2 on the Wiimote\r\nOr press sync if you are using a Wii U Pro Controller"), 0x80);
                                else
                                        Notify(PSTR("\r\nPlease enable discovery of your device"), 0x80);
#endif
                                hci_inquiry();
                                hci_state = HCI_INQUIRY_STATE;
                        } else
                                hci_state = HCI_SCANNING_STATE; // Don't try to connect to a Wiimote
                        break;

                case HCI_INQUIRY_STATE:
                        if(hci_check_flag(HCI_FLAG_DEVICE_FOUND)) {
                                hci_inquiry_cancel(); // Stop inquiry
#ifdef DEBUG_USB_HOST
                                if(pairWithWii)
                                        Notify(PSTR("\r\nWiimote found"), 0x80);
                                else
                                        Notify(PSTR("\r\nHID device found"), 0x80);

                                Notify(PSTR("\r\nNow just create the instance like so:"), 0x80);
                                if(pairWithWii)
                                        Notify(PSTR("\r\nWII Wii(&Btd);"), 0x80);
                                else
                                        Notify(PSTR("\r\nBTHID hid(&Btd);"), 0x80);

                                Notify(PSTR("\r\nAnd then press any button on the "), 0x80);
                                if(pairWithWii)
                                        Notify(PSTR("Wiimote"), 0x80);
                                else
                                        Notify(PSTR("device"), 0x80);
#endif
                                if(motionPlusInside) {
                                        hci_remote_name(); // We need to know the name to distinguish between a Wiimote and a Wii U Pro Controller
                                        hci_state = HCI_REMOTE_NAME_STATE;
                                } else
                                        hci_state = HCI_CONNECT_DEVICE_STATE;
                        }
                        break;

                case HCI_CONNECT_DEVICE_STATE:
                        if(hci_check_flag(HCI_FLAG_CMD_COMPLETE)) {
#ifdef DEBUG_USB_HOST
                                if(pairWithWii)
                                        Notify(PSTR("\r\nConnecting to Wiimote"), 0x80);
                                else
                                        Notify(PSTR("\r\nConnecting to HID device"), 0x80);
#endif
                                hci_connect();
                                hci_state = HCI_CONNECTED_DEVICE_STATE;
                        }
                        break;

                case HCI_CONNECTED_DEVICE_STATE:
                        if(hci_check_flag(HCI_FLAG_CONNECT_EVENT)) {
                                if(hci_check_flag(HCI_FLAG_CONNECT_COMPLETE)) {
#ifdef DEBUG_USB_HOST
                                        if(pairWithWii)
                                                Notify(PSTR("\r\nConnected to Wiimote"), 0x80);
                                        else
                                                Notify(PSTR("\r\nConnected to HID device"), 0x80);
#endif
                                        hci_authentication_request(); // This will start the pairing with the Wiimote
                                        hci_state = HCI_SCANNING_STATE;
                                } else {
#ifdef DEBUG_USB_HOST
                                        Notify(PSTR("\r\nTrying to connect one more time..."), 0x80);
#endif
                                        hci_connect(); // Try to connect one more time
                                }
                        }
                        break;

                case HCI_SCANNING_STATE:
                        if(!connectToWii && !pairWithWii && !connectToHIDDevice && !pairWithHIDDevice) {
#ifdef DEBUG_USB_HOST
                                Notify(PSTR("\r\nWait For Incoming Connection Request"), 0x80);
#endif
                                hci_write_scan_enable();
                                watingForConnection = true;
                                hci_state = HCI_CONNECT_IN_STATE;
                        }
                        break;

                case HCI_CONNECT_IN_STATE:
                        if(hci_check_flag(HCI_FLAG_INCOMING_REQUEST)) {
                                watingForConnection = false;
#ifdef DEBUG_USB_HOST
                                Notify(PSTR("\r\nIncoming Connection Request"), 0x80);
#endif
                                hci_remote_name();
                                hci_state = HCI_REMOTE_NAME_STATE;
                        } else if(hci_check_flag(HCI_FLAG_DISCONNECT_COMPLETE))
                                hci_state = HCI_DISCONNECT_STATE;
                        break;

                case HCI_REMOTE_NAME_STATE:
                        if(hci_check_flag(HCI_FLAG_REMOTE_NAME_COMPLETE)) {
#ifdef DEBUG_USB_HOST
                                Notify(PSTR("\r\nRemote Name: "), 0x80);
                                for(uint8_t i = 0; i < strlen(remote_name); i++)
                                        Notifyc(remote_name[i], 0x80);
#endif
                                if(strncmp((const char*)remote_name, "Nintendo", 8) == 0) {
                                        incomingWii = true;
#ifdef DEBUG_USB_HOST
                                        Notify(PSTR("\r\nWiimote is connecting"), 0x80);
#endif
                                        if(strncmp((const char*)remote_name, "Nintendo RVL-CNT-01-TR", 22) == 0) {
#ifdef DEBUG_USB_HOST
                                                Notify(PSTR(" with Motion Plus Inside"), 0x80);
#endif
                                                motionPlusInside = true;
                                        } else if(strncmp((const char*)remote_name, "Nintendo RVL-CNT-01-UC", 22) == 0) {
#ifdef DEBUG_USB_HOST
                                                Notify(PSTR(" - Wii U Pro Controller"), 0x80);
#endif
                                                motionPlusInside = true;
                                                wiiUProController = true;
                                        } else {
                                                motionPlusInside = false;
                                                wiiUProController = false;
                                        }
                                }
                                if(classOfDevice[2] == 0 && classOfDevice[1] == 0x25 && classOfDevice[0] == 0x08 && strncmp((const char*)remote_name, "Wireless Controller", 19) == 0) {
#ifdef DEBUG_USB_HOST
                                        Notify(PSTR("\r\nPS4 controller is connecting"), 0x80);
#endif
                                        incomingPS4 = true;
                                }
                                if(pairWithWii && motionPlusInside)
                                        hci_state = HCI_CONNECT_DEVICE_STATE;
                                else {
                                        hci_accept_connection();
                                        hci_state = HCI_CONNECTED_STATE;
                                }
                        }
                        break;

                case HCI_CONNECTED_STATE:
                        if(hci_check_flag(HCI_FLAG_CONNECT_COMPLETE)) {
#ifdef DEBUG_USB_HOST
                                Notify(PSTR("\r\nConnected to Device: "), 0x80);
                                for(int8_t i = 5; i > 0; i--) {
                                        D_PrintHex<uint8_t > (disc_bdaddr[i], 0x80);
                                        Notify(PSTR(":"), 0x80);
                                }
                                D_PrintHex<uint8_t > (disc_bdaddr[0], 0x80);
#endif
                                if(incomingPS4)
                                        connectToHIDDevice = true; // We should always connect to the PS4 controller

                                // Clear these flags for a new connection
                                l2capConnectionClaimed = false;
                                sdpConnectionClaimed = false;
                                rfcommConnectionClaimed = false;

                                hci_event_flag = 0;
                                hci_state = HCI_DONE_STATE;
                        }
                        break;

                case HCI_DONE_STATE:
                        hci_counter++;
                        if(hci_counter > 1000) { // Wait until we have looped 1000 times to make sure that the L2CAP connection has been started
                                hci_counter = 0;
                                hci_state = HCI_SCANNING_STATE;
                        }
                        break;

                case HCI_DISCONNECT_STATE:
                        if(hci_check_flag(HCI_FLAG_DISCONNECT_COMPLETE)) {
#ifdef DEBUG_USB_HOST
                                Notify(PSTR("\r\nHCI Disconnected from Device"), 0x80);
#endif
                                hci_event_flag = 0; // Clear all flags

                                // Reset all buffers
                                memset(hcibuf, 0, BULK_MAXPKTSIZE);
                                memset(l2capinbuf, 0, BULK_MAXPKTSIZE);

                                connectToWii = incomingWii = pairWithWii = false;
                                connectToHIDDevice = incomingHIDDevice = pairWithHIDDevice = false;
                                incomingPS4 = false;

                                hci_state = HCI_SCANNING_STATE;
                        }
                        break;
                default:
                        break;
        }
}
Example #3
0
/* Poll Bluetooth and print result */
void BTD::HCI_task() {
    switch (hci_state){
        case HCI_INIT_STATE:
            hci_counter++;
            if (hci_counter > hci_num_reset_loops) { // wait until we have looped x times to clear any old events
                hci_reset();
                hci_state = HCI_RESET_STATE;
                hci_counter = 0;
            }
            break;
            
        case HCI_RESET_STATE:
            hci_counter++;
            if (hci_cmd_complete) {
                hci_counter = 0;
#ifdef DEBUG
                Notify(PSTR("\r\nHCI Reset complete"));
#endif
                hci_state = HCI_BDADDR_STATE;
                hci_read_bdaddr(); 
            }
            else if (hci_counter > hci_num_reset_loops) {
                hci_num_reset_loops *= 10;
                if(hci_num_reset_loops > 2000)
                    hci_num_reset_loops = 2000;
#ifdef DEBUG
                Notify(PSTR("\r\nNo response to HCI Reset"));
#endif
                hci_state = HCI_INIT_STATE;
                hci_counter = 0;
            }
            break;
            
        case HCI_BDADDR_STATE:
            if (hci_read_bdaddr_complete) {
#ifdef DEBUG
                Notify(PSTR("\r\nLocal Bluetooth Address: "));
                for(int8_t i = 5; i > 0;i--) {
                    PrintHex<uint8_t>(my_bdaddr[i]); 
                    Notify(PSTR(":"));
                }      
                PrintHex<uint8_t>(my_bdaddr[0]);
#endif
                hci_read_local_version_information();
                hci_state = HCI_LOCAL_VERSION_STATE;                
            }
            break;
            
        case HCI_LOCAL_VERSION_STATE: // The local version is used by the PS3BT class
            if (hci_read_version_complete) {
                if(btdName != NULL) {
                    hci_set_local_name(btdName);
                    hci_state = HCI_SET_NAME_STATE;
                } else
                    hci_state = HCI_CHECK_WII_SERVICE;                    
            }
            break;
            
        case HCI_SET_NAME_STATE:
            if (hci_cmd_complete) {
#ifdef DEBUG               
                Notify(PSTR("\r\nThe name is set to: "));
                Serial.print(btdName);
#endif
                hci_state = HCI_CHECK_WII_SERVICE;
            }
            break;
            
        case HCI_CHECK_WII_SERVICE:
            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\r\nOr press sync if you are using a Wii U Pro Controller"));
#endif
                hci_inquiry();
                hci_state = HCI_INQUIRY_STATE;
            }
            else
                hci_state = HCI_SCANNING_STATE; // Don't try to connect to a Wiimote
            break;
            
        case HCI_INQUIRY_STATE:
            if(hci_wii_found) {
                hci_inquiry_cancel(); // Stop inquiry
#ifdef DEBUG
                Notify(PSTR("\r\nWiimote found"));                
                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                                
                if(motionPlusInside) {
                    hci_remote_name(); // We need to know the name to distinguish between a Wiimote and a Wii U Pro Controller
                    hci_state = HCI_REMOTE_NAME_STATE;
                } else
                    hci_state = HCI_CONNECT_WII_STATE;
            }
            break;
            
        case HCI_CONNECT_WII_STATE:
            if(hci_cmd_complete) {
#ifdef DEBUG
                Notify(PSTR("\r\nConnecting to Wiimote"));
#endif            
                hci_connect();
                hci_state = HCI_CONNECTED_WII_STATE;
            }
            break;
            
        case HCI_CONNECTED_WII_STATE:
            if(hci_connect_event) {
                if(hci_connect_complete) {
#ifdef DEBUG
                    Notify(PSTR("\r\nConnected to Wiimote"));
#endif                    
                    hci_authentication_request(); // This will start the pairing with the wiimote
                    hci_state = HCI_SCANNING_STATE;
                } else {
#ifdef DEBUG
                    Notify(PSTR("\r\nTrying to connect one more time..."));
#endif
                    hci_connect(); // Try to connect one more time
                }
            }
            break;
            
        case HCI_SCANNING_STATE:
            if(!connectToWii && !pairWithWii) {
#ifdef DEBUG
                Notify(PSTR("\r\nWait For Incoming Connection Request"));
#endif            
                hci_write_scan_enable();
                watingForConnection = true;
                hci_state = HCI_CONNECT_IN_STATE;
            }
            break;
            
        case HCI_CONNECT_IN_STATE:
            if(hci_incoming_connect_request) {
                watingForConnection = false;
#ifdef DEBUG
                Notify(PSTR("\r\nIncoming Connection Request"));
#endif                
                hci_remote_name();
                hci_state = HCI_REMOTE_NAME_STATE;
            } else if (hci_disconnect_complete)
                hci_state = HCI_DISCONNECT_STATE;
            break;     
            
        case HCI_REMOTE_NAME_STATE:
            if(hci_remote_name_complete) {
#ifdef DEBUG
                Notify(PSTR("\r\nRemote Name: "));
                for (uint8_t i = 0; i < 30; i++) {
                    if(remote_name[i] == NULL)
                        break;
                    Serial.write(remote_name[i]);
                }
#endif
                if(strncmp((const char*)remote_name, "Nintendo", 8) == 0) {
#ifdef DEBUG
                    Notify(PSTR("\r\nWiimote is connecting"));
#endif
                    if(strncmp((const char*)remote_name, "Nintendo RVL-CNT-01-TR", 22) == 0) {
#ifdef DEBUG
                        Notify(PSTR(" with Motion Plus Inside"));
#endif
                        motionPlusInside = true;
                    }
                    else if(strncmp((const char*)remote_name, "Nintendo RVL-CNT-01-UC", 22) == 0) {
#ifdef DEBUG
                        Notify(PSTR(" - Wii U Pro Controller"));
#endif
                        motionPlusInside = true;
                        wiiUProController = true;
                    } else {
                        motionPlusInside = false;
                        wiiUProController = false;
                    }
                    incomingWii = true;
                }
                if(pairWithWii && motionPlusInside)
                    hci_state = HCI_CONNECT_WII_STATE;
                else {
                    hci_accept_connection();
                    hci_state = HCI_CONNECTED_STATE;
                }
            }      
            break;
            
        case HCI_CONNECTED_STATE:
            if (hci_connect_complete) {     
#ifdef DEBUG
                Notify(PSTR("\r\nConnected to Device: "));
                for(int8_t i = 5; i>0;i--) {
                    PrintHex<uint8_t>(disc_bdaddr[i]);
                    Notify(PSTR(":"));
                }      
                PrintHex<uint8_t>(disc_bdaddr[0]);
#endif
                // Clear these flags for a new connection
                l2capConnectionClaimed = false;
                sdpConnectionClaimed = false;
                rfcommConnectionClaimed = false;
                          
                hci_event_flag = 0;
                hci_state = HCI_DONE_STATE;
            }
            break;

        case HCI_DONE_STATE:
            hci_counter++;
            if (hci_counter > 1000) { // Wait until we have looped 1000 times to make sure that the L2CAP connection has been started
                hci_counter = 0;
                hci_state = HCI_SCANNING_STATE;                
            }            
            break;
            
        case HCI_DISCONNECT_STATE:
            if (hci_disconnect_complete) {
#ifdef DEBUG
                Notify(PSTR("\r\nHCI Disconnected from Device"));
#endif
                hci_event_flag = 0; // Clear all flags 
                
                // Reset all buffers                        
                for (uint8_t i = 0; i < BULK_MAXPKTSIZE; i++)
                    hcibuf[i] = 0;        
                for (uint8_t i = 0; i < BULK_MAXPKTSIZE; i++)
                    l2capinbuf[i] = 0;
                                                        
                hci_state = HCI_SCANNING_STATE;
            }
            break;
        default:
            break;
    }
}
/* Poll Bluetooth and print result */
void BTD::HCI_task() {
    switch (hci_state){
        case HCI_INIT_STATE:
            hci_counter++;
            if (hci_counter > hci_num_reset_loops) { // wait until we have looped x times to clear any old events
                hci_reset();
                hci_state = HCI_RESET_STATE;
                hci_counter = 0;
            }
            break;
            
        case HCI_RESET_STATE:
            hci_counter++;
            if (hci_cmd_complete) {
#ifdef DEBUG
                Notify(PSTR("\r\nHCI Reset complete"));
#endif
                hci_state = HCI_BDADDR_STATE;
                hci_read_bdaddr(); 
            }
            else if (hci_counter > hci_num_reset_loops) {
                hci_num_reset_loops *= 10;
                if(hci_num_reset_loops > 2000)
                    hci_num_reset_loops = 2000;
#ifdef DEBUG
                Notify(PSTR("\r\nNo response to HCI Reset"));
#endif
                hci_state = HCI_INIT_STATE;
                hci_counter = 0;
            }
            break;
            
        case HCI_BDADDR_STATE:
            if (hci_read_bdaddr_complete) {
#ifdef DEBUG
                Notify(PSTR("\r\nLocal Bluetooth Address: "));
                for(int8_t i = 5; i > 0;i--) {
                    PrintHex<uint8_t>(my_bdaddr[i]); 
                    Notify(PSTR(":"));
                }      
                PrintHex<uint8_t>(my_bdaddr[0]);
#endif
                hci_read_local_version_information();
                hci_state = HCI_LOCAL_VERSION_STATE;                
            }
            break;
            
        case HCI_LOCAL_VERSION_STATE: // The local version is used by the PS3BT class
            if (hci_read_version_complete) {
                if(btdName != NULL) {
                    hci_set_local_name(btdName);
                    hci_state = HCI_SET_NAME_STATE;
                } else
                    hci_state = HCI_CHECK_WII_SERVICE;                    
            }
            break;
            
        case HCI_SET_NAME_STATE:
            if (hci_cmd_complete) {
#ifdef DEBUG               
                Notify(PSTR("\r\nThe name is set to: "));
                Serial.print(btdName);
#endif
                hci_state = HCI_CHECK_WII_SERVICE;
            }
            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) {
#ifdef DEBUG
                    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;
            }
            else
                hci_state = HCI_SCANNING_STATE; // Don't try to connect to a Wiimote
            break;
            
        case HCI_INQUIRY_STATE:
            if(hci_wii_found) {
                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<uint8_t>(disc_bdaddr[i]);
                    Notify(PSTR(","));
                }
                Notify(PSTR("0x"));
                PrintHex<uint8_t>(disc_bdaddr[0]);
                Notify(PSTR(");"));
#endif                                
                hci_state = HCI_CONNECT_WII_STATE;
            }
            break;
            
        case HCI_CONNECT_WII_STATE:
            if(!hci_wii_found || hci_cmd_complete) {
#ifdef DEBUG
                Notify(PSTR("\r\nConnecting to Wiimote"));
#endif            
                hci_connect();
                hci_state = HCI_CONNECTED_WII_STATE;
            }
            break;
            
        case HCI_CONNECTED_WII_STATE:
            if(hci_connect_event) {
                if(hci_connect_complete) {
#ifdef DEBUG
                    Notify(PSTR("\r\nConnected to Wiimote"));
#endif
                    connectToWii = true; // Only send the ACL data to the Wii service
                    hci_state = HCI_SCANNING_STATE;
                } else {
#ifdef DEBUG
                    Notify(PSTR("\r\nTrying to connect one more time..."));
#endif
                    hci_connect(); // Try to connect one more time
                }
            }
            break;
            
        case HCI_SCANNING_STATE:
            if(!connectToWii) {
#ifdef DEBUG
                Notify(PSTR("\r\nWait For Incoming Connection Request"));
#endif            
                hci_write_scan_enable();
                watingForConnection = true;
                hci_state = HCI_CONNECT_IN_STATE;
            }
            break;
            
        case HCI_CONNECT_IN_STATE:
            if(hci_incoming_connect_request) {
                watingForConnection = false;
#ifdef DEBUG
                Notify(PSTR("\r\nIncoming Connection Request"));
#endif                
                hci_remote_name();
                hci_state = HCI_REMOTE_NAME_STATE;
            } else if (hci_disconnect_complete)
                hci_state = HCI_DISCONNECT_STATE;
            break;     
            
        case HCI_REMOTE_NAME_STATE:
            if(hci_remote_name_complete) {
#ifdef DEBUG
                Notify(PSTR("\r\nRemote Name: "));
                for (uint8_t i = 0; i < 30; i++) {
                    if(remote_name[i] == NULL)
                        break;
                    Serial.write(remote_name[i]);   
                }             
#endif
                hci_accept_connection();
                hci_state = HCI_CONNECTED_STATE;                                
            }      
            break;
            
        case HCI_CONNECTED_STATE:
            if (hci_connect_complete) {     
#ifdef DEBUG
                Notify(PSTR("\r\nConnected to Device: "));
                for(int8_t i = 5; i>0;i--) {
                    PrintHex<uint8_t>(disc_bdaddr[i]);
                    Notify(PSTR(":"));
                }      
                PrintHex<uint8_t>(disc_bdaddr[0]);
#endif
                hci_write_scan_disable();
                hci_state = HCI_DISABLE_SCAN_STATE;
            }
            break;
            
        case HCI_DISABLE_SCAN_STATE:
            if (hci_cmd_complete) {                    
#ifdef DEBUG
                Notify(PSTR("\r\nScan Disabled"));
#endif
                hci_event_flag = 0;
                hci_state = HCI_DONE_STATE;
            }
            break;
            
        case HCI_DONE_STATE:
            hci_counter++;
            if (hci_counter > 250) { // Wait until we have looped 250 times to make sure that the L2CAP connection has been started
                hci_state = HCI_SCANNING_STATE;
                l2capConnectionClaimed = false;
            }            
            break;
            
        case HCI_DISCONNECT_STATE:
            if (hci_disconnect_complete) {
#ifdef DEBUG
                Notify(PSTR("\r\nHCI Disconnected from Device"));
#endif
                hci_event_flag = 0; // Clear all flags 
                
                // Reset all buffers                        
                for (uint8_t i = 0; i < BULK_MAXPKTSIZE; i++)
                    hcibuf[i] = 0;        
                for (uint8_t i = 0; i < BULK_MAXPKTSIZE; i++)
                    l2capinbuf[i] = 0;
                                                        
                hci_state = HCI_SCANNING_STATE;
            }
            break;
        default:
            break;
    }
}