00001 #include "wextensions.h"
00002
00003
00004 #include <opie2/odebug.h>
00005 using namespace Opie::Core;
00006
00007
00008 #include <qfile.h>
00009 #include <qtextstream.h>
00010
00011
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
00038
00039
00040
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
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
00135
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
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();
00189 wstream.readLine();
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
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