Based on PS3_BlueUSB with reference to http://blog.goo.ne.jp/roboz80/e/10e7bf38d3a63b996ca2894e9fb5e3b6

Dependencies:   TextLCD mbed

Committer:
kenbumono
Date:
Tue Jul 05 08:25:40 2011 +0000
Revision:
0:44619612f575

        

Who changed what in which revision?

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