takayuki ikai / Mbed 2 deprecated BlueWii

Dependencies:   mbed

Committer:
ikaii
Date:
Mon Dec 06 17:02:12 2010 +0000
Revision:
0:010465683d59

        

Who changed what in which revision?

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