Diff: hci.h
- Revision:
- 0:f6f434d9a03a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hci.h Sat Dec 17 02:17:39 2011 +0000
@@ -0,0 +1,224 @@
+/*
+Copyright (c) 2010 Peter Barrett
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef HCI_H_INCLUDED
+#define HCI_H_INCLUDED
+
+#include "Socket.h"
+
+#pragma pack(1)
+
+#define ERR_HCI_DEVICE_NOT_FOUND -300
+
+class HCI;
+class HCITransport;
+class BTDevice;
+
+typedef struct
+{
+ u8 addr[6];
+} BD_ADDR;
+
+typedef struct
+{
+ BD_ADDR bdaddr;
+ u8 pscan_rep_mode;
+ u8 pscan_period_mode;
+ u8 pscan_mode;
+ u8 dev_class[3];
+ u16 clock_offset;
+} inquiry_info;
+
+typedef struct
+{
+ u8 status;
+ u16 handle;
+ BD_ADDR bdaddr;
+ u8 link_type;
+ u8 encr_mode;
+} connection_info;
+
+// Address struct for creating L2CAP sockets
+typedef struct {
+ SocketAddrHdr hdr;
+ BD_ADDR bdaddr;
+ u16 psm;
+} L2CAPAddr;
+
+#pragma pack(4)
+
+class BTDevice;
+typedef struct
+{
+ public:
+ SocketInternal si;
+ BTDevice* btdevice;
+ u16 scid;
+ u16 dcid;
+} L2CAPSocket;
+
+#define MAX_HCL_NAME_LENGTH 20 // TODO - BTDevice wants to be a multiple of 4
+
+// BTDevice encapsulates individual device state
+// It provides L2CAP layer sockets
+
+class BTDevice : public SocketHandler
+{
+ public:
+ HCITransport* _transport;
+ inquiry_info _info;
+ u16 _handle; // acl connection handle
+ u8 _state; // connection state
+ u8 _txid;
+ char _name[MAX_HCL_NAME_LENGTH];
+
+ void Init();
+
+ BD_ADDR* GetAddress() { return &_info.bdaddr; }
+
+ // Called from HCI
+ void ACLRecv(const u8* data, int len);
+
+ // SocketHandler
+ virtual int Open(SocketInternal* sock, SocketAddrHdr* addr);
+ virtual int Send(SocketInternal* sock, const u8* data, int len);
+ virtual int Close(SocketInternal* sock);
+
+private:
+ L2CAPSocket* SCIDToSocket(int scid);
+ int Send(const u8* data, int len);
+ int Send(u8 c, u8 id, u16* params, int count);
+ int Connect(int scid, int psm);
+ int Disconnect(int scid, int dcid);
+ int ConfigureRequest(int dcid);
+ int ConfigureResponse(u8 rxid, int dcid);
+ int DisconnectResponse(u8 rxid, int scid, int dcid);
+ void Control(const u8* data, int len);
+};
+
+enum HCI_CALLBACK_EVENT
+{
+ CALLBACK_NONE,
+ CALLBACK_READY,
+ CALLBACK_INQUIRY_RESULT,
+ CALLBACK_INQUIRY_DONE,
+ CALLBACK_REMOTE_NAME,
+ CALLBACK_CONNECTION_COMPLETE,
+ CALLBACK_CONNECTION_FAILED
+};
+
+// L2CAP Protocol/Service Multiplexor (PSM) values
+
+#define L2CAP_PSM_ANY 0x0000 /* Any/Invalid PSM */
+#define L2CAP_PSM_SDP 0x0001 /* Service Discovery Protocol */
+#define L2CAP_PSM_RFCOMM 0x0003 /* RFCOMM protocol */
+#define L2CAP_PSM_TCP 0x0005 /* Telephony Control Protocol */
+#define L2CAP_PSM_TCS 0x0007 /* TCS cordless */
+#define L2CAP_PSM_BNEP 0x000f /* Bluetooth Network Encapsulation Protocol*/
+#define L2CAP_PSM_HID_CNTL 0x0011 /* HID Control */
+#define L2CAP_PSM_HID_INTR 0x0013 /* HID Interrupt */
+#define L2CAP_PSM_ESDP 0x0015 /* Extended Service Discovery Profile */
+#define L2CAP_PSM_AVCTP 0x0017 /* Audio/Visual Control Transport Protocol */
+#define L2CAP_PSM_AVDTP 0x0019 /* Audio/Visual Distribution */
+
+// Callback from inquiry
+typedef int (*HCICallback)(HCI* hci, HCI_CALLBACK_EVENT evt, const u8* data, int len);
+
+#define MAX_BTDEVICES 8
+
+class HCITransport;
+class HCI : public SocketHandler
+{
+ HCITransport* _transport;
+ HCICallback _callback;
+ BD_ADDR _localAddr;
+
+ BTDevice _devices[MAX_BTDEVICES];
+ int _deviceCount;
+
+ int _acl_mtu;
+ int _acl_max_pkt;
+ int _sco_mtu;
+ int _sco_max_pkt;
+
+ int _state;
+
+ public:
+
+ // Open a local adapter
+ int Open(HCITransport* transport, HCICallback callback);
+
+ // Return list of discovered addreses
+ int GetDevices(BTDevice** devices, int maxDevices);
+
+ // Lookup a device by address or handle
+ BTDevice* Find(const BD_ADDR* addr);
+ BTDevice* Find(int handle);
+
+ // Disconnect from a remote device
+ int Disconnect(const BD_ADDR* addr);
+ int DisconnectAll();
+
+ // see what devies are in the system
+ int Inquiry(int duration = 10);
+
+ // get a name, delivered in callback
+ int RemoteNameRequest(const BD_ADDR* addr);
+
+ // Connect to a remote device
+ int CreateConnection(const BD_ADDR* remoteAddr);
+
+ bool Busy();
+
+ // called from transport
+ void HCIRecv(const u8* data, int len);
+
+ // called from transport
+ void ACLRecv(const u8* data, int len);
+
+ // SocketHandler methods for maintaining L2CAP sockets
+ virtual int Open(SocketInternal* sock, SocketAddrHdr* addr);
+ virtual int Send(SocketInternal* sock, const u8* data, int len);
+ virtual int Close(SocketInternal* sock);
+
+ private:
+ void InquiryResult(const inquiry_info* info);
+ void RemoteName(const BD_ADDR* addr, const char* name);
+ void ConnectComplete(const connection_info* info);
+ void DisconnectComplete(int handle);
+ int SendCmd(int cmd, const u8* params = 0, int len = 0);
+ void OnCommandComplete(int cmd, const u8* data, int len);
+ void Callback(HCI_CALLBACK_EVENT c, const u8* data, int len);
+ int PinCodeReply(const u8* data);
+};
+
+class HCITransport
+{
+protected:
+ HCI* _target;
+public:
+ void Set(HCI* target) { _target = target; };
+ virtual void HCISend(const u8* data, int len) = 0;
+ virtual void ACLSend(const u8* data, int len) = 0;
+};
+
+#endif