BlueUSB with USB-> SERIAL (CP210x) GPIO pins working.

Dependencies:   mbed

Committer:
tecnosys
Date:
Fri Apr 23 05:04:28 2010 +0000
Revision:
0:a14eaa2e1445

        

Who changed what in which revision?

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