1 /* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
3 This software may be distributed and modified under the terms of the GNU
4 General Public License version 2 (GPL2) as published by the Free Software
5 Foundation and appearing in the file GPL2.TXT included in the packaging of
6 this file. Please note that GPL2 Section 2[b] requires that all works based
7 on this software must also be made publicly available under the terms of
13 Kristian Lauszus, TKJ Electronics
14 Web : http://www.tkjelectronics.com
15 e-mail : kristianl@tkjelectronics.com
19 // To enable serial debugging see "settings.h"
20 //#define EXTRADEBUG // Uncomment to get even more debugging data
22 const uint8_t BTD::BTD_CONTROL_PIPE
= 0;
23 const uint8_t BTD::BTD_EVENT_PIPE
= 1;
24 const uint8_t BTD::BTD_DATAIN_PIPE
= 2;
25 const uint8_t BTD::BTD_DATAOUT_PIPE
= 3;
30 connectToHIDDevice(false),
31 pairWithHIDDevice(false),
32 pUsb(p
), // Pointer to USB class instance - mandatory
33 bAddress(0), // Device address - mandatory
34 bNumEP(1), // If config descriptor needs to be parsed
35 qNextPollTime(0), // Reset NextPollTime
37 bPollEnable(false) // Don't start polling before dongle is connected
39 for(uint8_t i
= 0; i
< BTD_NUM_SERVICES
; i
++)
42 Initialize(); // Set all variables, endpoint structs etc. to default values
44 if(pUsb
) // Register in USB subsystem
45 pUsb
->RegisterDeviceClass(this); // Set devConfig[] entry
48 uint8_t BTD::ConfigureDevice(uint8_t parent
, uint8_t port
, bool lowspeed
) {
49 const uint8_t constBufSize
= sizeof (USB_DEVICE_DESCRIPTOR
);
50 uint8_t buf
[constBufSize
];
51 USB_DEVICE_DESCRIPTOR
* udd
= reinterpret_cast<USB_DEVICE_DESCRIPTOR
*>(buf
);
54 EpInfo
*oldep_ptr
= NULL
;
56 Initialize(); // Set all variables, endpoint structs etc. to default values
58 AddressPool
&addrPool
= pUsb
->GetAddressPool(); // Get memory address of USB device address pool
60 Notify(PSTR("\r\nBTD ConfigureDevice"), 0x80);
63 if(bAddress
) { // Check if address has already been assigned to an instance
65 Notify(PSTR("\r\nAddress in use"), 0x80);
67 return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE
;
70 p
= addrPool
.GetUsbDevicePtr(0); // Get pointer to pseudo device with address 0 assigned
73 Notify(PSTR("\r\nAddress not found"), 0x80);
75 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL
;
80 Notify(PSTR("\r\nepinfo is null"), 0x80);
82 return USB_ERROR_EPINFO_IS_NULL
;
85 oldep_ptr
= p
->epinfo
; // Save old pointer to EP_RECORD of address 0
86 p
->epinfo
= epInfo
; // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
87 p
->lowspeed
= lowspeed
;
88 rcode
= pUsb
->getDevDescr(0, 0, constBufSize
, (uint8_t*)buf
); // Get device descriptor - addr, ep, nbytes, data
90 p
->epinfo
= oldep_ptr
; // Restore p->epinfo
95 bAddress
= addrPool
.AllocAddress(parent
, false, port
); // Allocate new address according to device class
99 Notify(PSTR("\r\nOut of address space"), 0x80);
101 return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL
;
104 epInfo
[0].maxPktSize
= udd
->bMaxPacketSize0
; // Extract Max Packet Size from device descriptor
105 epInfo
[1].epAddr
= udd
->bNumConfigurations
; // Steal and abuse from epInfo structure to save memory
108 PID
= udd
->idProduct
;
110 return USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET
;
113 #ifdef DEBUG_USB_HOST
114 NotifyFailGetDevDescr(rcode
);
117 rcode
= USB_ERROR_FailGetDevDescr
;
122 uint8_t BTD::Init(uint8_t parent
, uint8_t port
, bool lowspeed
) {
124 uint8_t num_of_conf
= epInfo
[1].epAddr
; // Number of configurations
125 epInfo
[1].epAddr
= 0;
127 AddressPool
&addrPool
= pUsb
->GetAddressPool();
129 Notify(PSTR("\r\nBTD Init"), 0x80);
131 UsbDevice
*p
= addrPool
.GetUsbDevicePtr(bAddress
); // Get pointer to assigned address record
134 #ifdef DEBUG_USB_HOST
135 Notify(PSTR("\r\nAddress not found"), 0x80);
137 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL
;
140 delay(300); // Assign new address to the device
142 rcode
= pUsb
->setAddr(0, 0, bAddress
); // Assign new address to the device
144 #ifdef DEBUG_USB_HOST
145 Notify(PSTR("\r\nsetAddr: "), 0x80);
146 D_PrintHex
<uint8_t > (rcode
, 0x80);
152 Notify(PSTR("\r\nAddr: "), 0x80);
153 D_PrintHex
<uint8_t > (bAddress
, 0x80);
158 p
= addrPool
.GetUsbDevicePtr(bAddress
); // Get pointer to assigned address record
160 #ifdef DEBUG_USB_HOST
161 Notify(PSTR("\r\nAddress not found"), 0x80);
163 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL
;
166 p
->lowspeed
= lowspeed
;
168 rcode
= pUsb
->setEpInfoEntry(bAddress
, 1, epInfo
); // Assign epInfo to epinfo pointer - only EP0 is known
170 goto FailSetDevTblEntry
;
172 if(VID
== PS3_VID
&& (PID
== PS3_PID
|| PID
== PS3NAVIGATION_PID
|| PID
== PS3MOVE_PID
)) {
174 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
176 goto FailSetConfDescr
;
178 #ifdef DEBUG_USB_HOST
179 if(PID
== PS3_PID
|| PID
== PS3NAVIGATION_PID
) {
181 Notify(PSTR("\r\nDualshock 3 Controller Connected"), 0x80);
182 else // It must be a navigation controller
183 Notify(PSTR("\r\nNavigation Controller Connected"), 0x80);
184 } else // It must be a Motion controller
185 Notify(PSTR("\r\nMotion Controller Connected"), 0x80);
188 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) {
189 #ifdef DEBUG_USB_HOST
190 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);
193 if(PID
== PS3_PID
|| PID
== PS3NAVIGATION_PID
)
194 setBdaddr(my_bdaddr
); // Set internal Bluetooth address
196 setMoveBdaddr(my_bdaddr
); // Set internal Bluetooth address
197 #ifdef DEBUG_USB_HOST
198 Notify(PSTR("\r\nBluetooth Address was set to: "), 0x80);
199 for(int8_t i
= 5; i
> 0; i
--) {
200 D_PrintHex
<uint8_t > (my_bdaddr
[i
], 0x80);
201 Notify(PSTR(":"), 0x80);
203 D_PrintHex
<uint8_t > (my_bdaddr
[0], 0x80);
207 pUsb
->setConf(bAddress
, epInfo
[ BTD_CONTROL_PIPE
].epAddr
, 0); // Reset configuration value
208 pUsb
->setAddr(bAddress
, 0, 0); // Reset address
209 Release(); // Release device
210 return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED
; // Return
212 // Check if attached device is a Bluetooth dongle and fill endpoint data structure
213 // First interface in the configuration must have Bluetooth assigned Class/Subclass/Protocol
214 // And 3 endpoints - interrupt-IN, bulk-IN, bulk-OUT, not necessarily in this order
215 for(uint8_t i
= 0; i
< num_of_conf
; i
++) {
216 if(VID
== IOGEAR_GBU521_VID
&& PID
== IOGEAR_GBU521_PID
) {
217 ConfigDescParser
<USB_CLASS_VENDOR_SPECIFIC
, WI_SUBCLASS_RF
, WI_PROTOCOL_BT
, CP_MASK_COMPARE_ALL
> confDescrParser(this); // Needed for the IOGEAR GBU521
218 rcode
= pUsb
->getConfDescr(bAddress
, 0, i
, &confDescrParser
);
220 ConfigDescParser
<USB_CLASS_WIRELESS_CTRL
, WI_SUBCLASS_RF
, WI_PROTOCOL_BT
, CP_MASK_COMPARE_ALL
> confDescrParser(this);
221 rcode
= pUsb
->getConfDescr(bAddress
, 0, i
, &confDescrParser
);
223 if(rcode
) // Check error code
224 goto FailGetConfDescr
;
225 if(bNumEP
>= BTD_MAX_ENDPOINTS
) // All endpoints extracted
229 if(bNumEP
< BTD_MAX_ENDPOINTS
)
230 goto FailUnknownDevice
;
232 // Assign epInfo to epinfo pointer - this time all 3 endpoins
233 rcode
= pUsb
->setEpInfoEntry(bAddress
, bNumEP
, epInfo
);
235 goto FailSetDevTblEntry
;
237 // Set Configuration Value
238 rcode
= pUsb
->setConf(bAddress
, epInfo
[ BTD_CONTROL_PIPE
].epAddr
, bConfNum
);
240 goto FailSetConfDescr
;
242 hci_num_reset_loops
= 100; // only loop 100 times before trying to send the hci reset command
244 hci_state
= HCI_INIT_STATE
;
245 watingForConnection
= false;
248 #ifdef DEBUG_USB_HOST
249 Notify(PSTR("\r\nBluetooth Dongle Initialized"), 0x80);
252 return 0; // Successful configuration
254 /* Diagnostic messages */
256 #ifdef DEBUG_USB_HOST
257 NotifyFailSetDevTblEntry();
262 #ifdef DEBUG_USB_HOST
263 NotifyFailGetConfDescr();
268 #ifdef DEBUG_USB_HOST
269 NotifyFailSetConfDescr();
274 #ifdef DEBUG_USB_HOST
275 NotifyFailUnknownDevice(VID
, PID
);
277 pUsb
->setAddr(bAddress
, 0, 0); // Reset address
278 rcode
= USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED
;
280 #ifdef DEBUG_USB_HOST
281 Notify(PSTR("\r\nBTD Init Failed, error code: "), 0x80);
288 void BTD::Initialize() {
290 for(i
= 0; i
< BTD_MAX_ENDPOINTS
; i
++) {
291 epInfo
[i
].epAddr
= 0;
292 epInfo
[i
].maxPktSize
= (i
) ? 0 : 8;
293 epInfo
[i
].epAttribs
= 0;
294 epInfo
[i
].bmNakPower
= (i
) ? USB_NAK_NOWAIT
: USB_NAK_MAX_POWER
;
296 for(i
= 0; i
< BTD_NUM_SERVICES
; i
++) {
298 btService
[i
]->Reset(); // Reset all Bluetooth services
301 connectToWii
= false;
303 connectToHIDDevice
= false;
304 incomingHIDDevice
= false;
306 bAddress
= 0; // Clear device address
307 bNumEP
= 1; // Must have to be reset to 1
308 qNextPollTime
= 0; // Reset next poll time
310 bPollEnable
= false; // Don't start polling before dongle is connected
313 /* Extracts interrupt-IN, bulk-IN, bulk-OUT endpoint information from config descriptor */
314 void BTD::EndpointXtract(uint8_t conf
, uint8_t iface
, uint8_t alt
, uint8_t proto
, const USB_ENDPOINT_DESCRIPTOR
*pep
) {
315 //ErrorMessage<uint8_t>(PSTR("Conf.Val"),conf);
316 //ErrorMessage<uint8_t>(PSTR("Iface Num"),iface);
317 //ErrorMessage<uint8_t>(PSTR("Alt.Set"),alt);
319 if(alt
) // Wrong interface - by BT spec, no alt setting
325 if((pep
->bmAttributes
& 0x03) == 3 && (pep
->bEndpointAddress
& 0x80) == 0x80) { // Interrupt In endpoint found
326 index
= BTD_EVENT_PIPE
;
327 epInfo
[index
].bmNakPower
= USB_NAK_NOWAIT
;
329 if((pep
->bmAttributes
& 0x02) == 2) // Bulk endpoint found
330 index
= ((pep
->bEndpointAddress
& 0x80) == 0x80) ? BTD_DATAIN_PIPE
: BTD_DATAOUT_PIPE
;
335 // Fill the rest of endpoint data structure
336 epInfo
[index
].epAddr
= (pep
->bEndpointAddress
& 0x0F);
337 epInfo
[index
].maxPktSize
= (uint8_t)pep
->wMaxPacketSize
;
339 PrintEndpointDescriptor(pep
);
341 if(pollInterval
< pep
->bInterval
) // Set the polling interval as the largest polling interval obtained from endpoints
342 pollInterval
= pep
->bInterval
;
346 void BTD::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR
* ep_ptr
) {
348 Notify(PSTR("\r\nEndpoint descriptor:"), 0x80);
349 Notify(PSTR("\r\nLength:\t\t"), 0x80);
350 D_PrintHex
<uint8_t > (ep_ptr
->bLength
, 0x80);
351 Notify(PSTR("\r\nType:\t\t"), 0x80);
352 D_PrintHex
<uint8_t > (ep_ptr
->bDescriptorType
, 0x80);
353 Notify(PSTR("\r\nAddress:\t"), 0x80);
354 D_PrintHex
<uint8_t > (ep_ptr
->bEndpointAddress
, 0x80);
355 Notify(PSTR("\r\nAttributes:\t"), 0x80);
356 D_PrintHex
<uint8_t > (ep_ptr
->bmAttributes
, 0x80);
357 Notify(PSTR("\r\nMaxPktSize:\t"), 0x80);
358 D_PrintHex
<uint16_t > (ep_ptr
->wMaxPacketSize
, 0x80);
359 Notify(PSTR("\r\nPoll Intrv:\t"), 0x80);
360 D_PrintHex
<uint8_t > (ep_ptr
->bInterval
, 0x80);
364 /* Performs a cleanup after failed Init() attempt */
365 uint8_t BTD::Release() {
366 Initialize(); // Set all variables, endpoint structs etc. to default values
367 pUsb
->GetAddressPool().FreeAddress(bAddress
);
371 uint8_t BTD::Poll() {
374 if((long)(millis() - qNextPollTime
) >= 0L) { // Don't poll if shorter than polling interval
375 qNextPollTime
= millis() + pollInterval
; // Set new poll time
376 HCI_event_task(); // Poll the HCI event pipe
377 HCI_task(); // HCI state machine
378 ACL_event_task(); // Poll the ACL input pipe too
383 void BTD::disconnect() {
384 for(uint8_t i
= 0; i
< BTD_NUM_SERVICES
; i
++)
386 btService
[i
]->disconnect();
389 void BTD::HCI_event_task() {
390 uint16_t length
= BULK_MAXPKTSIZE
; // Request more than 16 bytes anyway, the inTransfer routine will take care of this
391 uint8_t rcode
= pUsb
->inTransfer(bAddress
, epInfo
[ BTD_EVENT_PIPE
].epAddr
, &length
, hcibuf
); // Input on endpoint 1
393 if(!rcode
|| rcode
== hrNAK
) { // Check for errors
394 switch(hcibuf
[0]) { // Switch on event type
395 case EV_COMMAND_COMPLETE
:
396 if(!hcibuf
[5]) { // Check if command succeeded
397 hci_set_flag(HCI_FLAG_CMD_COMPLETE
); // Set command complete flag
398 if((hcibuf
[3] == 0x01) && (hcibuf
[4] == 0x10)) { // Parameters from read local version information
399 hci_version
= hcibuf
[6]; // Used to check if it supports 2.0+EDR - see http://www.bluetooth.org/Technical/AssignedNumbers/hci.htm
400 hci_set_flag(HCI_FLAG_READ_VERSION
);
401 } else if((hcibuf
[3] == 0x09) && (hcibuf
[4] == 0x10)) { // Parameters from read local bluetooth address
402 for(uint8_t i
= 0; i
< 6; i
++)
403 my_bdaddr
[i
] = hcibuf
[6 + i
];
404 hci_set_flag(HCI_FLAG_READ_BDADDR
);
409 case EV_COMMAND_STATUS
:
410 if(hcibuf
[2]) { // Show status on serial if not OK
411 #ifdef DEBUG_USB_HOST
412 Notify(PSTR("\r\nHCI Command Failed: "), 0x80);
413 D_PrintHex
<uint8_t > (hcibuf
[2], 0x80);
418 case EV_INQUIRY_COMPLETE
:
419 if(inquiry_counter
>= 5 && (pairWithWii
|| pairWithHIDDevice
)) {
421 #ifdef DEBUG_USB_HOST
423 Notify(PSTR("\r\nCouldn't find Wiimote"), 0x80);
425 Notify(PSTR("\r\nCouldn't find HID device"), 0x80);
427 connectToWii
= false;
429 connectToHIDDevice
= false;
430 pairWithHIDDevice
= false;
431 hci_state
= HCI_SCANNING_STATE
;
436 case EV_INQUIRY_RESULT
:
437 if(hcibuf
[2]) { // Check that there is more than zero responses
439 Notify(PSTR("\r\nNumber of responses: "), 0x80);
440 Notify(hcibuf
[2], 0x80);
442 for(uint8_t i
= 0; i
< hcibuf
[2]; i
++) {
443 uint8_t offset
= 8 * hcibuf
[2] + 3 * i
;
445 for(uint8_t j
= 0; j
< 3; j
++)
446 classOfDevice
[j
] = hcibuf
[j
+ 4 + offset
];
449 Notify(PSTR("\r\nClass of device: "), 0x80);
450 D_PrintHex
<uint8_t > (classOfDevice
[2], 0x80);
451 Notify(PSTR(" "), 0x80);
452 D_PrintHex
<uint8_t > (classOfDevice
[1], 0x80);
453 Notify(PSTR(" "), 0x80);
454 D_PrintHex
<uint8_t > (classOfDevice
[0], 0x80);
457 if(pairWithWii
&& classOfDevice
[2] == 0x00 && (classOfDevice
[1] & 0x05) && (classOfDevice
[0] & 0x0C)) { // See http://wiibrew.org/wiki/Wiimote#SDP_information
458 checkRemoteName
= true; // Check remote name to distinguish between the different controllers
460 for(uint8_t j
= 0; j
< 6; j
++)
461 disc_bdaddr
[j
] = hcibuf
[j
+ 3 + 6 * i
];
463 hci_set_flag(HCI_FLAG_DEVICE_FOUND
);
465 } 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
466 #ifdef DEBUG_USB_HOST
467 if(classOfDevice
[0] & 0x80)
468 Notify(PSTR("\r\nMouse found"), 0x80);
469 if(classOfDevice
[0] & 0x40)
470 Notify(PSTR("\r\nKeyboard found"), 0x80);
471 if(classOfDevice
[0] & 0x08)
472 Notify(PSTR("\r\nGamepad found"), 0x80);
475 for(uint8_t j
= 0; j
< 6; j
++)
476 disc_bdaddr
[j
] = hcibuf
[j
+ 3 + 6 * i
];
478 hci_set_flag(HCI_FLAG_DEVICE_FOUND
);
485 case EV_CONNECT_COMPLETE
:
486 hci_set_flag(HCI_FLAG_CONNECT_EVENT
);
487 if(!hcibuf
[2]) { // Check if connected OK
489 Notify(PSTR("\r\nConnection established"), 0x80);
491 hci_handle
= hcibuf
[3] | ((hcibuf
[4] & 0x0F) << 8); // Store the handle for the ACL connection
492 hci_set_flag(HCI_FLAG_CONNECT_COMPLETE
); // Set connection complete flag
494 hci_state
= HCI_CHECK_DEVICE_SERVICE
;
495 #ifdef DEBUG_USB_HOST
496 Notify(PSTR("\r\nConnection Failed: "), 0x80);
497 D_PrintHex
<uint8_t > (hcibuf
[2], 0x80);
502 case EV_DISCONNECT_COMPLETE
:
503 if(!hcibuf
[2]) { // Check if disconnected OK
504 hci_set_flag(HCI_FLAG_DISCONNECT_COMPLETE
); // Set disconnect command complete flag
505 hci_clear_flag(HCI_FLAG_CONNECT_COMPLETE
); // Clear connection complete flag
509 case EV_REMOTE_NAME_COMPLETE
:
510 if(!hcibuf
[2]) { // Check if reading is OK
511 for(uint8_t i
= 0; i
< min(sizeof (remote_name
), sizeof (hcibuf
) - 9); i
++) {
512 remote_name
[i
] = hcibuf
[9 + i
];
513 if(remote_name
[i
] == '\0') // End of string
516 // TODO: Altid sæt '\0' i remote name!
517 hci_set_flag(HCI_FLAG_REMOTE_NAME_COMPLETE
);
521 case EV_INCOMING_CONNECT
:
522 for(uint8_t i
= 0; i
< 6; i
++)
523 disc_bdaddr
[i
] = hcibuf
[i
+ 2];
525 for(uint8_t i
= 0; i
< 3; i
++)
526 classOfDevice
[i
] = hcibuf
[i
+ 8];
528 if((classOfDevice
[1] & 0x05) && (classOfDevice
[0] & 0xC8)) { // Check if it is a mouse, keyboard or a gamepad
529 #ifdef DEBUG_USB_HOST
530 if(classOfDevice
[0] & 0x80)
531 Notify(PSTR("\r\nMouse is connecting"), 0x80);
532 if(classOfDevice
[0] & 0x40)
533 Notify(PSTR("\r\nKeyboard is connecting"), 0x80);
534 if(classOfDevice
[0] & 0x08)
535 Notify(PSTR("\r\nGamepad is connecting"), 0x80);
537 incomingHIDDevice
= true;
541 Notify(PSTR("\r\nClass of device: "), 0x80);
542 D_PrintHex
<uint8_t > (classOfDevice
[2], 0x80);
543 Notify(PSTR(" "), 0x80);
544 D_PrintHex
<uint8_t > (classOfDevice
[1], 0x80);
545 Notify(PSTR(" "), 0x80);
546 D_PrintHex
<uint8_t > (classOfDevice
[0], 0x80);
548 hci_set_flag(HCI_FLAG_INCOMING_REQUEST
);
551 case EV_PIN_CODE_REQUEST
:
553 #ifdef DEBUG_USB_HOST
554 Notify(PSTR("\r\nPairing with Wiimote"), 0x80);
556 hci_pin_code_request_reply();
557 } else if(btdPin
!= NULL
) {
558 #ifdef DEBUG_USB_HOST
559 Notify(PSTR("\r\nBluetooth pin is set too: "), 0x80);
560 NotifyStr(btdPin
, 0x80);
562 hci_pin_code_request_reply();
564 #ifdef DEBUG_USB_HOST
565 Notify(PSTR("\r\nNo pin was set"), 0x80);
567 hci_pin_code_negative_request_reply();
571 case EV_LINK_KEY_REQUEST
:
572 #ifdef DEBUG_USB_HOST
573 Notify(PSTR("\r\nReceived Key Request"), 0x80);
575 hci_link_key_request_negative_reply();
578 case EV_AUTHENTICATION_COMPLETE
:
579 if(pairWithWii
&& !connectToWii
) {
580 #ifdef DEBUG_USB_HOST
581 Notify(PSTR("\r\nPairing successful with Wiimote"), 0x80);
583 connectToWii
= true; // Used to indicate to the Wii service, that it should connect to this device
584 } else if(pairWithHIDDevice
&& !connectToHIDDevice
) {
585 #ifdef DEBUG_USB_HOST
586 Notify(PSTR("\r\nPairing successful with HID device"), 0x80);
588 connectToHIDDevice
= true; // Used to indicate to the BTHID service, that it should connect to this device
591 /* We will just ignore the following events */
592 case EV_NUM_COMPLETE_PKT
:
593 case EV_ROLE_CHANGED
:
594 case EV_PAGE_SCAN_REP_MODE
:
595 case EV_LOOPBACK_COMMAND
:
596 case EV_DATA_BUFFER_OVERFLOW
:
597 case EV_CHANGE_CONNECTION_LINK
:
598 case EV_MAX_SLOTS_CHANGE
:
599 case EV_QOS_SETUP_COMPLETE
:
600 case EV_LINK_KEY_NOTIFICATION
:
601 case EV_ENCRYPTION_CHANGE
:
602 case EV_READ_REMOTE_VERSION_INFORMATION_COMPLETE
:
606 if(hcibuf
[0] != 0x00) {
607 Notify(PSTR("\r\nUnmanaged HCI Event: "), 0x80);
608 D_PrintHex
<uint8_t > (hcibuf
[0], 0x80);
616 Notify(PSTR("\r\nHCI event error: "), 0x80);
617 D_PrintHex
<uint8_t > (rcode
, 0x80);
622 /* Poll Bluetooth and print result */
623 void BTD::HCI_task() {
627 if(hci_counter
> hci_num_reset_loops
) { // wait until we have looped x times to clear any old events
629 hci_state
= HCI_RESET_STATE
;
634 case HCI_RESET_STATE
:
636 if(hci_check_flag(HCI_FLAG_CMD_COMPLETE
)) {
638 #ifdef DEBUG_USB_HOST
639 Notify(PSTR("\r\nHCI Reset complete"), 0x80);
641 hci_state
= HCI_CLASS_STATE
;
642 hci_write_class_of_device();
643 } else if(hci_counter
> hci_num_reset_loops
) {
644 hci_num_reset_loops
*= 10;
645 if(hci_num_reset_loops
> 2000)
646 hci_num_reset_loops
= 2000;
647 #ifdef DEBUG_USB_HOST
648 Notify(PSTR("\r\nNo response to HCI Reset"), 0x80);
650 hci_state
= HCI_INIT_STATE
;
655 case HCI_CLASS_STATE
:
656 if(hci_check_flag(HCI_FLAG_CMD_COMPLETE
)) {
657 #ifdef DEBUG_USB_HOST
658 Notify(PSTR("\r\nWrite class of device"), 0x80);
660 hci_state
= HCI_BDADDR_STATE
;
665 case HCI_BDADDR_STATE
:
666 if(hci_check_flag(HCI_FLAG_READ_BDADDR
)) {
667 #ifdef DEBUG_USB_HOST
668 Notify(PSTR("\r\nLocal Bluetooth Address: "), 0x80);
669 for(int8_t i
= 5; i
> 0; i
--) {
670 D_PrintHex
<uint8_t > (my_bdaddr
[i
], 0x80);
671 Notify(PSTR(":"), 0x80);
673 D_PrintHex
<uint8_t > (my_bdaddr
[0], 0x80);
675 hci_read_local_version_information();
676 hci_state
= HCI_LOCAL_VERSION_STATE
;
680 case HCI_LOCAL_VERSION_STATE
: // The local version is used by the PS3BT class
681 if(hci_check_flag(HCI_FLAG_READ_VERSION
)) {
682 if(btdName
!= NULL
) {
683 hci_set_local_name(btdName
);
684 hci_state
= HCI_SET_NAME_STATE
;
686 hci_state
= HCI_CHECK_DEVICE_SERVICE
;
690 case HCI_SET_NAME_STATE
:
691 if(hci_check_flag(HCI_FLAG_CMD_COMPLETE
)) {
692 #ifdef DEBUG_USB_HOST
693 Notify(PSTR("\r\nThe name is set to: "), 0x80);
694 NotifyStr(btdName
, 0x80);
696 hci_state
= HCI_CHECK_DEVICE_SERVICE
;
700 case HCI_CHECK_DEVICE_SERVICE
:
701 if(pairWithHIDDevice
|| pairWithWii
) { // Check if it should try to connect to a Wiimote
702 #ifdef DEBUG_USB_HOST
704 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);
706 Notify(PSTR("\r\nPlease enable discovery of your device"), 0x80);
709 hci_state
= HCI_INQUIRY_STATE
;
711 hci_state
= HCI_SCANNING_STATE
; // Don't try to connect to a Wiimote
714 case HCI_INQUIRY_STATE
:
715 if(hci_check_flag(HCI_FLAG_DEVICE_FOUND
)) {
716 hci_inquiry_cancel(); // Stop inquiry
717 #ifdef DEBUG_USB_HOST
719 Notify(PSTR("\r\nWiimote found"), 0x80);
721 Notify(PSTR("\r\nHID device found"), 0x80);
723 Notify(PSTR("\r\nNow just create the instance like so:"), 0x80);
725 Notify(PSTR("\r\nWII Wii(&Btd);"), 0x80);
727 Notify(PSTR("\r\nBTHID bthid(&Btd);"), 0x80);
729 Notify(PSTR("\r\nAnd then press any button on the "), 0x80);
731 Notify(PSTR("Wiimote"), 0x80);
733 Notify(PSTR("device"), 0x80);
735 if(checkRemoteName
) {
736 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
737 hci_state
= HCI_REMOTE_NAME_STATE
;
739 hci_state
= HCI_CONNECT_DEVICE_STATE
;
743 case HCI_CONNECT_DEVICE_STATE
:
744 if(hci_check_flag(HCI_FLAG_CMD_COMPLETE
)) {
745 #ifdef DEBUG_USB_HOST
747 Notify(PSTR("\r\nConnecting to Wiimote"), 0x80);
749 Notify(PSTR("\r\nConnecting to HID device"), 0x80);
751 checkRemoteName
= false;
753 hci_state
= HCI_CONNECTED_DEVICE_STATE
;
757 case HCI_CONNECTED_DEVICE_STATE
:
758 if(hci_check_flag(HCI_FLAG_CONNECT_EVENT
)) {
759 if(hci_check_flag(HCI_FLAG_CONNECT_COMPLETE
)) {
760 #ifdef DEBUG_USB_HOST
762 Notify(PSTR("\r\nConnected to Wiimote"), 0x80);
764 Notify(PSTR("\r\nConnected to HID device"), 0x80);
766 hci_authentication_request(); // This will start the pairing with the Wiimote
767 hci_state
= HCI_SCANNING_STATE
;
769 #ifdef DEBUG_USB_HOST
770 Notify(PSTR("\r\nTrying to connect one more time..."), 0x80);
772 hci_connect(); // Try to connect one more time
777 case HCI_SCANNING_STATE
:
778 if(!connectToWii
&& !pairWithWii
&& !connectToHIDDevice
&& !pairWithHIDDevice
) {
779 #ifdef DEBUG_USB_HOST
780 Notify(PSTR("\r\nWait For Incoming Connection Request"), 0x80);
782 hci_write_scan_enable();
783 watingForConnection
= true;
784 hci_state
= HCI_CONNECT_IN_STATE
;
788 case HCI_CONNECT_IN_STATE
:
789 if(hci_check_flag(HCI_FLAG_INCOMING_REQUEST
)) {
790 watingForConnection
= false;
791 #ifdef DEBUG_USB_HOST
792 Notify(PSTR("\r\nIncoming Connection Request"), 0x80);
795 hci_state
= HCI_REMOTE_NAME_STATE
;
796 } else if(hci_check_flag(HCI_FLAG_DISCONNECT_COMPLETE
))
797 hci_state
= HCI_DISCONNECT_STATE
;
800 case HCI_REMOTE_NAME_STATE
:
801 if(hci_check_flag(HCI_FLAG_REMOTE_NAME_COMPLETE
)) {
802 #ifdef DEBUG_USB_HOST
803 Notify(PSTR("\r\nRemote Name: "), 0x80);
804 for(uint8_t i
= 0; i
< strlen(remote_name
); i
++)
805 Notifyc(remote_name
[i
], 0x80);
807 if(strncmp((const char*)remote_name
, "Nintendo", 8) == 0) {
809 motionPlusInside
= false;
810 wiiUProController
= false;
811 pairWiiUsingSync
= false;
812 #ifdef DEBUG_USB_HOST
813 Notify(PSTR("\r\nWiimote is connecting"), 0x80);
815 if(strncmp((const char*)remote_name
, "Nintendo RVL-CNT-01-TR", 22) == 0) {
816 #ifdef DEBUG_USB_HOST
817 Notify(PSTR(" with Motion Plus Inside"), 0x80);
819 motionPlusInside
= true;
820 } else if(strncmp((const char*)remote_name
, "Nintendo RVL-CNT-01-UC", 22) == 0) {
821 #ifdef DEBUG_USB_HOST
822 Notify(PSTR(" - Wii U Pro Controller"), 0x80);
824 wiiUProController
= motionPlusInside
= pairWiiUsingSync
= true;
825 } else if(strncmp((const char*)remote_name
, "Nintendo RVL-WBC-01", 19) == 0) {
826 #ifdef DEBUG_USB_HOST
827 Notify(PSTR(" - Wii Balance Board"), 0x80);
829 pairWiiUsingSync
= true;
832 if(classOfDevice
[2] == 0 && classOfDevice
[1] == 0x25 && classOfDevice
[0] == 0x08 && strncmp((const char*)remote_name
, "Wireless Controller", 19) == 0) {
833 #ifdef DEBUG_USB_HOST
834 Notify(PSTR("\r\nPS4 controller is connecting"), 0x80);
838 if(pairWithWii
&& checkRemoteName
)
839 hci_state
= HCI_CONNECT_DEVICE_STATE
;
841 hci_accept_connection();
842 hci_state
= HCI_CONNECTED_STATE
;
847 case HCI_CONNECTED_STATE
:
848 if(hci_check_flag(HCI_FLAG_CONNECT_COMPLETE
)) {
849 #ifdef DEBUG_USB_HOST
850 Notify(PSTR("\r\nConnected to Device: "), 0x80);
851 for(int8_t i
= 5; i
> 0; i
--) {
852 D_PrintHex
<uint8_t > (disc_bdaddr
[i
], 0x80);
853 Notify(PSTR(":"), 0x80);
855 D_PrintHex
<uint8_t > (disc_bdaddr
[0], 0x80);
858 connectToHIDDevice
= true; // We should always connect to the PS4 controller
860 // Clear these flags for a new connection
861 l2capConnectionClaimed
= false;
862 sdpConnectionClaimed
= false;
863 rfcommConnectionClaimed
= false;
866 hci_state
= HCI_DONE_STATE
;
872 if(hci_counter
> 1000) { // Wait until we have looped 1000 times to make sure that the L2CAP connection has been started
874 hci_state
= HCI_SCANNING_STATE
;
878 case HCI_DISCONNECT_STATE
:
879 if(hci_check_flag(HCI_FLAG_DISCONNECT_COMPLETE
)) {
880 #ifdef DEBUG_USB_HOST
881 Notify(PSTR("\r\nHCI Disconnected from Device"), 0x80);
883 hci_event_flag
= 0; // Clear all flags
886 memset(hcibuf
, 0, BULK_MAXPKTSIZE
);
887 memset(l2capinbuf
, 0, BULK_MAXPKTSIZE
);
889 connectToWii
= incomingWii
= pairWithWii
= false;
890 connectToHIDDevice
= incomingHIDDevice
= pairWithHIDDevice
= checkRemoteName
= false;
893 hci_state
= HCI_SCANNING_STATE
;
901 void BTD::ACL_event_task() {
902 uint16_t length
= BULK_MAXPKTSIZE
;
903 uint8_t rcode
= pUsb
->inTransfer(bAddress
, epInfo
[ BTD_DATAIN_PIPE
].epAddr
, &length
, l2capinbuf
); // Input on endpoint 2
905 if(!rcode
) { // Check for errors
906 if(length
> 0) { // Check if any data was read
907 for(uint8_t i
= 0; i
< BTD_NUM_SERVICES
; i
++) {
909 btService
[i
]->ACLData(l2capinbuf
);
914 else if(rcode
!= hrNAK
) {
915 Notify(PSTR("\r\nACL data in error: "), 0x80);
916 D_PrintHex
<uint8_t > (rcode
, 0x80);
919 for(uint8_t i
= 0; i
< BTD_NUM_SERVICES
; i
++)
924 /************************************************************/
927 /************************************************************/
928 void BTD::HCI_Command(uint8_t* data
, uint16_t nbytes
) {
929 hci_clear_flag(HCI_FLAG_CMD_COMPLETE
);
930 pUsb
->ctrlReq(bAddress
, epInfo
[ BTD_CONTROL_PIPE
].epAddr
, bmREQ_HCI_OUT
, 0x00, 0x00, 0x00, 0x00, nbytes
, nbytes
, data
, NULL
);
933 void BTD::hci_reset() {
934 hci_event_flag
= 0; // Clear all the flags
935 hcibuf
[0] = 0x03; // HCI OCF = 3
936 hcibuf
[1] = 0x03 << 2; // HCI OGF = 3
939 HCI_Command(hcibuf
, 3);
942 void BTD::hci_write_scan_enable() {
943 hci_clear_flag(HCI_FLAG_INCOMING_REQUEST
);
944 hcibuf
[0] = 0x1A; // HCI OCF = 1A
945 hcibuf
[1] = 0x03 << 2; // HCI OGF = 3
946 hcibuf
[2] = 0x01; // parameter length = 1
948 hcibuf
[3] = 0x03; // Inquiry Scan enabled. Page Scan enabled.
950 hcibuf
[3] = 0x02; // Inquiry Scan disabled. Page Scan enabled.
952 HCI_Command(hcibuf
, 4);
955 void BTD::hci_write_scan_disable() {
956 hcibuf
[0] = 0x1A; // HCI OCF = 1A
957 hcibuf
[1] = 0x03 << 2; // HCI OGF = 3
958 hcibuf
[2] = 0x01; // parameter length = 1
959 hcibuf
[3] = 0x00; // Inquiry Scan disabled. Page Scan disabled.
961 HCI_Command(hcibuf
, 4);
964 void BTD::hci_read_bdaddr() {
965 hci_clear_flag(HCI_FLAG_READ_BDADDR
);
966 hcibuf
[0] = 0x09; // HCI OCF = 9
967 hcibuf
[1] = 0x04 << 2; // HCI OGF = 4
970 HCI_Command(hcibuf
, 3);
973 void BTD::hci_read_local_version_information() {
974 hci_clear_flag(HCI_FLAG_READ_VERSION
);
975 hcibuf
[0] = 0x01; // HCI OCF = 1
976 hcibuf
[1] = 0x04 << 2; // HCI OGF = 4
979 HCI_Command(hcibuf
, 3);
982 void BTD::hci_accept_connection() {
983 hci_clear_flag(HCI_FLAG_CONNECT_COMPLETE
);
984 hcibuf
[0] = 0x09; // HCI OCF = 9
985 hcibuf
[1] = 0x01 << 2; // HCI OGF = 1
986 hcibuf
[2] = 0x07; // parameter length 7
987 hcibuf
[3] = disc_bdaddr
[0]; // 6 octet bdaddr
988 hcibuf
[4] = disc_bdaddr
[1];
989 hcibuf
[5] = disc_bdaddr
[2];
990 hcibuf
[6] = disc_bdaddr
[3];
991 hcibuf
[7] = disc_bdaddr
[4];
992 hcibuf
[8] = disc_bdaddr
[5];
993 hcibuf
[9] = 0x00; // Switch role to master
995 HCI_Command(hcibuf
, 10);
998 void BTD::hci_remote_name() {
999 hci_clear_flag(HCI_FLAG_REMOTE_NAME_COMPLETE
);
1000 hcibuf
[0] = 0x19; // HCI OCF = 19
1001 hcibuf
[1] = 0x01 << 2; // HCI OGF = 1
1002 hcibuf
[2] = 0x0A; // parameter length = 10
1003 hcibuf
[3] = disc_bdaddr
[0]; // 6 octet bdaddr
1004 hcibuf
[4] = disc_bdaddr
[1];
1005 hcibuf
[5] = disc_bdaddr
[2];
1006 hcibuf
[6] = disc_bdaddr
[3];
1007 hcibuf
[7] = disc_bdaddr
[4];
1008 hcibuf
[8] = disc_bdaddr
[5];
1009 hcibuf
[9] = 0x01; // Page Scan Repetition Mode
1010 hcibuf
[10] = 0x00; // Reserved
1011 hcibuf
[11] = 0x00; // Clock offset - low byte
1012 hcibuf
[12] = 0x00; // Clock offset - high byte
1014 HCI_Command(hcibuf
, 13);
1017 void BTD::hci_set_local_name(const char* name
) {
1018 hcibuf
[0] = 0x13; // HCI OCF = 13
1019 hcibuf
[1] = 0x03 << 2; // HCI OGF = 3
1020 hcibuf
[2] = strlen(name
) + 1; // parameter length = the length of the string + end byte
1022 for(i
= 0; i
< strlen(name
); i
++)
1023 hcibuf
[i
+ 3] = name
[i
];
1024 hcibuf
[i
+ 3] = 0x00; // End of string
1026 HCI_Command(hcibuf
, 4 + strlen(name
));
1029 void BTD::hci_inquiry() {
1030 hci_clear_flag(HCI_FLAG_DEVICE_FOUND
);
1032 hcibuf
[1] = 0x01 << 2; // HCI OGF = 1
1033 hcibuf
[2] = 0x05; // Parameter Total Length = 5
1034 hcibuf
[3] = 0x33; // LAP: Genera/Unlimited Inquiry Access Code (GIAC = 0x9E8B33) - see https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm
1037 hcibuf
[6] = 0x30; // Inquiry time = 61.44 sec (maximum)
1038 hcibuf
[7] = 0x0A; // 10 number of responses
1040 HCI_Command(hcibuf
, 8);
1043 void BTD::hci_inquiry_cancel() {
1045 hcibuf
[1] = 0x01 << 2; // HCI OGF = 1
1046 hcibuf
[2] = 0x00; // Parameter Total Length = 0
1048 HCI_Command(hcibuf
, 3);
1051 void BTD::hci_connect() {
1052 hci_connect(disc_bdaddr
); // Use last discovered device
1055 void BTD::hci_connect(uint8_t *bdaddr
) {
1056 hci_clear_flag(HCI_FLAG_CONNECT_COMPLETE
| HCI_FLAG_CONNECT_EVENT
);
1058 hcibuf
[1] = 0x01 << 2; // HCI OGF = 1
1059 hcibuf
[2] = 0x0D; // parameter Total Length = 13
1060 hcibuf
[3] = bdaddr
[0]; // 6 octet bdaddr (LSB)
1061 hcibuf
[4] = bdaddr
[1];
1062 hcibuf
[5] = bdaddr
[2];
1063 hcibuf
[6] = bdaddr
[3];
1064 hcibuf
[7] = bdaddr
[4];
1065 hcibuf
[8] = bdaddr
[5];
1066 hcibuf
[9] = 0x18; // DM1 or DH1 may be used
1067 hcibuf
[10] = 0xCC; // DM3, DH3, DM5, DH5 may be used
1068 hcibuf
[11] = 0x01; // Page repetition mode R1
1069 hcibuf
[12] = 0x00; // Reserved
1070 hcibuf
[13] = 0x00; // Clock offset
1071 hcibuf
[14] = 0x00; // Invalid clock offset
1072 hcibuf
[15] = 0x00; // Do not allow role switch
1074 HCI_Command(hcibuf
, 16);
1077 void BTD::hci_pin_code_request_reply() {
1078 hcibuf
[0] = 0x0D; // HCI OCF = 0D
1079 hcibuf
[1] = 0x01 << 2; // HCI OGF = 1
1080 hcibuf
[2] = 0x17; // parameter length 23
1081 hcibuf
[3] = disc_bdaddr
[0]; // 6 octet bdaddr
1082 hcibuf
[4] = disc_bdaddr
[1];
1083 hcibuf
[5] = disc_bdaddr
[2];
1084 hcibuf
[6] = disc_bdaddr
[3];
1085 hcibuf
[7] = disc_bdaddr
[4];
1086 hcibuf
[8] = disc_bdaddr
[5];
1088 hcibuf
[9] = 6; // Pin length is the length of the Bluetooth address
1089 if(pairWiiUsingSync
) {
1090 #ifdef DEBUG_USB_HOST
1091 Notify(PSTR("\r\nParing with Wii controller via SYNC"), 0x80);
1093 for(uint8_t i
= 0; i
< 6; i
++)
1094 hcibuf
[10 + i
] = my_bdaddr
[i
]; // The pin is the Bluetooth dongles Bluetooth address backwards
1096 for(uint8_t i
= 0; i
< 6; i
++)
1097 hcibuf
[10 + i
] = disc_bdaddr
[i
]; // The pin is the Wiimote's Bluetooth address backwards
1099 for(uint8_t i
= 16; i
< 26; i
++)
1100 hcibuf
[i
] = 0x00; // The rest should be 0
1102 hcibuf
[9] = strlen(btdPin
); // Length of pin
1104 for(i
= 0; i
< strlen(btdPin
); i
++) // The maximum size of the pin is 16
1105 hcibuf
[i
+ 10] = btdPin
[i
];
1107 hcibuf
[i
+ 10] = 0x00; // The rest should be 0
1110 HCI_Command(hcibuf
, 26);
1113 void BTD::hci_pin_code_negative_request_reply() {
1114 hcibuf
[0] = 0x0E; // HCI OCF = 0E
1115 hcibuf
[1] = 0x01 << 2; // HCI OGF = 1
1116 hcibuf
[2] = 0x06; // parameter length 6
1117 hcibuf
[3] = disc_bdaddr
[0]; // 6 octet bdaddr
1118 hcibuf
[4] = disc_bdaddr
[1];
1119 hcibuf
[5] = disc_bdaddr
[2];
1120 hcibuf
[6] = disc_bdaddr
[3];
1121 hcibuf
[7] = disc_bdaddr
[4];
1122 hcibuf
[8] = disc_bdaddr
[5];
1124 HCI_Command(hcibuf
, 9);
1127 void BTD::hci_link_key_request_negative_reply() {
1128 hcibuf
[0] = 0x0C; // HCI OCF = 0C
1129 hcibuf
[1] = 0x01 << 2; // HCI OGF = 1
1130 hcibuf
[2] = 0x06; // parameter length 6
1131 hcibuf
[3] = disc_bdaddr
[0]; // 6 octet bdaddr
1132 hcibuf
[4] = disc_bdaddr
[1];
1133 hcibuf
[5] = disc_bdaddr
[2];
1134 hcibuf
[6] = disc_bdaddr
[3];
1135 hcibuf
[7] = disc_bdaddr
[4];
1136 hcibuf
[8] = disc_bdaddr
[5];
1138 HCI_Command(hcibuf
, 9);
1141 void BTD::hci_authentication_request() {
1142 hcibuf
[0] = 0x11; // HCI OCF = 11
1143 hcibuf
[1] = 0x01 << 2; // HCI OGF = 1
1144 hcibuf
[2] = 0x02; // parameter length = 2
1145 hcibuf
[3] = (uint8_t)(hci_handle
& 0xFF); //connection handle - low byte
1146 hcibuf
[4] = (uint8_t)((hci_handle
>> 8) & 0x0F); //connection handle - high byte
1148 HCI_Command(hcibuf
, 5);
1151 void BTD::hci_disconnect(uint16_t handle
) { // This is called by the different services
1152 hci_clear_flag(HCI_FLAG_DISCONNECT_COMPLETE
);
1153 hcibuf
[0] = 0x06; // HCI OCF = 6
1154 hcibuf
[1] = 0x01 << 2; // HCI OGF = 1
1155 hcibuf
[2] = 0x03; // parameter length = 3
1156 hcibuf
[3] = (uint8_t)(handle
& 0xFF); //connection handle - low byte
1157 hcibuf
[4] = (uint8_t)((handle
>> 8) & 0x0F); //connection handle - high byte
1158 hcibuf
[5] = 0x13; // reason
1160 HCI_Command(hcibuf
, 6);
1163 void BTD::hci_write_class_of_device() { // See http://bluetooth-pentest.narod.ru/software/bluetooth_class_of_device-service_generator.html
1164 hcibuf
[0] = 0x24; // HCI OCF = 24
1165 hcibuf
[1] = 0x03 << 2; // HCI OGF = 3
1166 hcibuf
[2] = 0x03; // parameter length = 3
1167 hcibuf
[3] = 0x04; // Robot
1168 hcibuf
[4] = 0x08; // Toy
1171 HCI_Command(hcibuf
, 6);
1173 /*******************************************************************
1175 * HCI ACL Data Packet *
1177 * buf[0] buf[1] buf[2] buf[3]
1178 * 0 4 8 11 12 16 24 31 MSB
1179 * .-+-+-+-+-+-+-+-|-+-+-+-|-+-|-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-.
1180 * | HCI Handle |PB |BC | Data Total Length | HCI ACL Data Packet
1181 * .-+-+-+-+-+-+-+-|-+-+-+-|-+-|-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-.
1183 * buf[4] buf[5] buf[6] buf[7]
1185 * .-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-.
1186 * | Length | Channel ID | Basic L2CAP header
1187 * .-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-.
1189 * buf[8] buf[9] buf[10] buf[11]
1191 * .-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-.
1192 * | Code | Identifier | Length | Control frame (C-frame)
1193 * .-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-. (signaling packet format)
1195 /************************************************************/
1196 /* L2CAP Commands */
1198 /************************************************************/
1199 void BTD::L2CAP_Command(uint16_t handle
, uint8_t* data
, uint8_t nbytes
, uint8_t channelLow
, uint8_t channelHigh
) {
1200 uint8_t buf
[8 + nbytes
];
1201 buf
[0] = (uint8_t)(handle
& 0xff); // HCI handle with PB,BC flag
1202 buf
[1] = (uint8_t)(((handle
>> 8) & 0x0f) | 0x20);
1203 buf
[2] = (uint8_t)((4 + nbytes
) & 0xff); // HCI ACL total data length
1204 buf
[3] = (uint8_t)((4 + nbytes
) >> 8);
1205 buf
[4] = (uint8_t)(nbytes
& 0xff); // L2CAP header: Length
1206 buf
[5] = (uint8_t)(nbytes
>> 8);
1207 buf
[6] = channelLow
;
1208 buf
[7] = channelHigh
;
1210 for(uint16_t i
= 0; i
< nbytes
; i
++) // L2CAP C-frame
1211 buf
[8 + i
] = data
[i
];
1213 uint8_t rcode
= pUsb
->outTransfer(bAddress
, epInfo
[ BTD_DATAOUT_PIPE
].epAddr
, (8 + nbytes
), buf
);
1215 delay(100); // This small delay prevents it from overflowing if it fails
1216 #ifdef DEBUG_USB_HOST
1217 Notify(PSTR("\r\nError sending L2CAP message: 0x"), 0x80);
1218 D_PrintHex
<uint8_t > (rcode
, 0x80);
1219 Notify(PSTR(" - Channel ID: "), 0x80);
1220 D_PrintHex
<uint8_t > (channelHigh
, 0x80);
1221 Notify(PSTR(" "), 0x80);
1222 D_PrintHex
<uint8_t > (channelLow
, 0x80);
1227 void BTD::l2cap_connection_request(uint16_t handle
, uint8_t rxid
, uint8_t* scid
, uint16_t psm
) {
1228 l2capoutbuf
[0] = L2CAP_CMD_CONNECTION_REQUEST
; // Code
1229 l2capoutbuf
[1] = rxid
; // Identifier
1230 l2capoutbuf
[2] = 0x04; // Length
1231 l2capoutbuf
[3] = 0x00;
1232 l2capoutbuf
[4] = (uint8_t)(psm
& 0xff); // PSM
1233 l2capoutbuf
[5] = (uint8_t)(psm
>> 8);
1234 l2capoutbuf
[6] = scid
[0]; // Source CID
1235 l2capoutbuf
[7] = scid
[1];
1237 L2CAP_Command(handle
, l2capoutbuf
, 8);
1240 void BTD::l2cap_connection_response(uint16_t handle
, uint8_t rxid
, uint8_t* dcid
, uint8_t* scid
, uint8_t result
) {
1241 l2capoutbuf
[0] = L2CAP_CMD_CONNECTION_RESPONSE
; // Code
1242 l2capoutbuf
[1] = rxid
; // Identifier
1243 l2capoutbuf
[2] = 0x08; // Length
1244 l2capoutbuf
[3] = 0x00;
1245 l2capoutbuf
[4] = dcid
[0]; // Destination CID
1246 l2capoutbuf
[5] = dcid
[1];
1247 l2capoutbuf
[6] = scid
[0]; // Source CID
1248 l2capoutbuf
[7] = scid
[1];
1249 l2capoutbuf
[8] = result
; // Result: Pending or Success
1250 l2capoutbuf
[9] = 0x00;
1251 l2capoutbuf
[10] = 0x00; // No further information
1252 l2capoutbuf
[11] = 0x00;
1254 L2CAP_Command(handle
, l2capoutbuf
, 12);
1257 void BTD::l2cap_config_request(uint16_t handle
, uint8_t rxid
, uint8_t* dcid
) {
1258 l2capoutbuf
[0] = L2CAP_CMD_CONFIG_REQUEST
; // Code
1259 l2capoutbuf
[1] = rxid
; // Identifier
1260 l2capoutbuf
[2] = 0x08; // Length
1261 l2capoutbuf
[3] = 0x00;
1262 l2capoutbuf
[4] = dcid
[0]; // Destination CID
1263 l2capoutbuf
[5] = dcid
[1];
1264 l2capoutbuf
[6] = 0x00; // Flags
1265 l2capoutbuf
[7] = 0x00;
1266 l2capoutbuf
[8] = 0x01; // Config Opt: type = MTU (Maximum Transmission Unit) - Hint
1267 l2capoutbuf
[9] = 0x02; // Config Opt: length
1268 l2capoutbuf
[10] = 0xFF; // MTU
1269 l2capoutbuf
[11] = 0xFF;
1271 L2CAP_Command(handle
, l2capoutbuf
, 12);
1274 void BTD::l2cap_config_response(uint16_t handle
, uint8_t rxid
, uint8_t* scid
) {
1275 l2capoutbuf
[0] = L2CAP_CMD_CONFIG_RESPONSE
; // Code
1276 l2capoutbuf
[1] = rxid
; // Identifier
1277 l2capoutbuf
[2] = 0x0A; // Length
1278 l2capoutbuf
[3] = 0x00;
1279 l2capoutbuf
[4] = scid
[0]; // Source CID
1280 l2capoutbuf
[5] = scid
[1];
1281 l2capoutbuf
[6] = 0x00; // Flag
1282 l2capoutbuf
[7] = 0x00;
1283 l2capoutbuf
[8] = 0x00; // Result
1284 l2capoutbuf
[9] = 0x00;
1285 l2capoutbuf
[10] = 0x01; // Config
1286 l2capoutbuf
[11] = 0x02;
1287 l2capoutbuf
[12] = 0xA0;
1288 l2capoutbuf
[13] = 0x02;
1290 L2CAP_Command(handle
, l2capoutbuf
, 14);
1293 void BTD::l2cap_disconnection_request(uint16_t handle
, uint8_t rxid
, uint8_t* dcid
, uint8_t* scid
) {
1294 l2capoutbuf
[0] = L2CAP_CMD_DISCONNECT_REQUEST
; // Code
1295 l2capoutbuf
[1] = rxid
; // Identifier
1296 l2capoutbuf
[2] = 0x04; // Length
1297 l2capoutbuf
[3] = 0x00;
1298 l2capoutbuf
[4] = dcid
[0];
1299 l2capoutbuf
[5] = dcid
[1];
1300 l2capoutbuf
[6] = scid
[0];
1301 l2capoutbuf
[7] = scid
[1];
1303 L2CAP_Command(handle
, l2capoutbuf
, 8);
1306 void BTD::l2cap_disconnection_response(uint16_t handle
, uint8_t rxid
, uint8_t* dcid
, uint8_t* scid
) {
1307 l2capoutbuf
[0] = L2CAP_CMD_DISCONNECT_RESPONSE
; // Code
1308 l2capoutbuf
[1] = rxid
; // Identifier
1309 l2capoutbuf
[2] = 0x04; // Length
1310 l2capoutbuf
[3] = 0x00;
1311 l2capoutbuf
[4] = dcid
[0];
1312 l2capoutbuf
[5] = dcid
[1];
1313 l2capoutbuf
[6] = scid
[0];
1314 l2capoutbuf
[7] = scid
[1];
1316 L2CAP_Command(handle
, l2capoutbuf
, 8);
1319 void BTD::l2cap_information_response(uint16_t handle
, uint8_t rxid
, uint8_t infoTypeLow
, uint8_t infoTypeHigh
) {
1320 l2capoutbuf
[0] = L2CAP_CMD_INFORMATION_RESPONSE
; // Code
1321 l2capoutbuf
[1] = rxid
; // Identifier
1322 l2capoutbuf
[2] = 0x08; // Length
1323 l2capoutbuf
[3] = 0x00;
1324 l2capoutbuf
[4] = infoTypeLow
;
1325 l2capoutbuf
[5] = infoTypeHigh
;
1326 l2capoutbuf
[6] = 0x00; // Result = success
1327 l2capoutbuf
[7] = 0x00; // Result = success
1328 l2capoutbuf
[8] = 0x00;
1329 l2capoutbuf
[9] = 0x00;
1330 l2capoutbuf
[10] = 0x00;
1331 l2capoutbuf
[11] = 0x00;
1333 L2CAP_Command(handle
, l2capoutbuf
, 12);
1336 /* PS3 Commands - only set Bluetooth address is implemented in this library */
1337 void BTD::setBdaddr(uint8_t* bdaddr
) {
1338 /* Set the internal Bluetooth address */
1343 for(uint8_t i
= 0; i
< 6; i
++)
1344 buf
[i
+ 2] = bdaddr
[5 - i
]; // Copy into buffer, has to be written reversed, so it is MSB first
1346 // 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
1347 pUsb
->ctrlReq(bAddress
, epInfo
[BTD_CONTROL_PIPE
].epAddr
, bmREQ_HID_OUT
, HID_REQUEST_SET_REPORT
, 0xF5, 0x03, 0x00, 8, 8, buf
, NULL
);
1350 void BTD::setMoveBdaddr(uint8_t* bdaddr
) {
1351 /* Set the internal Bluetooth address */
1359 for(uint8_t i
= 0; i
< 6; i
++)
1360 buf
[i
+ 1] = bdaddr
[i
];
1362 // 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
1363 pUsb
->ctrlReq(bAddress
, epInfo
[BTD_CONTROL_PIPE
].epAddr
, bmREQ_HID_OUT
, HID_REQUEST_SET_REPORT
, 0x05, 0x03, 0x00, 11, 11, buf
, NULL
);