うおーるぼっと用プログラム Wiiリモコンからのダイレクト操作モードのみ BlueUSBをベースに使用しています。

Dependencies:   BD6211F mbed SimpleFilter

Committer:
jksoft
Date:
Fri Apr 29 15:50:23 2011 +0000
Revision:
0:4f749f62c6d7

        

Who changed what in which revision?

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