3/5

Dependencies:   mbed

Committer:
yuki0701
Date:
Tue Mar 05 04:30:35 2019 +0000
Revision:
1:530908de68c6
Parent:
0:a56be39653d0
a

Who changed what in which revision?

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