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

wireless.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2002-2004 Michael 'Mickey' Lauer <mickey@vanille.de>
00003 **
00004 ** This file may be distributed and/or modified under the terms of the
00005 ** GNU General Public License version 2 as published by the Free Software
00006 ** Foundation and appearing in the file LICENSE.GPL included in the
00007 ** packaging of this file.
00008 **
00009 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00010 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00011 **
00012 **********************************************************************/
00013 
00014 #include "wireless.h"
00015 #include "mgraph.h"
00016 #include "advancedconfig.h"
00017 
00018 /* OPIE */
00019 #include <opie2/odebug.h>
00020 #include <opie2/onetwork.h>
00021 #include <opie2/otaskbarapplet.h>
00022 #include <qpe/config.h>
00023 #include <qpe/qpeapplication.h>
00024 using namespace Opie::Core;
00025 using namespace Opie::Ui;
00026 using namespace Opie::Net;
00027 
00028 /* QT */
00029 #include <qradiobutton.h>
00030 #include <qpushbutton.h>
00031 #include <qpainter.h>
00032 #include <qlabel.h>
00033 #include <qslider.h>
00034 #include <qbuttongroup.h>
00035 #include <qlayout.h>
00036 #include <qfile.h>
00037 #include <qtextstream.h>
00038 
00039 /* STD */
00040 #include <math.h>
00041 #include <sys/types.h>
00042 #include <signal.h>
00043 #if defined (__GNUC__) && (__GNUC__ < 3)
00044 #define round qRound
00045 #endif
00046 
00047 //#define MDEBUG
00048 #undef MDEBUG
00049 
00050 WirelessControl::WirelessControl( WirelessApplet *applet, QWidget *parent, const char *name )
00051         : QFrame( parent, name, WStyle_StaysOnTop | WType_Popup ), applet( applet )
00052 {
00053 
00054     readConfig();
00055     writeConfigEntry( "UpdateFrequency", updateFrequency );
00056 
00057     setFrameStyle( QFrame::PopupPanel | QFrame::Raised );
00058     QGridLayout *grid = new QGridLayout( this, 3, 2, 6, 2, "top layout" );
00059 
00060     /* status label */
00061 
00062     statusLabel = new QLabel( this, "statuslabel" );
00063     QString text( "Wireless Status:<br>"
00064                   "*** Unknown ***<br>"
00065                   "Card not inserted ?<br>"
00066                   "Or Sharp ROM ?<br>"
00067                   "CELL: 00:00:00:00:00:00" );
00068     /*    QString text( "Station: Unknown<br>"
00069                         "ESSID: Unknown<br>"
00070                         "MODE: Unknown<br>"
00071                         "FREQ: Unknown<br>"
00072                         "CELL: AA:BB:CC:DD:EE:FF" ); */
00073     statusLabel->setText( text );
00074     statusLabel->setFixedSize( statusLabel->sizeHint() );
00075     grid->addWidget( statusLabel, 0, 0 );
00076 
00077     /* visualization group box */
00078 
00079     /* quality graph */
00080 
00081     mgraph = new MGraph( this );
00082     mgraph->setFrameStyle( QFrame::Panel | QFrame::Sunken );
00083     mgraph->setMin( 0 );
00084     mgraph->setMax( 92 );
00085     grid->addWidget( mgraph, 1, 0 );
00086     mgraph->setFocusPolicy( QWidget::NoFocus );
00087 
00088     /* advanced configuration Button */
00089 
00090     QPushButton* advanced = new QPushButton( "Advanced...", this );
00091     advanced->setFocusPolicy( QWidget::NoFocus );
00092     grid->addWidget( advanced, 2, 0, Qt::AlignCenter );
00093     connect( advanced, SIGNAL( clicked() ),
00094              this, SLOT( advancedConfigClicked() ) );
00095 
00096     /* update Frequency Label */
00097 
00098     updateLabel = new QLabel( this );
00099     text.sprintf( "Update every %d s", updateFrequency );
00100     updateLabel->setText( text );
00101     grid->addWidget( updateLabel, 2, 1 );
00102 
00103     /* update Frequency Slider */
00104 
00105     QSlider* updateSlider = new QSlider( QSlider::Horizontal, this );
00106     updateSlider->setRange( 0, 9 );
00107     updateSlider->setValue( updateFrequency );
00108     updateSlider->setTickmarks( QSlider::Both );
00109     updateSlider->setTickInterval( 1 );
00110     updateSlider->setSteps( 1, 1 );
00111     updateSlider->setFocusPolicy( QWidget::NoFocus );
00112     grid->addWidget( updateSlider, 1, 1 );
00113     connect( updateSlider, SIGNAL( valueChanged(int) ),
00114              this, SLOT( updateDelayChange(int) ) );
00115 
00116     setFixedSize( sizeHint() );
00117     setFocusPolicy( QWidget::NoFocus );
00118 
00119     applet->updateDelayChange( updateFrequency );
00120 
00121     applet->updateDHCPConfig( rocESSID, rocFREQ, rocAP, rocMODE );
00122 }
00123 
00124 void WirelessControl::advancedConfigClicked()
00125 {
00126     AdvancedConfig * a = new AdvancedConfig( this, "dialog", TRUE );
00127     int result = a->exec();
00128     a->hide();
00129     delete a;
00130     if ( result == QDialog::Accepted )
00131     {
00132         readConfig();
00133         applet->updateDHCPConfig( rocESSID, rocFREQ, rocAP, rocMODE );
00134     }
00135 }
00136 
00137 void WirelessControl::updateDelayChange( int delay )
00138 {
00139     QString text;
00140     text.sprintf( "Update every %d s", delay );
00141     updateLabel->setText( text );
00142     applet->updateDelayChange( delay );
00143     writeConfigEntry( "UpdateFrequency", delay );
00144 }
00145 
00146 void WirelessControl::displayStyleChange( int style )
00147 {
00148     applet->displayStyleChange( style );
00149     writeConfigEntry( "DisplayStyle", style );
00150 }
00151 
00152 void WirelessControl::show ( bool )
00153 {
00154     QPoint curPos = applet->mapToGlobal( QPoint ( 0, 0 ) );
00155 
00156     int w = sizeHint().width();
00157     int x = curPos.x() - ( w / 2 );
00158 
00159     if ( ( x + w ) > QPEApplication::desktop() ->width() )
00160         x = QPEApplication::desktop ( ) -> width ( ) - w;
00161 
00162     move( QMAX(x,0), curPos.y () - sizeHint().height () );
00163     QFrame::show();
00164 }
00165 
00166 void WirelessControl::readConfig()
00167 {
00168     Config cfg( "qpe" );
00169     cfg.setGroup( "Wireless" );
00170 
00171     updateFrequency = cfg.readNumEntry( "UpdateFrequency", 2 );
00172     rocESSID = cfg.readBoolEntry( "renew_dhcp_on_essid_change", false );
00173     rocFREQ = cfg.readBoolEntry( "renew_dhcp_on_freq_change", false );
00174     rocAP = cfg.readBoolEntry( "renew_dhcp_on_ap_change", false );
00175     rocMODE = cfg.readBoolEntry( "renew_dhcp_on_mode_change", false );
00176 }
00177 
00178 void WirelessControl::writeConfigEntry( const char *entry, int val )
00179 {
00180     Config cfg( "qpe" );
00181     cfg.setGroup( "Wireless" );
00182     cfg.writeEntry( entry, val );
00183 }
00184 
00185 //===========================================================================
00186 
00187 WirelessApplet::WirelessApplet( QWidget *parent, const char *name )
00188         : QWidget( parent, name ),
00189         timer( 0 ), interface( 0 ), oldiface( 0 ),
00190         rocESSID( false ), rocFREQ( false ), rocAP( false ), rocMODE( false )
00191 {
00192     setFixedHeight( 18 );
00193     setFixedWidth( 14 );
00194     status = new WirelessControl( this, this, "wireless status" );
00195 }
00196 
00197 void WirelessApplet::checkInterface()
00198 {
00199     interface = 0L;
00200     ONetwork* net = ONetwork::instance();
00201     net->synchronize();
00202     ONetwork::InterfaceIterator it = net->iterator();
00203 
00204     while ( it.current() && !it.current()->isWireless() ) ++it;
00205 
00206     if ( it.current() && it.current()->isWireless() )
00207         interface = static_cast<OWirelessNetworkInterface*>( it.current() );
00208 
00209     if ( interface )
00210     {
00211 #ifdef MDEBUG
00212         odebug << "WIFIAPPLET: using interface '" << ( const char* ) interface->name() << "'" << oendl; 
00213 #endif
00214 
00215     }
00216     else
00217     {
00218 #ifdef MDEBUG
00219         odebug << "WIFIAPPLET: D'oh! No Wireless interface present... :(" << oendl; 
00220 #endif
00221         hide();
00222     }
00223 }
00224 
00225 void WirelessApplet::renewDHCP()
00226 {
00227 #ifdef MDEBUG
00228     odebug << "WIFIAPPLET: Going to request a DHCP configuration renew." << oendl; 
00229 #endif
00230 
00231     QString pidfile;
00232     if ( !interface )
00233         return ;
00234     QString ifacename( interface->name() );
00235 
00236     // At first we are trying dhcpcd
00237 
00238     pidfile.sprintf( "/var/run/dhcpcd-%s.pid", ( const char* ) ifacename );
00239 #ifdef MDEBUG
00240     odebug << "WIFIAPPLET: dhcpcd pidfile is '" << ( const char* ) pidfile << "'" << oendl; 
00241 #endif
00242     int pid;
00243     QFile pfile( pidfile );
00244     bool hasFile = pfile.open( IO_ReadOnly );
00245     QTextStream s( &pfile );
00246     if ( hasFile )
00247     {
00248         s >> pid;
00249 #ifdef MDEBUG
00250         odebug << "WIFIAPPLET: sent SIGALARM to pid " << pid << "" << oendl; 
00251 #endif
00252         kill( pid, SIGALRM );
00253         return ;
00254     }
00255 
00256     // No dhcpcd, so we are trying udhcpc
00257 #ifdef MDEBUG
00258     odebug << "WIFIAPPLET: dhcpcd not available." << oendl; 
00259 #endif
00260     pidfile.sprintf( "/var/run/udhcpc.%s.pid", ( const char* ) ifacename );
00261 #ifdef MDEBUG
00262     odebug << "WIFIAPPLET: udhcpc pidfile is '" << ( const char* ) pidfile << "'" << oendl; 
00263 #endif
00264     QFile pfile2( pidfile );
00265     hasFile = pfile2.open( IO_ReadOnly );
00266     QTextStream s2( &pfile2 );
00267     if ( hasFile )
00268     {
00269         s2 >> pid;
00270 #ifdef MDEBUG
00271         odebug << "WIFIAPPLET: sent SIGUSR1 to pid " << pid << "" << oendl; 
00272 #endif
00273         kill( pid, SIGUSR1 );
00274         return ;
00275     }
00276 }
00277 
00278 void WirelessApplet::updateDHCPConfig( bool ESSID, bool FREQ, bool AP, bool MODE )
00279 {
00280     rocESSID = ESSID;
00281     rocFREQ = FREQ;
00282     rocAP = AP;
00283     rocMODE = MODE;
00284 }
00285 
00286 void WirelessApplet::updateDelayChange( int delay )
00287 {
00288     if ( timer )
00289         killTimer( timer );
00290     delay *= 1000;
00291     if ( delay == 0 )
00292         delay = 50;
00293     timer = startTimer( delay );
00294 }
00295 
00296 void WirelessApplet::displayStyleChange( int style )
00297 {
00298     visualStyle = style;
00299     repaint();
00300 }
00301 
00302 WirelessApplet::~WirelessApplet()
00303 {}
00304 
00305 void WirelessApplet::timerEvent( QTimerEvent* )
00306 {
00307 #ifdef MDEBUG
00308     odebug << "WirelessApplet::timerEvent" << oendl; 
00309 #endif
00310     if ( interface )
00311     {
00312         if ( !ONetwork::instance()->isPresent( (const char*) interface->name() ) )
00313         {
00314 #ifdef MDEBUG
00315             odebug << "WIFIAPPLET: Interface no longer present." << oendl; 
00316 #endif
00317             interface = 0L;
00318             mustRepaint();
00319             return;
00320         }
00321 
00322         if ( mustRepaint() )
00323         {
00324 #ifdef MDEBUG
00325             odebug << "WIFIAPPLET: A value has changed -> repainting." << oendl; 
00326 #endif
00327             repaint();
00328         }
00329 
00330         if ( status->isVisible() )
00331         {
00332             updatePopupWindow();
00333         }
00334     }
00335     else
00336     {
00337         checkInterface();
00338     }
00339 }
00340 
00341 void WirelessApplet::mousePressEvent( QMouseEvent * )
00342 {
00343     if ( status->isVisible() )
00344         status->hide();
00345     else
00346         status->show( true );
00347 }
00348 
00349 bool WirelessApplet::mustRepaint()
00350 {
00351     // check if there are enough changes to justify a (flickering) repaint
00352 
00353     // has the interface changed?
00354 
00355     if ( interface != oldiface )
00356     {
00357         oldiface = interface;
00358         if ( interface )
00359         {
00360 #ifdef MDEBUG
00361             odebug << "WIFIAPPLET: We had no interface but now we have one! :-)" << oendl; 
00362 #endif
00363             show();
00364         }
00365         else
00366         {
00367 #ifdef MDEBUG
00368             odebug << "WIFIAPPLET: We had a interface but now we don't have one! ;-(" << oendl; 
00369 #endif
00370             hide();
00371             return true;
00372         }
00373     }
00374 
00375     int rings = numberOfRings();
00376 
00377     if ( rings != oldrings )
00378     {
00379         oldrings = rings;
00380         return true;
00381     }
00382 
00383     int noiseH = 50; // iface->noisePercent() * ( height() - 3 ) / 100;
00384     int signalH = interface->signalStrength() * ( height() - 3 ) / 100;
00385     int qualityH = 50; // iface->qualityPercent() * ( height() - 3 ) / 100;
00386 
00387     if ( ( noiseH != oldnoiseH )
00388             || ( signalH != oldsignalH )
00389             || ( qualityH != oldqualityH ) )
00390     {
00391         oldnoiseH = noiseH;
00392         oldsignalH = signalH;
00393         oldqualityH = qualityH;
00394         return true;
00395     }
00396 
00397     if ( rocESSID && ( oldESSID != interface->SSID() ) )
00398     {
00399 #ifdef MDEBUG
00400         odebug << "WIFIAPPLET: ESSID has changed." << oendl; 
00401 #endif
00402         renewDHCP();
00403     }
00404     else if ( rocFREQ && ( oldFREQ != interface->frequency() ) )
00405     {
00406 #ifdef MDEBUG
00407         odebug << "WIFIAPPLET: FREQ has changed." << oendl; 
00408 #endif
00409         renewDHCP();
00410     }
00411     else if ( rocAP && ( oldAP != interface->associatedAP().toString() ) )
00412     {
00413 #ifdef MDEBUG
00414         odebug << "WIFIAPPLET: AP has changed." << oendl; 
00415 #endif
00416         renewDHCP();
00417     }
00418     else if ( rocMODE && ( oldMODE != interface->mode() ) )
00419     {
00420 #ifdef MDEBUG
00421         odebug << "WIFIAPPLET: MODE has changed." << oendl; 
00422 #endif
00423         renewDHCP();
00424     }
00425 
00426     oldESSID = interface->SSID();
00427     oldMODE = interface->mode();
00428     oldFREQ = interface->frequency();
00429     oldAP = interface->associatedAP().toString();
00430 
00431     return false;
00432 }
00433 
00434 void WirelessApplet::updatePopupWindow()
00435 {
00436     int qualityH = interface->signalStrength();
00437 
00438     if ( status->mgraph )
00439         status->mgraph->addValue( qualityH, false );
00440 
00441     QString freqString;
00442     QString cell = ( interface->mode() == "Managed" ) ? "AP: " : "Cell: ";
00443     freqString.sprintf( "%.3f GHz", interface->frequency() );
00444     status->statusLabel->setText( "Station: " + interface->nickName() + "<br>" +
00445                                   "ESSID: " + interface->SSID() + "<br>" +
00446                                   "MODE: " + interface->mode() + "<br>" +
00447                                   "FREQ: " + freqString + "<br>" +
00448                                   cell + " " + interface->associatedAP().toString() );
00449 }
00450 
00451 int WirelessApplet::numberOfRings()
00452 {
00453     if ( !interface ) return -1;
00454     int qualityH = interface->signalStrength();
00455     odebug << "quality = " << qualityH << "" << oendl; 
00456     if ( qualityH < 1 ) return -1;
00457     if ( qualityH < 20 ) return 0;
00458     if ( qualityH < 40 ) return 1;
00459     if ( qualityH < 60 ) return 2;
00460     if ( qualityH < 65 ) return 3;
00461     return 4;
00462 }
00463 
00464 void WirelessApplet::paintEvent( QPaintEvent* )
00465 {
00466     QPainter p( this );
00467     int h = height();
00468     int w = width();
00469     int m = 2;
00470 
00471     p.drawLine( m, h-m-1, round( w/2.0 ), round( 0+h/3.0 ) );
00472     p.drawLine(         round( w/2.0 ), round( 0+h/3.0 ), w-m, h-m-1 );
00473     p.setPen( QColor( 150, 150, 150 ) );
00474     p.drawLine( w-m, h-m-1, m, h-m-1 );
00475 
00476     int rings = numberOfRings();
00477 
00478     if ( rings == -1 )
00479     {
00480         p.setPen( QPen( QColor( 200, 20, 20 ), 2 )  );
00481         p.drawLine( w/2-m-m, h/2-m-m, w/2+m+m, h/2+m+m );
00482         p.drawLine( w/2+m+m, h/2-m-m, w/2-m-m, h/2+m+m );
00483         return;
00484     }
00485 
00486     odebug << "WirelessApplet: painting " << rings << " rings" << oendl; 
00487     int radius = 2;
00488     int rstep = 4;
00489     int maxrings = w/rstep;
00490 
00491     p.setPen( QColor( 200, 20, 20 ) );
00492     for ( int i = 0; i < rings; ++i )
00493     {
00494         p.drawEllipse( w/2 - radius/2, h/3 - radius/2, radius, radius );
00495         radius += rstep;
00496     };
00497 
00498 
00499 
00500 }
00501 
00502 
00503 int WirelessApplet::position()
00504 {
00505     return 6;
00506 }
00507 
00508 EXPORT_OPIE_APPLET_v1(  WirelessApplet )
00509 

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