Committer:
hosei2
Date:
Tue Jul 10 11:36:47 2012 +0000
Revision:
0:db1ba09e8bfa
zzz

Who changed what in which revision?

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