takayuki ikai / Mbed 2 deprecated BlueWii

Dependencies:   mbed

Committer:
ikaii
Date:
Mon Dec 06 17:02:12 2010 +0000
Revision:
0:010465683d59

        

Who changed what in which revision?

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