主導機 mbed用のプログラムです
Dependencies: mbed
Fork of PS3_BlueUSB_user_ver2 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 #include <mbed.h> 00032 00033 #include "Utils.h" 00034 #include "hci.h" 00035 #include "hci_private.h" 00036 00037 enum hci_callback_evt 00038 { 00039 NONE, 00040 CONNECT, 00041 DISCONECT, 00042 INQUIRYRESULT 00043 }; 00044 00045 #define MAX_BLUETOOTH_ADAPTERS 1 00046 00047 enum StateMask { 00048 MASK_RESET = 1, 00049 MASK_READ_BUFFER_SIZE = 2, 00050 MASK_READ_BD_ADDR = 4, 00051 MASK_INITED = 8, 00052 MASK_INQUIRY = 16, 00053 MASK_REMOTE_NAME = 32, 00054 MASK_CREATE_CONNECTION = 64 00055 }; 00056 00057 int HCI::Open(HCITransport* transport, HCICallback callback) 00058 { 00059 _transport = transport; 00060 _transport->Set(this); 00061 _callback = callback; 00062 _state = 0; 00063 for (int i = 0; i < MAX_BTDEVICES; i++) 00064 { 00065 _devices[i].Init(); 00066 _devices[i]._transport = transport; 00067 } 00068 return SendCmd(HCI_OP_RESET); 00069 } 00070 00071 void printf(const BD_ADDR* addr); 00072 void fprintf(FILE *fp,const BD_ADDR* addr); 00073 00074 BTDevice* HCI::Find(const BD_ADDR* addr) 00075 { 00076 for (int i = 0; i < MAX_BTDEVICES; i++) 00077 if (_devices[i]._state != 0 && memcmp(addr,&_devices[i]._info.bdaddr,6) == 0) 00078 return &_devices[i]; 00079 return 0; 00080 } 00081 00082 BTDevice* HCI::Find(int handle) 00083 { 00084 for (int i = 0; i < MAX_BTDEVICES; i++) 00085 if (_devices[i]._state != 0 && handle == _devices[i]._handle) 00086 return &_devices[i]; 00087 return 0; 00088 } 00089 // 00090 bool HCI::Busy() 00091 { 00092 return (_state & (MASK_INQUIRY | MASK_REMOTE_NAME | MASK_CREATE_CONNECTION)) != 0; 00093 } 00094 00095 int HCI::Inquiry(int duration) 00096 { 00097 _state |= MASK_INQUIRY; 00098 u8 buf[5]; 00099 buf[0] = 0x33; 00100 buf[1] = 0x8B; 00101 buf[2] = 0x9E; 00102 buf[3] = duration; 00103 buf[4] = 5; // 5 results 00104 SendCmd(HCI_OP_INQUIRY,buf,sizeof(buf)); 00105 return 0; 00106 } 00107 00108 int HCI::WriteScanEnable() 00109 { 00110 00111 //u8 buf[2]; 00112 //buf[0] = 0x03; 00113 //buf[1] = 0x01; 00114 u8 buf[1]; 00115 buf[0] = 0x03; 00116 00117 SendCmd(HCI_OP_WRITE_SCAN_ENABLE,buf,sizeof(buf)); 00118 return 0; 00119 } 00120 00121 int HCI::AcceptConnection(const BD_ADDR* addr) 00122 { 00123 //u8 buf[6+4]; 00124 //memset(buf,0,sizeof(buf)); 00125 //memcpy(buf,addr,6); 00126 //buf[7] = 0; 00127 u8 buf[6+1]; 00128 memset(buf,0,sizeof(buf)); 00129 memcpy(buf,addr,6); 00130 buf[6] = 0; 00131 00132 SendCmd(HCI_OP_ACCEPT_CONN_REQ,buf,sizeof(buf)); 00133 return 0; 00134 } 00135 00136 int HCI::SendCmd(int cmd, const u8* params, int len) 00137 { 00138 u8 b[32]; 00139 b[0] = cmd; 00140 b[1] = (cmd >> 8); 00141 b[2] = len; 00142 if (params) 00143 memcpy(b+3,params,len); 00144 _transport->HCISend(b,len+3); 00145 return 0; 00146 } 00147 00148 void HCI::OnCommandComplete(int cmd, const u8* data, int len) 00149 { 00150 // printf("%04X %s",cmd,CmdStr(cmd)); 00151 if (len < 0) 00152 return; 00153 //printfBytes(" complete",data,min(16,len)); 00154 00155 switch (cmd) 00156 { 00157 // Init phase 0 00158 case HCI_OP_RESET: // Reset done, init chain to HCI_OP_READ_LOCAL_NAME 00159 SendCmd(HCI_OP_READ_BUFFER_SIZE); 00160 _state |= MASK_RESET; 00161 break; 00162 00163 // Init phase 1 00164 case HCI_OP_READ_BUFFER_SIZE: 00165 _acl_mtu = LE16(data); 00166 _sco_mtu = data[2]; 00167 _acl_max_pkt = LE16(data+3); 00168 _sco_max_pkt = LE16(data+5); 00169 SendCmd(HCI_OP_READ_BD_ADDR); 00170 _state |= MASK_READ_BUFFER_SIZE; 00171 break; 00172 00173 // Init phase 2 00174 case HCI_OP_READ_BD_ADDR: 00175 { 00176 LocalFileSystem local("local"); 00177 FILE *fp; 00178 fp = fopen("/local/data.p3b", "w"); 00179 _localAddr = *((BD_ADDR*)data); // Local Address 00180 printf("Local Address: "); 00181 printf(&_localAddr); 00182 fprintf(fp,&_localAddr); 00183 fclose(fp); 00184 printf("\r\n"); 00185 _state |= MASK_READ_BD_ADDR; 00186 _state |= MASK_INITED; 00187 Callback(CALLBACK_READY,data,6);}; 00188 break; 00189 00190 // 0CXX 00191 case HCI_OP_READ_LOCAL_NAME: 00192 break; 00193 00194 case HCI_OP_READ_LOCAL_VERSION: 00195 // params 00196 //SendCmd(HCI_OP_READ_LOCAL_NAME); 00197 break; 00198 00199 case HCI_OP_READ_LOCAL_COMMANDS: 00200 break; 00201 00202 case HCI_OP_READ_LOCAL_FEATURES: 00203 //SendCmd(HCI_OP_READ_LOCAL_VERSION); 00204 break; 00205 00206 case HCI_OP_READ_LOCAL_EXT_FEATURES: 00207 break; 00208 00209 case HCI_OP_PIN_CODE_REPLY: 00210 printf("Got pin reply\r\n"); 00211 break; 00212 00213 default: 00214 //printf("Unrecognized Command %04X\r\n",cmd); 00215 break; 00216 } 00217 } 00218 00219 void HCI::Callback(HCI_CALLBACK_EVENT c, const u8* data, int len) 00220 { 00221 _callback(this,c,data,len); 00222 } 00223 00224 int HCI::RemoteNameRequest(const BD_ADDR* addr) 00225 { 00226 _state |= MASK_REMOTE_NAME; 00227 u8 buf[6+4]; 00228 memset(buf,0,sizeof(buf)); 00229 memcpy(buf,addr,6); 00230 buf[7] = 1; 00231 return SendCmd(HCI_OP_REMOTE_NAME_REQ,buf,sizeof(buf)); 00232 } 00233 00234 int HCI::CreateConnection(const BD_ADDR* remoteAddr) 00235 { 00236 _state |= MASK_CREATE_CONNECTION; 00237 u8 buf[6+7]; 00238 memset(buf,0,sizeof(buf)); 00239 memcpy(buf,remoteAddr,6); 00240 buf[6] = 0x18; // DM1,DH1 00241 buf[7] = 0xCC; // DM3, DH3, DM5, DH5 00242 buf[8] = 1; // Page Repetition R1 00243 return SendCmd(HCI_OP_CREATE_CONN,buf,sizeof(buf)); 00244 } 00245 00246 int HCI::Disconnect(const BD_ADDR* bdaddr) 00247 { 00248 BTDevice* d = Find(bdaddr); 00249 if (!d) 00250 return ERR_HCI_DEVICE_NOT_FOUND; 00251 int handle = d->_handle; 00252 printf("Disconnect from %d\r\n",handle); 00253 _state |= MASK_CREATE_CONNECTION; 00254 u8 buf[3]; 00255 buf[0] = handle; 00256 buf[1] = (handle >> 8); 00257 buf[2] = 0x13; 00258 return SendCmd(HCI_OP_DISCONNECT,buf,sizeof(buf)); 00259 } 00260 00261 void HCI::DisconnectComplete(int handle) 00262 { 00263 BTDevice* d = Find(handle); 00264 if (!d) 00265 return; 00266 d->_handle = 0; 00267 } 00268 00269 int HCI::DisconnectAll() 00270 { 00271 BTDevice* devs[8]; 00272 int count = GetDevices(devs,8); 00273 for (int i = 0; i < count; i++) 00274 Disconnect(&devs[i]->_info.bdaddr); 00275 return 0; 00276 } 00277 00278 int HCI::PinCodeReply(const u8* data) 00279 { 00280 u8 b[6+1+16]; 00281 memset(b,0,sizeof(b)); 00282 memcpy(b,data,6); 00283 b[6] = 4; 00284 b[7] = '0'; 00285 b[8] = '0'; 00286 b[9] = '0'; 00287 b[10] = '0'; 00288 return SendCmd(HCI_OP_PIN_CODE_REPLY,b,sizeof(b)); 00289 } 00290 00291 void HCI::InquiryResult(const inquiry_info* info) 00292 { 00293 BTDevice* bt = Find(&info->bdaddr); 00294 if (!bt) // new device 00295 { 00296 for (int i = 0; i < MAX_BTDEVICES; i++) 00297 { 00298 if (_devices[i]._state == 0) 00299 { 00300 bt = _devices + i; 00301 bt->_state = 1; 00302 break; 00303 } 00304 } 00305 if (!bt) 00306 { 00307 printf("HCI::InquiryResult too many devices\r\n"); 00308 return; // Too many devices! 00309 } 00310 } 00311 00312 bt->_info = *info; 00313 } 00314 00315 int HCI::GetDevices(BTDevice** devices, int maxDevices) 00316 { 00317 int j = 0; 00318 for (int i = 0; i < MAX_BTDEVICES; i++) 00319 { 00320 if (_devices[i]._state != 0) 00321 { 00322 devices[j++] = _devices + i; 00323 if (j == maxDevices) 00324 break; 00325 } 00326 } 00327 return j; 00328 } 00329 00330 void HCI::RemoteName(const BD_ADDR* addr, const char* name) 00331 { 00332 BTDevice* d = Find(addr); 00333 if (d) 00334 { 00335 strncpy(d->_name,name,sizeof(d->_name)-1); 00336 d->_name[sizeof(d->_name)-1] = 0; 00337 } 00338 } 00339 00340 void HCI::ConnectComplete(const connection_info* info) 00341 { 00342 BTDevice* d = Find(&info->bdaddr); 00343 if (!d) 00344 return; 00345 if (info->status == 0) 00346 { 00347 d->_handle = info->handle; 00348 printf("Connected on %04X\r\n",info->handle); 00349 } else 00350 printf("Connection failed with %d\r\n",info->status); 00351 } 00352 00353 void HCI::ConnectRequest(const request_info* info) 00354 { 00355 BTDevice* bt = Find(&info->bdaddr); 00356 if (!bt) // new device 00357 { 00358 for (int i = 0; i < MAX_BTDEVICES; i++) 00359 { 00360 if (_devices[i]._state == 0) 00361 { 00362 bt = _devices + i; 00363 bt->_state = 1; 00364 break; 00365 } 00366 } 00367 if (!bt) 00368 { 00369 printf("HCI::ConnectRequest too many devices\r\n"); 00370 return; // Too many devices! 00371 } 00372 } 00373 bt->_info.bdaddr = info->bdaddr; 00374 memcpy(bt->_info.dev_class,info->dev_class,3); 00375 AcceptConnection(&info->bdaddr); 00376 } 00377 00378 void HCI::HCIRecv(const u8* data, int len) 00379 { 00380 //printfBytes(EvtStr(data[0]),data,len); 00381 //printfBytes(EvtStr(data[0]),data,min(len,16)); 00382 //printf("HCI Event %02X\r\n",data[0]); 00383 switch (data[0]) 00384 { 00385 case HCI_EV_INQUIRY_COMPLETE: 00386 printfBytes("Inquiry Complete",data,data[1]); 00387 _state &= ~MASK_INQUIRY; 00388 Callback(CALLBACK_INQUIRY_DONE,0,0); 00389 WriteScanEnable(); 00390 break; 00391 00392 case HCI_EV_INQUIRY_RESULT: 00393 { 00394 const u8* end = data[1] + data + 2; 00395 data += 3; 00396 while (data < end) 00397 { 00398 inquiry_info align; 00399 memcpy(&align,data,sizeof(inquiry_info)); 00400 InquiryResult(&align); 00401 Callback(CALLBACK_INQUIRY_RESULT,(u8*)&align,sizeof(inquiry_info)); 00402 data += 14; 00403 } 00404 } 00405 break; 00406 00407 case HCI_EV_CONN_COMPLETE: 00408 _state &= ~MASK_CREATE_CONNECTION; 00409 { 00410 connection_info align; 00411 memcpy(&align,data+2,sizeof(connection_info)); 00412 ConnectComplete(&align); 00413 Callback(CALLBACK_CONNECTION_COMPLETE,(u8*)&align,sizeof(connection_info)); 00414 } 00415 break; 00416 00417 case HCI_EV_CONN_REQUEST: 00418 { 00419 request_info align; 00420 memcpy(&align,data+2,sizeof(request_info)); 00421 ConnectRequest(&align); 00422 } 00423 break; 00424 00425 case HCI_EV_DISCONN_COMPLETE: 00426 DisconnectComplete(LE16(data+3)); 00427 break; 00428 00429 case HCI_EV_REMOTE_NAME: 00430 { 00431 BD_ADDR* addr = (BD_ADDR*)(data+3); 00432 const char* name = (const char*)(data + 9); 00433 RemoteName(addr,name); 00434 } 00435 Callback(CALLBACK_REMOTE_NAME,data+3,LE16(data+1)); // addr is in here too 00436 _state &= ~MASK_REMOTE_NAME; 00437 break; 00438 00439 case HCI_EV_CMD_STATUS: 00440 { 00441 const char* errs = HCIErrStr(data[2]); 00442 printf("Status %s %s\r\n",CmdStr(LE16(data+4)),errs); 00443 } 00444 break; 00445 00446 case HCI_EV_CMD_COMPLETE: 00447 OnCommandComplete(data[3] | (data[4] << 8),data+6,data[1]-4); 00448 break; 00449 00450 case HCI_EV_PIN_CODE_REQ: 00451 PinCodeReply(data+2); 00452 break; 00453 00454 case HCI_EV_LINK_KEY_REQ: 00455 SendCmd(HCI_OP_LINK_KEY_NEG_REPLY,data+2,6); 00456 break; 00457 00458 default: 00459 ; 00460 // printfBytes("HCI Event:",data,data[1]+2); 00461 } 00462 } 00463 00464 int HCI::Open(SocketInternal* sock, SocketAddrHdr* addr) 00465 { 00466 L2CAPSocket* l2capsock = (L2CAPSocket*)sock; 00467 L2CAPAddr* l2capaddr = (L2CAPAddr*)addr; 00468 BTDevice* bt = Find(&l2capaddr->bdaddr); 00469 if (!bt) 00470 { 00471 printf("Can't open l2cap %d on ",l2capaddr->psm); 00472 printf(&l2capaddr->bdaddr); 00473 printf("\r\n"); 00474 return ERR_HCI_DEVICE_NOT_FOUND; 00475 } 00476 l2capsock->btdevice = bt; 00477 return bt->Open(sock,addr); 00478 } 00479 00480 int HCI::Create(SocketInternal* sock, SocketAddrHdr* addr) 00481 { 00482 L2CAPSocket* l2capsock = (L2CAPSocket*)sock; 00483 L2CAPAddr* l2capaddr = (L2CAPAddr*)addr; 00484 BTDevice* bt = Find(&l2capaddr->bdaddr); 00485 if (!bt) 00486 { 00487 printf("HCI Create: Can't open l2cap on "); 00488 printf(&l2capaddr->bdaddr); 00489 printf("\r\n"); 00490 return ERR_HCI_DEVICE_NOT_FOUND; 00491 } 00492 l2capsock->btdevice = bt; 00493 //return 0; 00494 return bt->Create(sock,addr); 00495 } 00496 00497 00498 int HCI::Accept(SocketInternal* sock, SocketAddrHdr* addr) 00499 { 00500 00501 printf("Call to HCI Accept \r\n"); 00502 00503 L2CAPSocket* l2capsock = (L2CAPSocket*)sock; 00504 L2CAPAddr* l2capaddr = (L2CAPAddr*)addr; 00505 BTDevice* bt = Find(&l2capaddr->bdaddr); 00506 if (!bt) 00507 { 00508 //printf("Can't open l2cap %d on ",l2capaddr->psm); 00509 printf("HCI Accept: Can't open l2cap on "); 00510 printf(&l2capaddr->bdaddr); 00511 printf("\r\n"); 00512 return ERR_HCI_DEVICE_NOT_FOUND; 00513 } 00514 //l2capsock->btdevice = bt; 00515 return bt->Open(sock,addr); 00516 00517 } 00518 00519 /** 00520 SocketInternal* HCI::Create(SocketInternal* sock) 00521 { 00522 return sock; 00523 } 00524 **/ 00525 00526 00527 int HCI::Send(SocketInternal* sock, const u8* data, int len) 00528 { 00529 L2CAPSocket* l2capsock = (L2CAPSocket*)sock; 00530 return l2capsock->btdevice->Send(sock,data,len); // Pointless double dispatch 00531 } 00532 00533 int HCI::Close(SocketInternal* sock) 00534 { 00535 L2CAPSocket* l2capsock = (L2CAPSocket*)sock; 00536 return l2capsock->btdevice->Close(sock); // Pointless double dispatch 00537 } 00538 00539 void HCI::ACLRecv(const u8* data, int len) 00540 { 00541 int handle = LE16(data); 00542 BD_ADDR* addr; 00543 BTDevice* d = Find(handle & 0x0FFF); 00544 addr = &d->_info.bdaddr; 00545 00546 if (d) 00547 d->ACLRecv(addr,data,len); 00548 } 00549 00550 //=================================================================== 00551 //===================================================================
Generated on Fri Jul 15 2022 20:54:11 by 1.7.2