Dependents:   Test_Wiimote

Committer:
bediyap
Date:
Sat Dec 17 06:59:19 2011 +0000
Revision:
3:37e5ebd509ea
Parent:
2:5c2bfbd63297
disable serial
todo:
auto detect wii disconnection due to battery failure ...

Who changed what in which revision?

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