Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: UsbHostMAX3421E_Hello
BTD.cpp
00001 /* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved. 00002 00003 This software may be distributed and modified under the terms of the GNU 00004 General Public License version 2 (GPL2) as published by the Free Software 00005 Foundation and appearing in the file GPL2.TXT included in the packaging of 00006 this file. Please note that GPL2 Section 2[b] requires that all works based 00007 on this software must also be made publicly available under the terms of 00008 the GPL2 ("Copyleft"). 00009 00010 Contact information 00011 ------------------- 00012 00013 Kristian Lauszus, TKJ Electronics 00014 Web : http://www.tkjelectronics.com 00015 e-mail : kristianl@tkjelectronics.com 00016 */ 00017 00018 #include "BTD.h" 00019 // To enable serial debugging see "settings.h" 00020 //#define EXTRADEBUG // Uncomment to get even more debugging data 00021 00022 const uint8_t BTD::BTD_CONTROL_PIPE = 0; 00023 const uint8_t BTD::BTD_EVENT_PIPE = 1; 00024 const uint8_t BTD::BTD_DATAIN_PIPE = 2; 00025 const uint8_t BTD::BTD_DATAOUT_PIPE = 3; 00026 00027 BTD::BTD(Usb *p) : 00028 connectToWii(false), 00029 pairWithWii(false), 00030 connectToHIDDevice(false), 00031 pairWithHIDDevice(false), 00032 pUsb(p), // Pointer to USB class instance - mandatory 00033 bAddress(0), // Device address - mandatory 00034 bNumEP(1), // If config descriptor needs to be parsed 00035 qNextPollTime(0), // Reset NextPollTime 00036 pollInterval(0), 00037 bPollEnable(false) // Don't start polling before dongle is connected 00038 { 00039 for(uint8_t i = 0; i < BTD_NUM_SERVICES; i++) 00040 btService[i] = NULL; 00041 00042 Initialize(); // Set all variables, endpoint structs etc. to default values 00043 00044 if(pUsb) // Register in USB subsystem 00045 pUsb->RegisterDeviceClass(this); // Set devConfig[] entry 00046 } 00047 00048 uint8_t BTD::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) { 00049 const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR); 00050 uint8_t buf[constBufSize]; 00051 USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR*>(buf); 00052 uint8_t rcode; 00053 UsbDevice *p = NULL; 00054 EpInfo *oldep_ptr = NULL; 00055 00056 Initialize(); // Set all variables, endpoint structs etc. to default values 00057 00058 AddressPool &addrPool = pUsb->GetAddressPool(); // Get memory address of USB device address pool 00059 #ifdef EXTRADEBUG 00060 Notify(PSTR("\r\nBTD ConfigureDevice"), 0x80); 00061 #endif 00062 00063 if(bAddress) { // Check if address has already been assigned to an instance 00064 #ifdef DEBUG_USB_HOST 00065 Notify(PSTR("\r\nAddress in use"), 0x80); 00066 #endif 00067 return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE; 00068 } 00069 00070 p = addrPool.GetUsbDevicePtr(0); // Get pointer to pseudo device with address 0 assigned 00071 if(!p) { 00072 #ifdef DEBUG_USB_HOST 00073 Notify(PSTR("\r\nAddress not found"), 0x80); 00074 #endif 00075 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; 00076 } 00077 00078 if(!p->epinfo) { 00079 #ifdef DEBUG_USB_HOST 00080 Notify(PSTR("\r\nepinfo is null"), 0x80); 00081 #endif 00082 return USB_ERROR_EPINFO_IS_NULL; 00083 } 00084 00085 oldep_ptr = p->epinfo; // Save old pointer to EP_RECORD of address 0 00086 p->epinfo = epInfo; // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence 00087 p->lowspeed = lowspeed; 00088 rcode = pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data 00089 00090 p->epinfo = oldep_ptr; // Restore p->epinfo 00091 00092 if(rcode) 00093 goto FailGetDevDescr; 00094 00095 bAddress = addrPool.AllocAddress(parent, false, port); // Allocate new address according to device class 00096 00097 if(!bAddress) { 00098 #ifdef DEBUG_USB_HOST 00099 Notify(PSTR("\r\nOut of address space"), 0x80); 00100 #endif 00101 return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; 00102 } 00103 00104 if (udd->bDeviceClass == 0x09) // Some dongles have an USB hub inside 00105 goto FailHub; 00106 00107 epInfo[0].maxPktSize = udd->bMaxPacketSize0; // Extract Max Packet Size from device descriptor 00108 epInfo[1].epAddr = udd->bNumConfigurations; // Steal and abuse from epInfo structure to save memory 00109 00110 VID = udd->idVendor; 00111 PID = udd->idProduct; 00112 00113 return USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET; 00114 00115 FailHub: 00116 #ifdef DEBUG_USB_HOST 00117 Notify(PSTR("\r\nPlease create a hub instance in your code: \"USBHub Hub1(&Usb);\""), 0x80); 00118 #endif 00119 pUsb->setAddr(bAddress, 0, 0); // Reset address 00120 rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; 00121 Release(); 00122 return rcode; 00123 00124 FailGetDevDescr: 00125 #ifdef DEBUG_USB_HOST 00126 NotifyFailGetDevDescr(rcode); 00127 #endif 00128 if(rcode != hrJERR) 00129 rcode = USB_ERROR_FailGetDevDescr; 00130 Release(); 00131 return rcode; 00132 }; 00133 00134 uint8_t BTD::Init(uint8_t parent __attribute__((unused)), uint8_t port __attribute__((unused)), bool lowspeed) { 00135 uint8_t rcode; 00136 uint8_t num_of_conf = epInfo[1].epAddr; // Number of configurations 00137 epInfo[1].epAddr = 0; 00138 00139 AddressPool &addrPool = pUsb->GetAddressPool(); 00140 #ifdef EXTRADEBUG 00141 Notify(PSTR("\r\nBTD Init"), 0x80); 00142 #endif 00143 UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record 00144 00145 if(!p) { 00146 #ifdef DEBUG_USB_HOST 00147 Notify(PSTR("\r\nAddress not found"), 0x80); 00148 #endif 00149 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; 00150 } 00151 00152 wait_ms(300); // Assign new address to the device 00153 00154 rcode = pUsb->setAddr(0, 0, bAddress); // Assign new address to the device 00155 if(rcode) { 00156 #ifdef DEBUG_USB_HOST 00157 Notify(PSTR("\r\nsetAddr: "), 0x80); 00158 D_PrintHex<uint8_t > (rcode, 0x80); 00159 #endif 00160 p->lowspeed = false; 00161 goto Fail; 00162 } 00163 #ifdef EXTRADEBUG 00164 Notify(PSTR("\r\nAddr: "), 0x80); 00165 D_PrintHex<uint8_t > (bAddress, 0x80); 00166 #endif 00167 00168 p->lowspeed = false; 00169 00170 p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record 00171 if(!p) { 00172 #ifdef DEBUG_USB_HOST 00173 Notify(PSTR("\r\nAddress not found"), 0x80); 00174 #endif 00175 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; 00176 } 00177 00178 p->lowspeed = lowspeed; 00179 00180 rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); // Assign epInfo to epinfo pointer - only EP0 is known 00181 if(rcode) 00182 goto FailSetDevTblEntry; 00183 00184 if(VID == PS3_VID && (PID == PS3_PID || PID == PS3NAVIGATION_PID || PID == PS3MOVE_PID)) { 00185 wait_ms(100); 00186 rcode = pUsb->setConf(bAddress, epInfo[ BTD_CONTROL_PIPE ].epAddr, 1); // We only need the Control endpoint, so we don't have to initialize the other endpoints of device 00187 if(rcode) 00188 goto FailSetConfDescr; 00189 00190 #ifdef DEBUG_USB_HOST 00191 if(PID == PS3_PID || PID == PS3NAVIGATION_PID) { 00192 if(PID == PS3_PID) 00193 Notify(PSTR("\r\nDualshock 3 Controller Connected"), 0x80); 00194 else // It must be a navigation controller 00195 Notify(PSTR("\r\nNavigation Controller Connected"), 0x80); 00196 } else // It must be a Motion controller 00197 Notify(PSTR("\r\nMotion Controller Connected"), 0x80); 00198 #endif 00199 00200 if(my_bdaddr[0] == 0x00 && my_bdaddr[1] == 0x00 && my_bdaddr[2] == 0x00 && my_bdaddr[3] == 0x00 && my_bdaddr[4] == 0x00 && my_bdaddr[5] == 0x00) { 00201 #ifdef DEBUG_USB_HOST 00202 Notify(PSTR("\r\nPlease plug in the dongle before trying to pair with the PS3 Controller\r\nor set the Bluetooth address in the constructor of the PS3BT class"), 0x80); 00203 #endif 00204 } else { 00205 if(PID == PS3_PID || PID == PS3NAVIGATION_PID) 00206 setBdaddr(my_bdaddr); // Set internal Bluetooth address 00207 else 00208 setMoveBdaddr(my_bdaddr); // Set internal Bluetooth address 00209 #ifdef DEBUG_USB_HOST 00210 Notify(PSTR("\r\nBluetooth Address was set to: "), 0x80); 00211 for(int8_t i = 5; i > 0; i--) { 00212 D_PrintHex<uint8_t > (my_bdaddr[i], 0x80); 00213 Notify(PSTR(":"), 0x80); 00214 } 00215 D_PrintHex<uint8_t > (my_bdaddr[0], 0x80); 00216 #endif 00217 } 00218 00219 pUsb->setConf(bAddress, epInfo[ BTD_CONTROL_PIPE ].epAddr, 0); // Reset configuration value 00220 pUsb->setAddr(bAddress, 0, 0); // Reset address 00221 Release(); // Release device 00222 return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; // Return 00223 } else { 00224 // Check if attached device is a Bluetooth dongle and fill endpoint data structure 00225 // First interface in the configuration must have Bluetooth assigned Class/Subclass/Protocol 00226 // And 3 endpoints - interrupt-IN, bulk-IN, bulk-OUT, not necessarily in this order 00227 for(uint8_t i = 0; i < num_of_conf; i++) { 00228 if((VID == IOGEAR_GBU521_VID && PID == IOGEAR_GBU521_PID) || (VID == BELKIN_F8T065BF_VID && PID == BELKIN_F8T065BF_PID)) { 00229 ConfigDescParser<USB_CLASS_VENDOR_SPECIFIC, WI_SUBCLASS_RF, WI_PROTOCOL_BT, CP_MASK_COMPARE_ALL> confDescrParser(this); // Workaround issue with some dongles 00230 rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser); 00231 } else { 00232 ConfigDescParser<USB_CLASS_WIRELESS_CTRL, WI_SUBCLASS_RF, WI_PROTOCOL_BT, CP_MASK_COMPARE_ALL> confDescrParser(this); // Set class id according to the specification 00233 rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser); 00234 } 00235 if(rcode) // Check error code 00236 goto FailGetConfDescr; 00237 if(bNumEP >= BTD_MAX_ENDPOINTS) // All endpoints extracted 00238 break; 00239 } 00240 00241 if(bNumEP < BTD_MAX_ENDPOINTS) 00242 goto FailUnknownDevice; 00243 00244 // Assign epInfo to epinfo pointer - this time all 3 endpoins 00245 rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo); 00246 if(rcode) 00247 goto FailSetDevTblEntry; 00248 00249 // Set Configuration Value 00250 rcode = pUsb->setConf(bAddress, epInfo[ BTD_CONTROL_PIPE ].epAddr, bConfNum); 00251 if(rcode) 00252 goto FailSetConfDescr; 00253 00254 hci_num_reset_loops = 100; // only loop 100 times before trying to send the hci reset command 00255 hci_counter = 0; 00256 hci_state = HCI_INIT_STATE; 00257 waitingForConnection = false; 00258 bPollEnable = true; 00259 00260 #ifdef DEBUG_USB_HOST 00261 Notify(PSTR("\r\nBluetooth Dongle Initialized"), 0x80); 00262 #endif 00263 } 00264 return 0; // Successful configuration 00265 00266 /* Diagnostic messages */ 00267 FailSetDevTblEntry: 00268 #ifdef DEBUG_USB_HOST 00269 NotifyFailSetDevTblEntry(); 00270 goto Fail; 00271 #endif 00272 00273 FailGetConfDescr: 00274 #ifdef DEBUG_USB_HOST 00275 NotifyFailGetConfDescr(); 00276 goto Fail; 00277 #endif 00278 00279 FailSetConfDescr: 00280 #ifdef DEBUG_USB_HOST 00281 NotifyFailSetConfDescr(); 00282 #endif 00283 goto Fail; 00284 00285 FailUnknownDevice: 00286 #ifdef DEBUG_USB_HOST 00287 NotifyFailUnknownDevice(VID, PID); 00288 #endif 00289 pUsb->setAddr(bAddress, 0, 0); // Reset address 00290 rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; 00291 Fail: 00292 #ifdef DEBUG_USB_HOST 00293 Notify(PSTR("\r\nBTD Init Failed, error code: "), 0x80); 00294 NotifyFail(rcode); 00295 #endif 00296 Release(); 00297 return rcode; 00298 } 00299 00300 void BTD::Initialize() { 00301 uint8_t i; 00302 for(i = 0; i < BTD_MAX_ENDPOINTS; i++) { 00303 epInfo[i].epAddr = 0; 00304 epInfo[i].maxPktSize = (i) ? 0 : 8; 00305 epInfo[i].bmSndToggle = 0; 00306 epInfo[i].bmRcvToggle = 0; 00307 epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER; 00308 } 00309 for(i = 0; i < BTD_NUM_SERVICES; i++) { 00310 if(btService[i]) 00311 btService[i]->Reset(); // Reset all Bluetooth services 00312 } 00313 00314 connectToWii = false; 00315 incomingWii = false; 00316 connectToHIDDevice = false; 00317 incomingHIDDevice = false; 00318 incomingPS4 = false; 00319 bAddress = 0; // Clear device address 00320 bNumEP = 1; // Must have to be reset to 1 00321 qNextPollTime = 0; // Reset next poll time 00322 pollInterval = 0; 00323 bPollEnable = false; // Don't start polling before dongle is connected 00324 } 00325 00326 /* Extracts interrupt-IN, bulk-IN, bulk-OUT endpoint information from config descriptor */ 00327 void BTD::EndpointXtract(uint8_t conf, uint8_t iface __attribute__((unused)), uint8_t alt, uint8_t proto __attribute__((unused)), const USB_ENDPOINT_DESCRIPTOR *pep) { 00328 //ErrorMessage<uint8_t>(PSTR("Conf.Val"),conf); 00329 //ErrorMessage<uint8_t>(PSTR("Iface Num"),iface); 00330 //ErrorMessage<uint8_t>(PSTR("Alt.Set"),alt); 00331 00332 if(alt) // Wrong interface - by BT spec, no alt setting 00333 return; 00334 00335 bConfNum = conf; 00336 uint8_t index; 00337 00338 if((pep->bmAttributes & bmUSB_TRANSFER_TYPE) == USB_TRANSFER_TYPE_INTERRUPT && (pep->bEndpointAddress & 0x80) == 0x80) { // Interrupt In endpoint found 00339 index = BTD_EVENT_PIPE; 00340 epInfo[index].bmNakPower = USB_NAK_NOWAIT; 00341 } else if((pep->bmAttributes & bmUSB_TRANSFER_TYPE) == USB_TRANSFER_TYPE_BULK) // Bulk endpoint found 00342 index = ((pep->bEndpointAddress & 0x80) == 0x80) ? BTD_DATAIN_PIPE : BTD_DATAOUT_PIPE; 00343 else 00344 return; 00345 00346 // Fill the rest of endpoint data structure 00347 epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F); 00348 epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize; 00349 #ifdef EXTRADEBUG 00350 PrintEndpointDescriptor(pep); 00351 #endif 00352 if(pollInterval < pep->bInterval) // Set the polling interval as the largest polling interval obtained from endpoints 00353 pollInterval = pep->bInterval; 00354 bNumEP++; 00355 } 00356 00357 void BTD::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr __attribute__((unused))) { 00358 #ifdef EXTRADEBUG 00359 Notify(PSTR("\r\nEndpoint descriptor:"), 0x80); 00360 Notify(PSTR("\r\nLength:\t\t"), 0x80); 00361 D_PrintHex<uint8_t > (ep_ptr->bLength, 0x80); 00362 Notify(PSTR("\r\nType:\t\t"), 0x80); 00363 D_PrintHex<uint8_t > (ep_ptr->bDescriptorType, 0x80); 00364 Notify(PSTR("\r\nAddress:\t"), 0x80); 00365 D_PrintHex<uint8_t > (ep_ptr->bEndpointAddress, 0x80); 00366 Notify(PSTR("\r\nAttributes:\t"), 0x80); 00367 D_PrintHex<uint8_t > (ep_ptr->bmAttributes, 0x80); 00368 Notify(PSTR("\r\nMaxPktSize:\t"), 0x80); 00369 D_PrintHex<uint16_t > (ep_ptr->wMaxPacketSize, 0x80); 00370 Notify(PSTR("\r\nPoll Intrv:\t"), 0x80); 00371 D_PrintHex<uint8_t > (ep_ptr->bInterval, 0x80); 00372 #endif 00373 } 00374 00375 /* Performs a cleanup after failed Init() attempt */ 00376 uint8_t BTD::Release() { 00377 Initialize(); // Set all variables, endpoint structs etc. to default values 00378 pUsb->GetAddressPool().FreeAddress(bAddress); 00379 return 0; 00380 } 00381 00382 uint8_t BTD::Poll() { 00383 if(!bPollEnable) 00384 return 0; 00385 if((int32_t)((uint32_t)millis() - qNextPollTime) >= 0L) { // Don't poll if shorter than polling interval 00386 qNextPollTime = (uint32_t)millis() + pollInterval; // Set new poll time 00387 HCI_event_task(); // Poll the HCI event pipe 00388 HCI_task(); // HCI state machine 00389 ACL_event_task(); // Poll the ACL input pipe too 00390 } 00391 return 0; 00392 } 00393 00394 void BTD::disconnect() { 00395 for(uint8_t i = 0; i < BTD_NUM_SERVICES; i++) 00396 if(btService[i]) 00397 btService[i]->disconnect(); 00398 }; 00399 00400 void BTD::HCI_event_task() { 00401 uint16_t length = BULK_MAXPKTSIZE; // Request more than 16 bytes anyway, the inTransfer routine will take care of this 00402 uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[ BTD_EVENT_PIPE ].epAddr, &length, hcibuf, pollInterval); // Input on endpoint 1 00403 00404 if(!rcode || rcode == hrNAK) { // Check for errors 00405 switch(hcibuf[0]) { // Switch on event type 00406 case EV_COMMAND_COMPLETE: 00407 if(!hcibuf[5]) { // Check if command succeeded 00408 hci_set_flag(HCI_FLAG_CMD_COMPLETE); // Set command complete flag 00409 if((hcibuf[3] == 0x01) && (hcibuf[4] == 0x10)) { // Parameters from read local version information 00410 hci_version = hcibuf[6]; // Used to check if it supports 2.0+EDR - see http://www.bluetooth.org/Technical/AssignedNumbers/hci.htm 00411 hci_set_flag(HCI_FLAG_READ_VERSION); 00412 } else if((hcibuf[3] == 0x09) && (hcibuf[4] == 0x10)) { // Parameters from read local bluetooth address 00413 for(uint8_t i = 0; i < 6; i++) 00414 my_bdaddr[i] = hcibuf[6 + i]; 00415 hci_set_flag(HCI_FLAG_READ_BDADDR); 00416 } 00417 } 00418 break; 00419 00420 case EV_COMMAND_STATUS: 00421 if(hcibuf[2]) { // Show status on serial if not OK 00422 #ifdef DEBUG_USB_HOST 00423 Notify(PSTR("\r\nHCI Command Failed: "), 0x80); 00424 D_PrintHex<uint8_t > (hcibuf[2], 0x80); 00425 #endif 00426 } 00427 break; 00428 00429 case EV_INQUIRY_COMPLETE: 00430 if(inquiry_counter >= 5 && (pairWithWii || pairWithHIDDevice)) { 00431 inquiry_counter = 0; 00432 #ifdef DEBUG_USB_HOST 00433 if(pairWithWii) 00434 Notify(PSTR("\r\nCouldn't find Wiimote"), 0x80); 00435 else 00436 Notify(PSTR("\r\nCouldn't find HID device"), 0x80); 00437 #endif 00438 connectToWii = false; 00439 pairWithWii = false; 00440 connectToHIDDevice = false; 00441 pairWithHIDDevice = false; 00442 hci_state = HCI_SCANNING_STATE; 00443 } 00444 inquiry_counter++; 00445 break; 00446 00447 case EV_INQUIRY_RESULT: 00448 if(hcibuf[2]) { // Check that there is more than zero responses 00449 #ifdef EXTRADEBUG 00450 Notify(PSTR("\r\nNumber of responses: "), 0x80); 00451 Notify(hcibuf[2], 0x80); 00452 #endif 00453 for(uint8_t i = 0; i < hcibuf[2]; i++) { 00454 uint8_t offset = 8 * hcibuf[2] + 3 * i; 00455 00456 for(uint8_t j = 0; j < 3; j++) 00457 classOfDevice[j] = hcibuf[j + 4 + offset]; 00458 00459 #ifdef EXTRADEBUG 00460 Notify(PSTR("\r\nClass of device: "), 0x80); 00461 D_PrintHex<uint8_t > (classOfDevice[2], 0x80); 00462 Notify(PSTR(" "), 0x80); 00463 D_PrintHex<uint8_t > (classOfDevice[1], 0x80); 00464 Notify(PSTR(" "), 0x80); 00465 D_PrintHex<uint8_t > (classOfDevice[0], 0x80); 00466 #endif 00467 00468 if(pairWithWii && classOfDevice[2] == 0x00 && (classOfDevice[1] & 0x05) && (classOfDevice[0] & 0x0C)) { // See http://wiibrew.org/wiki/Wiimote#SDP_information 00469 checkRemoteName = true; // Check remote name to distinguish between the different controllers 00470 00471 for(uint8_t j = 0; j < 6; j++) 00472 disc_bdaddr[j] = hcibuf[j + 3 + 6 * i]; 00473 00474 hci_set_flag(HCI_FLAG_DEVICE_FOUND); 00475 break; 00476 } else if(pairWithHIDDevice && (classOfDevice[1] & 0x05) && (classOfDevice[0] & 0xC8)) { // Check if it is a mouse, keyboard or a gamepad - see: http://bluetooth-pentest.narod.ru/software/bluetooth_class_of_device-service_generator.html 00477 #ifdef DEBUG_USB_HOST 00478 if(classOfDevice[0] & 0x80) 00479 Notify(PSTR("\r\nMouse found"), 0x80); 00480 if(classOfDevice[0] & 0x40) 00481 Notify(PSTR("\r\nKeyboard found"), 0x80); 00482 if(classOfDevice[0] & 0x08) 00483 Notify(PSTR("\r\nGamepad found"), 0x80); 00484 #endif 00485 00486 for(uint8_t j = 0; j < 6; j++) 00487 disc_bdaddr[j] = hcibuf[j + 3 + 6 * i]; 00488 00489 hci_set_flag(HCI_FLAG_DEVICE_FOUND); 00490 break; 00491 } 00492 } 00493 } 00494 break; 00495 00496 case EV_CONNECT_COMPLETE: 00497 hci_set_flag(HCI_FLAG_CONNECT_EVENT); 00498 if(!hcibuf[2]) { // Check if connected OK 00499 #ifdef EXTRADEBUG 00500 Notify(PSTR("\r\nConnection established"), 0x80); 00501 #endif 00502 hci_handle = hcibuf[3] | ((hcibuf[4] & 0x0F) << 8); // Store the handle for the ACL connection 00503 hci_set_flag(HCI_FLAG_CONNECT_COMPLETE); // Set connection complete flag 00504 } else { 00505 hci_state = HCI_CHECK_DEVICE_SERVICE; 00506 #ifdef DEBUG_USB_HOST 00507 Notify(PSTR("\r\nConnection Failed: "), 0x80); 00508 D_PrintHex<uint8_t > (hcibuf[2], 0x80); 00509 #endif 00510 } 00511 break; 00512 00513 case EV_DISCONNECT_COMPLETE: 00514 if(!hcibuf[2]) { // Check if disconnected OK 00515 hci_set_flag(HCI_FLAG_DISCONNECT_COMPLETE); // Set disconnect command complete flag 00516 hci_clear_flag(HCI_FLAG_CONNECT_COMPLETE); // Clear connection complete flag 00517 } 00518 break; 00519 00520 case EV_REMOTE_NAME_COMPLETE: 00521 if(!hcibuf[2]) { // Check if reading is OK 00522 for(uint8_t i = 0; i < min(sizeof (remote_name), sizeof (hcibuf) - 9); i++) { 00523 remote_name[i] = hcibuf[9 + i]; 00524 if(remote_name[i] == '\0') // End of string 00525 break; 00526 } 00527 // TODO: Altid sæt '\0' i remote name! 00528 hci_set_flag(HCI_FLAG_REMOTE_NAME_COMPLETE); 00529 } 00530 break; 00531 00532 case EV_INCOMING_CONNECT: 00533 for(uint8_t i = 0; i < 6; i++) 00534 disc_bdaddr[i] = hcibuf[i + 2]; 00535 00536 for(uint8_t i = 0; i < 3; i++) 00537 classOfDevice[i] = hcibuf[i + 8]; 00538 00539 if((classOfDevice[1] & 0x05) && (classOfDevice[0] & 0xC8)) { // Check if it is a mouse, keyboard or a gamepad 00540 #ifdef DEBUG_USB_HOST 00541 if(classOfDevice[0] & 0x80) 00542 Notify(PSTR("\r\nMouse is connecting"), 0x80); 00543 if(classOfDevice[0] & 0x40) 00544 Notify(PSTR("\r\nKeyboard is connecting"), 0x80); 00545 if(classOfDevice[0] & 0x08) 00546 Notify(PSTR("\r\nGamepad is connecting"), 0x80); 00547 #endif 00548 incomingHIDDevice = true; 00549 } 00550 00551 #ifdef EXTRADEBUG 00552 Notify(PSTR("\r\nClass of device: "), 0x80); 00553 D_PrintHex<uint8_t > (classOfDevice[2], 0x80); 00554 Notify(PSTR(" "), 0x80); 00555 D_PrintHex<uint8_t > (classOfDevice[1], 0x80); 00556 Notify(PSTR(" "), 0x80); 00557 D_PrintHex<uint8_t > (classOfDevice[0], 0x80); 00558 #endif 00559 hci_set_flag(HCI_FLAG_INCOMING_REQUEST); 00560 break; 00561 00562 case EV_PIN_CODE_REQUEST: 00563 if(pairWithWii) { 00564 #ifdef DEBUG_USB_HOST 00565 Notify(PSTR("\r\nPairing with Wiimote"), 0x80); 00566 #endif 00567 hci_pin_code_request_reply(); 00568 } else if(btdPin != NULL) { 00569 #ifdef DEBUG_USB_HOST 00570 Notify(PSTR("\r\nBluetooth pin is set too: "), 0x80); 00571 NotifyStr(btdPin, 0x80); 00572 #endif 00573 hci_pin_code_request_reply(); 00574 } else { 00575 #ifdef DEBUG_USB_HOST 00576 Notify(PSTR("\r\nNo pin was set"), 0x80); 00577 #endif 00578 hci_pin_code_negative_request_reply(); 00579 } 00580 break; 00581 00582 case EV_LINK_KEY_REQUEST: 00583 #ifdef DEBUG_USB_HOST 00584 Notify(PSTR("\r\nReceived Key Request"), 0x80); 00585 #endif 00586 hci_link_key_request_negative_reply(); 00587 break; 00588 00589 case EV_AUTHENTICATION_COMPLETE: 00590 if(!hcibuf[2]) { // Check if pairing was successful 00591 if(pairWithWii && !connectToWii) { 00592 #ifdef DEBUG_USB_HOST 00593 Notify(PSTR("\r\nPairing successful with Wiimote"), 0x80); 00594 #endif 00595 connectToWii = true; // Used to indicate to the Wii service, that it should connect to this device 00596 } else if(pairWithHIDDevice && !connectToHIDDevice) { 00597 #ifdef DEBUG_USB_HOST 00598 Notify(PSTR("\r\nPairing successful with HID device"), 0x80); 00599 #endif 00600 connectToHIDDevice = true; // Used to indicate to the BTHID service, that it should connect to this device 00601 } 00602 } else { 00603 #ifdef DEBUG_USB_HOST 00604 Notify(PSTR("\r\nPairing Failed: "), 0x80); 00605 D_PrintHex<uint8_t > (hcibuf[2], 0x80); 00606 #endif 00607 hci_disconnect(hci_handle); 00608 hci_state = HCI_DISCONNECT_STATE; 00609 } 00610 break; 00611 /* We will just ignore the following events */ 00612 case EV_NUM_COMPLETE_PKT: 00613 case EV_ROLE_CHANGED: 00614 case EV_PAGE_SCAN_REP_MODE: 00615 case EV_LOOPBACK_COMMAND: 00616 case EV_DATA_BUFFER_OVERFLOW: 00617 case EV_CHANGE_CONNECTION_LINK: 00618 case EV_MAX_SLOTS_CHANGE: 00619 case EV_QOS_SETUP_COMPLETE: 00620 case EV_LINK_KEY_NOTIFICATION: 00621 case EV_ENCRYPTION_CHANGE: 00622 case EV_READ_REMOTE_VERSION_INFORMATION_COMPLETE: 00623 break; 00624 #ifdef EXTRADEBUG 00625 default: 00626 if(hcibuf[0] != 0x00) { 00627 Notify(PSTR("\r\nUnmanaged HCI Event: "), 0x80); 00628 D_PrintHex<uint8_t > (hcibuf[0], 0x80); 00629 } 00630 break; 00631 #endif 00632 } // Switch 00633 } 00634 #ifdef EXTRADEBUG 00635 else { 00636 Notify(PSTR("\r\nHCI event error: "), 0x80); 00637 D_PrintHex<uint8_t > (rcode, 0x80); 00638 } 00639 #endif 00640 } 00641 00642 /* Poll Bluetooth and print result */ 00643 void BTD::HCI_task() { 00644 switch(hci_state) { 00645 case HCI_INIT_STATE: 00646 hci_counter++; 00647 if(hci_counter > hci_num_reset_loops) { // wait until we have looped x times to clear any old events 00648 hci_reset(); 00649 hci_state = HCI_RESET_STATE; 00650 hci_counter = 0; 00651 } 00652 break; 00653 00654 case HCI_RESET_STATE: 00655 hci_counter++; 00656 if(hci_check_flag(HCI_FLAG_CMD_COMPLETE)) { 00657 hci_counter = 0; 00658 #ifdef DEBUG_USB_HOST 00659 Notify(PSTR("\r\nHCI Reset complete"), 0x80); 00660 #endif 00661 hci_state = HCI_CLASS_STATE; 00662 hci_write_class_of_device(); 00663 } else if(hci_counter > hci_num_reset_loops) { 00664 hci_num_reset_loops *= 10; 00665 if(hci_num_reset_loops > 2000) 00666 hci_num_reset_loops = 2000; 00667 #ifdef DEBUG_USB_HOST 00668 Notify(PSTR("\r\nNo response to HCI Reset"), 0x80); 00669 #endif 00670 hci_state = HCI_INIT_STATE; 00671 hci_counter = 0; 00672 } 00673 break; 00674 00675 case HCI_CLASS_STATE: 00676 if(hci_check_flag(HCI_FLAG_CMD_COMPLETE)) { 00677 #ifdef DEBUG_USB_HOST 00678 Notify(PSTR("\r\nWrite class of device"), 0x80); 00679 #endif 00680 hci_state = HCI_BDADDR_STATE; 00681 hci_read_bdaddr(); 00682 } 00683 break; 00684 00685 case HCI_BDADDR_STATE: 00686 if(hci_check_flag(HCI_FLAG_READ_BDADDR)) { 00687 #ifdef DEBUG_USB_HOST 00688 Notify(PSTR("\r\nLocal Bluetooth Address: "), 0x80); 00689 for(int8_t i = 5; i > 0; i--) { 00690 D_PrintHex<uint8_t > (my_bdaddr[i], 0x80); 00691 Notify(PSTR(":"), 0x80); 00692 } 00693 D_PrintHex<uint8_t > (my_bdaddr[0], 0x80); 00694 #endif 00695 hci_read_local_version_information(); 00696 hci_state = HCI_LOCAL_VERSION_STATE; 00697 } 00698 break; 00699 00700 case HCI_LOCAL_VERSION_STATE: // The local version is used by the PS3BT class 00701 if(hci_check_flag(HCI_FLAG_READ_VERSION)) { 00702 if(btdName != NULL) { 00703 hci_set_local_name(btdName); 00704 hci_state = HCI_SET_NAME_STATE; 00705 } else 00706 hci_state = HCI_CHECK_DEVICE_SERVICE; 00707 } 00708 break; 00709 00710 case HCI_SET_NAME_STATE: 00711 if(hci_check_flag(HCI_FLAG_CMD_COMPLETE)) { 00712 #ifdef DEBUG_USB_HOST 00713 Notify(PSTR("\r\nThe name is set to: "), 0x80); 00714 NotifyStr(btdName, 0x80); 00715 #endif 00716 hci_state = HCI_CHECK_DEVICE_SERVICE; 00717 } 00718 break; 00719 00720 case HCI_CHECK_DEVICE_SERVICE: 00721 if(pairWithHIDDevice || pairWithWii) { // Check if it should try to connect to a Wiimote 00722 #ifdef DEBUG_USB_HOST 00723 if(pairWithWii) 00724 Notify(PSTR("\r\nStarting inquiry\r\nPress 1 & 2 on the Wiimote\r\nOr press the SYNC button if you are using a Wii U Pro Controller or a Wii Balance Board"), 0x80); 00725 else 00726 Notify(PSTR("\r\nPlease enable discovery of your device"), 0x80); 00727 #endif 00728 hci_inquiry(); 00729 hci_state = HCI_INQUIRY_STATE; 00730 } else 00731 hci_state = HCI_SCANNING_STATE; // Don't try to connect to a Wiimote 00732 break; 00733 00734 case HCI_INQUIRY_STATE: 00735 if(hci_check_flag(HCI_FLAG_DEVICE_FOUND)) { 00736 hci_inquiry_cancel(); // Stop inquiry 00737 #ifdef DEBUG_USB_HOST 00738 if(pairWithWii) 00739 Notify(PSTR("\r\nWiimote found"), 0x80); 00740 else 00741 Notify(PSTR("\r\nHID device found"), 0x80); 00742 00743 Notify(PSTR("\r\nNow just create the instance like so:"), 0x80); 00744 if(pairWithWii) 00745 Notify(PSTR("\r\nWII Wii(&Btd);"), 0x80); 00746 else 00747 Notify(PSTR("\r\nBTHID bthid(&Btd);"), 0x80); 00748 00749 Notify(PSTR("\r\nAnd then press any button on the "), 0x80); 00750 if(pairWithWii) 00751 Notify(PSTR("Wiimote"), 0x80); 00752 else 00753 Notify(PSTR("device"), 0x80); 00754 #endif 00755 if(checkRemoteName) { 00756 hci_remote_name(); // We need to know the name to distinguish between the Wiimote, the new Wiimote with Motion Plus inside, a Wii U Pro Controller and a Wii Balance Board 00757 hci_state = HCI_REMOTE_NAME_STATE; 00758 } else 00759 hci_state = HCI_CONNECT_DEVICE_STATE; 00760 } 00761 break; 00762 00763 case HCI_CONNECT_DEVICE_STATE: 00764 if(hci_check_flag(HCI_FLAG_CMD_COMPLETE)) { 00765 #ifdef DEBUG_USB_HOST 00766 if(pairWithWii) 00767 Notify(PSTR("\r\nConnecting to Wiimote"), 0x80); 00768 else 00769 Notify(PSTR("\r\nConnecting to HID device"), 0x80); 00770 #endif 00771 checkRemoteName = false; 00772 hci_connect(); 00773 hci_state = HCI_CONNECTED_DEVICE_STATE; 00774 } 00775 break; 00776 00777 case HCI_CONNECTED_DEVICE_STATE: 00778 if(hci_check_flag(HCI_FLAG_CONNECT_EVENT)) { 00779 if(hci_check_flag(HCI_FLAG_CONNECT_COMPLETE)) { 00780 #ifdef DEBUG_USB_HOST 00781 if(pairWithWii) 00782 Notify(PSTR("\r\nConnected to Wiimote"), 0x80); 00783 else 00784 Notify(PSTR("\r\nConnected to HID device"), 0x80); 00785 #endif 00786 hci_authentication_request(); // This will start the pairing with the Wiimote 00787 hci_state = HCI_SCANNING_STATE; 00788 } else { 00789 #ifdef DEBUG_USB_HOST 00790 Notify(PSTR("\r\nTrying to connect one more time..."), 0x80); 00791 #endif 00792 hci_connect(); // Try to connect one more time 00793 } 00794 } 00795 break; 00796 00797 case HCI_SCANNING_STATE: 00798 if(!connectToWii && !pairWithWii && !connectToHIDDevice && !pairWithHIDDevice) { 00799 #ifdef DEBUG_USB_HOST 00800 Notify(PSTR("\r\nWait For Incoming Connection Request"), 0x80); 00801 #endif 00802 hci_write_scan_enable(); 00803 waitingForConnection = true; 00804 hci_state = HCI_CONNECT_IN_STATE; 00805 } 00806 break; 00807 00808 case HCI_CONNECT_IN_STATE: 00809 if(hci_check_flag(HCI_FLAG_INCOMING_REQUEST)) { 00810 waitingForConnection = false; 00811 #ifdef DEBUG_USB_HOST 00812 Notify(PSTR("\r\nIncoming Connection Request"), 0x80); 00813 #endif 00814 hci_remote_name(); 00815 hci_state = HCI_REMOTE_NAME_STATE; 00816 } else if(hci_check_flag(HCI_FLAG_DISCONNECT_COMPLETE)) 00817 hci_state = HCI_DISCONNECT_STATE; 00818 break; 00819 00820 case HCI_REMOTE_NAME_STATE: 00821 if(hci_check_flag(HCI_FLAG_REMOTE_NAME_COMPLETE)) { 00822 #ifdef DEBUG_USB_HOST 00823 Notify(PSTR("\r\nRemote Name: "), 0x80); 00824 for(uint8_t i = 0; i < strlen(remote_name); i++) 00825 Notifyc(remote_name[i], 0x80); 00826 #endif 00827 if(strncmp((const char*)remote_name, "Nintendo", 8) == 0) { 00828 incomingWii = true; 00829 motionPlusInside = false; 00830 wiiUProController = false; 00831 pairWiiUsingSync = false; 00832 #ifdef DEBUG_USB_HOST 00833 Notify(PSTR("\r\nWiimote is connecting"), 0x80); 00834 #endif 00835 if(strncmp((const char*)remote_name, "Nintendo RVL-CNT-01-TR", 22) == 0) { 00836 #ifdef DEBUG_USB_HOST 00837 Notify(PSTR(" with Motion Plus Inside"), 0x80); 00838 #endif 00839 motionPlusInside = true; 00840 } else if(strncmp((const char*)remote_name, "Nintendo RVL-CNT-01-UC", 22) == 0) { 00841 #ifdef DEBUG_USB_HOST 00842 Notify(PSTR(" - Wii U Pro Controller"), 0x80); 00843 #endif 00844 wiiUProController = motionPlusInside = pairWiiUsingSync = true; 00845 } else if(strncmp((const char*)remote_name, "Nintendo RVL-WBC-01", 19) == 0) { 00846 #ifdef DEBUG_USB_HOST 00847 Notify(PSTR(" - Wii Balance Board"), 0x80); 00848 #endif 00849 pairWiiUsingSync = true; 00850 } 00851 } 00852 if(classOfDevice[2] == 0 && classOfDevice[1] == 0x25 && classOfDevice[0] == 0x08 && strncmp((const char*)remote_name, "Wireless Controller", 19) == 0) { 00853 #ifdef DEBUG_USB_HOST 00854 Notify(PSTR("\r\nPS4 controller is connecting"), 0x80); 00855 #endif 00856 incomingPS4 = true; 00857 } 00858 if(pairWithWii && checkRemoteName) 00859 hci_state = HCI_CONNECT_DEVICE_STATE; 00860 else { 00861 hci_accept_connection(); 00862 hci_state = HCI_CONNECTED_STATE; 00863 } 00864 } 00865 break; 00866 00867 case HCI_CONNECTED_STATE: 00868 if(hci_check_flag(HCI_FLAG_CONNECT_COMPLETE)) { 00869 #ifdef DEBUG_USB_HOST 00870 Notify(PSTR("\r\nConnected to Device: "), 0x80); 00871 for(int8_t i = 5; i > 0; i--) { 00872 D_PrintHex<uint8_t > (disc_bdaddr[i], 0x80); 00873 Notify(PSTR(":"), 0x80); 00874 } 00875 D_PrintHex<uint8_t > (disc_bdaddr[0], 0x80); 00876 #endif 00877 if(incomingPS4) 00878 connectToHIDDevice = true; // We should always connect to the PS4 controller 00879 00880 // Clear these flags for a new connection 00881 l2capConnectionClaimed = false; 00882 sdpConnectionClaimed = false; 00883 rfcommConnectionClaimed = false; 00884 00885 hci_event_flag = 0; 00886 hci_state = HCI_DONE_STATE; 00887 } 00888 break; 00889 00890 case HCI_DONE_STATE: 00891 hci_counter++; 00892 if(hci_counter > 1000) { // Wait until we have looped 1000 times to make sure that the L2CAP connection has been started 00893 hci_counter = 0; 00894 hci_state = HCI_SCANNING_STATE; 00895 } 00896 break; 00897 00898 case HCI_DISCONNECT_STATE: 00899 if(hci_check_flag(HCI_FLAG_DISCONNECT_COMPLETE)) { 00900 #ifdef DEBUG_USB_HOST 00901 Notify(PSTR("\r\nHCI Disconnected from Device"), 0x80); 00902 #endif 00903 hci_event_flag = 0; // Clear all flags 00904 00905 // Reset all buffers 00906 memset(hcibuf, 0, BULK_MAXPKTSIZE); 00907 memset(l2capinbuf, 0, BULK_MAXPKTSIZE); 00908 00909 connectToWii = incomingWii = pairWithWii = false; 00910 connectToHIDDevice = incomingHIDDevice = pairWithHIDDevice = checkRemoteName = false; 00911 incomingPS4 = false; 00912 00913 hci_state = HCI_SCANNING_STATE; 00914 } 00915 break; 00916 default: 00917 break; 00918 } 00919 } 00920 00921 void BTD::ACL_event_task() { 00922 uint16_t length = BULK_MAXPKTSIZE; 00923 uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[ BTD_DATAIN_PIPE ].epAddr, &length, l2capinbuf, pollInterval); // Input on endpoint 2 00924 00925 if(!rcode) { // Check for errors 00926 if(length > 0) { // Check if any data was read 00927 for(uint8_t i = 0; i < BTD_NUM_SERVICES; i++) { 00928 if(btService[i]) 00929 btService[i]->ACLData(l2capinbuf); 00930 } 00931 } 00932 } 00933 #ifdef EXTRADEBUG 00934 else if(rcode != hrNAK) { 00935 Notify(PSTR("\r\nACL data in error: "), 0x80); 00936 D_PrintHex<uint8_t > (rcode, 0x80); 00937 } 00938 #endif 00939 for(uint8_t i = 0; i < BTD_NUM_SERVICES; i++) 00940 if(btService[i]) 00941 btService[i]->Run(); 00942 } 00943 00944 /************************************************************/ 00945 /* HCI Commands */ 00946 00947 /************************************************************/ 00948 void BTD::HCI_Command(uint8_t* data, uint16_t nbytes) { 00949 hci_clear_flag(HCI_FLAG_CMD_COMPLETE); 00950 pUsb->ctrlReq(bAddress, epInfo[ BTD_CONTROL_PIPE ].epAddr, bmREQ_HCI_OUT, 0x00, 0x00, 0x00, 0x00, nbytes, nbytes, data, NULL); 00951 } 00952 00953 void BTD::hci_reset() { 00954 hci_event_flag = 0; // Clear all the flags 00955 hcibuf[0] = 0x03; // HCI OCF = 3 00956 hcibuf[1] = 0x03 << 2; // HCI OGF = 3 00957 hcibuf[2] = 0x00; 00958 00959 HCI_Command(hcibuf, 3); 00960 } 00961 00962 void BTD::hci_write_scan_enable() { 00963 hci_clear_flag(HCI_FLAG_INCOMING_REQUEST); 00964 hcibuf[0] = 0x1A; // HCI OCF = 1A 00965 hcibuf[1] = 0x03 << 2; // HCI OGF = 3 00966 hcibuf[2] = 0x01; // parameter length = 1 00967 if(btdName != NULL) 00968 hcibuf[3] = 0x03; // Inquiry Scan enabled. Page Scan enabled. 00969 else 00970 hcibuf[3] = 0x02; // Inquiry Scan disabled. Page Scan enabled. 00971 00972 HCI_Command(hcibuf, 4); 00973 } 00974 00975 void BTD::hci_write_scan_disable() { 00976 hcibuf[0] = 0x1A; // HCI OCF = 1A 00977 hcibuf[1] = 0x03 << 2; // HCI OGF = 3 00978 hcibuf[2] = 0x01; // parameter length = 1 00979 hcibuf[3] = 0x00; // Inquiry Scan disabled. Page Scan disabled. 00980 00981 HCI_Command(hcibuf, 4); 00982 } 00983 00984 void BTD::hci_read_bdaddr() { 00985 hci_clear_flag(HCI_FLAG_READ_BDADDR); 00986 hcibuf[0] = 0x09; // HCI OCF = 9 00987 hcibuf[1] = 0x04 << 2; // HCI OGF = 4 00988 hcibuf[2] = 0x00; 00989 00990 HCI_Command(hcibuf, 3); 00991 } 00992 00993 void BTD::hci_read_local_version_information() { 00994 hci_clear_flag(HCI_FLAG_READ_VERSION); 00995 hcibuf[0] = 0x01; // HCI OCF = 1 00996 hcibuf[1] = 0x04 << 2; // HCI OGF = 4 00997 hcibuf[2] = 0x00; 00998 00999 HCI_Command(hcibuf, 3); 01000 } 01001 01002 void BTD::hci_accept_connection() { 01003 hci_clear_flag(HCI_FLAG_CONNECT_COMPLETE); 01004 hcibuf[0] = 0x09; // HCI OCF = 9 01005 hcibuf[1] = 0x01 << 2; // HCI OGF = 1 01006 hcibuf[2] = 0x07; // parameter length 7 01007 hcibuf[3] = disc_bdaddr[0]; // 6 octet bdaddr 01008 hcibuf[4] = disc_bdaddr[1]; 01009 hcibuf[5] = disc_bdaddr[2]; 01010 hcibuf[6] = disc_bdaddr[3]; 01011 hcibuf[7] = disc_bdaddr[4]; 01012 hcibuf[8] = disc_bdaddr[5]; 01013 hcibuf[9] = 0x00; // Switch role to master 01014 01015 HCI_Command(hcibuf, 10); 01016 } 01017 01018 void BTD::hci_remote_name() { 01019 hci_clear_flag(HCI_FLAG_REMOTE_NAME_COMPLETE); 01020 hcibuf[0] = 0x19; // HCI OCF = 19 01021 hcibuf[1] = 0x01 << 2; // HCI OGF = 1 01022 hcibuf[2] = 0x0A; // parameter length = 10 01023 hcibuf[3] = disc_bdaddr[0]; // 6 octet bdaddr 01024 hcibuf[4] = disc_bdaddr[1]; 01025 hcibuf[5] = disc_bdaddr[2]; 01026 hcibuf[6] = disc_bdaddr[3]; 01027 hcibuf[7] = disc_bdaddr[4]; 01028 hcibuf[8] = disc_bdaddr[5]; 01029 hcibuf[9] = 0x01; // Page Scan Repetition Mode 01030 hcibuf[10] = 0x00; // Reserved 01031 hcibuf[11] = 0x00; // Clock offset - low byte 01032 hcibuf[12] = 0x00; // Clock offset - high byte 01033 01034 HCI_Command(hcibuf, 13); 01035 } 01036 01037 void BTD::hci_set_local_name(const char* name) { 01038 hcibuf[0] = 0x13; // HCI OCF = 13 01039 hcibuf[1] = 0x03 << 2; // HCI OGF = 3 01040 hcibuf[2] = strlen(name) + 1; // parameter length = the length of the string + end byte 01041 uint8_t i; 01042 for(i = 0; i < strlen(name); i++) 01043 hcibuf[i + 3] = name[i]; 01044 hcibuf[i + 3] = 0x00; // End of string 01045 01046 HCI_Command(hcibuf, 4 + strlen(name)); 01047 } 01048 01049 void BTD::hci_inquiry() { 01050 hci_clear_flag(HCI_FLAG_DEVICE_FOUND); 01051 hcibuf[0] = 0x01; 01052 hcibuf[1] = 0x01 << 2; // HCI OGF = 1 01053 hcibuf[2] = 0x05; // Parameter Total Length = 5 01054 hcibuf[3] = 0x33; // LAP: Genera/Unlimited Inquiry Access Code (GIAC = 0x9E8B33) - see https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm 01055 hcibuf[4] = 0x8B; 01056 hcibuf[5] = 0x9E; 01057 hcibuf[6] = 0x30; // Inquiry time = 61.44 sec (maximum) 01058 hcibuf[7] = 0x0A; // 10 number of responses 01059 01060 HCI_Command(hcibuf, 8); 01061 } 01062 01063 void BTD::hci_inquiry_cancel() { 01064 hcibuf[0] = 0x02; 01065 hcibuf[1] = 0x01 << 2; // HCI OGF = 1 01066 hcibuf[2] = 0x00; // Parameter Total Length = 0 01067 01068 HCI_Command(hcibuf, 3); 01069 } 01070 01071 void BTD::hci_connect() { 01072 hci_connect(disc_bdaddr); // Use last discovered device 01073 } 01074 01075 void BTD::hci_connect(uint8_t *bdaddr) { 01076 hci_clear_flag(HCI_FLAG_CONNECT_COMPLETE | HCI_FLAG_CONNECT_EVENT); 01077 hcibuf[0] = 0x05; 01078 hcibuf[1] = 0x01 << 2; // HCI OGF = 1 01079 hcibuf[2] = 0x0D; // parameter Total Length = 13 01080 hcibuf[3] = bdaddr[0]; // 6 octet bdaddr (LSB) 01081 hcibuf[4] = bdaddr[1]; 01082 hcibuf[5] = bdaddr[2]; 01083 hcibuf[6] = bdaddr[3]; 01084 hcibuf[7] = bdaddr[4]; 01085 hcibuf[8] = bdaddr[5]; 01086 hcibuf[9] = 0x18; // DM1 or DH1 may be used 01087 hcibuf[10] = 0xCC; // DM3, DH3, DM5, DH5 may be used 01088 hcibuf[11] = 0x01; // Page repetition mode R1 01089 hcibuf[12] = 0x00; // Reserved 01090 hcibuf[13] = 0x00; // Clock offset 01091 hcibuf[14] = 0x00; // Invalid clock offset 01092 hcibuf[15] = 0x00; // Do not allow role switch 01093 01094 HCI_Command(hcibuf, 16); 01095 } 01096 01097 void BTD::hci_pin_code_request_reply() { 01098 hcibuf[0] = 0x0D; // HCI OCF = 0D 01099 hcibuf[1] = 0x01 << 2; // HCI OGF = 1 01100 hcibuf[2] = 0x17; // parameter length 23 01101 hcibuf[3] = disc_bdaddr[0]; // 6 octet bdaddr 01102 hcibuf[4] = disc_bdaddr[1]; 01103 hcibuf[5] = disc_bdaddr[2]; 01104 hcibuf[6] = disc_bdaddr[3]; 01105 hcibuf[7] = disc_bdaddr[4]; 01106 hcibuf[8] = disc_bdaddr[5]; 01107 if(pairWithWii) { 01108 hcibuf[9] = 6; // Pin length is the length of the Bluetooth address 01109 if(pairWiiUsingSync) { 01110 #ifdef DEBUG_USB_HOST 01111 Notify(PSTR("\r\nPairing with Wii controller via SYNC"), 0x80); 01112 #endif 01113 for(uint8_t i = 0; i < 6; i++) 01114 hcibuf[10 + i] = my_bdaddr[i]; // The pin is the Bluetooth dongles Bluetooth address backwards 01115 } else { 01116 for(uint8_t i = 0; i < 6; i++) 01117 hcibuf[10 + i] = disc_bdaddr[i]; // The pin is the Wiimote's Bluetooth address backwards 01118 } 01119 for(uint8_t i = 16; i < 26; i++) 01120 hcibuf[i] = 0x00; // The rest should be 0 01121 } else { 01122 hcibuf[9] = strlen(btdPin); // Length of pin 01123 uint8_t i; 01124 for(i = 0; i < strlen(btdPin); i++) // The maximum size of the pin is 16 01125 hcibuf[i + 10] = btdPin[i]; 01126 for(; i < 16; i++) 01127 hcibuf[i + 10] = 0x00; // The rest should be 0 01128 } 01129 01130 HCI_Command(hcibuf, 26); 01131 } 01132 01133 void BTD::hci_pin_code_negative_request_reply() { 01134 hcibuf[0] = 0x0E; // HCI OCF = 0E 01135 hcibuf[1] = 0x01 << 2; // HCI OGF = 1 01136 hcibuf[2] = 0x06; // parameter length 6 01137 hcibuf[3] = disc_bdaddr[0]; // 6 octet bdaddr 01138 hcibuf[4] = disc_bdaddr[1]; 01139 hcibuf[5] = disc_bdaddr[2]; 01140 hcibuf[6] = disc_bdaddr[3]; 01141 hcibuf[7] = disc_bdaddr[4]; 01142 hcibuf[8] = disc_bdaddr[5]; 01143 01144 HCI_Command(hcibuf, 9); 01145 } 01146 01147 void BTD::hci_link_key_request_negative_reply() { 01148 hcibuf[0] = 0x0C; // HCI OCF = 0C 01149 hcibuf[1] = 0x01 << 2; // HCI OGF = 1 01150 hcibuf[2] = 0x06; // parameter length 6 01151 hcibuf[3] = disc_bdaddr[0]; // 6 octet bdaddr 01152 hcibuf[4] = disc_bdaddr[1]; 01153 hcibuf[5] = disc_bdaddr[2]; 01154 hcibuf[6] = disc_bdaddr[3]; 01155 hcibuf[7] = disc_bdaddr[4]; 01156 hcibuf[8] = disc_bdaddr[5]; 01157 01158 HCI_Command(hcibuf, 9); 01159 } 01160 01161 void BTD::hci_authentication_request() { 01162 hcibuf[0] = 0x11; // HCI OCF = 11 01163 hcibuf[1] = 0x01 << 2; // HCI OGF = 1 01164 hcibuf[2] = 0x02; // parameter length = 2 01165 hcibuf[3] = (uint8_t)(hci_handle & 0xFF); //connection handle - low byte 01166 hcibuf[4] = (uint8_t)((hci_handle >> 8) & 0x0F); //connection handle - high byte 01167 01168 HCI_Command(hcibuf, 5); 01169 } 01170 01171 void BTD::hci_disconnect(uint16_t handle) { // This is called by the different services 01172 hci_clear_flag(HCI_FLAG_DISCONNECT_COMPLETE); 01173 hcibuf[0] = 0x06; // HCI OCF = 6 01174 hcibuf[1] = 0x01 << 2; // HCI OGF = 1 01175 hcibuf[2] = 0x03; // parameter length = 3 01176 hcibuf[3] = (uint8_t)(handle & 0xFF); //connection handle - low byte 01177 hcibuf[4] = (uint8_t)((handle >> 8) & 0x0F); //connection handle - high byte 01178 hcibuf[5] = 0x13; // reason 01179 01180 HCI_Command(hcibuf, 6); 01181 } 01182 01183 void BTD::hci_write_class_of_device() { // See http://bluetooth-pentest.narod.ru/software/bluetooth_class_of_device-service_generator.html 01184 hcibuf[0] = 0x24; // HCI OCF = 24 01185 hcibuf[1] = 0x03 << 2; // HCI OGF = 3 01186 hcibuf[2] = 0x03; // parameter length = 3 01187 hcibuf[3] = 0x04; // Robot 01188 hcibuf[4] = 0x08; // Toy 01189 hcibuf[5] = 0x00; 01190 01191 HCI_Command(hcibuf, 6); 01192 } 01193 /******************************************************************* 01194 * * 01195 * HCI ACL Data Packet * 01196 * * 01197 * buf[0] buf[1] buf[2] buf[3] 01198 * 0 4 8 11 12 16 24 31 MSB 01199 * .-+-+-+-+-+-+-+-|-+-+-+-|-+-|-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-. 01200 * | HCI Handle |PB |BC | Data Total Length | HCI ACL Data Packet 01201 * .-+-+-+-+-+-+-+-|-+-+-+-|-+-|-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-. 01202 * 01203 * buf[4] buf[5] buf[6] buf[7] 01204 * 0 8 16 31 MSB 01205 * .-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-. 01206 * | Length | Channel ID | Basic L2CAP header 01207 * .-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-. 01208 * 01209 * buf[8] buf[9] buf[10] buf[11] 01210 * 0 8 16 31 MSB 01211 * .-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-. 01212 * | Code | Identifier | Length | Control frame (C-frame) 01213 * .-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-. (signaling packet format) 01214 */ 01215 /************************************************************/ 01216 /* L2CAP Commands */ 01217 01218 /************************************************************/ 01219 void BTD::L2CAP_Command(uint16_t handle, uint8_t* data, uint8_t nbytes, uint8_t channelLow, uint8_t channelHigh) { 01220 uint8_t buf[8 + nbytes]; 01221 buf[0] = (uint8_t)(handle & 0xff); // HCI handle with PB,BC flag 01222 buf[1] = (uint8_t)(((handle >> 8) & 0x0f) | 0x20); 01223 buf[2] = (uint8_t)((4 + nbytes) & 0xff); // HCI ACL total data length 01224 buf[3] = (uint8_t)((4 + nbytes) >> 8); 01225 buf[4] = (uint8_t)(nbytes & 0xff); // L2CAP header: Length 01226 buf[5] = (uint8_t)(nbytes >> 8); 01227 buf[6] = channelLow; 01228 buf[7] = channelHigh; 01229 01230 for(uint16_t i = 0; i < nbytes; i++) // L2CAP C-frame 01231 buf[8 + i] = data[i]; 01232 01233 uint8_t rcode = pUsb->outTransfer(bAddress, epInfo[ BTD_DATAOUT_PIPE ].epAddr, (8 + nbytes), buf); 01234 if(rcode) { 01235 wait_ms(100); // This small delay prevents it from overflowing if it fails 01236 #ifdef DEBUG_USB_HOST 01237 Notify(PSTR("\r\nError sending L2CAP message: 0x"), 0x80); 01238 D_PrintHex<uint8_t > (rcode, 0x80); 01239 Notify(PSTR(" - Channel ID: "), 0x80); 01240 D_PrintHex<uint8_t > (channelHigh, 0x80); 01241 Notify(PSTR(" "), 0x80); 01242 D_PrintHex<uint8_t > (channelLow, 0x80); 01243 #endif 01244 } 01245 } 01246 01247 void BTD::l2cap_connection_request(uint16_t handle, uint8_t rxid, uint8_t* scid, uint16_t psm) { 01248 l2capoutbuf[0] = L2CAP_CMD_CONNECTION_REQUEST; // Code 01249 l2capoutbuf[1] = rxid; // Identifier 01250 l2capoutbuf[2] = 0x04; // Length 01251 l2capoutbuf[3] = 0x00; 01252 l2capoutbuf[4] = (uint8_t)(psm & 0xff); // PSM 01253 l2capoutbuf[5] = (uint8_t)(psm >> 8); 01254 l2capoutbuf[6] = scid[0]; // Source CID 01255 l2capoutbuf[7] = scid[1]; 01256 01257 L2CAP_Command(handle, l2capoutbuf, 8); 01258 } 01259 01260 void BTD::l2cap_connection_response(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid, uint8_t result) { 01261 l2capoutbuf[0] = L2CAP_CMD_CONNECTION_RESPONSE; // Code 01262 l2capoutbuf[1] = rxid; // Identifier 01263 l2capoutbuf[2] = 0x08; // Length 01264 l2capoutbuf[3] = 0x00; 01265 l2capoutbuf[4] = dcid[0]; // Destination CID 01266 l2capoutbuf[5] = dcid[1]; 01267 l2capoutbuf[6] = scid[0]; // Source CID 01268 l2capoutbuf[7] = scid[1]; 01269 l2capoutbuf[8] = result; // Result: Pending or Success 01270 l2capoutbuf[9] = 0x00; 01271 l2capoutbuf[10] = 0x00; // No further information 01272 l2capoutbuf[11] = 0x00; 01273 01274 L2CAP_Command(handle, l2capoutbuf, 12); 01275 } 01276 01277 void BTD::l2cap_config_request(uint16_t handle, uint8_t rxid, uint8_t* dcid) { 01278 l2capoutbuf[0] = L2CAP_CMD_CONFIG_REQUEST; // Code 01279 l2capoutbuf[1] = rxid; // Identifier 01280 l2capoutbuf[2] = 0x08; // Length 01281 l2capoutbuf[3] = 0x00; 01282 l2capoutbuf[4] = dcid[0]; // Destination CID 01283 l2capoutbuf[5] = dcid[1]; 01284 l2capoutbuf[6] = 0x00; // Flags 01285 l2capoutbuf[7] = 0x00; 01286 l2capoutbuf[8] = 0x01; // Config Opt: type = MTU (Maximum Transmission Unit) - Hint 01287 l2capoutbuf[9] = 0x02; // Config Opt: length 01288 l2capoutbuf[10] = 0xFF; // MTU 01289 l2capoutbuf[11] = 0xFF; 01290 01291 L2CAP_Command(handle, l2capoutbuf, 12); 01292 } 01293 01294 void BTD::l2cap_config_response(uint16_t handle, uint8_t rxid, uint8_t* scid) { 01295 l2capoutbuf[0] = L2CAP_CMD_CONFIG_RESPONSE; // Code 01296 l2capoutbuf[1] = rxid; // Identifier 01297 l2capoutbuf[2] = 0x0A; // Length 01298 l2capoutbuf[3] = 0x00; 01299 l2capoutbuf[4] = scid[0]; // Source CID 01300 l2capoutbuf[5] = scid[1]; 01301 l2capoutbuf[6] = 0x00; // Flag 01302 l2capoutbuf[7] = 0x00; 01303 l2capoutbuf[8] = 0x00; // Result 01304 l2capoutbuf[9] = 0x00; 01305 l2capoutbuf[10] = 0x01; // Config 01306 l2capoutbuf[11] = 0x02; 01307 l2capoutbuf[12] = 0xA0; 01308 l2capoutbuf[13] = 0x02; 01309 01310 L2CAP_Command(handle, l2capoutbuf, 14); 01311 } 01312 01313 void BTD::l2cap_disconnection_request(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid) { 01314 l2capoutbuf[0] = L2CAP_CMD_DISCONNECT_REQUEST; // Code 01315 l2capoutbuf[1] = rxid; // Identifier 01316 l2capoutbuf[2] = 0x04; // Length 01317 l2capoutbuf[3] = 0x00; 01318 l2capoutbuf[4] = dcid[0]; 01319 l2capoutbuf[5] = dcid[1]; 01320 l2capoutbuf[6] = scid[0]; 01321 l2capoutbuf[7] = scid[1]; 01322 01323 L2CAP_Command(handle, l2capoutbuf, 8); 01324 } 01325 01326 void BTD::l2cap_disconnection_response(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid) { 01327 l2capoutbuf[0] = L2CAP_CMD_DISCONNECT_RESPONSE; // Code 01328 l2capoutbuf[1] = rxid; // Identifier 01329 l2capoutbuf[2] = 0x04; // Length 01330 l2capoutbuf[3] = 0x00; 01331 l2capoutbuf[4] = dcid[0]; 01332 l2capoutbuf[5] = dcid[1]; 01333 l2capoutbuf[6] = scid[0]; 01334 l2capoutbuf[7] = scid[1]; 01335 01336 L2CAP_Command(handle, l2capoutbuf, 8); 01337 } 01338 01339 void BTD::l2cap_information_response(uint16_t handle, uint8_t rxid, uint8_t infoTypeLow, uint8_t infoTypeHigh) { 01340 l2capoutbuf[0] = L2CAP_CMD_INFORMATION_RESPONSE; // Code 01341 l2capoutbuf[1] = rxid; // Identifier 01342 l2capoutbuf[2] = 0x08; // Length 01343 l2capoutbuf[3] = 0x00; 01344 l2capoutbuf[4] = infoTypeLow; 01345 l2capoutbuf[5] = infoTypeHigh; 01346 l2capoutbuf[6] = 0x00; // Result = success 01347 l2capoutbuf[7] = 0x00; // Result = success 01348 l2capoutbuf[8] = 0x00; 01349 l2capoutbuf[9] = 0x00; 01350 l2capoutbuf[10] = 0x00; 01351 l2capoutbuf[11] = 0x00; 01352 01353 L2CAP_Command(handle, l2capoutbuf, 12); 01354 } 01355 01356 /* PS3 Commands - only set Bluetooth address is implemented in this library */ 01357 void BTD::setBdaddr(uint8_t* bdaddr) { 01358 /* Set the internal Bluetooth address */ 01359 uint8_t buf[8]; 01360 buf[0] = 0x01; 01361 buf[1] = 0x00; 01362 01363 for(uint8_t i = 0; i < 6; i++) 01364 buf[i + 2] = bdaddr[5 - i]; // Copy into buffer, has to be written reversed, so it is MSB first 01365 01366 // bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0xF5), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data 01367 pUsb->ctrlReq(bAddress, epInfo[BTD_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL); 01368 } 01369 01370 void BTD::setMoveBdaddr(uint8_t* bdaddr) { 01371 /* Set the internal Bluetooth address */ 01372 uint8_t buf[11]; 01373 buf[0] = 0x05; 01374 buf[7] = 0x10; 01375 buf[8] = 0x01; 01376 buf[9] = 0x02; 01377 buf[10] = 0x12; 01378 01379 for(uint8_t i = 0; i < 6; i++) 01380 buf[i + 1] = bdaddr[i]; 01381 01382 // bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x05), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data 01383 pUsb->ctrlReq(bAddress, epInfo[BTD_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x05, 0x03, 0x00, 11, 11, buf, NULL); 01384 }
Generated on Tue Jul 12 2022 18:12:04 by
