XOOMの動作状況を聞き処理を変えてみました。 USBケーブルを抜いた際に処理を終了するようにしました。

Dependencies:   mbed

Committer:
abe00makoto
Date:
Fri May 27 18:51:15 2011 +0000
Revision:
3:432e5675d240
Parent:
0:9fb6c423e32c
nexus one support
maybe support add XOOM ,nexus S

Who changed what in which revision?

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