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:
Sun Jun 19 13:19:52 2011 +0000
Revision:
8:d29e42b5ae53
Parent:
7:99068afea04d
Child:
9:c76a3f8f9245
added seteventfilter

Who changed what in which revision?

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