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
00034
00035
00036
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
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
00128
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
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();
00182 wstream.readLine();
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
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