class library to access fischertechnik interfaces via USB

Dependencies:   FatFileSystem mbed myBlueUSB neigbourhood rfcomm sdp

Committer:
networker
Date:
Wed Jun 15 19:12:25 2011 +0000
Revision:
0:7da612835693
initial version
; Bluetooth support incomplete

Who changed what in which revision?

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