手動機アーム、mbed基盤のspiをおくるだけのプログラムです(9/4)

Dependencies:   SPI_master_arm_shudouki mbed

Fork of SPI_master_arm_shudouki2 by F^3 RC 2班

Committer:
yoka06
Date:
Mon Aug 21 08:49:06 2017 +0000
Revision:
0:76d1c7f13415
a

Who changed what in which revision?

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