Bluetooth support for MBED with $2 Bluetooth dongles. Includes a USB host and built in support for bluetooth HID devices such as mice, keyboards and wii controllers.

Dependencies:   mbed

Committer:
peterbarrett1967
Date:
Sat Apr 10 00:30:24 2010 +0000
Revision:
0:606b230e5b4a

        

Who changed what in which revision?

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