Zoltan Hudak / UsbHostMAX3421E

Dependents:   UsbHostMAX3421E_Hello

Committer:
hudakz
Date:
Sun Jul 12 20:39:26 2020 +0000
Revision:
0:84353c479782
Child:
1:2263e77400e9
MAX3421E-based USB Host Shield Library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:84353c479782 1 /* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
hudakz 0:84353c479782 2
hudakz 0:84353c479782 3 This software may be distributed and modified under the terms of the GNU
hudakz 0:84353c479782 4 General Public License version 2 (GPL2) as published by the Free Software
hudakz 0:84353c479782 5 Foundation and appearing in the file GPL2.TXT included in the packaging of
hudakz 0:84353c479782 6 this file. Please note that GPL2 Section 2[b] requires that all works based
hudakz 0:84353c479782 7 on this software must also be made publicly available under the terms of
hudakz 0:84353c479782 8 the GPL2 ("Copyleft").
hudakz 0:84353c479782 9
hudakz 0:84353c479782 10 Contact information
hudakz 0:84353c479782 11 -------------------
hudakz 0:84353c479782 12
hudakz 0:84353c479782 13 Kristian Lauszus, TKJ Electronics
hudakz 0:84353c479782 14 Web : http://www.tkjelectronics.com
hudakz 0:84353c479782 15 e-mail : kristianl@tkjelectronics.com
hudakz 0:84353c479782 16 */
hudakz 0:84353c479782 17
hudakz 0:84353c479782 18 #ifndef _btd_h_
hudakz 0:84353c479782 19 #define _btd_h_
hudakz 0:84353c479782 20
hudakz 0:84353c479782 21 #include "Usb.h"
hudakz 0:84353c479782 22 #include "usbhid.h"
hudakz 0:84353c479782 23 #include "mbed.h"
hudakz 0:84353c479782 24
hudakz 0:84353c479782 25 //PID and VID of the Sony PS3 devices
hudakz 0:84353c479782 26 #define PS3_VID 0x054C // Sony Corporation
hudakz 0:84353c479782 27 #define PS3_PID 0x0268 // PS3 Controller DualShock 3
hudakz 0:84353c479782 28 #define PS3NAVIGATION_PID 0x042F // Navigation controller
hudakz 0:84353c479782 29 #define PS3MOVE_PID 0x03D5 // Motion controller
hudakz 0:84353c479782 30
hudakz 0:84353c479782 31 // These dongles do not present themselves correctly, so we have to check for them manually
hudakz 0:84353c479782 32 #define IOGEAR_GBU521_VID 0x0A5C
hudakz 0:84353c479782 33 #define IOGEAR_GBU521_PID 0x21E8
hudakz 0:84353c479782 34 #define BELKIN_F8T065BF_VID 0x050D
hudakz 0:84353c479782 35 #define BELKIN_F8T065BF_PID 0x065A
hudakz 0:84353c479782 36
hudakz 0:84353c479782 37 /* Bluetooth dongle data taken from descriptors */
hudakz 0:84353c479782 38 #define BULK_MAXPKTSIZE 64 // Max size for ACL data
hudakz 0:84353c479782 39
hudakz 0:84353c479782 40 // Used in control endpoint header for HCI Commands
hudakz 0:84353c479782 41 #define bmREQ_HCI_OUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
hudakz 0:84353c479782 42
hudakz 0:84353c479782 43 /* Bluetooth HCI states for hci_task() */
hudakz 0:84353c479782 44 #define HCI_INIT_STATE 0
hudakz 0:84353c479782 45 #define HCI_RESET_STATE 1
hudakz 0:84353c479782 46 #define HCI_CLASS_STATE 2
hudakz 0:84353c479782 47 #define HCI_BDADDR_STATE 3
hudakz 0:84353c479782 48 #define HCI_LOCAL_VERSION_STATE 4
hudakz 0:84353c479782 49 #define HCI_SET_NAME_STATE 5
hudakz 0:84353c479782 50 #define HCI_CHECK_DEVICE_SERVICE 6
hudakz 0:84353c479782 51
hudakz 0:84353c479782 52 #define HCI_INQUIRY_STATE 7 // These three states are only used if it should pair and connect to a device
hudakz 0:84353c479782 53 #define HCI_CONNECT_DEVICE_STATE 8
hudakz 0:84353c479782 54 #define HCI_CONNECTED_DEVICE_STATE 9
hudakz 0:84353c479782 55
hudakz 0:84353c479782 56 #define HCI_SCANNING_STATE 10
hudakz 0:84353c479782 57 #define HCI_CONNECT_IN_STATE 11
hudakz 0:84353c479782 58 #define HCI_REMOTE_NAME_STATE 12
hudakz 0:84353c479782 59 #define HCI_CONNECTED_STATE 13
hudakz 0:84353c479782 60 #define HCI_DISABLE_SCAN_STATE 14
hudakz 0:84353c479782 61 #define HCI_DONE_STATE 15
hudakz 0:84353c479782 62 #define HCI_DISCONNECT_STATE 16
hudakz 0:84353c479782 63
hudakz 0:84353c479782 64 /* HCI event flags*/
hudakz 0:84353c479782 65 #define HCI_FLAG_CMD_COMPLETE (1UL << 0)
hudakz 0:84353c479782 66 #define HCI_FLAG_CONNECT_COMPLETE (1UL << 1)
hudakz 0:84353c479782 67 #define HCI_FLAG_DISCONNECT_COMPLETE (1UL << 2)
hudakz 0:84353c479782 68 #define HCI_FLAG_REMOTE_NAME_COMPLETE (1UL << 3)
hudakz 0:84353c479782 69 #define HCI_FLAG_INCOMING_REQUEST (1UL << 4)
hudakz 0:84353c479782 70 #define HCI_FLAG_READ_BDADDR (1UL << 5)
hudakz 0:84353c479782 71 #define HCI_FLAG_READ_VERSION (1UL << 6)
hudakz 0:84353c479782 72 #define HCI_FLAG_DEVICE_FOUND (1UL << 7)
hudakz 0:84353c479782 73 #define HCI_FLAG_CONNECT_EVENT (1UL << 8)
hudakz 0:84353c479782 74
hudakz 0:84353c479782 75 /* Macros for HCI event flag tests */
hudakz 0:84353c479782 76 #define hci_check_flag(flag) (hci_event_flag & (flag))
hudakz 0:84353c479782 77 #define hci_set_flag(flag) (hci_event_flag |= (flag))
hudakz 0:84353c479782 78 #define hci_clear_flag(flag) (hci_event_flag &= ~(flag))
hudakz 0:84353c479782 79
hudakz 0:84353c479782 80 /* HCI Events managed */
hudakz 0:84353c479782 81 #define EV_INQUIRY_COMPLETE 0x01
hudakz 0:84353c479782 82 #define EV_INQUIRY_RESULT 0x02
hudakz 0:84353c479782 83 #define EV_CONNECT_COMPLETE 0x03
hudakz 0:84353c479782 84 #define EV_INCOMING_CONNECT 0x04
hudakz 0:84353c479782 85 #define EV_DISCONNECT_COMPLETE 0x05
hudakz 0:84353c479782 86 #define EV_AUTHENTICATION_COMPLETE 0x06
hudakz 0:84353c479782 87 #define EV_REMOTE_NAME_COMPLETE 0x07
hudakz 0:84353c479782 88 #define EV_ENCRYPTION_CHANGE 0x08
hudakz 0:84353c479782 89 #define EV_CHANGE_CONNECTION_LINK 0x09
hudakz 0:84353c479782 90 #define EV_ROLE_CHANGED 0x12
hudakz 0:84353c479782 91 #define EV_NUM_COMPLETE_PKT 0x13
hudakz 0:84353c479782 92 #define EV_PIN_CODE_REQUEST 0x16
hudakz 0:84353c479782 93 #define EV_LINK_KEY_REQUEST 0x17
hudakz 0:84353c479782 94 #define EV_LINK_KEY_NOTIFICATION 0x18
hudakz 0:84353c479782 95 #define EV_DATA_BUFFER_OVERFLOW 0x1A
hudakz 0:84353c479782 96 #define EV_MAX_SLOTS_CHANGE 0x1B
hudakz 0:84353c479782 97 #define EV_READ_REMOTE_VERSION_INFORMATION_COMPLETE 0x0C
hudakz 0:84353c479782 98 #define EV_QOS_SETUP_COMPLETE 0x0D
hudakz 0:84353c479782 99 #define EV_COMMAND_COMPLETE 0x0E
hudakz 0:84353c479782 100 #define EV_COMMAND_STATUS 0x0F
hudakz 0:84353c479782 101 #define EV_LOOPBACK_COMMAND 0x19
hudakz 0:84353c479782 102 #define EV_PAGE_SCAN_REP_MODE 0x20
hudakz 0:84353c479782 103
hudakz 0:84353c479782 104 /* Bluetooth states for the different Bluetooth drivers */
hudakz 0:84353c479782 105 #define L2CAP_WAIT 0
hudakz 0:84353c479782 106 #define L2CAP_DONE 1
hudakz 0:84353c479782 107
hudakz 0:84353c479782 108 /* Used for HID Control channel */
hudakz 0:84353c479782 109 #define L2CAP_CONTROL_CONNECT_REQUEST 2
hudakz 0:84353c479782 110 #define L2CAP_CONTROL_CONFIG_REQUEST 3
hudakz 0:84353c479782 111 #define L2CAP_CONTROL_SUCCESS 4
hudakz 0:84353c479782 112 #define L2CAP_CONTROL_DISCONNECT 5
hudakz 0:84353c479782 113
hudakz 0:84353c479782 114 /* Used for HID Interrupt channel */
hudakz 0:84353c479782 115 #define L2CAP_INTERRUPT_SETUP 6
hudakz 0:84353c479782 116 #define L2CAP_INTERRUPT_CONNECT_REQUEST 7
hudakz 0:84353c479782 117 #define L2CAP_INTERRUPT_CONFIG_REQUEST 8
hudakz 0:84353c479782 118 #define L2CAP_INTERRUPT_DISCONNECT 9
hudakz 0:84353c479782 119
hudakz 0:84353c479782 120 /* Used for SDP channel */
hudakz 0:84353c479782 121 #define L2CAP_SDP_WAIT 10
hudakz 0:84353c479782 122 #define L2CAP_SDP_SUCCESS 11
hudakz 0:84353c479782 123
hudakz 0:84353c479782 124 /* Used for RFCOMM channel */
hudakz 0:84353c479782 125 #define L2CAP_RFCOMM_WAIT 12
hudakz 0:84353c479782 126 #define L2CAP_RFCOMM_SUCCESS 13
hudakz 0:84353c479782 127
hudakz 0:84353c479782 128 #define L2CAP_DISCONNECT_RESPONSE 14 // Used for both SDP and RFCOMM channel
hudakz 0:84353c479782 129
hudakz 0:84353c479782 130 /* Bluetooth states used by some drivers */
hudakz 0:84353c479782 131 #define TURN_ON_LED 17
hudakz 0:84353c479782 132 #define PS3_ENABLE_SIXAXIS 18
hudakz 0:84353c479782 133 #define WII_CHECK_MOTION_PLUS_STATE 19
hudakz 0:84353c479782 134 #define WII_CHECK_EXTENSION_STATE 20
hudakz 0:84353c479782 135 #define WII_INIT_MOTION_PLUS_STATE 21
hudakz 0:84353c479782 136
hudakz 0:84353c479782 137 /* L2CAP event flags for HID Control channel */
hudakz 0:84353c479782 138 #define L2CAP_FLAG_CONNECTION_CONTROL_REQUEST (1UL << 0)
hudakz 0:84353c479782 139 #define L2CAP_FLAG_CONFIG_CONTROL_SUCCESS (1UL << 1)
hudakz 0:84353c479782 140 #define L2CAP_FLAG_CONTROL_CONNECTED (1UL << 2)
hudakz 0:84353c479782 141 #define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE (1UL << 3)
hudakz 0:84353c479782 142
hudakz 0:84353c479782 143 /* L2CAP event flags for HID Interrupt channel */
hudakz 0:84353c479782 144 #define L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST (1UL << 4)
hudakz 0:84353c479782 145 #define L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS (1UL << 5)
hudakz 0:84353c479782 146 #define L2CAP_FLAG_INTERRUPT_CONNECTED (1UL << 6)
hudakz 0:84353c479782 147 #define L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE (1UL << 7)
hudakz 0:84353c479782 148
hudakz 0:84353c479782 149 /* L2CAP event flags for SDP channel */
hudakz 0:84353c479782 150 #define L2CAP_FLAG_CONNECTION_SDP_REQUEST (1UL << 8)
hudakz 0:84353c479782 151 #define L2CAP_FLAG_CONFIG_SDP_SUCCESS (1UL << 9)
hudakz 0:84353c479782 152 #define L2CAP_FLAG_DISCONNECT_SDP_REQUEST (1UL << 10)
hudakz 0:84353c479782 153
hudakz 0:84353c479782 154 /* L2CAP event flags for RFCOMM channel */
hudakz 0:84353c479782 155 #define L2CAP_FLAG_CONNECTION_RFCOMM_REQUEST (1UL << 11)
hudakz 0:84353c479782 156 #define L2CAP_FLAG_CONFIG_RFCOMM_SUCCESS (1UL << 12)
hudakz 0:84353c479782 157 #define L2CAP_FLAG_DISCONNECT_RFCOMM_REQUEST (1UL << 13)
hudakz 0:84353c479782 158
hudakz 0:84353c479782 159 #define L2CAP_FLAG_DISCONNECT_RESPONSE (1UL << 14)
hudakz 0:84353c479782 160
hudakz 0:84353c479782 161 /* Macros for L2CAP event flag tests */
hudakz 0:84353c479782 162 #define l2cap_check_flag(flag) (l2cap_event_flag & (flag))
hudakz 0:84353c479782 163 #define l2cap_set_flag(flag) (l2cap_event_flag |= (flag))
hudakz 0:84353c479782 164 #define l2cap_clear_flag(flag) (l2cap_event_flag &= ~(flag))
hudakz 0:84353c479782 165
hudakz 0:84353c479782 166 /* L2CAP signaling commands */
hudakz 0:84353c479782 167 #define L2CAP_CMD_COMMAND_REJECT 0x01
hudakz 0:84353c479782 168 #define L2CAP_CMD_CONNECTION_REQUEST 0x02
hudakz 0:84353c479782 169 #define L2CAP_CMD_CONNECTION_RESPONSE 0x03
hudakz 0:84353c479782 170 #define L2CAP_CMD_CONFIG_REQUEST 0x04
hudakz 0:84353c479782 171 #define L2CAP_CMD_CONFIG_RESPONSE 0x05
hudakz 0:84353c479782 172 #define L2CAP_CMD_DISCONNECT_REQUEST 0x06
hudakz 0:84353c479782 173 #define L2CAP_CMD_DISCONNECT_RESPONSE 0x07
hudakz 0:84353c479782 174 #define L2CAP_CMD_INFORMATION_REQUEST 0x0A
hudakz 0:84353c479782 175 #define L2CAP_CMD_INFORMATION_RESPONSE 0x0B
hudakz 0:84353c479782 176
hudakz 0:84353c479782 177 // Used For Connection Response - Remember to Include High Byte
hudakz 0:84353c479782 178 #define PENDING 0x01
hudakz 0:84353c479782 179 #define SUCCESSFUL 0x00
hudakz 0:84353c479782 180
hudakz 0:84353c479782 181 /* Bluetooth L2CAP PSM - see http://www.bluetooth.org/Technical/AssignedNumbers/logical_link.htm */
hudakz 0:84353c479782 182 #define SDP_PSM 0x01 // Service Discovery Protocol PSM Value
hudakz 0:84353c479782 183 #define RFCOMM_PSM 0x03 // RFCOMM PSM Value
hudakz 0:84353c479782 184 #define HID_CTRL_PSM 0x11 // HID_Control PSM Value
hudakz 0:84353c479782 185 #define HID_INTR_PSM 0x13 // HID_Interrupt PSM Value
hudakz 0:84353c479782 186
hudakz 0:84353c479782 187 // Used to determine if it is a Bluetooth dongle
hudakz 0:84353c479782 188 #define WI_SUBCLASS_RF 0x01 // RF Controller
hudakz 0:84353c479782 189 #define WI_PROTOCOL_BT 0x01 // Bluetooth Programming Interface
hudakz 0:84353c479782 190
hudakz 0:84353c479782 191 #define BTD_MAX_ENDPOINTS 4
hudakz 0:84353c479782 192 #define BTD_NUM_SERVICES 4 // Max number of Bluetooth services - if you need more than 4 simply increase this number
hudakz 0:84353c479782 193
hudakz 0:84353c479782 194 #define PAIR 1
hudakz 0:84353c479782 195
hudakz 0:84353c479782 196 class BluetoothService;
hudakz 0:84353c479782 197
hudakz 0:84353c479782 198 /**
hudakz 0:84353c479782 199 * The Bluetooth Dongle class will take care of all the USB communication
hudakz 0:84353c479782 200 * and then pass the data to the BluetoothService classes.
hudakz 0:84353c479782 201 */
hudakz 0:84353c479782 202 class BTD : public USBDeviceConfig, public UsbConfigXtracter {
hudakz 0:84353c479782 203 public:
hudakz 0:84353c479782 204 /**
hudakz 0:84353c479782 205 * Constructor for the BTD class.
hudakz 0:84353c479782 206 * @param p Pointer to USB class instance.
hudakz 0:84353c479782 207 */
hudakz 0:84353c479782 208 BTD(USB *p);
hudakz 0:84353c479782 209
hudakz 0:84353c479782 210 /** @name USBDeviceConfig implementation */
hudakz 0:84353c479782 211 /**
hudakz 0:84353c479782 212 * Address assignment and basic initialization is done here.
hudakz 0:84353c479782 213 * @param parent Hub number.
hudakz 0:84353c479782 214 * @param port Port number on the hub.
hudakz 0:84353c479782 215 * @param lowspeed Speed of the device.
hudakz 0:84353c479782 216 * @return 0 on success.
hudakz 0:84353c479782 217 */
hudakz 0:84353c479782 218 uint8_t ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed);
hudakz 0:84353c479782 219 /**
hudakz 0:84353c479782 220 * Initialize the Bluetooth dongle.
hudakz 0:84353c479782 221 * @param parent Hub number.
hudakz 0:84353c479782 222 * @param port Port number on the hub.
hudakz 0:84353c479782 223 * @param lowspeed Speed of the device.
hudakz 0:84353c479782 224 * @return 0 on success.
hudakz 0:84353c479782 225 */
hudakz 0:84353c479782 226 uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
hudakz 0:84353c479782 227 /**
hudakz 0:84353c479782 228 * Release the USB device.
hudakz 0:84353c479782 229 * @return 0 on success.
hudakz 0:84353c479782 230 */
hudakz 0:84353c479782 231 uint8_t Release();
hudakz 0:84353c479782 232 /**
hudakz 0:84353c479782 233 * Poll the USB Input endpoints and run the state machines.
hudakz 0:84353c479782 234 * @return 0 on success.
hudakz 0:84353c479782 235 */
hudakz 0:84353c479782 236 uint8_t Poll();
hudakz 0:84353c479782 237
hudakz 0:84353c479782 238 /**
hudakz 0:84353c479782 239 * Get the device address.
hudakz 0:84353c479782 240 * @return The device address.
hudakz 0:84353c479782 241 */
hudakz 0:84353c479782 242 virtual uint8_t GetAddress() {
hudakz 0:84353c479782 243 return bAddress;
hudakz 0:84353c479782 244 };
hudakz 0:84353c479782 245
hudakz 0:84353c479782 246 /**
hudakz 0:84353c479782 247 * Used to check if the dongle has been initialized.
hudakz 0:84353c479782 248 * @return True if it's ready.
hudakz 0:84353c479782 249 */
hudakz 0:84353c479782 250 virtual bool isReady() {
hudakz 0:84353c479782 251 return bPollEnable;
hudakz 0:84353c479782 252 };
hudakz 0:84353c479782 253
hudakz 0:84353c479782 254 /**
hudakz 0:84353c479782 255 * Used by the USB core to check what this driver support.
hudakz 0:84353c479782 256 * @param klass The device's USB class.
hudakz 0:84353c479782 257 * @return Returns true if the device's USB class matches this driver.
hudakz 0:84353c479782 258 */
hudakz 0:84353c479782 259 virtual bool DEVCLASSOK(uint8_t klass) {
hudakz 0:84353c479782 260 return (klass == USB_CLASS_WIRELESS_CTRL);
hudakz 0:84353c479782 261 };
hudakz 0:84353c479782 262
hudakz 0:84353c479782 263 /**
hudakz 0:84353c479782 264 * Used by the USB core to check what this driver support.
hudakz 0:84353c479782 265 * Used to set the Bluetooth address into the PS3 controllers.
hudakz 0:84353c479782 266 * @param vid The device's VID.
hudakz 0:84353c479782 267 * @param pid The device's PID.
hudakz 0:84353c479782 268 * @return Returns true if the device's VID and PID matches this driver.
hudakz 0:84353c479782 269 */
hudakz 0:84353c479782 270 virtual bool VIDPIDOK(uint16_t vid, uint16_t pid) {
hudakz 0:84353c479782 271 if((vid == IOGEAR_GBU521_VID && pid == IOGEAR_GBU521_PID) || (vid == BELKIN_F8T065BF_VID && pid == BELKIN_F8T065BF_PID))
hudakz 0:84353c479782 272 return true;
hudakz 0:84353c479782 273 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) { // Check if Bluetooth address is set
hudakz 0:84353c479782 274 if(vid == PS3_VID && (pid == PS3_PID || pid == PS3NAVIGATION_PID || pid == PS3MOVE_PID))
hudakz 0:84353c479782 275 return true;
hudakz 0:84353c479782 276 }
hudakz 0:84353c479782 277 return false;
hudakz 0:84353c479782 278 };
hudakz 0:84353c479782 279 /**@}*/
hudakz 0:84353c479782 280
hudakz 0:84353c479782 281 /** @name UsbConfigXtracter implementation */
hudakz 0:84353c479782 282 /**
hudakz 0:84353c479782 283 * UsbConfigXtracter implementation, used to extract endpoint information.
hudakz 0:84353c479782 284 * @param conf Configuration value.
hudakz 0:84353c479782 285 * @param iface Interface number.
hudakz 0:84353c479782 286 * @param alt Alternate setting.
hudakz 0:84353c479782 287 * @param proto Interface Protocol.
hudakz 0:84353c479782 288 * @param ep Endpoint Descriptor.
hudakz 0:84353c479782 289 */
hudakz 0:84353c479782 290 void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
hudakz 0:84353c479782 291 /**@}*/
hudakz 0:84353c479782 292
hudakz 0:84353c479782 293 /** Disconnects both the L2CAP Channel and the HCI Connection for all Bluetooth services. */
hudakz 0:84353c479782 294 void disconnect();
hudakz 0:84353c479782 295
hudakz 0:84353c479782 296 /**
hudakz 0:84353c479782 297 * Register Bluetooth dongle members/services.
hudakz 0:84353c479782 298 * @param pService Pointer to BluetoothService class instance.
hudakz 0:84353c479782 299 * @return The service ID on success or -1 on fail.
hudakz 0:84353c479782 300 */
hudakz 0:84353c479782 301 int8_t registerBluetoothService(BluetoothService *pService) {
hudakz 0:84353c479782 302 for(uint8_t i = 0; i < BTD_NUM_SERVICES; i++) {
hudakz 0:84353c479782 303 if(!btService[i]) {
hudakz 0:84353c479782 304 btService[i] = pService;
hudakz 0:84353c479782 305 return i; // Return ID
hudakz 0:84353c479782 306 }
hudakz 0:84353c479782 307 }
hudakz 0:84353c479782 308 return -1; // Error registering BluetoothService
hudakz 0:84353c479782 309 };
hudakz 0:84353c479782 310
hudakz 0:84353c479782 311 /** @name HCI Commands */
hudakz 0:84353c479782 312 /**
hudakz 0:84353c479782 313 * Used to send a HCI Command.
hudakz 0:84353c479782 314 * @param data Data to send.
hudakz 0:84353c479782 315 * @param nbytes Number of bytes to send.
hudakz 0:84353c479782 316 */
hudakz 0:84353c479782 317 void HCI_Command(uint8_t* data, uint16_t nbytes);
hudakz 0:84353c479782 318 /** Reset the Bluetooth dongle. */
hudakz 0:84353c479782 319 void hci_reset();
hudakz 0:84353c479782 320 /** Read the Bluetooth address of the dongle. */
hudakz 0:84353c479782 321 void hci_read_bdaddr();
hudakz 0:84353c479782 322 /** Read the HCI Version of the Bluetooth dongle. */
hudakz 0:84353c479782 323 void hci_read_local_version_information();
hudakz 0:84353c479782 324 /**
hudakz 0:84353c479782 325 * Set the local name of the Bluetooth dongle.
hudakz 0:84353c479782 326 * @param name Desired name.
hudakz 0:84353c479782 327 */
hudakz 0:84353c479782 328 void hci_set_local_name(const char* name);
hudakz 0:84353c479782 329 /** Enable visibility to other Bluetooth devices. */
hudakz 0:84353c479782 330 void hci_write_scan_enable();
hudakz 0:84353c479782 331 /** Disable visibility to other Bluetooth devices. */
hudakz 0:84353c479782 332 void hci_write_scan_disable();
hudakz 0:84353c479782 333 /** Read the remote devices name. */
hudakz 0:84353c479782 334 void hci_remote_name();
hudakz 0:84353c479782 335 /** Accept the connection with the Bluetooth device. */
hudakz 0:84353c479782 336 void hci_accept_connection();
hudakz 0:84353c479782 337 /**
hudakz 0:84353c479782 338 * Disconnect the HCI connection.
hudakz 0:84353c479782 339 * @param handle The HCI Handle for the connection.
hudakz 0:84353c479782 340 */
hudakz 0:84353c479782 341 void hci_disconnect(uint16_t handle);
hudakz 0:84353c479782 342 /**
hudakz 0:84353c479782 343 * Respond with the pin for the connection.
hudakz 0:84353c479782 344 * The pin is automatically set for the Wii library,
hudakz 0:84353c479782 345 * but can be customized for the SPP library.
hudakz 0:84353c479782 346 */
hudakz 0:84353c479782 347 void hci_pin_code_request_reply();
hudakz 0:84353c479782 348 /** Respons when no pin was set. */
hudakz 0:84353c479782 349 void hci_pin_code_negative_request_reply();
hudakz 0:84353c479782 350 /**
hudakz 0:84353c479782 351 * Command is used to reply to a Link Key Request event from the BR/EDR Controller
hudakz 0:84353c479782 352 * if the Host does not have a stored Link Key for the connection.
hudakz 0:84353c479782 353 */
hudakz 0:84353c479782 354 void hci_link_key_request_negative_reply();
hudakz 0:84353c479782 355 /** Used to try to authenticate with the remote device. */
hudakz 0:84353c479782 356 void hci_authentication_request();
hudakz 0:84353c479782 357 /** Start a HCI inquiry. */
hudakz 0:84353c479782 358 void hci_inquiry();
hudakz 0:84353c479782 359 /** Cancel a HCI inquiry. */
hudakz 0:84353c479782 360 void hci_inquiry_cancel();
hudakz 0:84353c479782 361 /** Connect to last device communicated with. */
hudakz 0:84353c479782 362 void hci_connect();
hudakz 0:84353c479782 363 /**
hudakz 0:84353c479782 364 * Connect to device.
hudakz 0:84353c479782 365 * @param bdaddr Bluetooth address of the device.
hudakz 0:84353c479782 366 */
hudakz 0:84353c479782 367 void hci_connect(uint8_t *bdaddr);
hudakz 0:84353c479782 368 /** Used to a set the class of the device. */
hudakz 0:84353c479782 369 void hci_write_class_of_device();
hudakz 0:84353c479782 370 /**@}*/
hudakz 0:84353c479782 371
hudakz 0:84353c479782 372 /** @name L2CAP Commands */
hudakz 0:84353c479782 373 /**
hudakz 0:84353c479782 374 * Used to send L2CAP Commands.
hudakz 0:84353c479782 375 * @param handle HCI Handle.
hudakz 0:84353c479782 376 * @param data Data to send.
hudakz 0:84353c479782 377 * @param nbytes Number of bytes to send.
hudakz 0:84353c479782 378 * @param channelLow,channelHigh Low and high byte of channel to send to.
hudakz 0:84353c479782 379 * If argument is omitted then the Standard L2CAP header: Channel ID (0x01) for ACL-U will be used.
hudakz 0:84353c479782 380 */
hudakz 0:84353c479782 381 void L2CAP_Command(uint16_t handle, uint8_t* data, uint8_t nbytes, uint8_t channelLow = 0x01, uint8_t channelHigh = 0x00);
hudakz 0:84353c479782 382 /**
hudakz 0:84353c479782 383 * L2CAP Connection Request.
hudakz 0:84353c479782 384 * @param handle HCI handle.
hudakz 0:84353c479782 385 * @param rxid Identifier.
hudakz 0:84353c479782 386 * @param scid Source Channel Identifier.
hudakz 0:84353c479782 387 * @param psm Protocol/Service Multiplexer - see: https://www.bluetooth.org/Technical/AssignedNumbers/logical_link.htm.
hudakz 0:84353c479782 388 */
hudakz 0:84353c479782 389 void l2cap_connection_request(uint16_t handle, uint8_t rxid, uint8_t* scid, uint16_t psm);
hudakz 0:84353c479782 390 /**
hudakz 0:84353c479782 391 * L2CAP Connection Response.
hudakz 0:84353c479782 392 * @param handle HCI handle.
hudakz 0:84353c479782 393 * @param rxid Identifier.
hudakz 0:84353c479782 394 * @param dcid Destination Channel Identifier.
hudakz 0:84353c479782 395 * @param scid Source Channel Identifier.
hudakz 0:84353c479782 396 * @param result Result - First send ::PENDING and then ::SUCCESSFUL.
hudakz 0:84353c479782 397 */
hudakz 0:84353c479782 398 void l2cap_connection_response(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid, uint8_t result);
hudakz 0:84353c479782 399 /**
hudakz 0:84353c479782 400 * L2CAP Config Request.
hudakz 0:84353c479782 401 * @param handle HCI Handle.
hudakz 0:84353c479782 402 * @param rxid Identifier.
hudakz 0:84353c479782 403 * @param dcid Destination Channel Identifier.
hudakz 0:84353c479782 404 */
hudakz 0:84353c479782 405 void l2cap_config_request(uint16_t handle, uint8_t rxid, uint8_t* dcid);
hudakz 0:84353c479782 406 /**
hudakz 0:84353c479782 407 * L2CAP Config Response.
hudakz 0:84353c479782 408 * @param handle HCI Handle.
hudakz 0:84353c479782 409 * @param rxid Identifier.
hudakz 0:84353c479782 410 * @param scid Source Channel Identifier.
hudakz 0:84353c479782 411 */
hudakz 0:84353c479782 412 void l2cap_config_response(uint16_t handle, uint8_t rxid, uint8_t* scid);
hudakz 0:84353c479782 413 /**
hudakz 0:84353c479782 414 * L2CAP Disconnection Request.
hudakz 0:84353c479782 415 * @param handle HCI Handle.
hudakz 0:84353c479782 416 * @param rxid Identifier.
hudakz 0:84353c479782 417 * @param dcid Device Channel Identifier.
hudakz 0:84353c479782 418 * @param scid Source Channel Identifier.
hudakz 0:84353c479782 419 */
hudakz 0:84353c479782 420 void l2cap_disconnection_request(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid);
hudakz 0:84353c479782 421 /**
hudakz 0:84353c479782 422 * L2CAP Disconnection Response.
hudakz 0:84353c479782 423 * @param handle HCI Handle.
hudakz 0:84353c479782 424 * @param rxid Identifier.
hudakz 0:84353c479782 425 * @param dcid Device Channel Identifier.
hudakz 0:84353c479782 426 * @param scid Source Channel Identifier.
hudakz 0:84353c479782 427 */
hudakz 0:84353c479782 428 void l2cap_disconnection_response(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid);
hudakz 0:84353c479782 429 /**
hudakz 0:84353c479782 430 * L2CAP Information Response.
hudakz 0:84353c479782 431 * @param handle HCI Handle.
hudakz 0:84353c479782 432 * @param rxid Identifier.
hudakz 0:84353c479782 433 * @param infoTypeLow,infoTypeHigh Infotype.
hudakz 0:84353c479782 434 */
hudakz 0:84353c479782 435 void l2cap_information_response(uint16_t handle, uint8_t rxid, uint8_t infoTypeLow, uint8_t infoTypeHigh);
hudakz 0:84353c479782 436 /**@}*/
hudakz 0:84353c479782 437
hudakz 0:84353c479782 438 /** Use this to see if it is waiting for a incoming connection. */
hudakz 0:84353c479782 439 bool waitingForConnection;
hudakz 0:84353c479782 440 /** This is used by the service to know when to store the device information. */
hudakz 0:84353c479782 441 bool l2capConnectionClaimed;
hudakz 0:84353c479782 442 /** This is used by the SPP library to claim the current SDP incoming request. */
hudakz 0:84353c479782 443 bool sdpConnectionClaimed;
hudakz 0:84353c479782 444 /** This is used by the SPP library to claim the current RFCOMM incoming request. */
hudakz 0:84353c479782 445 bool rfcommConnectionClaimed;
hudakz 0:84353c479782 446
hudakz 0:84353c479782 447 /** The name you wish to make the dongle show up as. It is set automatically by the SPP library. */
hudakz 0:84353c479782 448 const char* btdName;
hudakz 0:84353c479782 449 /** The pin you wish to make the dongle use for authentication. It is set automatically by the SPP and BTHID library. */
hudakz 0:84353c479782 450 const char* btdPin;
hudakz 0:84353c479782 451
hudakz 0:84353c479782 452 /** The bluetooth dongles Bluetooth address. */
hudakz 0:84353c479782 453 uint8_t my_bdaddr[6];
hudakz 0:84353c479782 454 /** HCI handle for the last connection. */
hudakz 0:84353c479782 455 uint16_t hci_handle;
hudakz 0:84353c479782 456 /** Last incoming devices Bluetooth address. */
hudakz 0:84353c479782 457 uint8_t disc_bdaddr[6];
hudakz 0:84353c479782 458 /** First 30 chars of last remote name. */
hudakz 0:84353c479782 459 char remote_name[30];
hudakz 0:84353c479782 460 /**
hudakz 0:84353c479782 461 * The supported HCI Version read from the Bluetooth dongle.
hudakz 0:84353c479782 462 * Used by the PS3BT library to check the HCI Version of the Bluetooth dongle,
hudakz 0:84353c479782 463 * it should be at least 3 to work properly with the library.
hudakz 0:84353c479782 464 */
hudakz 0:84353c479782 465 uint8_t hci_version;
hudakz 0:84353c479782 466
hudakz 0:84353c479782 467 /** Call this function to pair with a Wiimote */
hudakz 0:84353c479782 468 void pairWithWiimote() {
hudakz 0:84353c479782 469 pairWithWii = true;
hudakz 0:84353c479782 470 hci_state = HCI_CHECK_DEVICE_SERVICE;
hudakz 0:84353c479782 471 };
hudakz 0:84353c479782 472 /** Used to only send the ACL data to the Wiimote. */
hudakz 0:84353c479782 473 bool connectToWii;
hudakz 0:84353c479782 474 /** True if a Wiimote is connecting. */
hudakz 0:84353c479782 475 bool incomingWii;
hudakz 0:84353c479782 476 /** True when it should pair with a Wiimote. */
hudakz 0:84353c479782 477 bool pairWithWii;
hudakz 0:84353c479782 478 /** True if it's the new Wiimote with the Motion Plus Inside or a Wii U Pro Controller. */
hudakz 0:84353c479782 479 bool motionPlusInside;
hudakz 0:84353c479782 480 /** True if it's a Wii U Pro Controller. */
hudakz 0:84353c479782 481 bool wiiUProController;
hudakz 0:84353c479782 482
hudakz 0:84353c479782 483 /** Call this function to pair with a HID device */
hudakz 0:84353c479782 484 void pairWithHID() {
hudakz 0:84353c479782 485 waitingForConnection = false;
hudakz 0:84353c479782 486 pairWithHIDDevice = true;
hudakz 0:84353c479782 487 hci_state = HCI_CHECK_DEVICE_SERVICE;
hudakz 0:84353c479782 488 };
hudakz 0:84353c479782 489 /** Used to only send the ACL data to the HID device. */
hudakz 0:84353c479782 490 bool connectToHIDDevice;
hudakz 0:84353c479782 491 /** True if a HID device is connecting. */
hudakz 0:84353c479782 492 bool incomingHIDDevice;
hudakz 0:84353c479782 493 /** True when it should pair with a device like a mouse or keyboard. */
hudakz 0:84353c479782 494 bool pairWithHIDDevice;
hudakz 0:84353c479782 495
hudakz 0:84353c479782 496 /**
hudakz 0:84353c479782 497 * Read the poll interval taken from the endpoint descriptors.
hudakz 0:84353c479782 498 * @return The poll interval in ms.
hudakz 0:84353c479782 499 */
hudakz 0:84353c479782 500 uint8_t readPollInterval() {
hudakz 0:84353c479782 501 return pollInterval;
hudakz 0:84353c479782 502 };
hudakz 0:84353c479782 503
hudakz 0:84353c479782 504 protected:
hudakz 0:84353c479782 505 /** Pointer to USB class instance. */
hudakz 0:84353c479782 506 USB *pUsb;
hudakz 0:84353c479782 507 /** Device address. */
hudakz 0:84353c479782 508 uint8_t bAddress;
hudakz 0:84353c479782 509 /** Endpoint info structure. */
hudakz 0:84353c479782 510 EpInfo epInfo[BTD_MAX_ENDPOINTS];
hudakz 0:84353c479782 511
hudakz 0:84353c479782 512 /** Configuration number. */
hudakz 0:84353c479782 513 uint8_t bConfNum;
hudakz 0:84353c479782 514 /** Total number of endpoints in the configuration. */
hudakz 0:84353c479782 515 uint8_t bNumEP;
hudakz 0:84353c479782 516 /** Next poll time based on poll interval taken from the USB descriptor. */
hudakz 0:84353c479782 517 uint32_t qNextPollTime;
hudakz 0:84353c479782 518
hudakz 0:84353c479782 519 /** Bluetooth dongle control endpoint. */
hudakz 0:84353c479782 520 static const uint8_t BTD_CONTROL_PIPE;
hudakz 0:84353c479782 521 /** HCI event endpoint index. */
hudakz 0:84353c479782 522 static const uint8_t BTD_EVENT_PIPE;
hudakz 0:84353c479782 523 /** ACL In endpoint index. */
hudakz 0:84353c479782 524 static const uint8_t BTD_DATAIN_PIPE;
hudakz 0:84353c479782 525 /** ACL Out endpoint index. */
hudakz 0:84353c479782 526 static const uint8_t BTD_DATAOUT_PIPE;
hudakz 0:84353c479782 527
hudakz 0:84353c479782 528 /**
hudakz 0:84353c479782 529 * Used to print the USB Endpoint Descriptor.
hudakz 0:84353c479782 530 * @param ep_ptr Pointer to USB Endpoint Descriptor.
hudakz 0:84353c479782 531 */
hudakz 0:84353c479782 532 void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
hudakz 0:84353c479782 533
hudakz 0:84353c479782 534 private:
hudakz 0:84353c479782 535 void Initialize(); // Set all variables, endpoint structs etc. to default values
hudakz 0:84353c479782 536 BluetoothService *btService[BTD_NUM_SERVICES];
hudakz 0:84353c479782 537
hudakz 0:84353c479782 538 uint16_t PID, VID; // PID and VID of device connected
hudakz 0:84353c479782 539
hudakz 0:84353c479782 540 uint8_t pollInterval;
hudakz 0:84353c479782 541 bool bPollEnable;
hudakz 0:84353c479782 542
hudakz 0:84353c479782 543 bool pairWiiUsingSync; // True if pairing was done using the Wii SYNC button.
hudakz 0:84353c479782 544 bool checkRemoteName; // Used to check remote device's name before connecting.
hudakz 0:84353c479782 545 bool incomingPS4; // True if a PS4 controller is connecting
hudakz 0:84353c479782 546 uint8_t classOfDevice[3]; // Class of device of last device
hudakz 0:84353c479782 547
hudakz 0:84353c479782 548 /* Variables used by high level HCI task */
hudakz 0:84353c479782 549 uint8_t hci_state; // Current state of Bluetooth HCI connection
hudakz 0:84353c479782 550 uint16_t hci_counter; // Counter used for Bluetooth HCI reset loops
hudakz 0:84353c479782 551 uint16_t hci_num_reset_loops; // This value indicate how many times it should read before trying to reset
hudakz 0:84353c479782 552 uint16_t hci_event_flag; // HCI flags of received Bluetooth events
hudakz 0:84353c479782 553 uint8_t inquiry_counter;
hudakz 0:84353c479782 554
hudakz 0:84353c479782 555 uint8_t hcibuf[BULK_MAXPKTSIZE]; // General purpose buffer for HCI data
hudakz 0:84353c479782 556 uint8_t l2capinbuf[BULK_MAXPKTSIZE]; // General purpose buffer for L2CAP in data
hudakz 0:84353c479782 557 uint8_t l2capoutbuf[14]; // General purpose buffer for L2CAP out data
hudakz 0:84353c479782 558
hudakz 0:84353c479782 559 /* State machines */
hudakz 0:84353c479782 560 void HCI_event_task(); // Poll the HCI event pipe
hudakz 0:84353c479782 561 void HCI_task(); // HCI state machine
hudakz 0:84353c479782 562 void ACL_event_task(); // ACL input pipe
hudakz 0:84353c479782 563
hudakz 0:84353c479782 564 /* Used to set the Bluetooth Address internally to the PS3 Controllers */
hudakz 0:84353c479782 565 void setBdaddr(uint8_t* BDADDR);
hudakz 0:84353c479782 566 void setMoveBdaddr(uint8_t* BDADDR);
hudakz 0:84353c479782 567 };
hudakz 0:84353c479782 568
hudakz 0:84353c479782 569 /** All Bluetooth services should inherit this class. */
hudakz 0:84353c479782 570 class BluetoothService {
hudakz 0:84353c479782 571 public:
hudakz 0:84353c479782 572 BluetoothService(BTD *p) : pBtd(p) {
hudakz 0:84353c479782 573 if(pBtd)
hudakz 0:84353c479782 574 pBtd->registerBluetoothService(this); // Register it as a Bluetooth service
hudakz 0:84353c479782 575 };
hudakz 0:84353c479782 576 /**
hudakz 0:84353c479782 577 * Used to pass acldata to the Bluetooth service.
hudakz 0:84353c479782 578 * @param ACLData Pointer to the incoming acldata.
hudakz 0:84353c479782 579 */
hudakz 0:84353c479782 580 virtual void ACLData(uint8_t* ACLData) = 0;
hudakz 0:84353c479782 581 /** Used to run the different state machines in the Bluetooth service. */
hudakz 0:84353c479782 582 virtual void Run() = 0;
hudakz 0:84353c479782 583 /** Used to reset the Bluetooth service. */
hudakz 0:84353c479782 584 virtual void Reset() = 0;
hudakz 0:84353c479782 585 /** Used to disconnect both the L2CAP Channel and the HCI Connection for the Bluetooth service. */
hudakz 0:84353c479782 586 virtual void disconnect() = 0;
hudakz 0:84353c479782 587
hudakz 0:84353c479782 588 /**
hudakz 0:84353c479782 589 * Used to call your own function when the device is successfully initialized.
hudakz 0:84353c479782 590 * @param funcOnInit Function to call.
hudakz 0:84353c479782 591 */
hudakz 0:84353c479782 592 void attachOnInit(void (*funcOnInit)(void)) {
hudakz 0:84353c479782 593 pFuncOnInit = funcOnInit; // TODO: This really belong in a class of it's own as it is repeated several times
hudakz 0:84353c479782 594 };
hudakz 0:84353c479782 595
hudakz 0:84353c479782 596 protected:
hudakz 0:84353c479782 597 /**
hudakz 0:84353c479782 598 * Called when a device is successfully initialized.
hudakz 0:84353c479782 599 * Use attachOnInit(void (*funcOnInit)(void)) to call your own function.
hudakz 0:84353c479782 600 * This is useful for instance if you want to set the LEDs in a specific way.
hudakz 0:84353c479782 601 */
hudakz 0:84353c479782 602 virtual void onInit() = 0;
hudakz 0:84353c479782 603
hudakz 0:84353c479782 604 /** Used to check if the incoming L2CAP data matches the HCI Handle */
hudakz 0:84353c479782 605 bool checkHciHandle(uint8_t *buf, uint16_t handle) {
hudakz 0:84353c479782 606 return (buf[0] == (handle & 0xFF)) && (buf[1] == ((handle >> 8) | 0x20));
hudakz 0:84353c479782 607 }
hudakz 0:84353c479782 608
hudakz 0:84353c479782 609 /** Pointer to function called in onInit(). */
hudakz 0:84353c479782 610 void (*pFuncOnInit)(void);
hudakz 0:84353c479782 611
hudakz 0:84353c479782 612 /** Pointer to BTD instance. */
hudakz 0:84353c479782 613 BTD *pBtd;
hudakz 0:84353c479782 614
hudakz 0:84353c479782 615 /** The HCI Handle for the connection. */
hudakz 0:84353c479782 616 uint16_t hci_handle;
hudakz 0:84353c479782 617
hudakz 0:84353c479782 618 /** L2CAP flags of received Bluetooth events. */
hudakz 0:84353c479782 619 uint32_t l2cap_event_flag;
hudakz 0:84353c479782 620
hudakz 0:84353c479782 621 /** Identifier for L2CAP commands. */
hudakz 0:84353c479782 622 uint8_t identifier;
hudakz 0:84353c479782 623 };
hudakz 0:84353c479782 624
hudakz 0:84353c479782 625 #endif