Test version of BlueUSB stack. Includes SDP and RFCOMM. As Client it allows to connect to my fischertechnik TX Controller. As Server it echo\\\\\\\'s characters to Putty. PIN=1234

Dependencies:   mbed myUSBHost AvailableMemory

Dependents:   mbed_TANK_Kinect myBlueUSB_ros ftusbClass

Committer:
networker
Date:
Mon Apr 04 16:41:03 2011 +0000
Revision:
0:81ed8b6e4a8b
initial revision

Who changed what in which revision?

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