Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OTInquiry.cpp

Go to the documentation of this file.
00001 //-*-c++-*-
00002 /***************************************************************************
00003  *   Copyright (C) 2003 by Fred Schaettgen                                 *
00004  *   kdebluetooth@schaettgen.de                                            *
00005  *                                                                         *
00006  *   This program is free software; you can redistribute it and/or modify  *
00007  *   it under the terms of the GNU General Public License as published by  *
00008  *   the Free Software Foundation; either version 2 of the License, or     *
00009  *   (at your option) any later version.                                   *
00010  ***************************************************************************/
00011 
00012 
00013 #include <qcstring.h>
00014 #include <qsocket.h>
00015 #include <qdatetime.h>
00016 #include <qtimer.h>
00017 #include <qthread.h>
00018 #include <qapplication.h>
00019 
00020 #include <bluezlib.h>
00021 
00022 #include <OTGateway.h>
00023 #include <OTDriver.h>
00024 #include <OTPeer.h>
00025 #include <OTHCISocket.h>
00026 #include <OTInquiry.h>
00027 
00028 #include <opie2/odebug.h>
00029 
00030 using namespace Opietooth2;
00031 
00032 #define max(a,b)        (((a)>(b)) ? (a) : (b))
00033 #define min(a,b)        (((a)>(b)) ? (b) : (a))
00034 
00035 OTInquiry::OTInquiry( OTDriver * Drv ) : QObject( Drv ) {
00036 
00037     reset();
00038 
00039     InquiryTimeoutTimer = new QTimer(this);
00040 
00041     connect( InquiryTimeoutTimer, 
00042              SIGNAL(timeout()),
00043              this, 
00044              SLOT(slotInquiryTimeout()));
00045 
00046     Driver = Drv;
00047     Socket = Drv->openSocket();
00048     Socket->open();
00049 
00050     connect( Socket, 
00051              SIGNAL( event(unsigned char, QByteArray)),
00052              this, 
00053              SLOT(slotHCIEvent(unsigned char, QByteArray)));
00054 }
00055 
00056 OTInquiry::~OTInquiry() {
00057     stopInquiring();
00058 }
00059 
00060 void OTInquiry::stopInquiring( void ) {
00061     if( Socket ) {
00062       odebug << "Stop inquiry" << oendl;
00063       Driver->closeSocket();
00064       Socket = 0;
00065     }
00066 }
00067 
00068 bool OTInquiry::inquire( double timeout, int numResponses, int lap) {
00069 
00070     QByteArray cmdBuf(5);
00071 
00072     cmdBuf[0] = lap & 0xFF;
00073     cmdBuf[1] = (lap >> 8) & 0xFF;
00074     cmdBuf[2] = (lap >> 16) & 0xFF;
00075     cmdBuf[3] = max(0x01, min(0x30, int(timeout/1.28)));
00076     cmdBuf[4] = (unsigned char)numResponses;
00077 
00078     odebug << "Send HCI inquiry command. wait for " << cmdBuf[3] << oendl;
00079 
00080     Socket->sendCommand(0x01, 0x0001, cmdBuf);
00081 
00082     int status;
00083 
00084     if( Socket->readStatus(0x01, 0x0001, &status)) {
00085       if (status == 0) {
00086         SuccessfullyStarted = true;
00087         InquiryTimeoutTimer->start( int(1000*(timeout+1.0)), true);
00088         return true;
00089       }
00090       else {
00091         QString S =QString().sprintf( "%x", status );
00092         odebug << "OTInquiry::inquiry() failed: 0x" << S << oendl;
00093         emit finished();
00094         return false;
00095       }
00096     } else {
00097       odebug << "OTInquiry::inquiry(): Timeout." << oendl;
00098       return false;
00099     }
00100 }
00101 
00102 bool OTInquiry::isInquiring() {
00103     return InquiryTimeoutTimer->isActive();
00104 }
00105 
00106 bool OTInquiry::isFinished() {
00107     return SuccessfullyStarted && SuccessfullyEnded;
00108 }
00109       
00110 void OTInquiry::reset() {
00111 
00112     SuccessfullyStarted = false;
00113     SuccessfullyEnded = false;
00114     //addrCache.clear();
00115     //infoQueue.clear();
00116 }
00117 
00118 
00119 void OTInquiry::onPeerFound( OTPeer * Peer, bool IsNew ) {
00120     emit peerFound( Peer, IsNew );
00121 }
00122 
00123 void OTInquiry::slotInquiryTimeout() {
00124     emit error( tr( "Timeout while waiting for end of inquiry.") );
00125 }
00126 
00127 void OTInquiry::slotHCIEvent(unsigned char eventCode, QByteArray buf) {
00128 
00129     odebug << "OTInquiry: hci packet received: eventCode="
00130           << (unsigned int)eventCode 
00131           << " packetLength="
00132           << (unsigned int)buf.size() 
00133           << oendl;
00134 
00135     unsigned char *data = (unsigned char*)buf.data();
00136     switch (eventCode) {
00137       case EVT_INQUIRY_COMPLETE:
00138         { unsigned char status = data[0];
00139           odebug << "EVT_INQUIRY_COMPLETE status=" << status << oendl;
00140           InquiryTimeoutTimer->stop();
00141           if (status == 0) {
00142             if( SuccessfullyStarted == true) {
00143               odebug << "OTInquiry ended successfully" << oendl;
00144               SuccessfullyEnded = true;
00145             }
00146             emit finished();
00147           }
00148           else {
00149             emit error( tr( "OTInquiry completed with error (code %1)" ).
00150                           arg(status));
00151           }
00152         }
00153         break;
00154       case EVT_INQUIRY_RESULT:
00155         { int numResults = data[0];
00156           OTPeer * P = 0;
00157           bool IsNew;
00158           OTDeviceAddress Addr;
00159           QString N;
00160 
00161           inquiry_info *results = (inquiry_info*)(data+1);
00162 
00163           for (int n=0; n<numResults; n++) {
00164             Addr.setBDAddr( results[n].bdaddr );
00165 
00166             odebug << "INQUIRY_RESULT: "
00167                   << Addr.toString() 
00168                   << oendl;
00169 
00170             P = Driver->gateway()->findPeer( Addr );
00171 
00172             if( P ) {
00173               // peer known
00174               if( P->state() != OTPeer::Peer_Up ) {
00175                 P->setState( OTPeer::Peer_Up );
00176               }
00177               IsNew = 0;
00178             } else {
00179               IsNew = 1;
00180               // push the address to the address queue
00181               // where it can be consumed by nextNeighbour()
00182               P = new OTPeer( Driver->gateway() );
00183               P->setState( OTPeer::Peer_Up ); // we just detected it
00184               P->setAddress( Addr );
00185               //if( addrCache.find(info.addr) == addrCache.end()) {
00186               // addrCache.insert(info.addr);
00187 
00188               P->setDeviceClass( (results[n].dev_class[0] << 16) |
00189                                  (results[n].dev_class[1] << 8) |
00190                                  (results[n].dev_class[2] << 0) );
00191               // infoQueue.push_back(info);
00192               P->setName( Driver->getPeerName( Addr ) ); 
00193             }
00194 
00195             // call the handler. Emits a signal if not overwritten
00196             onPeerFound( P, IsNew );
00197 
00198             // }
00199           }
00200         }
00201         break;
00202       case EVT_CMD_STATUS :
00203         { int status = data[0];
00204           int numHciCmdPkts = data[1];
00205           int cmdOpcode = *((uint16_t*)(data+2));
00206           odebug << "EVT_CMD_STATUS status=" 
00207                 << status
00208                 << " numPkts=" 
00209                 << numHciCmdPkts 
00210                 << " cmdOpcode="
00211                 << cmdOpcode 
00212                 << oendl;
00213           if (cmdOpcode == OCF_INQUIRY) {
00214 
00215           }
00216         }
00217         break;
00218     }
00219 }

Generated on Sat Nov 5 16:17:55 2005 for OPIE by  doxygen 1.4.2