00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00115
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
00174 if( P->state() != OTPeer::Peer_Up ) {
00175 P->setState( OTPeer::Peer_Up );
00176 }
00177 IsNew = 0;
00178 } else {
00179 IsNew = 1;
00180
00181
00182 P = new OTPeer( Driver->gateway() );
00183 P->setState( OTPeer::Peer_Up );
00184 P->setAddress( Addr );
00185
00186
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
00192 P->setName( Driver->getPeerName( Addr ) );
00193 }
00194
00195
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 }