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

wextensions.cpp

Go to the documentation of this file.
00001 #include "wextensions.h"
00002 
00003 /* OPIE */
00004 #include <opie2/odebug.h>
00005 using namespace Opie::Core;
00006 
00007 /* QT */
00008 #include <qfile.h>
00009 #include <qtextstream.h>
00010 
00011 /* STD */
00012 #include <arpa/inet.h>
00013 #include <sys/socket.h>
00014 #include <sys/ioctl.h>
00015 #include <math.h>
00016 
00017 #define PROCNETWIRELESS "/proc/net/wireless"
00018 #define IW_LOWER 0
00019 #define IW_UPPER 256
00020 
00021 #warning This is duplicated code. Use libopienet2!
00022 
00026 WExtensions::WExtensions(QString interfaceName): hasWirelessExtensions(false), interface(interfaceName) {
00027   fd = socket( AF_INET, SOCK_DGRAM, 0 );
00028   if(fd == -1) 
00029     return;
00030 
00031   const char* buffer[200];
00032   memset( &iwr, 0, sizeof( iwr ) );
00033   iwr.u.essid.pointer = (caddr_t) buffer;
00034   iwr.u.essid.length = IW_ESSID_MAX_SIZE;
00035   iwr.u.essid.flags = 0;
00036   
00037   // check if it is an IEEE 802.11 standard conform
00038   // wireless device by sending SIOCGIWESSID
00039   // which also gives back the Extended Service Set ID
00040   // (see IEEE 802.11 for more information)
00041 
00042   const char* iname = interface.latin1();
00043   strcpy( iwr.ifr_ifrn.ifrn_name,  (const char *)iname );
00044   if ( 0 == ioctl( fd, SIOCGIWESSID, &iwr ) )
00045     hasWirelessExtensions = true;
00046 }
00047 
00051 QString WExtensions::station(){
00052   if(!hasWirelessExtensions)
00053     return QString();
00054   const char* buffer[200];
00055   iwr.u.data.pointer = (caddr_t) buffer;
00056   iwr.u.data.length = IW_ESSID_MAX_SIZE;
00057   iwr.u.data.flags = 0;
00058   if ( 0 == ioctl( fd, SIOCGIWNICKN, &iwr )){
00059     buffer[(unsigned int) iwr.u.data.length-1] = '\0';
00060     return (const char*) buffer;
00061   }
00062   return QString::null;
00063 }
00064 
00068 QString WExtensions::essid(){
00069   if(!hasWirelessExtensions)
00070     return QString();
00071   const char* buffer[200];
00072   memset(buffer,0x00,200);
00073   iwr.u.data.pointer = (caddr_t) buffer;
00074   iwr.u.data.length = IW_ESSID_MAX_SIZE;
00075   iwr.u.data.flags = 0;
00076   if ( 0 == ioctl( fd, SIOCGIWESSID, &iwr )){
00077     if (iwr.u.essid.length > IW_ESSID_MAX_SIZE)
00078       iwr.u.essid.length = IW_ESSID_MAX_SIZE;
00079     buffer[(unsigned int) iwr.u.essid.length] = '\0';
00080     return (const char*) buffer;
00081   }
00082   return QString::null;
00083 }
00084 
00088 QString WExtensions::mode(){
00089   if(!hasWirelessExtensions)
00090     return QString();
00091   if ( 0 == ioctl( fd, SIOCGIWMODE, &iwr ) )
00092     return QString("%1").arg(iwr.u.mode == IW_MODE_ADHOC ? "Ad-Hoc" : "Managed");
00093   return QString();
00094 }
00095 
00100 double WExtensions::frequency(){
00101   if(!hasWirelessExtensions)
00102     return 0;
00103   if ( 0 == ioctl( fd, SIOCGIWFREQ, &iwr ))
00104     return (double( iwr.u.freq.m ) * pow( 10, iwr.u.freq.e ) / 1000000000);
00105   return 0;
00106 }
00107 
00112 int WExtensions::channel(){
00113   if(!hasWirelessExtensions)
00114     return 0;
00115   if ( 0 != ioctl( fd, SIOCGIWFREQ, &iwr ))
00116     return 0;
00117   
00118   // http://www.elanix.com/pdf/an137e.pdf
00119 
00120   double num = (double( iwr.u.freq.m ) * pow( 10, iwr.u.freq.e ) / 1000000000);
00121   double left = 2.401;
00122   double right = 2.416;
00123   for(int channel = 1;  channel<= 15; channel++){
00124     if( num >= left && num <= right )
00125       return channel;
00126     left += 0.005;
00127     right += 0.005;
00128   }
00129   odebug << QString("Unknown frequency: %1, returning -1 for the channel.").arg(num).latin1() << oendl; 
00130   return -1;
00131 }
00132 
00133 /***
00134  * Get the current rate that the card is transmiting at.
00135  * @return double the rate, 0 if error.
00136  */ 
00137 double WExtensions::rate(){
00138   if(!hasWirelessExtensions)
00139     return 0;
00140   if(0 == ioctl(fd, SIOCGIWRATE, &iwr)){
00141     return ((double)iwr.u.bitrate.value)/1000000;
00142   }
00143   return 0;
00144 }
00145 
00146 
00150 QString WExtensions::ap(){
00151   if(!hasWirelessExtensions)
00152     return QString();
00153   if ( 0 == ioctl( fd, SIOCGIWAP, &iwr )){
00154     QString ap;
00155     ap = ap.sprintf( "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00156       iwr.u.ap_addr.sa_data[0]&0xff,
00157       iwr.u.ap_addr.sa_data[1]&0xff,
00158       iwr.u.ap_addr.sa_data[2]&0xff,
00159       iwr.u.ap_addr.sa_data[3]&0xff,
00160       iwr.u.ap_addr.sa_data[4]&0xff,
00161       iwr.u.ap_addr.sa_data[5]&0xff );
00162     return ap;
00163   }
00164   else return QString();
00165 }
00166 
00174 bool WExtensions::stats(int &signal, int &noise, int &quality){
00175   // gather link quality from /proc/net/wireless
00176   if(!QFile::exists(PROCNETWIRELESS))
00177     return false;
00178 
00179   char c;
00180   QString status;
00181   QString name;
00182   
00183   QFile wfile( PROCNETWIRELESS );
00184   if(!wfile.open( IO_ReadOnly ))
00185     return false;
00186   
00187   QTextStream wstream( &wfile );
00188   wstream.readLine();  // skip the first two lines
00189   wstream.readLine();  // because they only contain headers
00190   while(!wstream.atEnd()){
00191     wstream >> name >> status >> quality >> c >> signal >> c >> noise;
00192     if(name == QString("%1:").arg(interface)){
00193       if ( quality > 92 )
00194         odebug << "WIFIAPPLET: D'oh! Quality " << quality << " > estimated max!\n" << oendl; 
00195       if ( ( signal > IW_UPPER ) || ( signal < IW_LOWER ) )
00196         odebug << "WIFIAPPLET: Doh! Strength " << signal << " > estimated max!\n" << oendl; 
00197       if ( ( noise > IW_UPPER ) || ( noise < IW_LOWER ) )
00198         odebug << "WIFIAPPLET: Doh! Noise " << noise << " > estimated max!\n" << oendl; 
00199       //odebug << QString("q:%1, s:%2, n:%3").arg(quality).arg(signal).arg(noise).latin1() << oendl; 
00200       signal = ( ( signal-IW_LOWER ) * 100 ) / IW_UPPER;
00201       noise = ( ( noise-IW_LOWER ) * 100 ) / IW_UPPER;
00202       quality = ( quality*100 ) / 92;
00203       return true;
00204     }  
00205   }
00206 
00207   odebug << "WExtensions::statsCard no longer present." << oendl; 
00208   quality = -1;
00209   signal = IW_LOWER;
00210   noise = IW_LOWER;
00211   return false;
00212 }
00213 
00214 // wextensions.cpp

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