Bluetooth support for MBED with $2 Bluetooth dongles. Includes a USB host and built in support for bluetooth HID devices such as mice, keyboards and wii controllers.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers hci.h Source File

hci.h

00001 /*
00002 Copyright (c) 2010 Peter Barrett
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a copy
00005 of this software and associated documentation files (the "Software"), to deal
00006 in the Software without restriction, including without limitation the rights
00007 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008 copies of the Software, and to permit persons to whom the Software is
00009 furnished to do so, subject to the following conditions:
00010 
00011 The above copyright notice and this permission notice shall be included in
00012 all copies or substantial portions of the Software.
00013 
00014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00020 THE SOFTWARE.
00021 */
00022 
00023 #ifndef HCI_H_INCLUDED
00024 #define HCI_H_INCLUDED
00025 
00026 #include "Socket.h"
00027 
00028 #pragma pack(1)
00029 
00030 #define ERR_HCI_DEVICE_NOT_FOUND -300
00031 
00032 class HCI;
00033 class HCITransport;
00034 class BTDevice;
00035 
00036 typedef struct
00037 {
00038     u8  addr[6];
00039 } BD_ADDR;
00040 
00041 typedef struct
00042 {
00043     BD_ADDR bdaddr;
00044     u8  pscan_rep_mode;
00045     u8  pscan_period_mode;
00046     u8  pscan_mode;
00047     u8  dev_class[3];
00048     u16 clock_offset;
00049 } inquiry_info;
00050 
00051 typedef struct
00052 {
00053     u8  status;
00054     u16 handle;
00055     BD_ADDR bdaddr;
00056     u8  link_type;
00057     u8  encr_mode;
00058 } connection_info;
00059 
00060 //  Address struct for creating L2CAP sockets
00061 typedef struct {
00062     SocketAddrHdr hdr;
00063     BD_ADDR bdaddr;
00064     u16 psm;
00065 } L2CAPAddr;
00066 
00067 #pragma pack(4)
00068 
00069 class BTDevice;
00070 typedef struct
00071 {
00072     public:
00073     SocketInternal si;
00074     BTDevice* btdevice;
00075     u16 scid;
00076     u16 dcid;
00077 } L2CAPSocket;
00078 
00079 #define MAX_HCL_NAME_LENGTH 20  // TODO - BTDevice wants to be a multiple of 4
00080 
00081 //  BTDevice encapsulates individual device state
00082 //  It provides L2CAP layer sockets
00083 
00084 class BTDevice : public SocketHandler
00085 {
00086     public:
00087     HCITransport* _transport;
00088     inquiry_info  _info;
00089     u16 _handle;     // acl connection handle
00090     u8  _state;      // connection state
00091     u8  _txid;
00092     char   _name[MAX_HCL_NAME_LENGTH];
00093 
00094     void Init();
00095 
00096     BD_ADDR* GetAddress() { return &_info.bdaddr; }
00097 
00098     //  Called from HCI
00099     void ACLRecv(const u8* data, int len);
00100 
00101     // SocketHandler
00102     virtual int Open(SocketInternal* sock, SocketAddrHdr* addr);
00103     virtual int Send(SocketInternal* sock, const u8* data, int len);
00104     virtual int Close(SocketInternal* sock);
00105 
00106 private:
00107     L2CAPSocket* SCIDToSocket(int scid);
00108     int Send(const u8* data, int len);
00109     int Send(u8 c, u8 id, u16* params, int count);
00110     int Connect(int scid, int psm);
00111     int Disconnect(int scid, int dcid);
00112     int ConfigureRequest(int dcid);
00113     int ConfigureResponse(u8 rxid, int dcid);
00114     int DisconnectResponse(u8 rxid, int scid, int dcid);
00115     void Control(const u8* data, int len);
00116 };
00117 
00118 enum HCI_CALLBACK_EVENT
00119 {
00120     CALLBACK_NONE,
00121     CALLBACK_READY,
00122     CALLBACK_INQUIRY_RESULT,
00123     CALLBACK_INQUIRY_DONE,
00124     CALLBACK_REMOTE_NAME,
00125     CALLBACK_CONNECTION_COMPLETE,
00126     CALLBACK_CONNECTION_FAILED
00127 };
00128 
00129 //  L2CAP Protocol/Service Multiplexor (PSM) values
00130 
00131 #define L2CAP_PSM_ANY                   0x0000  /* Any/Invalid PSM */
00132 #define L2CAP_PSM_SDP                   0x0001  /* Service Discovery Protocol */
00133 #define L2CAP_PSM_RFCOMM                0x0003  /* RFCOMM protocol */
00134 #define L2CAP_PSM_TCP                   0x0005  /* Telephony Control Protocol */
00135 #define L2CAP_PSM_TCS                   0x0007  /* TCS cordless */
00136 #define L2CAP_PSM_BNEP                  0x000f  /* Bluetooth Network Encapsulation Protocol*/
00137 #define L2CAP_PSM_HID_CNTL              0x0011  /* HID Control */
00138 #define L2CAP_PSM_HID_INTR              0x0013  /* HID Interrupt */
00139 #define L2CAP_PSM_ESDP                  0x0015  /* Extended Service Discovery Profile */
00140 #define L2CAP_PSM_AVCTP                 0x0017  /* Audio/Visual Control Transport Protocol */
00141 #define L2CAP_PSM_AVDTP                 0x0019  /* Audio/Visual Distribution */
00142 
00143 //  Callback from inquiry
00144 typedef int (*HCICallback)(HCI* hci, HCI_CALLBACK_EVENT evt, const u8* data, int len);
00145 
00146 #define MAX_BTDEVICES 8
00147 
00148 class HCITransport;
00149 class HCI : public SocketHandler
00150 {
00151     HCITransport* _transport;
00152     HCICallback _callback;
00153     BD_ADDR  _localAddr;
00154 
00155     BTDevice _devices[MAX_BTDEVICES];
00156     int _deviceCount;
00157 
00158     int _acl_mtu;
00159     int _acl_max_pkt;
00160     int _sco_mtu;
00161     int _sco_max_pkt;
00162 
00163     int _state;
00164 
00165     public:
00166 
00167     //  Open a local adapter
00168     int Open(HCITransport* transport, HCICallback callback);
00169 
00170     //  Return list of discovered addreses
00171     int GetDevices(BTDevice** devices, int maxDevices);
00172 
00173     //  Lookup a device by address or handle
00174     BTDevice* Find(const BD_ADDR* addr);
00175     BTDevice* Find(int handle);
00176 
00177     //  Disconnect from a remote device
00178     int Disconnect(const BD_ADDR* addr);
00179     int DisconnectAll();
00180 
00181     //  see what devies are in the system
00182     int Inquiry(int duration = 10);
00183 
00184     //  get a name, delivered in callback
00185     int RemoteNameRequest(const BD_ADDR* addr);
00186 
00187     //  Connect to a remote device
00188     int CreateConnection(const BD_ADDR* remoteAddr);
00189 
00190     bool Busy();
00191 
00192     //  called from transport
00193     void HCIRecv(const u8* data, int len);
00194 
00195     //  called from transport
00196     void ACLRecv(const u8* data, int len);
00197 
00198     //  SocketHandler methods for maintaining L2CAP sockets
00199     virtual int Open(SocketInternal* sock, SocketAddrHdr* addr);
00200     virtual int Send(SocketInternal* sock, const u8* data, int len);
00201     virtual int Close(SocketInternal* sock);
00202 
00203     private:
00204     void    InquiryResult(const inquiry_info* info);
00205     void    RemoteName(const BD_ADDR* addr, const char* name);
00206     void    ConnectComplete(const connection_info* info);
00207     void    DisconnectComplete(int handle);
00208     int     SendCmd(int cmd, const u8* params = 0, int len = 0);
00209     void    OnCommandComplete(int cmd, const u8* data, int len);
00210     void    Callback(HCI_CALLBACK_EVENT c, const u8* data, int len);
00211     int     PinCodeReply(const u8* data);
00212 };
00213 
00214 class HCITransport
00215 {
00216 protected:
00217     HCI* _target;
00218 public:
00219     void Set(HCI* target) { _target = target; };
00220     virtual void HCISend(const u8* data, int len) = 0;
00221     virtual void ACLSend(const u8* data, int len) = 0;
00222 };
00223 
00224 #endif