3/5

Dependencies:   mbed

Committer:
la00noix
Date:
Wed Feb 27 04:58:52 2019 +0000
Revision:
0:a56be39653d0
a

Who changed what in which revision?

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