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 /*
radiojunkbox 0:3b4e3e2ec6a5 3 Copyright (c) 2010 Peter Barrett
radiojunkbox 0:3b4e3e2ec6a5 4
radiojunkbox 0:3b4e3e2ec6a5 5 Permission is hereby granted, free of charge, to any person obtaining a copy
radiojunkbox 0:3b4e3e2ec6a5 6 of this software and associated documentation files (the "Software"), to deal
radiojunkbox 0:3b4e3e2ec6a5 7 in the Software without restriction, including without limitation the rights
radiojunkbox 0:3b4e3e2ec6a5 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
radiojunkbox 0:3b4e3e2ec6a5 9 copies of the Software, and to permit persons to whom the Software is
radiojunkbox 0:3b4e3e2ec6a5 10 furnished to do so, subject to the following conditions:
radiojunkbox 0:3b4e3e2ec6a5 11
radiojunkbox 0:3b4e3e2ec6a5 12 The above copyright notice and this permission notice shall be included in
radiojunkbox 0:3b4e3e2ec6a5 13 all copies or substantial portions of the Software.
radiojunkbox 0:3b4e3e2ec6a5 14
radiojunkbox 0:3b4e3e2ec6a5 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
radiojunkbox 0:3b4e3e2ec6a5 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
radiojunkbox 0:3b4e3e2ec6a5 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
radiojunkbox 0:3b4e3e2ec6a5 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
radiojunkbox 0:3b4e3e2ec6a5 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
radiojunkbox 0:3b4e3e2ec6a5 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
radiojunkbox 0:3b4e3e2ec6a5 21 THE SOFTWARE.
radiojunkbox 0:3b4e3e2ec6a5 22 */
radiojunkbox 0:3b4e3e2ec6a5 23
radiojunkbox 0:3b4e3e2ec6a5 24 #include <stdio.h>
radiojunkbox 0:3b4e3e2ec6a5 25 #include <stdlib.h>
radiojunkbox 0:3b4e3e2ec6a5 26 #include <stdio.h>
radiojunkbox 0:3b4e3e2ec6a5 27 #include <string.h>
radiojunkbox 0:3b4e3e2ec6a5 28
radiojunkbox 0:3b4e3e2ec6a5 29 #include "Utils.h"
radiojunkbox 0:3b4e3e2ec6a5 30 #include "hci.h"
radiojunkbox 0:3b4e3e2ec6a5 31 #include "hci_private.h"
radiojunkbox 0:3b4e3e2ec6a5 32
radiojunkbox 0:3b4e3e2ec6a5 33 enum hci_callback_evt
radiojunkbox 0:3b4e3e2ec6a5 34 {
radiojunkbox 0:3b4e3e2ec6a5 35 NONE,
radiojunkbox 0:3b4e3e2ec6a5 36 CONNECT,
radiojunkbox 0:3b4e3e2ec6a5 37 DISCONECT,
radiojunkbox 0:3b4e3e2ec6a5 38 INQUIRYRESULT
radiojunkbox 0:3b4e3e2ec6a5 39 };
radiojunkbox 0:3b4e3e2ec6a5 40
radiojunkbox 0:3b4e3e2ec6a5 41 #define MAX_BLUETOOTH_ADAPTERS 1
radiojunkbox 0:3b4e3e2ec6a5 42
radiojunkbox 0:3b4e3e2ec6a5 43 enum StateMask {
radiojunkbox 0:3b4e3e2ec6a5 44 MASK_RESET = 1,
radiojunkbox 0:3b4e3e2ec6a5 45 MASK_READ_BUFFER_SIZE = 2,
radiojunkbox 0:3b4e3e2ec6a5 46 MASK_READ_BD_ADDR = 4,
radiojunkbox 0:3b4e3e2ec6a5 47 MASK_INITED = 8,
radiojunkbox 0:3b4e3e2ec6a5 48 MASK_INQUIRY = 16,
radiojunkbox 0:3b4e3e2ec6a5 49 MASK_REMOTE_NAME = 32,
radiojunkbox 0:3b4e3e2ec6a5 50 MASK_CREATE_CONNECTION = 64
radiojunkbox 0:3b4e3e2ec6a5 51 };
radiojunkbox 0:3b4e3e2ec6a5 52
radiojunkbox 0:3b4e3e2ec6a5 53 int HCI::Open(HCITransport* transport, HCICallback callback)
radiojunkbox 0:3b4e3e2ec6a5 54 {
radiojunkbox 0:3b4e3e2ec6a5 55 _transport = transport;
radiojunkbox 0:3b4e3e2ec6a5 56 _transport->Set(this);
radiojunkbox 0:3b4e3e2ec6a5 57 _callback = callback;
radiojunkbox 0:3b4e3e2ec6a5 58 _state = 0;
radiojunkbox 0:3b4e3e2ec6a5 59 for (int i = 0; i < MAX_BTDEVICES; i++)
radiojunkbox 0:3b4e3e2ec6a5 60 {
radiojunkbox 0:3b4e3e2ec6a5 61 _devices[i].Init();
radiojunkbox 0:3b4e3e2ec6a5 62 _devices[i]._transport = transport;
radiojunkbox 0:3b4e3e2ec6a5 63 }
radiojunkbox 0:3b4e3e2ec6a5 64 return SendCmd(HCI_OP_RESET);
radiojunkbox 0:3b4e3e2ec6a5 65 }
radiojunkbox 0:3b4e3e2ec6a5 66
radiojunkbox 0:3b4e3e2ec6a5 67 void printf(const BD_ADDR* addr);
radiojunkbox 0:3b4e3e2ec6a5 68
radiojunkbox 0:3b4e3e2ec6a5 69 BTDevice* HCI::Find(const BD_ADDR* addr)
radiojunkbox 0:3b4e3e2ec6a5 70 {
radiojunkbox 0:3b4e3e2ec6a5 71 for (int i = 0; i < MAX_BTDEVICES; i++)
radiojunkbox 0:3b4e3e2ec6a5 72 if (_devices[i]._state != 0 && memcmp(addr,&_devices[i]._info.bdaddr,6) == 0)
radiojunkbox 0:3b4e3e2ec6a5 73 return &_devices[i];
radiojunkbox 0:3b4e3e2ec6a5 74 return 0;
radiojunkbox 0:3b4e3e2ec6a5 75 }
radiojunkbox 0:3b4e3e2ec6a5 76
radiojunkbox 0:3b4e3e2ec6a5 77 BTDevice* HCI::Find(int handle)
radiojunkbox 0:3b4e3e2ec6a5 78 {
radiojunkbox 0:3b4e3e2ec6a5 79 for (int i = 0; i < MAX_BTDEVICES; i++)
radiojunkbox 0:3b4e3e2ec6a5 80 if (_devices[i]._state != 0 && handle == _devices[i]._handle)
radiojunkbox 0:3b4e3e2ec6a5 81 return &_devices[i];
radiojunkbox 0:3b4e3e2ec6a5 82 return 0;
radiojunkbox 0:3b4e3e2ec6a5 83 }
radiojunkbox 0:3b4e3e2ec6a5 84 //
radiojunkbox 0:3b4e3e2ec6a5 85 bool HCI::Busy()
radiojunkbox 0:3b4e3e2ec6a5 86 {
radiojunkbox 0:3b4e3e2ec6a5 87 return (_state & (MASK_INQUIRY | MASK_REMOTE_NAME | MASK_CREATE_CONNECTION)) != 0;
radiojunkbox 0:3b4e3e2ec6a5 88 }
radiojunkbox 0:3b4e3e2ec6a5 89
radiojunkbox 0:3b4e3e2ec6a5 90 int HCI::Inquiry(int duration)
radiojunkbox 0:3b4e3e2ec6a5 91 {
radiojunkbox 0:3b4e3e2ec6a5 92 _state |= MASK_INQUIRY;
radiojunkbox 0:3b4e3e2ec6a5 93 u8 buf[5];
radiojunkbox 0:3b4e3e2ec6a5 94 buf[0] = 0x33;
radiojunkbox 0:3b4e3e2ec6a5 95 buf[1] = 0x8B;
radiojunkbox 0:3b4e3e2ec6a5 96 buf[2] = 0x9E;
radiojunkbox 0:3b4e3e2ec6a5 97 buf[3] = duration;
radiojunkbox 0:3b4e3e2ec6a5 98 buf[4] = 5; // 5 results
radiojunkbox 0:3b4e3e2ec6a5 99 SendCmd(HCI_OP_INQUIRY,buf,sizeof(buf));
radiojunkbox 0:3b4e3e2ec6a5 100 return 0;
radiojunkbox 0:3b4e3e2ec6a5 101 }
radiojunkbox 0:3b4e3e2ec6a5 102
radiojunkbox 0:3b4e3e2ec6a5 103 int HCI::SendCmd(int cmd, const u8* params, int len)
radiojunkbox 0:3b4e3e2ec6a5 104 {
radiojunkbox 0:3b4e3e2ec6a5 105 u8 b[32];
radiojunkbox 0:3b4e3e2ec6a5 106 b[0] = cmd;
radiojunkbox 0:3b4e3e2ec6a5 107 b[1] = (cmd >> 8);
radiojunkbox 0:3b4e3e2ec6a5 108 b[2] = len;
radiojunkbox 0:3b4e3e2ec6a5 109 if (params)
radiojunkbox 0:3b4e3e2ec6a5 110 memcpy(b+3,params,len);
radiojunkbox 0:3b4e3e2ec6a5 111 _transport->HCISend(b,len+3);
radiojunkbox 0:3b4e3e2ec6a5 112 return 0;
radiojunkbox 0:3b4e3e2ec6a5 113 }
radiojunkbox 0:3b4e3e2ec6a5 114
radiojunkbox 0:3b4e3e2ec6a5 115 void HCI::OnCommandComplete(int cmd, const u8* data, int len)
radiojunkbox 0:3b4e3e2ec6a5 116 {
radiojunkbox 0:3b4e3e2ec6a5 117 // printf("%04X %s",cmd,CmdStr(cmd));
radiojunkbox 0:3b4e3e2ec6a5 118 if (len < 0)
radiojunkbox 0:3b4e3e2ec6a5 119 return;
radiojunkbox 0:3b4e3e2ec6a5 120 //printfBytes(" complete",data,min(16,len));
radiojunkbox 0:3b4e3e2ec6a5 121
radiojunkbox 0:3b4e3e2ec6a5 122 switch (cmd)
radiojunkbox 0:3b4e3e2ec6a5 123 {
radiojunkbox 0:3b4e3e2ec6a5 124 // Init phase 0
radiojunkbox 0:3b4e3e2ec6a5 125 case HCI_OP_RESET: // Reset done, init chain to HCI_OP_READ_LOCAL_NAME
radiojunkbox 0:3b4e3e2ec6a5 126 SendCmd(HCI_OP_READ_BUFFER_SIZE);
radiojunkbox 0:3b4e3e2ec6a5 127 _state |= MASK_RESET;
radiojunkbox 0:3b4e3e2ec6a5 128 break;
radiojunkbox 0:3b4e3e2ec6a5 129
radiojunkbox 0:3b4e3e2ec6a5 130 // Init phase 1
radiojunkbox 0:3b4e3e2ec6a5 131 case HCI_OP_READ_BUFFER_SIZE:
radiojunkbox 0:3b4e3e2ec6a5 132 _acl_mtu = LE16(data);
radiojunkbox 0:3b4e3e2ec6a5 133 _sco_mtu = data[2];
radiojunkbox 0:3b4e3e2ec6a5 134 _acl_max_pkt = LE16(data+3);
radiojunkbox 0:3b4e3e2ec6a5 135 _sco_max_pkt = LE16(data+5);
radiojunkbox 0:3b4e3e2ec6a5 136 SendCmd(HCI_OP_READ_BD_ADDR);
radiojunkbox 0:3b4e3e2ec6a5 137 _state |= MASK_READ_BUFFER_SIZE;
radiojunkbox 0:3b4e3e2ec6a5 138 break;
radiojunkbox 0:3b4e3e2ec6a5 139
radiojunkbox 0:3b4e3e2ec6a5 140 // Init phase 2
radiojunkbox 0:3b4e3e2ec6a5 141 case HCI_OP_READ_BD_ADDR:
radiojunkbox 0:3b4e3e2ec6a5 142 _localAddr = *((BD_ADDR*)data); // Local Address
radiojunkbox 0:3b4e3e2ec6a5 143 _state |= MASK_READ_BD_ADDR;
radiojunkbox 0:3b4e3e2ec6a5 144 _state |= MASK_INITED;
radiojunkbox 0:3b4e3e2ec6a5 145 Callback(CALLBACK_READY,data,6);
radiojunkbox 0:3b4e3e2ec6a5 146 break;
radiojunkbox 0:3b4e3e2ec6a5 147
radiojunkbox 0:3b4e3e2ec6a5 148 // 0CXX
radiojunkbox 0:3b4e3e2ec6a5 149 case HCI_OP_READ_LOCAL_NAME:
radiojunkbox 0:3b4e3e2ec6a5 150 break;
radiojunkbox 0:3b4e3e2ec6a5 151
radiojunkbox 0:3b4e3e2ec6a5 152 case HCI_OP_READ_LOCAL_VERSION:
radiojunkbox 0:3b4e3e2ec6a5 153 // params
radiojunkbox 0:3b4e3e2ec6a5 154 //SendCmd(HCI_OP_READ_LOCAL_NAME);
radiojunkbox 0:3b4e3e2ec6a5 155 break;
radiojunkbox 0:3b4e3e2ec6a5 156
radiojunkbox 0:3b4e3e2ec6a5 157 case HCI_OP_READ_LOCAL_COMMANDS:
radiojunkbox 0:3b4e3e2ec6a5 158 break;
radiojunkbox 0:3b4e3e2ec6a5 159
radiojunkbox 0:3b4e3e2ec6a5 160 case HCI_OP_READ_LOCAL_FEATURES:
radiojunkbox 0:3b4e3e2ec6a5 161 //SendCmd(HCI_OP_READ_LOCAL_VERSION);
radiojunkbox 0:3b4e3e2ec6a5 162 break;
radiojunkbox 0:3b4e3e2ec6a5 163
radiojunkbox 0:3b4e3e2ec6a5 164 case HCI_OP_READ_LOCAL_EXT_FEATURES:
radiojunkbox 0:3b4e3e2ec6a5 165 break;
radiojunkbox 0:3b4e3e2ec6a5 166
radiojunkbox 0:3b4e3e2ec6a5 167 case HCI_OP_PIN_CODE_REPLY:
radiojunkbox 0:3b4e3e2ec6a5 168 printf("Got pin reply\n");
radiojunkbox 0:3b4e3e2ec6a5 169 break;
radiojunkbox 0:3b4e3e2ec6a5 170
radiojunkbox 0:3b4e3e2ec6a5 171 default:
radiojunkbox 0:3b4e3e2ec6a5 172 printf("Unrecognized Command %04X\n",cmd);
radiojunkbox 0:3b4e3e2ec6a5 173 break;
radiojunkbox 0:3b4e3e2ec6a5 174 }
radiojunkbox 0:3b4e3e2ec6a5 175 }
radiojunkbox 0:3b4e3e2ec6a5 176
radiojunkbox 0:3b4e3e2ec6a5 177 void HCI::Callback(HCI_CALLBACK_EVENT c, const u8* data, int len)
radiojunkbox 0:3b4e3e2ec6a5 178 {
radiojunkbox 0:3b4e3e2ec6a5 179 _callback(this,c,data,len);
radiojunkbox 0:3b4e3e2ec6a5 180 }
radiojunkbox 0:3b4e3e2ec6a5 181
radiojunkbox 0:3b4e3e2ec6a5 182 int HCI::RemoteNameRequest(const BD_ADDR* addr)
radiojunkbox 0:3b4e3e2ec6a5 183 {
radiojunkbox 0:3b4e3e2ec6a5 184 _state |= MASK_REMOTE_NAME;
radiojunkbox 0:3b4e3e2ec6a5 185 u8 buf[6+4];
radiojunkbox 0:3b4e3e2ec6a5 186 memset(buf,0,sizeof(buf));
radiojunkbox 0:3b4e3e2ec6a5 187 memcpy(buf,addr,6);
radiojunkbox 0:3b4e3e2ec6a5 188 buf[7] = 1;
radiojunkbox 0:3b4e3e2ec6a5 189 return SendCmd(HCI_OP_REMOTE_NAME_REQ,buf,sizeof(buf));
radiojunkbox 0:3b4e3e2ec6a5 190 }
radiojunkbox 0:3b4e3e2ec6a5 191
radiojunkbox 0:3b4e3e2ec6a5 192 int HCI::CreateConnection(const BD_ADDR* remoteAddr)
radiojunkbox 0:3b4e3e2ec6a5 193 {
radiojunkbox 0:3b4e3e2ec6a5 194 _state |= MASK_CREATE_CONNECTION;
radiojunkbox 0:3b4e3e2ec6a5 195 u8 buf[6+7];
radiojunkbox 0:3b4e3e2ec6a5 196 memset(buf,0,sizeof(buf));
radiojunkbox 0:3b4e3e2ec6a5 197 memcpy(buf,remoteAddr,6);
radiojunkbox 0:3b4e3e2ec6a5 198 buf[6] = 0x18; // DM1,DH1
radiojunkbox 0:3b4e3e2ec6a5 199 buf[7] = 0xCC; // DM3, DH3, DM5, DH5
radiojunkbox 0:3b4e3e2ec6a5 200 buf[8] = 1; // Page Repetition R1
radiojunkbox 0:3b4e3e2ec6a5 201 return SendCmd(HCI_OP_CREATE_CONN,buf,sizeof(buf));
radiojunkbox 0:3b4e3e2ec6a5 202 }
radiojunkbox 0:3b4e3e2ec6a5 203
radiojunkbox 0:3b4e3e2ec6a5 204 int HCI::Disconnect(const BD_ADDR* bdaddr)
radiojunkbox 0:3b4e3e2ec6a5 205 {
radiojunkbox 0:3b4e3e2ec6a5 206 BTDevice* d = Find(bdaddr);
radiojunkbox 0:3b4e3e2ec6a5 207 if (!d)
radiojunkbox 0:3b4e3e2ec6a5 208 return ERR_HCI_DEVICE_NOT_FOUND;
radiojunkbox 0:3b4e3e2ec6a5 209 int handle = d->_handle;
radiojunkbox 0:3b4e3e2ec6a5 210 printf("Disconnect from %d\n",handle);
radiojunkbox 0:3b4e3e2ec6a5 211 _state |= MASK_CREATE_CONNECTION;
radiojunkbox 0:3b4e3e2ec6a5 212 u8 buf[3];
radiojunkbox 0:3b4e3e2ec6a5 213 buf[0] = handle;
radiojunkbox 0:3b4e3e2ec6a5 214 buf[1] = (handle >> 8);
radiojunkbox 0:3b4e3e2ec6a5 215 buf[2] = 0x13;
radiojunkbox 0:3b4e3e2ec6a5 216 return SendCmd(HCI_OP_DISCONNECT,buf,sizeof(buf));
radiojunkbox 0:3b4e3e2ec6a5 217 }
radiojunkbox 0:3b4e3e2ec6a5 218
radiojunkbox 0:3b4e3e2ec6a5 219 void HCI::DisconnectComplete(int handle)
radiojunkbox 0:3b4e3e2ec6a5 220 {
radiojunkbox 0:3b4e3e2ec6a5 221 BTDevice* d = Find(handle);
radiojunkbox 0:3b4e3e2ec6a5 222 if (!d)
radiojunkbox 0:3b4e3e2ec6a5 223 return;
radiojunkbox 0:3b4e3e2ec6a5 224 d->_handle = 0;
radiojunkbox 0:3b4e3e2ec6a5 225 }
radiojunkbox 0:3b4e3e2ec6a5 226
radiojunkbox 0:3b4e3e2ec6a5 227 int HCI::DisconnectAll()
radiojunkbox 0:3b4e3e2ec6a5 228 {
radiojunkbox 0:3b4e3e2ec6a5 229 BTDevice* devs[8];
radiojunkbox 0:3b4e3e2ec6a5 230 int count = GetDevices(devs,8);
radiojunkbox 0:3b4e3e2ec6a5 231 for (int i = 0; i < count; i++)
radiojunkbox 0:3b4e3e2ec6a5 232 Disconnect(&devs[i]->_info.bdaddr);
radiojunkbox 0:3b4e3e2ec6a5 233 return 0;
radiojunkbox 0:3b4e3e2ec6a5 234 }
radiojunkbox 0:3b4e3e2ec6a5 235
radiojunkbox 0:3b4e3e2ec6a5 236 int HCI::PinCodeReply(const u8* data)
radiojunkbox 0:3b4e3e2ec6a5 237 {
radiojunkbox 0:3b4e3e2ec6a5 238 u8 b[6+1+16];
radiojunkbox 0:3b4e3e2ec6a5 239 memset(b,0,sizeof(b));
radiojunkbox 0:3b4e3e2ec6a5 240 memcpy(b,data,6);
radiojunkbox 0:3b4e3e2ec6a5 241 b[6] = 4;
radiojunkbox 0:3b4e3e2ec6a5 242 b[7] = '0';
radiojunkbox 0:3b4e3e2ec6a5 243 b[8] = '0';
radiojunkbox 0:3b4e3e2ec6a5 244 b[9] = '0';
radiojunkbox 0:3b4e3e2ec6a5 245 b[10] = '0';
radiojunkbox 0:3b4e3e2ec6a5 246 return SendCmd(HCI_OP_PIN_CODE_REPLY,b,sizeof(b));
radiojunkbox 0:3b4e3e2ec6a5 247 }
radiojunkbox 0:3b4e3e2ec6a5 248
radiojunkbox 0:3b4e3e2ec6a5 249 void HCI::InquiryResult(const inquiry_info* info)
radiojunkbox 0:3b4e3e2ec6a5 250 {
radiojunkbox 0:3b4e3e2ec6a5 251 BTDevice* bt = Find(&info->bdaddr);
radiojunkbox 0:3b4e3e2ec6a5 252 if (!bt) // new device
radiojunkbox 0:3b4e3e2ec6a5 253 {
radiojunkbox 0:3b4e3e2ec6a5 254 for (int i = 0; i < MAX_BTDEVICES; i++)
radiojunkbox 0:3b4e3e2ec6a5 255 {
radiojunkbox 0:3b4e3e2ec6a5 256 if (_devices[i]._state == 0)
radiojunkbox 0:3b4e3e2ec6a5 257 {
radiojunkbox 0:3b4e3e2ec6a5 258 bt = _devices + i;
radiojunkbox 0:3b4e3e2ec6a5 259 bt->_state = 1;
radiojunkbox 0:3b4e3e2ec6a5 260 break;
radiojunkbox 0:3b4e3e2ec6a5 261 }
radiojunkbox 0:3b4e3e2ec6a5 262 }
radiojunkbox 0:3b4e3e2ec6a5 263 if (!bt)
radiojunkbox 0:3b4e3e2ec6a5 264 {
radiojunkbox 0:3b4e3e2ec6a5 265 printf("HCI::InquiryResult too many devices\n");
radiojunkbox 0:3b4e3e2ec6a5 266 return; // Too many devices!
radiojunkbox 0:3b4e3e2ec6a5 267 }
radiojunkbox 0:3b4e3e2ec6a5 268 }
radiojunkbox 0:3b4e3e2ec6a5 269
radiojunkbox 0:3b4e3e2ec6a5 270 bt->_info = *info;
radiojunkbox 0:3b4e3e2ec6a5 271 }
radiojunkbox 0:3b4e3e2ec6a5 272
radiojunkbox 0:3b4e3e2ec6a5 273 int HCI::GetDevices(BTDevice** devices, int maxDevices)
radiojunkbox 0:3b4e3e2ec6a5 274 {
radiojunkbox 0:3b4e3e2ec6a5 275 int j = 0;
radiojunkbox 0:3b4e3e2ec6a5 276 for (int i = 0; i < MAX_BTDEVICES; i++)
radiojunkbox 0:3b4e3e2ec6a5 277 {
radiojunkbox 0:3b4e3e2ec6a5 278 if (_devices[i]._state != 0)
radiojunkbox 0:3b4e3e2ec6a5 279 {
radiojunkbox 0:3b4e3e2ec6a5 280 devices[j++] = _devices + i;
radiojunkbox 0:3b4e3e2ec6a5 281 if (j == maxDevices)
radiojunkbox 0:3b4e3e2ec6a5 282 break;
radiojunkbox 0:3b4e3e2ec6a5 283 }
radiojunkbox 0:3b4e3e2ec6a5 284 }
radiojunkbox 0:3b4e3e2ec6a5 285 return j;
radiojunkbox 0:3b4e3e2ec6a5 286 }
radiojunkbox 0:3b4e3e2ec6a5 287
radiojunkbox 0:3b4e3e2ec6a5 288 void HCI::RemoteName(const BD_ADDR* addr, const char* name)
radiojunkbox 0:3b4e3e2ec6a5 289 {
radiojunkbox 0:3b4e3e2ec6a5 290 BTDevice* d = Find(addr);
radiojunkbox 0:3b4e3e2ec6a5 291 if (d)
radiojunkbox 0:3b4e3e2ec6a5 292 {
radiojunkbox 0:3b4e3e2ec6a5 293 strncpy(d->_name,name,sizeof(d->_name)-1);
radiojunkbox 0:3b4e3e2ec6a5 294 d->_name[sizeof(d->_name)-1] = 0;
radiojunkbox 0:3b4e3e2ec6a5 295 }
radiojunkbox 0:3b4e3e2ec6a5 296 }
radiojunkbox 0:3b4e3e2ec6a5 297
radiojunkbox 0:3b4e3e2ec6a5 298 void HCI::ConnectComplete(const connection_info* info)
radiojunkbox 0:3b4e3e2ec6a5 299 {
radiojunkbox 0:3b4e3e2ec6a5 300 BTDevice* d = Find(&info->bdaddr);
radiojunkbox 0:3b4e3e2ec6a5 301 if (!d)
radiojunkbox 0:3b4e3e2ec6a5 302 return;
radiojunkbox 0:3b4e3e2ec6a5 303 if (info->status == 0)
radiojunkbox 0:3b4e3e2ec6a5 304 {
radiojunkbox 0:3b4e3e2ec6a5 305 d->_handle = info->handle;
radiojunkbox 0:3b4e3e2ec6a5 306 printf("Connected on %04X\n",info->handle);
radiojunkbox 0:3b4e3e2ec6a5 307 } else
radiojunkbox 0:3b4e3e2ec6a5 308 printf("Connection failed with %d\n",info->status);
radiojunkbox 0:3b4e3e2ec6a5 309 }
radiojunkbox 0:3b4e3e2ec6a5 310
radiojunkbox 0:3b4e3e2ec6a5 311 void HCI::HCIRecv(const u8* data, int len)
radiojunkbox 0:3b4e3e2ec6a5 312 {
radiojunkbox 0:3b4e3e2ec6a5 313 // printfBytes(EvtStr(data[0]),data,min(len,16));
radiojunkbox 0:3b4e3e2ec6a5 314 switch (data[0])
radiojunkbox 0:3b4e3e2ec6a5 315 {
radiojunkbox 0:3b4e3e2ec6a5 316 case HCI_EV_INQUIRY_COMPLETE:
radiojunkbox 0:3b4e3e2ec6a5 317 printfBytes("Inquiry Complete",data,data[1]);
radiojunkbox 0:3b4e3e2ec6a5 318 _state &= ~MASK_INQUIRY;
radiojunkbox 0:3b4e3e2ec6a5 319 Callback(CALLBACK_INQUIRY_DONE,0,0);
radiojunkbox 0:3b4e3e2ec6a5 320 break;
radiojunkbox 0:3b4e3e2ec6a5 321
radiojunkbox 0:3b4e3e2ec6a5 322 case HCI_EV_INQUIRY_RESULT:
radiojunkbox 0:3b4e3e2ec6a5 323 {
radiojunkbox 0:3b4e3e2ec6a5 324 const u8* end = data[1] + data + 2;
radiojunkbox 0:3b4e3e2ec6a5 325 data += 3;
radiojunkbox 0:3b4e3e2ec6a5 326 while (data < end)
radiojunkbox 0:3b4e3e2ec6a5 327 {
radiojunkbox 0:3b4e3e2ec6a5 328 inquiry_info align;
radiojunkbox 0:3b4e3e2ec6a5 329 memcpy(&align,data,sizeof(inquiry_info));
radiojunkbox 0:3b4e3e2ec6a5 330 InquiryResult(&align);
radiojunkbox 0:3b4e3e2ec6a5 331 Callback(CALLBACK_INQUIRY_RESULT,(u8*)&align,sizeof(inquiry_info));
radiojunkbox 0:3b4e3e2ec6a5 332 data += 14;
radiojunkbox 0:3b4e3e2ec6a5 333 }
radiojunkbox 0:3b4e3e2ec6a5 334 }
radiojunkbox 0:3b4e3e2ec6a5 335 break;
radiojunkbox 0:3b4e3e2ec6a5 336
radiojunkbox 0:3b4e3e2ec6a5 337 case HCI_EV_CONN_COMPLETE:
radiojunkbox 0:3b4e3e2ec6a5 338 _state &= ~MASK_CREATE_CONNECTION;
radiojunkbox 0:3b4e3e2ec6a5 339 {
radiojunkbox 0:3b4e3e2ec6a5 340 connection_info align;
radiojunkbox 0:3b4e3e2ec6a5 341 memcpy(&align,data+2,sizeof(connection_info));
radiojunkbox 0:3b4e3e2ec6a5 342 ConnectComplete(&align);
radiojunkbox 0:3b4e3e2ec6a5 343 Callback(CALLBACK_CONNECTION_COMPLETE,(u8*)&align,sizeof(connection_info));
radiojunkbox 0:3b4e3e2ec6a5 344 }
radiojunkbox 0:3b4e3e2ec6a5 345 break;
radiojunkbox 0:3b4e3e2ec6a5 346
radiojunkbox 0:3b4e3e2ec6a5 347 case HCI_EV_CONN_REQUEST:
radiojunkbox 0:3b4e3e2ec6a5 348 break;
radiojunkbox 0:3b4e3e2ec6a5 349
radiojunkbox 0:3b4e3e2ec6a5 350 case HCI_EV_DISCONN_COMPLETE:
radiojunkbox 0:3b4e3e2ec6a5 351 DisconnectComplete(LE16(data+3));
radiojunkbox 0:3b4e3e2ec6a5 352 break;
radiojunkbox 0:3b4e3e2ec6a5 353
radiojunkbox 0:3b4e3e2ec6a5 354 case HCI_EV_REMOTE_NAME:
radiojunkbox 0:3b4e3e2ec6a5 355 {
radiojunkbox 0:3b4e3e2ec6a5 356 BD_ADDR* addr = (BD_ADDR*)(data+3);
radiojunkbox 0:3b4e3e2ec6a5 357 const char* name = (const char*)(data + 9);
radiojunkbox 0:3b4e3e2ec6a5 358 RemoteName(addr,name);
radiojunkbox 0:3b4e3e2ec6a5 359 }
radiojunkbox 0:3b4e3e2ec6a5 360 Callback(CALLBACK_REMOTE_NAME,data+3,LE16(data+1)); // addr is in here too
radiojunkbox 0:3b4e3e2ec6a5 361 _state &= ~MASK_REMOTE_NAME;
radiojunkbox 0:3b4e3e2ec6a5 362 break;
radiojunkbox 0:3b4e3e2ec6a5 363
radiojunkbox 0:3b4e3e2ec6a5 364 case HCI_EV_CMD_STATUS:
radiojunkbox 0:3b4e3e2ec6a5 365 {
radiojunkbox 0:3b4e3e2ec6a5 366 const char* errs = HCIErrStr(data[2]);
radiojunkbox 0:3b4e3e2ec6a5 367 printf("Status %s %s\n",CmdStr(LE16(data+4)),errs);
radiojunkbox 0:3b4e3e2ec6a5 368 }
radiojunkbox 0:3b4e3e2ec6a5 369 break;
radiojunkbox 0:3b4e3e2ec6a5 370
radiojunkbox 0:3b4e3e2ec6a5 371 case HCI_EV_CMD_COMPLETE:
radiojunkbox 0:3b4e3e2ec6a5 372 OnCommandComplete(data[3] | (data[4] << 8),data+6,data[1]-4);
radiojunkbox 0:3b4e3e2ec6a5 373 break;
radiojunkbox 0:3b4e3e2ec6a5 374
radiojunkbox 0:3b4e3e2ec6a5 375 case HCI_EV_PIN_CODE_REQ:
radiojunkbox 0:3b4e3e2ec6a5 376 PinCodeReply(data+2);
radiojunkbox 0:3b4e3e2ec6a5 377 break;
radiojunkbox 0:3b4e3e2ec6a5 378
radiojunkbox 0:3b4e3e2ec6a5 379 case HCI_EV_LINK_KEY_REQ:
radiojunkbox 0:3b4e3e2ec6a5 380 SendCmd(HCI_OP_LINK_KEY_NEG_REPLY,data+2,6);
radiojunkbox 0:3b4e3e2ec6a5 381 break;
radiojunkbox 0:3b4e3e2ec6a5 382
radiojunkbox 0:3b4e3e2ec6a5 383 default:
radiojunkbox 0:3b4e3e2ec6a5 384 ;
radiojunkbox 0:3b4e3e2ec6a5 385 // printfBytes(":",data,data[1]+2);
radiojunkbox 0:3b4e3e2ec6a5 386 }
radiojunkbox 0:3b4e3e2ec6a5 387 }
radiojunkbox 0:3b4e3e2ec6a5 388
radiojunkbox 0:3b4e3e2ec6a5 389 int HCI::Open(SocketInternal* sock, SocketAddrHdr* addr)
radiojunkbox 0:3b4e3e2ec6a5 390 {
radiojunkbox 0:3b4e3e2ec6a5 391 L2CAPSocket* l2capsock = (L2CAPSocket*)sock;
radiojunkbox 0:3b4e3e2ec6a5 392 L2CAPAddr* l2capaddr = (L2CAPAddr*)addr;
radiojunkbox 0:3b4e3e2ec6a5 393 BTDevice* bt = Find(&l2capaddr->bdaddr);
radiojunkbox 0:3b4e3e2ec6a5 394 if (!bt)
radiojunkbox 0:3b4e3e2ec6a5 395 {
radiojunkbox 0:3b4e3e2ec6a5 396 printf("Can't open l2cap %d on ",l2capaddr->psm);
radiojunkbox 0:3b4e3e2ec6a5 397 printf(&l2capaddr->bdaddr);
radiojunkbox 0:3b4e3e2ec6a5 398 printf("\n");
radiojunkbox 0:3b4e3e2ec6a5 399 return ERR_HCI_DEVICE_NOT_FOUND;
radiojunkbox 0:3b4e3e2ec6a5 400 }
radiojunkbox 0:3b4e3e2ec6a5 401 l2capsock->btdevice = bt;
radiojunkbox 0:3b4e3e2ec6a5 402 return bt->Open(sock,addr);
radiojunkbox 0:3b4e3e2ec6a5 403 }
radiojunkbox 0:3b4e3e2ec6a5 404
radiojunkbox 0:3b4e3e2ec6a5 405 int HCI::Send(SocketInternal* sock, const u8* data, int len)
radiojunkbox 0:3b4e3e2ec6a5 406 {
radiojunkbox 0:3b4e3e2ec6a5 407 L2CAPSocket* l2capsock = (L2CAPSocket*)sock;
radiojunkbox 0:3b4e3e2ec6a5 408 return l2capsock->btdevice->Send(sock,data,len); // Pointless double dispatch
radiojunkbox 0:3b4e3e2ec6a5 409 }
radiojunkbox 0:3b4e3e2ec6a5 410
radiojunkbox 0:3b4e3e2ec6a5 411 int HCI::Close(SocketInternal* sock)
radiojunkbox 0:3b4e3e2ec6a5 412 {
radiojunkbox 0:3b4e3e2ec6a5 413 L2CAPSocket* l2capsock = (L2CAPSocket*)sock;
radiojunkbox 0:3b4e3e2ec6a5 414 return l2capsock->btdevice->Close(sock); // Pointless double dispatch
radiojunkbox 0:3b4e3e2ec6a5 415 }
radiojunkbox 0:3b4e3e2ec6a5 416
radiojunkbox 0:3b4e3e2ec6a5 417 void HCI::ACLRecv(const u8* data, int len)
radiojunkbox 0:3b4e3e2ec6a5 418 {
radiojunkbox 0:3b4e3e2ec6a5 419 int handle = LE16(data);
radiojunkbox 0:3b4e3e2ec6a5 420 BTDevice* d = Find(handle & 0x0FFF);
radiojunkbox 0:3b4e3e2ec6a5 421 if (d)
radiojunkbox 0:3b4e3e2ec6a5 422 d->ACLRecv(data,len);
radiojunkbox 0:3b4e3e2ec6a5 423 }
radiojunkbox 0:3b4e3e2ec6a5 424
radiojunkbox 0:3b4e3e2ec6a5 425 //===================================================================
radiojunkbox 0:3b4e3e2ec6a5 426 //===================================================================