主導機 mbed用のプログラムです

Dependencies:   mbed

Fork of PS3_BlueUSB_user_ver2 by 2017  部内対抗4班 ROBOSTEP

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