うおーるぼっと用プログラム Wiiリモコンからのダイレクト操作モードのみ BlueUSBをベースに使用しています。
Dependencies: BD6211F mbed SimpleFilter
hci.cpp
00001 00002 /* 00003 Copyright (c) 2010 Peter Barrett 00004 00005 Permission is hereby granted, free of charge, to any person obtaining a copy 00006 of this software and associated documentation files (the "Software"), to deal 00007 in the Software without restriction, including without limitation the rights 00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00009 copies of the Software, and to permit persons to whom the Software is 00010 furnished to do so, subject to the following conditions: 00011 00012 The above copyright notice and this permission notice shall be included in 00013 all copies or substantial portions of the Software. 00014 00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00021 THE SOFTWARE. 00022 */ 00023 00024 #include <stdio.h> 00025 #include <stdlib.h> 00026 #include <stdio.h> 00027 #include <string.h> 00028 00029 #include "Utils.h" 00030 #include "hci.h" 00031 #include "hci_private.h" 00032 00033 enum hci_callback_evt 00034 { 00035 NONE, 00036 CONNECT, 00037 DISCONECT, 00038 INQUIRYRESULT 00039 }; 00040 00041 #define MAX_BLUETOOTH_ADAPTERS 1 00042 00043 enum StateMask { 00044 MASK_RESET = 1, 00045 MASK_READ_BUFFER_SIZE = 2, 00046 MASK_READ_BD_ADDR = 4, 00047 MASK_INITED = 8, 00048 MASK_INQUIRY = 16, 00049 MASK_REMOTE_NAME = 32, 00050 MASK_CREATE_CONNECTION = 64 00051 }; 00052 00053 int HCI::Open(HCITransport* transport, HCICallback callback) 00054 { 00055 _transport = transport; 00056 _transport->Set(this); 00057 _callback = callback; 00058 _state = 0; 00059 for (int i = 0; i < MAX_BTDEVICES; i++) 00060 { 00061 _devices[i].Init(); 00062 _devices[i]._transport = transport; 00063 } 00064 return SendCmd(HCI_OP_RESET); 00065 } 00066 00067 void printf(const BD_ADDR* addr); 00068 00069 BTDevice* HCI::Find(const BD_ADDR* addr) 00070 { 00071 for (int i = 0; i < MAX_BTDEVICES; i++) 00072 if (_devices[i]._state != 0 && memcmp(addr,&_devices[i]._info.bdaddr,6) == 0) 00073 return &_devices[i]; 00074 return 0; 00075 } 00076 00077 BTDevice* HCI::Find(int handle) 00078 { 00079 for (int i = 0; i < MAX_BTDEVICES; i++) 00080 if (_devices[i]._state != 0 && handle == _devices[i]._handle) 00081 return &_devices[i]; 00082 return 0; 00083 } 00084 // 00085 bool HCI::Busy() 00086 { 00087 return (_state & (MASK_INQUIRY | MASK_REMOTE_NAME | MASK_CREATE_CONNECTION)) != 0; 00088 } 00089 00090 int HCI::Inquiry(int duration) 00091 { 00092 _state |= MASK_INQUIRY; 00093 u8 buf[5]; 00094 buf[0] = 0x33; 00095 buf[1] = 0x8B; 00096 buf[2] = 0x9E; 00097 buf[3] = duration; 00098 buf[4] = 5; // 5 results 00099 SendCmd(HCI_OP_INQUIRY,buf,sizeof(buf)); 00100 return 0; 00101 } 00102 00103 int HCI::SendCmd(int cmd, const u8* params, int len) 00104 { 00105 u8 b[32]; 00106 b[0] = cmd; 00107 b[1] = (cmd >> 8); 00108 b[2] = len; 00109 if (params) 00110 memcpy(b+3,params,len); 00111 _transport->HCISend(b,len+3); 00112 return 0; 00113 } 00114 00115 void HCI::OnCommandComplete(int cmd, const u8* data, int len) 00116 { 00117 // printf("%04X %s",cmd,CmdStr(cmd)); 00118 if (len < 0) 00119 return; 00120 //printfBytes(" complete",data,min(16,len)); 00121 00122 switch (cmd) 00123 { 00124 // Init phase 0 00125 case HCI_OP_RESET: // Reset done, init chain to HCI_OP_READ_LOCAL_NAME 00126 SendCmd(HCI_OP_READ_BUFFER_SIZE); 00127 _state |= MASK_RESET; 00128 break; 00129 00130 // Init phase 1 00131 case HCI_OP_READ_BUFFER_SIZE: 00132 _acl_mtu = LE16(data); 00133 _sco_mtu = data[2]; 00134 _acl_max_pkt = LE16(data+3); 00135 _sco_max_pkt = LE16(data+5); 00136 SendCmd(HCI_OP_READ_BD_ADDR); 00137 _state |= MASK_READ_BUFFER_SIZE; 00138 break; 00139 00140 // Init phase 2 00141 case HCI_OP_READ_BD_ADDR: 00142 _localAddr = *((BD_ADDR*)data); // Local Address 00143 _state |= MASK_READ_BD_ADDR; 00144 _state |= MASK_INITED; 00145 Callback(CALLBACK_READY,data,6); 00146 break; 00147 00148 // 0CXX 00149 case HCI_OP_READ_LOCAL_NAME: 00150 break; 00151 00152 case HCI_OP_READ_LOCAL_VERSION: 00153 // params 00154 //SendCmd(HCI_OP_READ_LOCAL_NAME); 00155 break; 00156 00157 case HCI_OP_READ_LOCAL_COMMANDS: 00158 break; 00159 00160 case HCI_OP_READ_LOCAL_FEATURES: 00161 //SendCmd(HCI_OP_READ_LOCAL_VERSION); 00162 break; 00163 00164 case HCI_OP_READ_LOCAL_EXT_FEATURES: 00165 break; 00166 00167 case HCI_OP_PIN_CODE_REPLY: 00168 printf("Got pin reply\n"); 00169 break; 00170 00171 default: 00172 printf("Unrecognized Command %04X\n",cmd); 00173 break; 00174 } 00175 } 00176 00177 void HCI::Callback(HCI_CALLBACK_EVENT c, const u8* data, int len) 00178 { 00179 _callback(this,c,data,len); 00180 } 00181 00182 int HCI::RemoteNameRequest(const BD_ADDR* addr) 00183 { 00184 _state |= MASK_REMOTE_NAME; 00185 u8 buf[6+4]; 00186 memset(buf,0,sizeof(buf)); 00187 memcpy(buf,addr,6); 00188 buf[7] = 1; 00189 return SendCmd(HCI_OP_REMOTE_NAME_REQ,buf,sizeof(buf)); 00190 } 00191 00192 int HCI::CreateConnection(const BD_ADDR* remoteAddr) 00193 { 00194 _state |= MASK_CREATE_CONNECTION; 00195 u8 buf[6+7]; 00196 memset(buf,0,sizeof(buf)); 00197 memcpy(buf,remoteAddr,6); 00198 buf[6] = 0x18; // DM1,DH1 00199 buf[7] = 0xCC; // DM3, DH3, DM5, DH5 00200 buf[8] = 1; // Page Repetition R1 00201 return SendCmd(HCI_OP_CREATE_CONN,buf,sizeof(buf)); 00202 } 00203 00204 int HCI::Disconnect(const BD_ADDR* bdaddr) 00205 { 00206 BTDevice* d = Find(bdaddr); 00207 if (!d) 00208 return ERR_HCI_DEVICE_NOT_FOUND; 00209 int handle = d->_handle; 00210 printf("Disconnect from %d\n",handle); 00211 _state |= MASK_CREATE_CONNECTION; 00212 u8 buf[3]; 00213 buf[0] = handle; 00214 buf[1] = (handle >> 8); 00215 buf[2] = 0x13; 00216 return SendCmd(HCI_OP_DISCONNECT,buf,sizeof(buf)); 00217 } 00218 00219 void HCI::DisconnectComplete(int handle) 00220 { 00221 BTDevice* d = Find(handle); 00222 if (!d) 00223 return; 00224 d->_handle = 0; 00225 } 00226 00227 int HCI::DisconnectAll() 00228 { 00229 BTDevice* devs[8]; 00230 int count = GetDevices(devs,8); 00231 for (int i = 0; i < count; i++) 00232 Disconnect(&devs[i]->_info.bdaddr); 00233 return 0; 00234 } 00235 00236 int HCI::PinCodeReply(const u8* data) 00237 { 00238 u8 b[6+1+16]; 00239 memset(b,0,sizeof(b)); 00240 memcpy(b,data,6); 00241 b[6] = 4; 00242 b[7] = '0'; 00243 b[8] = '0'; 00244 b[9] = '0'; 00245 b[10] = '0'; 00246 return SendCmd(HCI_OP_PIN_CODE_REPLY,b,sizeof(b)); 00247 } 00248 00249 void HCI::InquiryResult(const inquiry_info* info) 00250 { 00251 BTDevice* bt = Find(&info->bdaddr); 00252 if (!bt) // new device 00253 { 00254 for (int i = 0; i < MAX_BTDEVICES; i++) 00255 { 00256 if (_devices[i]._state == 0) 00257 { 00258 bt = _devices + i; 00259 bt->_state = 1; 00260 break; 00261 } 00262 } 00263 if (!bt) 00264 { 00265 printf("HCI::InquiryResult too many devices\n"); 00266 return; // Too many devices! 00267 } 00268 } 00269 00270 bt->_info = *info; 00271 } 00272 00273 int HCI::GetDevices(BTDevice** devices, int maxDevices) 00274 { 00275 int j = 0; 00276 for (int i = 0; i < MAX_BTDEVICES; i++) 00277 { 00278 if (_devices[i]._state != 0) 00279 { 00280 devices[j++] = _devices + i; 00281 if (j == maxDevices) 00282 break; 00283 } 00284 } 00285 return j; 00286 } 00287 00288 void HCI::RemoteName(const BD_ADDR* addr, const char* name) 00289 { 00290 BTDevice* d = Find(addr); 00291 if (d) 00292 { 00293 strncpy(d->_name,name,sizeof(d->_name)-1); 00294 d->_name[sizeof(d->_name)-1] = 0; 00295 } 00296 } 00297 00298 void HCI::ConnectComplete(const connection_info* info) 00299 { 00300 BTDevice* d = Find(&info->bdaddr); 00301 if (!d) 00302 return; 00303 if (info->status == 0) 00304 { 00305 d->_handle = info->handle; 00306 printf("Connected on %04X\n",info->handle); 00307 } else 00308 printf("Connection failed with %d\n",info->status); 00309 } 00310 00311 void HCI::HCIRecv(const u8* data, int len) 00312 { 00313 // printfBytes(EvtStr(data[0]),data,min(len,16)); 00314 switch (data[0]) 00315 { 00316 case HCI_EV_INQUIRY_COMPLETE: 00317 printfBytes("Inquiry Complete",data,data[1]); 00318 _state &= ~MASK_INQUIRY; 00319 Callback(CALLBACK_INQUIRY_DONE,0,0); 00320 break; 00321 00322 case HCI_EV_INQUIRY_RESULT: 00323 { 00324 const u8* end = data[1] + data + 2; 00325 data += 3; 00326 while (data < end) 00327 { 00328 inquiry_info align; 00329 memcpy(&align,data,sizeof(inquiry_info)); 00330 InquiryResult(&align); 00331 Callback(CALLBACK_INQUIRY_RESULT,(u8*)&align,sizeof(inquiry_info)); 00332 data += 14; 00333 } 00334 } 00335 break; 00336 00337 case HCI_EV_CONN_COMPLETE: 00338 _state &= ~MASK_CREATE_CONNECTION; 00339 { 00340 connection_info align; 00341 memcpy(&align,data+2,sizeof(connection_info)); 00342 ConnectComplete(&align); 00343 Callback(CALLBACK_CONNECTION_COMPLETE,(u8*)&align,sizeof(connection_info)); 00344 } 00345 break; 00346 00347 case HCI_EV_CONN_REQUEST: 00348 break; 00349 00350 case HCI_EV_DISCONN_COMPLETE: 00351 DisconnectComplete(LE16(data+3)); 00352 break; 00353 00354 case HCI_EV_REMOTE_NAME: 00355 { 00356 BD_ADDR* addr = (BD_ADDR*)(data+3); 00357 const char* name = (const char*)(data + 9); 00358 RemoteName(addr,name); 00359 } 00360 Callback(CALLBACK_REMOTE_NAME,data+3,LE16(data+1)); // addr is in here too 00361 _state &= ~MASK_REMOTE_NAME; 00362 break; 00363 00364 case HCI_EV_CMD_STATUS: 00365 { 00366 const char* errs = HCIErrStr(data[2]); 00367 printf("Status %s %s\n",CmdStr(LE16(data+4)),errs); 00368 } 00369 break; 00370 00371 case HCI_EV_CMD_COMPLETE: 00372 OnCommandComplete(data[3] | (data[4] << 8),data+6,data[1]-4); 00373 break; 00374 00375 case HCI_EV_PIN_CODE_REQ: 00376 PinCodeReply(data+2); 00377 break; 00378 00379 case HCI_EV_LINK_KEY_REQ: 00380 SendCmd(HCI_OP_LINK_KEY_NEG_REPLY,data+2,6); 00381 break; 00382 00383 default: 00384 ; 00385 // printfBytes(":",data,data[1]+2); 00386 } 00387 } 00388 00389 int HCI::Open(SocketInternal* sock, SocketAddrHdr* addr) 00390 { 00391 L2CAPSocket* l2capsock = (L2CAPSocket*)sock; 00392 L2CAPAddr* l2capaddr = (L2CAPAddr*)addr; 00393 BTDevice* bt = Find(&l2capaddr->bdaddr); 00394 if (!bt) 00395 { 00396 printf("Can't open l2cap %d on ",l2capaddr->psm); 00397 printf(&l2capaddr->bdaddr); 00398 printf("\n"); 00399 return ERR_HCI_DEVICE_NOT_FOUND; 00400 } 00401 l2capsock->btdevice = bt; 00402 return bt->Open(sock,addr); 00403 } 00404 00405 int HCI::Send(SocketInternal* sock, const u8* data, int len) 00406 { 00407 L2CAPSocket* l2capsock = (L2CAPSocket*)sock; 00408 return l2capsock->btdevice->Send(sock,data,len); // Pointless double dispatch 00409 } 00410 00411 int HCI::Close(SocketInternal* sock) 00412 { 00413 L2CAPSocket* l2capsock = (L2CAPSocket*)sock; 00414 return l2capsock->btdevice->Close(sock); // Pointless double dispatch 00415 } 00416 00417 void HCI::ACLRecv(const u8* data, int len) 00418 { 00419 int handle = LE16(data); 00420 BTDevice* d = Find(handle & 0x0FFF); 00421 if (d) 00422 d->ACLRecv(data,len); 00423 } 00424 00425 //=================================================================== 00426 //===================================================================
Generated on Thu Jul 14 2022 13:01:38 by 1.7.2