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:
Sat Jun 11 19:43:00 2011 +0000
Revision:
5:378c208637e3
Parent:
2:0118da9e5169

        

Who changed what in which revision?

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