This program uses code taken from another program called BlueUSB

Dependencies:   mbed

Committer:
madcowswe
Date:
Sat Dec 10 18:45:31 2011 +0000
Revision:
0:31713f62f35b

        

Who changed what in which revision?

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