BlueUSBをつかってみた

Dependencies:   FatFileSystem mbed

Fork of PS3_BlueUSB by Bart Janssens

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers hci.cpp Source File

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 //===================================================================