summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/settings/networksettings2/networksettings2/wextensions.cpp203
-rw-r--r--noncore/settings/networksettings2/networksettings2/wextensions.h34
2 files changed, 237 insertions, 0 deletions
diff --git a/noncore/settings/networksettings2/networksettings2/wextensions.cpp b/noncore/settings/networksettings2/networksettings2/wextensions.cpp
new file mode 100644
index 0000000..778990c
--- a/dev/null
+++ b/noncore/settings/networksettings2/networksettings2/wextensions.cpp
@@ -0,0 +1,203 @@
+#include "wextensions.h"
+
+#include <qfile.h>
+#include <qtextstream.h>
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+
+#include <opie2/odebug.h>
+using namespace Opie::Core;
+
+#include <math.h>
+
+#define PROCNETWIRELESS "/proc/net/wireless"
+#define IW_LOWER 0
+#define IW_UPPER 256
+
+/**
+ * Constructor. Sets hasWirelessExtensions
+ */
+WExtensions::WExtensions(QString interfaceName): hasWirelessExtensions(false), interface(interfaceName) {
+ fd = socket( AF_INET, SOCK_DGRAM, 0 );
+ if(fd == -1)
+ return;
+
+ const char* buffer[200];
+ memset( &iwr, 0, sizeof( iwr ) );
+ iwr.u.essid.pointer = (caddr_t) buffer;
+ iwr.u.essid.length = IW_ESSID_MAX_SIZE;
+ iwr.u.essid.flags = 0;
+
+ // check if it is an IEEE 802.11 standard conform
+ // wireless device by sending SIOCGIWESSID
+ // which also gives back the Extended Service Set ID
+ // (see IEEE 802.11 for more information)
+
+ const char* iname = interface.latin1();
+ strcpy( iwr.ifr_ifrn.ifrn_name, (const char *)iname );
+ if ( 0 == ioctl( fd, SIOCGIWESSID, &iwr ) )
+ hasWirelessExtensions = true;
+}
+
+/**
+ * @return QString the station name of the access point.
+ */
+QString WExtensions::station(){
+ if(!hasWirelessExtensions)
+ return QString();
+ const char* buffer[200];
+ iwr.u.data.pointer = (caddr_t) buffer;
+ iwr.u.data.length = IW_ESSID_MAX_SIZE;
+ iwr.u.data.flags = 0;
+ if ( 0 == ioctl( fd, SIOCGIWNICKN, &iwr )){
+ iwr.u.data.pointer[(unsigned int) iwr.u.data.length-1] = '\0';
+ return QString(iwr.u.data.pointer);
+ }
+ return QString();
+}
+
+/**
+ * @return QString the essid of the host 802.11 access point.
+ */
+QString WExtensions::essid(){
+ if(!hasWirelessExtensions)
+ return QString();
+ if ( 0 == ioctl( fd, SIOCGIWESSID, &iwr )){
+ iwr.u.essid.pointer[(unsigned int) iwr.u.essid.length] = '\0';
+ return QString(iwr.u.essid.pointer);
+ }
+ return QString();
+}
+
+/**
+ * @return QString the mode of interface
+ */
+QString WExtensions::mode(){
+ if(!hasWirelessExtensions)
+ return QString();
+ if ( 0 == ioctl( fd, SIOCGIWMODE, &iwr ) )
+ return QString("%1").arg(iwr.u.mode == IW_MODE_ADHOC ? "Ad-Hoc" : "Managed");
+ return QString();
+}
+
+/**
+ * Get the frequency that the interface is running at.
+ * @return int the frequency that the interfacae is running at.
+ */
+double WExtensions::frequency(){
+ if(!hasWirelessExtensions)
+ return 0;
+ if ( 0 == ioctl( fd, SIOCGIWFREQ, &iwr ))
+ return (double( iwr.u.freq.m ) * pow( 10, iwr.u.freq.e ) / 1000000000);
+ return 0;
+}
+
+/**
+ * Get the channel that the interface is running at.
+ * @return int the channel that the interfacae is running at.
+ */
+int WExtensions::channel(){
+ if(!hasWirelessExtensions)
+ return 0;
+ if ( 0 != ioctl( fd, SIOCGIWFREQ, &iwr ))
+ return 0;
+
+ // http://www.elanix.com/pdf/an137e.pdf
+
+ double num = (double( iwr.u.freq.m ) * pow( 10, iwr.u.freq.e ) / 1000000000);
+ double left = 2.401;
+ double right = 2.416;
+ for(int channel = 1; channel<= 15; channel++){
+ if( num >= left && num <= right )
+ return channel;
+ left += 0.005;
+ right += 0.005;
+ }
+ odebug << QString("Unknown frequency: %1, returning -1 for the channel.").arg(num).latin1() << oendl;
+ return -1;
+}
+
+/***
+ * Get the current rate that the card is transmiting at.
+ * @return double the rate, 0 if error.
+ */
+double WExtensions::rate(){
+ if(!hasWirelessExtensions)
+ return 0;
+ if(0 == ioctl(fd, SIOCGIWRATE, &iwr)){
+ return ((double)iwr.u.bitrate.value)/1000000;
+ }
+ return 0;
+}
+
+
+/**
+ * @return QString the AccessPoint that the interface is connected to.
+ */
+QString WExtensions::ap(){
+ if(!hasWirelessExtensions)
+ return QString();
+ if ( 0 == ioctl( fd, SIOCGIWAP, &iwr )){
+ QString ap;
+ ap = ap.sprintf( "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
+ iwr.u.ap_addr.sa_data[0]&0xff,
+ iwr.u.ap_addr.sa_data[1]&0xff,
+ iwr.u.ap_addr.sa_data[2]&0xff,
+ iwr.u.ap_addr.sa_data[3]&0xff,
+ iwr.u.ap_addr.sa_data[4]&0xff,
+ iwr.u.ap_addr.sa_data[5]&0xff );
+ return ap;
+ }
+ else return QString();
+}
+
+/**
+ * Get the stats for interfaces
+ * @param signal the signal strength of interface
+ * @param noise the noise level of the interface
+ * @param quality the quality level of the interface
+ * @return bool true if successful
+ */
+bool WExtensions::stats(int &signal, int &noise, int &quality){
+ // gather link quality from /proc/net/wireless
+ if(!QFile::exists(PROCNETWIRELESS))
+ return false;
+
+ char c;
+ QString status;
+ QString name;
+
+ QFile wfile( PROCNETWIRELESS );
+ if(!wfile.open( IO_ReadOnly ))
+ return false;
+
+ QTextStream wstream( &wfile );
+ wstream.readLine(); // skip the first two lines
+ wstream.readLine(); // because they only contain headers
+ while(!wstream.atEnd()){
+ wstream >> name >> status >> quality >> c >> signal >> c >> noise;
+ if(name == QString("%1:").arg(interface)){
+ if ( quality > 92 )
+ odebug << "WIFIAPPLET: D'oh! Quality " << quality << " > estimated max!\n" << oendl;
+ if ( ( signal > IW_UPPER ) || ( signal < IW_LOWER ) )
+ odebug << "WIFIAPPLET: Doh! Strength " << signal << " > estimated max!\n" << oendl;
+ if ( ( noise > IW_UPPER ) || ( noise < IW_LOWER ) )
+ odebug << "WIFIAPPLET: Doh! Noise " << noise << " > estimated max!\n" << oendl;
+ //odebug << QString("q:%1, s:%2, n:%3").arg(quality).arg(signal).arg(noise).latin1() << oendl;
+ signal = ( ( signal-IW_LOWER ) * 100 ) / IW_UPPER;
+ noise = ( ( noise-IW_LOWER ) * 100 ) / IW_UPPER;
+ quality = ( quality*100 ) / 92;
+ return true;
+ }
+ }
+
+ odebug << "WExtensions::statsCard no longer present." << oendl;
+ quality = -1;
+ signal = IW_LOWER;
+ noise = IW_LOWER;
+ return false;
+}
+
+// wextensions.cpp
diff --git a/noncore/settings/networksettings2/networksettings2/wextensions.h b/noncore/settings/networksettings2/networksettings2/wextensions.h
new file mode 100644
index 0000000..a89e33a
--- a/dev/null
+++ b/noncore/settings/networksettings2/networksettings2/wextensions.h
@@ -0,0 +1,34 @@
+#ifndef WEXTENSIONS_H
+#define WEXTENSIONS_H
+
+#include <qstring.h>
+
+#include <netinet/ip.h>
+#include <linux/wireless.h>
+
+class WExtensions {
+
+public:
+ WExtensions(QString interfaceName);
+ QString getInterfaceName(){return interface;};
+ bool doesHaveWirelessExtensions(){return hasWirelessExtensions;};
+ QString station();
+ QString essid();
+ QString mode();
+ double frequency();
+ int channel();
+ double rate();
+ QString ap();
+ bool stats( int &signal, int &noise, int &quality);
+
+private:
+ bool hasWirelessExtensions;
+ QString interface;
+
+ // Used in we calls
+ struct iwreq iwr;
+ int fd;
+
+};
+
+#endif