Based on Peter Barrett\'s work on BlueUSB, I added support for the PS3 Sixaxis controller (both USB and Bluetooth). When connecting a Sixaxis via USB, it will be paired with the (hardcoded) MAC address of my Bluetooth dongle.

Dependencies:   mbed

Dependents:   PS3_BlueUSB_downstate

Committer:
BartJanssens
Date:
Tue Apr 26 16:09:17 2011 +0000
Revision:
0:99a111b75cb4

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
BartJanssens 0:99a111b75cb4 1 /*
BartJanssens 0:99a111b75cb4 2 Copyright (c) 2010 Peter Barrett
BartJanssens 0:99a111b75cb4 3
BartJanssens 0:99a111b75cb4 4 Permission is hereby granted, free of charge, to any person obtaining a copy
BartJanssens 0:99a111b75cb4 5 of this software and associated documentation files (the "Software"), to deal
BartJanssens 0:99a111b75cb4 6 in the Software without restriction, including without limitation the rights
BartJanssens 0:99a111b75cb4 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
BartJanssens 0:99a111b75cb4 8 copies of the Software, and to permit persons to whom the Software is
BartJanssens 0:99a111b75cb4 9 furnished to do so, subject to the following conditions:
BartJanssens 0:99a111b75cb4 10
BartJanssens 0:99a111b75cb4 11 The above copyright notice and this permission notice shall be included in
BartJanssens 0:99a111b75cb4 12 all copies or substantial portions of the Software.
BartJanssens 0:99a111b75cb4 13
BartJanssens 0:99a111b75cb4 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
BartJanssens 0:99a111b75cb4 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
BartJanssens 0:99a111b75cb4 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
BartJanssens 0:99a111b75cb4 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
BartJanssens 0:99a111b75cb4 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
BartJanssens 0:99a111b75cb4 19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
BartJanssens 0:99a111b75cb4 20 THE SOFTWARE.
BartJanssens 0:99a111b75cb4 21 */
BartJanssens 0:99a111b75cb4 22
BartJanssens 0:99a111b75cb4 23 #ifndef HCI_H_INCLUDED
BartJanssens 0:99a111b75cb4 24 #define HCI_H_INCLUDED
BartJanssens 0:99a111b75cb4 25
BartJanssens 0:99a111b75cb4 26 #include "Socket.h"
BartJanssens 0:99a111b75cb4 27
BartJanssens 0:99a111b75cb4 28 #pragma pack(1)
BartJanssens 0:99a111b75cb4 29
BartJanssens 0:99a111b75cb4 30 #define ERR_HCI_DEVICE_NOT_FOUND -300
BartJanssens 0:99a111b75cb4 31
BartJanssens 0:99a111b75cb4 32 class HCI;
BartJanssens 0:99a111b75cb4 33 class HCITransport;
BartJanssens 0:99a111b75cb4 34 class BTDevice;
BartJanssens 0:99a111b75cb4 35
BartJanssens 0:99a111b75cb4 36 typedef struct
BartJanssens 0:99a111b75cb4 37 {
BartJanssens 0:99a111b75cb4 38 u8 addr[6];
BartJanssens 0:99a111b75cb4 39 } BD_ADDR;
BartJanssens 0:99a111b75cb4 40
BartJanssens 0:99a111b75cb4 41 typedef struct
BartJanssens 0:99a111b75cb4 42 {
BartJanssens 0:99a111b75cb4 43 BD_ADDR bdaddr;
BartJanssens 0:99a111b75cb4 44 u8 pscan_rep_mode;
BartJanssens 0:99a111b75cb4 45 u8 pscan_period_mode;
BartJanssens 0:99a111b75cb4 46 u8 pscan_mode;
BartJanssens 0:99a111b75cb4 47 u8 dev_class[3];
BartJanssens 0:99a111b75cb4 48 u16 clock_offset;
BartJanssens 0:99a111b75cb4 49 } inquiry_info;
BartJanssens 0:99a111b75cb4 50
BartJanssens 0:99a111b75cb4 51 typedef struct
BartJanssens 0:99a111b75cb4 52 {
BartJanssens 0:99a111b75cb4 53 BD_ADDR bdaddr;
BartJanssens 0:99a111b75cb4 54 u8 dev_class[3];
BartJanssens 0:99a111b75cb4 55 u8 link_type;
BartJanssens 0:99a111b75cb4 56 } request_info;
BartJanssens 0:99a111b75cb4 57
BartJanssens 0:99a111b75cb4 58 typedef struct
BartJanssens 0:99a111b75cb4 59 {
BartJanssens 0:99a111b75cb4 60 u8 status;
BartJanssens 0:99a111b75cb4 61 u16 handle;
BartJanssens 0:99a111b75cb4 62 BD_ADDR bdaddr;
BartJanssens 0:99a111b75cb4 63 u8 link_type;
BartJanssens 0:99a111b75cb4 64 u8 encr_mode;
BartJanssens 0:99a111b75cb4 65 } connection_info;
BartJanssens 0:99a111b75cb4 66
BartJanssens 0:99a111b75cb4 67 // Address struct for creating L2CAP sockets
BartJanssens 0:99a111b75cb4 68 typedef struct {
BartJanssens 0:99a111b75cb4 69 SocketAddrHdr hdr;
BartJanssens 0:99a111b75cb4 70 BD_ADDR bdaddr;
BartJanssens 0:99a111b75cb4 71 u16 psm;
BartJanssens 0:99a111b75cb4 72 } L2CAPAddr;
BartJanssens 0:99a111b75cb4 73
BartJanssens 0:99a111b75cb4 74 #pragma pack(4)
BartJanssens 0:99a111b75cb4 75
BartJanssens 0:99a111b75cb4 76 class BTDevice;
BartJanssens 0:99a111b75cb4 77 typedef struct
BartJanssens 0:99a111b75cb4 78 {
BartJanssens 0:99a111b75cb4 79 public:
BartJanssens 0:99a111b75cb4 80 SocketInternal si;
BartJanssens 0:99a111b75cb4 81 BTDevice* btdevice;
BartJanssens 0:99a111b75cb4 82 u16 scid;
BartJanssens 0:99a111b75cb4 83 u16 dcid;
BartJanssens 0:99a111b75cb4 84 } L2CAPSocket;
BartJanssens 0:99a111b75cb4 85
BartJanssens 0:99a111b75cb4 86 #define MAX_HCL_NAME_LENGTH 20 // TODO - BTDevice wants to be a multiple of 4
BartJanssens 0:99a111b75cb4 87 #define MAX_PORTS 3
BartJanssens 0:99a111b75cb4 88
BartJanssens 0:99a111b75cb4 89 // BTDevice encapsulates individual device state
BartJanssens 0:99a111b75cb4 90 // It provides L2CAP layer sockets
BartJanssens 0:99a111b75cb4 91
BartJanssens 0:99a111b75cb4 92 class BTDevice : public SocketHandler
BartJanssens 0:99a111b75cb4 93 {
BartJanssens 0:99a111b75cb4 94 public:
BartJanssens 0:99a111b75cb4 95 HCITransport* _transport;
BartJanssens 0:99a111b75cb4 96 inquiry_info _info;
BartJanssens 0:99a111b75cb4 97 u16 _handle; // acl connection handle
BartJanssens 0:99a111b75cb4 98 u8 _state; // connection state
BartJanssens 0:99a111b75cb4 99 u8 _txid;
BartJanssens 0:99a111b75cb4 100 char _name[MAX_HCL_NAME_LENGTH];
BartJanssens 0:99a111b75cb4 101
BartJanssens 0:99a111b75cb4 102 void Init();
BartJanssens 0:99a111b75cb4 103
BartJanssens 0:99a111b75cb4 104 BD_ADDR* GetAddress() { return &_info.bdaddr; }
BartJanssens 0:99a111b75cb4 105
BartJanssens 0:99a111b75cb4 106 // Called from HCI
BartJanssens 0:99a111b75cb4 107 void ACLRecv(const BD_ADDR* addr, const u8* data, int len);
BartJanssens 0:99a111b75cb4 108
BartJanssens 0:99a111b75cb4 109 // SocketHandler
BartJanssens 0:99a111b75cb4 110 virtual int Open(SocketInternal* sock, SocketAddrHdr* addr);
BartJanssens 0:99a111b75cb4 111 virtual int Send(SocketInternal* sock, const u8* data, int len);
BartJanssens 0:99a111b75cb4 112 virtual int Close(SocketInternal* sock);
BartJanssens 0:99a111b75cb4 113 // added by Bart Janssens
BartJanssens 0:99a111b75cb4 114 virtual int Create(SocketInternal* sock, SocketAddrHdr* addr);
BartJanssens 0:99a111b75cb4 115 virtual int Accept(SocketInternal* sock, SocketAddrHdr* addr);
BartJanssens 0:99a111b75cb4 116
BartJanssens 0:99a111b75cb4 117 private:
BartJanssens 0:99a111b75cb4 118 L2CAPSocket* SCIDToSocket(int scid);
BartJanssens 0:99a111b75cb4 119 int Send(const u8* data, int len);
BartJanssens 0:99a111b75cb4 120 int Send(u8 c, u8 id, u16* params, int count);
BartJanssens 0:99a111b75cb4 121 int Connect(int scid, int psm);
BartJanssens 0:99a111b75cb4 122 int Disconnect(int scid, int dcid);
BartJanssens 0:99a111b75cb4 123 int ConfigureRequest(int dcid);
BartJanssens 0:99a111b75cb4 124 int ConfigureResponse(u8 rxid, int dcid);
BartJanssens 0:99a111b75cb4 125 int DisconnectResponse(u8 rxid, int scid, int dcid);
BartJanssens 0:99a111b75cb4 126 // added by Bart Janssens
BartJanssens 0:99a111b75cb4 127 int AcceptResponse(u8 rxid, int scid, int dcid);
BartJanssens 0:99a111b75cb4 128 int RefuseResponse(u8 rxid);
BartJanssens 0:99a111b75cb4 129 //
BartJanssens 0:99a111b75cb4 130 void Control(const BD_ADDR* addr, const u8* data, int len);
BartJanssens 0:99a111b75cb4 131 };
BartJanssens 0:99a111b75cb4 132
BartJanssens 0:99a111b75cb4 133 enum HCI_CALLBACK_EVENT
BartJanssens 0:99a111b75cb4 134 {
BartJanssens 0:99a111b75cb4 135 CALLBACK_NONE,
BartJanssens 0:99a111b75cb4 136 CALLBACK_READY,
BartJanssens 0:99a111b75cb4 137 CALLBACK_INQUIRY_RESULT,
BartJanssens 0:99a111b75cb4 138 CALLBACK_INQUIRY_DONE,
BartJanssens 0:99a111b75cb4 139 CALLBACK_REMOTE_NAME,
BartJanssens 0:99a111b75cb4 140 CALLBACK_CONNECTION_COMPLETE,
BartJanssens 0:99a111b75cb4 141 CALLBACK_CONNECTION_FAILED
BartJanssens 0:99a111b75cb4 142 };
BartJanssens 0:99a111b75cb4 143
BartJanssens 0:99a111b75cb4 144 // L2CAP Protocol/Service Multiplexor (PSM) values
BartJanssens 0:99a111b75cb4 145
BartJanssens 0:99a111b75cb4 146 #define L2CAP_PSM_ANY 0x0000 /* Any/Invalid PSM */
BartJanssens 0:99a111b75cb4 147 #define L2CAP_PSM_SDP 0x0001 /* Service Discovery Protocol */
BartJanssens 0:99a111b75cb4 148 #define L2CAP_PSM_RFCOMM 0x0003 /* RFCOMM protocol */
BartJanssens 0:99a111b75cb4 149 #define L2CAP_PSM_TCP 0x0005 /* Telephony Control Protocol */
BartJanssens 0:99a111b75cb4 150 #define L2CAP_PSM_TCS 0x0007 /* TCS cordless */
BartJanssens 0:99a111b75cb4 151 #define L2CAP_PSM_BNEP 0x000f /* Bluetooth Network Encapsulation Protocol*/
BartJanssens 0:99a111b75cb4 152 #define L2CAP_PSM_HID_CNTL 0x0011 /* HID Control */
BartJanssens 0:99a111b75cb4 153 #define L2CAP_PSM_HID_INTR 0x0013 /* HID Interrupt */
BartJanssens 0:99a111b75cb4 154 #define L2CAP_PSM_ESDP 0x0015 /* Extended Service Discovery Profile */
BartJanssens 0:99a111b75cb4 155 #define L2CAP_PSM_AVCTP 0x0017 /* Audio/Visual Control Transport Protocol */
BartJanssens 0:99a111b75cb4 156 #define L2CAP_PSM_AVDTP 0x0019 /* Audio/Visual Distribution */
BartJanssens 0:99a111b75cb4 157
BartJanssens 0:99a111b75cb4 158 /* Connection response results */
BartJanssens 0:99a111b75cb4 159 #define L2CAP_CONN_SUCCESS 0x0000
BartJanssens 0:99a111b75cb4 160 #define L2CAP_CONN_PND 0x0001
BartJanssens 0:99a111b75cb4 161 #define L2CAP_CONN_REF_PSM 0x0002
BartJanssens 0:99a111b75cb4 162 #define L2CAP_CONN_REF_SEC 0x0003
BartJanssens 0:99a111b75cb4 163 #define L2CAP_CONN_REF_RES 0x0004
BartJanssens 0:99a111b75cb4 164 #define L2CAP_CONN_CFG_TO 0x0005 /* Implementation specific result */
BartJanssens 0:99a111b75cb4 165
BartJanssens 0:99a111b75cb4 166
BartJanssens 0:99a111b75cb4 167
BartJanssens 0:99a111b75cb4 168 // Callback from inquiry
BartJanssens 0:99a111b75cb4 169 typedef int (*HCICallback)(HCI* hci, HCI_CALLBACK_EVENT evt, const u8* data, int len);
BartJanssens 0:99a111b75cb4 170
BartJanssens 0:99a111b75cb4 171 #define MAX_BTDEVICES 8
BartJanssens 0:99a111b75cb4 172
BartJanssens 0:99a111b75cb4 173 class HCITransport;
BartJanssens 0:99a111b75cb4 174 class HCI : public SocketHandler
BartJanssens 0:99a111b75cb4 175 {
BartJanssens 0:99a111b75cb4 176 HCITransport* _transport;
BartJanssens 0:99a111b75cb4 177 HCICallback _callback;
BartJanssens 0:99a111b75cb4 178 BD_ADDR _localAddr;
BartJanssens 0:99a111b75cb4 179
BartJanssens 0:99a111b75cb4 180 BTDevice _devices[MAX_BTDEVICES];
BartJanssens 0:99a111b75cb4 181 int _deviceCount;
BartJanssens 0:99a111b75cb4 182
BartJanssens 0:99a111b75cb4 183 int _acl_mtu;
BartJanssens 0:99a111b75cb4 184 int _acl_max_pkt;
BartJanssens 0:99a111b75cb4 185 int _sco_mtu;
BartJanssens 0:99a111b75cb4 186 int _sco_max_pkt;
BartJanssens 0:99a111b75cb4 187
BartJanssens 0:99a111b75cb4 188 int _state;
BartJanssens 0:99a111b75cb4 189
BartJanssens 0:99a111b75cb4 190 public:
BartJanssens 0:99a111b75cb4 191
BartJanssens 0:99a111b75cb4 192 // Open a local adapter
BartJanssens 0:99a111b75cb4 193 int Open(HCITransport* transport, HCICallback callback);
BartJanssens 0:99a111b75cb4 194
BartJanssens 0:99a111b75cb4 195 // Return list of discovered addreses
BartJanssens 0:99a111b75cb4 196 int GetDevices(BTDevice** devices, int maxDevices);
BartJanssens 0:99a111b75cb4 197
BartJanssens 0:99a111b75cb4 198 // Lookup a device by address or handle
BartJanssens 0:99a111b75cb4 199 BTDevice* Find(const BD_ADDR* addr);
BartJanssens 0:99a111b75cb4 200 BTDevice* Find(int handle);
BartJanssens 0:99a111b75cb4 201
BartJanssens 0:99a111b75cb4 202 // Disconnect from a remote device
BartJanssens 0:99a111b75cb4 203 int Disconnect(const BD_ADDR* addr);
BartJanssens 0:99a111b75cb4 204 int DisconnectAll();
BartJanssens 0:99a111b75cb4 205
BartJanssens 0:99a111b75cb4 206 // see what devies are in the system
BartJanssens 0:99a111b75cb4 207 int Inquiry(int duration = 10);
BartJanssens 0:99a111b75cb4 208
BartJanssens 0:99a111b75cb4 209 // added by Bart Janssens
BartJanssens 0:99a111b75cb4 210 int WriteScanEnable();
BartJanssens 0:99a111b75cb4 211
BartJanssens 0:99a111b75cb4 212 int AcceptConnection(const BD_ADDR* addr);
BartJanssens 0:99a111b75cb4 213
BartJanssens 0:99a111b75cb4 214 // get a name, delivered in callback
BartJanssens 0:99a111b75cb4 215 int RemoteNameRequest(const BD_ADDR* addr);
BartJanssens 0:99a111b75cb4 216
BartJanssens 0:99a111b75cb4 217 // Connect to a remote device
BartJanssens 0:99a111b75cb4 218 int CreateConnection(const BD_ADDR* remoteAddr);
BartJanssens 0:99a111b75cb4 219
BartJanssens 0:99a111b75cb4 220 bool Busy();
BartJanssens 0:99a111b75cb4 221
BartJanssens 0:99a111b75cb4 222 // called from transport
BartJanssens 0:99a111b75cb4 223 void HCIRecv(const u8* data, int len);
BartJanssens 0:99a111b75cb4 224
BartJanssens 0:99a111b75cb4 225 // called from transport
BartJanssens 0:99a111b75cb4 226 void ACLRecv(const u8* data, int len);
BartJanssens 0:99a111b75cb4 227
BartJanssens 0:99a111b75cb4 228 // SocketHandler methods for maintaining L2CAP sockets
BartJanssens 0:99a111b75cb4 229 virtual int Open(SocketInternal* sock, SocketAddrHdr* addr);
BartJanssens 0:99a111b75cb4 230 virtual int Send(SocketInternal* sock, const u8* data, int len);
BartJanssens 0:99a111b75cb4 231 virtual int Close(SocketInternal* sock);
BartJanssens 0:99a111b75cb4 232 // added by Bart Janssens
BartJanssens 0:99a111b75cb4 233 virtual int Create(SocketInternal* sock, SocketAddrHdr* addr);
BartJanssens 0:99a111b75cb4 234 virtual int Accept(SocketInternal* sock, SocketAddrHdr* addr);
BartJanssens 0:99a111b75cb4 235
BartJanssens 0:99a111b75cb4 236 private:
BartJanssens 0:99a111b75cb4 237 void InquiryResult(const inquiry_info* info);
BartJanssens 0:99a111b75cb4 238 void RemoteName(const BD_ADDR* addr, const char* name);
BartJanssens 0:99a111b75cb4 239 void ConnectComplete(const connection_info* info);
BartJanssens 0:99a111b75cb4 240 void ConnectRequest(const request_info* info);
BartJanssens 0:99a111b75cb4 241 void DisconnectComplete(int handle);
BartJanssens 0:99a111b75cb4 242 int SendCmd(int cmd, const u8* params = 0, int len = 0);
BartJanssens 0:99a111b75cb4 243 void OnCommandComplete(int cmd, const u8* data, int len);
BartJanssens 0:99a111b75cb4 244 void Callback(HCI_CALLBACK_EVENT c, const u8* data, int len);
BartJanssens 0:99a111b75cb4 245 int PinCodeReply(const u8* data);
BartJanssens 0:99a111b75cb4 246 };
BartJanssens 0:99a111b75cb4 247
BartJanssens 0:99a111b75cb4 248 class HCITransport
BartJanssens 0:99a111b75cb4 249 {
BartJanssens 0:99a111b75cb4 250 protected:
BartJanssens 0:99a111b75cb4 251 HCI* _target;
BartJanssens 0:99a111b75cb4 252 public:
BartJanssens 0:99a111b75cb4 253 void Set(HCI* target) { _target = target; };
BartJanssens 0:99a111b75cb4 254 virtual void HCISend(const u8* data, int len) = 0;
BartJanssens 0:99a111b75cb4 255 virtual void ACLSend(const u8* data, int len) = 0;
BartJanssens 0:99a111b75cb4 256 };
BartJanssens 0:99a111b75cb4 257
BartJanssens 0:99a111b75cb4 258 #endif