Test Ver

Dependencies:   mbed FatFileSystem

Committer:
jksoft
Date:
Sat Nov 17 13:22:00 2012 +0000
Revision:
0:269589d8d2c2
Test Program

Who changed what in which revision?

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