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

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