local fix version of myBlueUSB (http://mbed.org/users/networker/code/myBlueUSB/). - merge deleted files which are required to compile. - enable echo back of received data via RFCOMM.

Dependencies:   AvailableMemory FatFileSystem mbed myUSBHost

Committer:
nobukuma
Date:
Sun Dec 08 21:52:09 2013 +0000
Revision:
2:9f25a7fa1a54
Parent:
0:003889bc474f
???BT??????????????????; ?????????????????

Who changed what in which revision?

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