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