KAMUI USB HOST MIDI-CV Example based on Peter Barrett's BlueUSB

Dependencies:   TextLCD mbed

Committer:
radiojunkbox
Date:
Fri May 11 15:31:59 2012 +0000
Revision:
0:3b4e3e2ec6a5
Rev. 0.1 alfa

Who changed what in which revision?

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