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

scanlist.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2002-2004 Michael 'Mickey' Lauer.  All rights reserved.
00003 **
00004 ** This file is part of Wellenreiter II.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 **********************************************************************/
00015 
00016 #include "scanlist.h"
00017 #include "configwindow.h"
00018 #include "logwindow.h"
00019 
00020 /* OPIE */
00021 #ifdef QWS
00022 #include <opie2/odebug.h>
00023 #include <opie2/oresource.h>
00024 #include <qpe/qpeapplication.h>
00025 #else
00026 #include "resource.h"
00027 #endif
00028 
00029 
00030 /* QT */
00031 #include <qcursor.h>
00032 #include <qdatetime.h>
00033 #include <qpopupmenu.h>
00034 #include <qcheckbox.h>
00035 
00036 /* STD */
00037 #include <assert.h>
00038 
00039 using namespace Opie::Core;
00040 using namespace Opie::Ui;
00041 using namespace Opie::Net;
00042 
00043 const int col_type = 0;
00044 const int col_essid = 0;
00045 const int col_sig = 1;
00046 const int col_ap = 2;
00047 const int col_channel = 3;
00048 const int col_wep = 4;
00049 const int col_traffic = 5;
00050 const int col_ip = 6;
00051 const int col_manuf = 7;
00052 const int col_firstseen = 8;
00053 const int col_lastseen = 9;
00054 const int col_location = 10;
00055 
00056 #define DEBUG
00057 
00058 MScanListView::MScanListView( QWidget* parent, const char* name )
00059               :OListView( parent, name )
00060 {
00061     setFrameShape( QListView::StyledPanel );
00062     setFrameShadow( QListView::Sunken );
00063 
00064     addColumn( tr( "Net/Station" ) );
00065     setColumnAlignment( col_essid, AlignLeft || AlignVCenter );
00066     addColumn( tr( "#" ) );
00067     setColumnAlignment( col_sig, AlignCenter );
00068     addColumn( tr( "MAC" ) );
00069     setColumnAlignment( col_ap, AlignCenter );
00070     addColumn( tr( "Chn" ) );
00071     setColumnAlignment( col_channel, AlignCenter );
00072     addColumn( tr( "W" ) );
00073     setColumnAlignment( col_wep, AlignCenter );
00074     addColumn( tr( "T" ) );
00075     setColumnAlignment( col_traffic, AlignCenter );
00076     addColumn( tr( "IP" ) );
00077     setColumnAlignment( col_ip, AlignCenter );
00078     addColumn( tr( "Manufacturer" ) );
00079     setColumnAlignment( col_manuf, AlignCenter );
00080     addColumn( tr( "First Seen" ) );
00081     setColumnAlignment( col_firstseen, AlignCenter );
00082     addColumn( tr( "Last Seen" ) );
00083     setColumnAlignment( col_lastseen, AlignCenter );
00084     addColumn( tr( "Location" ) );
00085     setColumnAlignment( col_location, AlignCenter );
00086     setRootIsDecorated( true );
00087     setAllColumnsShowFocus( true );
00088 
00089     connect( this, SIGNAL( rightButtonPressed(QListViewItem*,const QPoint&,int) ),
00090              this, SLOT( contextMenuRequested(QListViewItem*,const QPoint&,int) ) );
00091 
00092     #ifdef QWS
00093     QPEApplication::setStylusOperation( viewport(), QPEApplication::RightOnHold );
00094     #endif
00095 
00096 };
00097 
00098 
00099 MScanListView::~MScanListView()
00100 {
00101 };
00102 
00103 
00104 OListViewItem* MScanListView::childFactory()
00105 {
00106     return new MScanListItem( this );
00107 }
00108 
00109 
00110 void MScanListView::serializeTo( QDataStream& s) const
00111 {
00112     odebug << "serializing MScanListView" << oendl;
00113     OListView::serializeTo( s );
00114 }
00115 
00116 
00117 void MScanListView::serializeFrom( QDataStream& s)
00118 {
00119     odebug << "serializing MScanListView" << oendl;
00120     OListView::serializeFrom( s );
00121 }
00122 
00123 
00124 void MScanListView::addNewItem( const QString& type,
00125                                 const QString& essid,
00126                                 const OMacAddress& mac,
00127                                 bool wep,
00128                                 int channel,
00129                                 int signal,
00130                                 const GpsLocation& loc,
00131                                 bool probe )
00132 {
00133     QString macaddr = mac.toString(true);
00134 
00135     #ifdef DEBUG
00136     odebug << "MScanList::addNewItem( "  << type << " / "
00137            << essid << " / " << macaddr
00138            << " [" << channel << "]" << oendl;
00139     #endif
00140 
00141     // search, if we already have seen this net
00142 
00143     QString s;
00144     MScanListItem* network;
00145     MScanListItem* item = static_cast<MScanListItem*> ( firstChild() );
00146 
00147     while ( item && ( item->text( col_essid ) != essid ) )
00148     {
00149         #ifdef DEBUG
00150         odebug << "itemtext: " << item->text( col_essid ) << "" << oendl;
00151         #endif
00152         item = static_cast<MScanListItem*> ( item->nextSibling() );
00153     }
00154     if ( item )
00155     {
00156         // we have already seen this net, check all childs if MAC exists
00157 
00158         network = item;
00159 
00160         item = static_cast<MScanListItem*> ( item->firstChild() );
00161         assert( item ); // this shouldn't fail
00162 
00163         while ( item && ( item->text( col_ap ) != macaddr ) )
00164         {
00165             #ifdef DEBUG
00166             odebug << "subitemtext: " << item->text( col_ap ) << "" << oendl;
00167             #endif
00168             item = static_cast<MScanListItem*> ( item->nextSibling() );
00169         }
00170 
00171         if ( item )
00172         {
00173             // we have already seen this item, it's a dupe
00174             #ifdef DEBUG
00175             odebug << "" << macaddr << " is a dupe - ignoring..." << oendl;
00176             #endif
00177             item->receivedBeacon();
00178             return;
00179         }
00180     }
00181     else
00182     {
00183         s = QString( "(i) New network: ESSID '%1'" ).arg( essid );
00184         MLogWindow::logwindow()->log( s );
00185         network = new MScanListItem( this, "network", essid, QString::null, 0, 0, 0, probe );
00186     }
00187 
00188 
00189     // insert new station as child from network
00190     // no essid to reduce clutter, maybe later we have a nick or stationname to display!?
00191 
00192     #ifdef DEBUG
00193     odebug << "inserting new station " << macaddr << "" << oendl;
00194     #endif
00195 
00196     MScanListItem* station = new MScanListItem( network, type, "", macaddr, wep, channel, signal );
00197     station->setManufacturer( mac.manufacturer() );
00198     station->setLocation( loc.dmsPosition() );
00199 
00200     if ( type == "managed" )
00201     {
00202         s = QString( "(i) New Access Point in '%1' [%2]" ).arg( essid ).arg( channel );
00203     }
00204     else
00205     {
00206         s = QString( "(i) New AdHoc station in '%1' [%2]" ).arg( essid ).arg( channel );
00207     }
00208     MLogWindow::logwindow()->log( s );
00209 }
00210 
00211 
00212 void MScanListView::addIfNotExisting( MScanListItem* network, const OMacAddress& addr, const QString& type )
00213 {
00214     MScanListItem* subitem = static_cast<MScanListItem*>( network->firstChild() );
00215 
00216     while ( subitem && ( subitem->text( col_ap ) != addr.toString(true) ) )
00217     {
00218         #ifdef DEBUG
00219         odebug << "subitemtext: " << subitem->text( col_ap ) << "" << oendl;
00220         #endif
00221         subitem = static_cast<MScanListItem*> ( subitem->nextSibling() );
00222     }
00223 
00224     if ( subitem )
00225     {
00226         // we have already seen this item, it's a dupe
00227         #ifdef DEBUG
00228         odebug << "" << addr.toString(true) << " is a dupe - ignoring..." << oendl;
00229         #endif
00230         subitem->receivedBeacon(); //FIXME: sent data bit
00231         return;
00232     }
00233 
00234     // Hey, it seems to be a new item :-D
00235     MScanListItem* station = new MScanListItem( network, type, /* network->text( col_essid ) */ "", addr.toString(true), false, -1, -1 );
00236     station->setManufacturer( addr.manufacturer() );
00237 
00238     QString s;
00239     if ( type == "station" )
00240     {
00241         s = QString( "(i) New Station in '%1' [xx]" ).arg( network->text( col_essid ) );
00242     }
00243     else
00244     {
00245         s = QString( "(i) New Wireless Station in '%1' [xx]" ).arg( network->text( col_essid ) );
00246     }
00247     MLogWindow::logwindow()->log( s );
00248 }
00249 
00250 
00251 void MScanListView::WDStraffic( const OMacAddress& from, const OMacAddress& to, const OMacAddress& viaFrom, const OMacAddress& viaTo )
00252 {
00253     odebug << "WDSTraffic: " << viaFrom.toString() << " and " << viaTo.toString() << " seem to form a WDS" << oendl;
00254     QString s;
00255 //    MScanListItem* network;
00256 
00257     QListViewItemIterator it( this );
00258     while ( it.current() &&
00259             it.current()->text( col_ap ) != viaFrom.toString(true) &&
00260             it.current()->text( col_ap ) != viaTo.toString(true) ) ++it;
00261 
00262     MScanListItem* item = static_cast<MScanListItem*>( it.current() );
00263 
00264     if ( item ) // Either viaFrom or viaTo AP has shown up yet, so just add our two new stations
00265     {
00266         addIfNotExisting( static_cast<MScanListItem*>(item->parent()), from );
00267         addIfNotExisting( static_cast<MScanListItem*>(item->parent()), to );
00268     }
00269     else
00270     {
00271         odebug << "D'Oh! Stations without AP... ignoring for now... will handle this in 1.1 version :-D" << oendl;
00272         MLogWindow::logwindow()->log( "WARNING: Unhandled WSD traffic!" );
00273     }
00274 }
00275 
00276 
00277 void MScanListView::toDStraffic( const OMacAddress& from, const OMacAddress& /*to*/, const OMacAddress& via )
00278 {
00279     QString s;
00280 //    MScanListItem* network;
00281 
00282     QListViewItemIterator it( this );
00283     while ( it.current() && it.current()->text( col_ap ) != via.toString(true) ) ++it;
00284 
00285     MScanListItem* item = static_cast<MScanListItem*>( it.current() );
00286 
00287     if ( item ) // AP has shown up yet, so just add our new "from" - station
00288     {
00289         addIfNotExisting( static_cast<MScanListItem*>(item->parent()), from, "adhoc" );
00290     }
00291     else
00292     {
00293         odebug << "D'Oh! Station without AP... ignoring for now... will handle this in 1.1 :-D" << oendl;
00294         MLogWindow::logwindow()->log( "WARNING: Unhandled toDS traffic!" );
00295 
00296     }
00297 }
00298 
00299 
00300 void MScanListView::fromDStraffic( const OMacAddress& from, const OMacAddress& /*to*/, const OMacAddress& via )
00301 {
00302     QString s;
00303 //    MScanListItem* network;
00304 
00305     QListViewItemIterator it( this );
00306     while ( it.current() && it.current()->text( col_ap ) != via.toString(true) ) ++it;
00307 
00308     MScanListItem* item = static_cast<MScanListItem*>( it.current() );
00309 
00310     if ( item ) // AP has shown up yet, so just add our new "from" - station
00311     {
00312         addIfNotExisting( static_cast<MScanListItem*>(item->parent()), from, "station" );
00313     }
00314     else
00315     {
00316         odebug << "D'Oh! Station without AP... ignoring for now... will handle this in 1.1 :-D" << oendl;
00317         MLogWindow::logwindow()->log( "WARNING: Unhandled fromDS traffic!" );
00318     }
00319 }
00320 
00321 
00322 void MScanListView::IBSStraffic( const OMacAddress& /*from*/, const OMacAddress& /*to*/, const OMacAddress& /*via*/ )
00323 {
00324     owarn << "D'oh! Not yet implemented..." << oendl;
00325     MLogWindow::logwindow()->log( "WARNING: Unhandled IBSS traffic!" );
00326 }
00327 
00328 
00329 void MScanListView::identify( const OMacAddress& macaddr, const QString& ip )
00330 {
00331     odebug << "identify " << macaddr.toString() << " = " << ip << "" << oendl;
00332 
00333     QListViewItemIterator it( this );
00334     for ( ; it.current(); ++it )
00335     {
00336         if ( it.current()->text( col_ap ) == macaddr.toString(true) )
00337         {
00338             it.current()->setText( col_ip, ip );
00339             return;
00340         }
00341     }
00342     odebug << "D'oh! Received identification, but item not yet in list... ==> Handle this!" << oendl;
00343     MLogWindow::logwindow()->log( QString( "WARNING: Unhandled identification %1 = %2!" )
00344                                   .arg( macaddr.toString() ).arg( ip ) );
00345 }
00346 
00347 
00348 void MScanListView::addService( const QString& name, const OMacAddress& macaddr, const QString& ip )
00349 {
00350     odebug << "addService '" << name << "', Server = " << macaddr.toString() << " = " << ip << "" << oendl;
00351 
00352     //TODO: Refactor that out, we need it all over the place.
00353     //      Best to do it in a more comfortable abstraction in OListView
00354     //      (Hmm, didn't I already start something in this direction?)
00355 
00356     QListViewItemIterator it( this );
00357     for ( ; it.current(); ++it )
00358     {
00359         if ( it.current()->text( col_ap ) == macaddr.toString(true) )
00360         {
00361 
00362             MScanListItem* subitem = static_cast<MScanListItem*>( it.current()->firstChild() );
00363 
00364             while ( subitem && ( subitem->text( col_essid ) != name ) )
00365             {
00366                 #ifdef DEBUG
00367                 odebug << "subitemtext: " << subitem->text( col_essid ) << "" << oendl;
00368                 #endif
00369                 subitem = static_cast<MScanListItem*> ( subitem->nextSibling() );
00370             }
00371 
00372             if ( subitem )
00373             {
00374                 // we have already seen this item, it's a dupe
00375                 #ifdef DEBUG
00376                 odebug << "" << name << " is a dupe - ignoring..." << oendl;
00377                 #endif
00378                 subitem->receivedBeacon(); //FIXME: sent data bit
00379                 return;
00380             }
00381 
00382             // never seen that - add new item
00383 
00384             MScanListItem* item = new MScanListItem( it.current(), "service", "N/A", " ", false, -1, -1 );
00385             item->setText( col_essid, name );
00386 
00387             return;
00388         }
00389     }
00390     odebug << "D'oh! Received identification, but item not yet in list... ==> Handle this!" << oendl;
00391     MLogWindow::logwindow()->log( QString("WARNING: Unhandled service addition %s = %s!")
00392                                                      .arg( macaddr.toString() ).arg( ip ) );
00393 }
00394 
00395 
00396 void MScanListView::contextMenuRequested( QListViewItem* item, const QPoint&, int col )
00397 {
00398     if ( !item ) return;
00399 
00400     MScanListItem* itm = static_cast<MScanListItem*>( item );
00401 
00402     odebug << "contextMenuRequested on item '" << itm->text(0) << "' ("
00403            << itm->type << ") in column: '" << col << "'" << oendl;
00404 
00405     /* do something meaningful */
00406 
00407     return;
00408 }
00409 
00410 //============================================================
00411 // MScanListItem
00412 //============================================================
00413 
00414 MScanListItem::MScanListItem( QListView* parent, const QString& type, const QString& essid, const QString& macaddr,
00415                               bool wep, int channel, int signal, bool probed )
00416                :OListViewItem( parent, essid, QString::null, macaddr, QString::null, QString::null ),
00417                 _type( type ), _essid( essid ), _macaddr( macaddr ), _wep( wep ),
00418                 _channel( channel ), _signal( signal ), _beacons( 1 )
00419 {
00420     #ifdef DEBUG
00421     odebug << "creating scanlist item" << oendl;
00422     #endif
00423 
00424     if ( WellenreiterConfigWindow::instance() )
00425         WellenreiterConfigWindow::instance()->performAction( type, essid, macaddr, wep, channel, signal ); // better use signal/slot combination here
00426 
00427     decorateItem( type, essid, macaddr, wep, channel, signal, probed );
00428 }
00429 
00430 MScanListItem::MScanListItem( QListViewItem* parent, const QString& type, const QString& essid, const QString& macaddr,
00431                               bool wep, int channel, int signal )
00432                :OListViewItem( parent, essid, QString::null, macaddr, QString::null, QString::null )
00433 {
00434     #ifdef DEBUG
00435     odebug << "creating scanlist item" << oendl;
00436     #endif
00437     if ( WellenreiterConfigWindow::instance() )
00438         WellenreiterConfigWindow::instance()->performAction( type, essid, macaddr, wep, channel, signal ); // better use signal/slot combination here
00439 
00440     decorateItem( type, essid, macaddr, wep, channel, signal, false );
00441 }
00442 
00443 const QString& MScanListItem::essid() const
00444 {
00445     if ( type == "network" )
00446         return _essid;
00447     else
00448         return ( (MScanListItem*) parent() )->essid();
00449 }
00450 
00451 OListViewItem* MScanListItem::childFactory()
00452 {
00453     return new MScanListItem( this );
00454 }
00455 
00456 void MScanListItem::serializeTo( QDataStream& s ) const
00457 {
00458     #ifdef DEBUG
00459     odebug << "serializing MScanListItem" << oendl;
00460     #endif
00461     OListViewItem::serializeTo( s );
00462 
00463     s << _type;
00464     s << (Q_UINT8) ( _wep ? 'y' : 'n' );
00465 }
00466 
00467 void MScanListItem::serializeFrom( QDataStream& s )
00468 {
00469     #ifdef DEBUG
00470     odebug << "serializing MScanListItem" << oendl;
00471     #endif
00472     OListViewItem::serializeFrom( s );
00473 
00474     Q_UINT8 wep;
00475     s >> _type;
00476     s >> wep;
00477     _wep = (wep == 'y');
00478 
00479     QString name = QString( "wellenreiter/"+ _type );
00480     setPixmap( col_type, Opie::Core::OResource::loadPixmap( name, Opie::Core::OResource::SmallIcon ) );
00481     if ( _wep )
00482         setPixmap( col_wep, Opie::Core::OResource::loadPixmap( "wellenreiter/cracked", Opie::Core::OResource::SmallIcon ) ); //FIXME: rename the pixmap!
00483     listView()->triggerUpdate();
00484 }
00485 
00486 void MScanListItem::decorateItem( QString type, QString essid, QString macaddr, bool wep, int channel, int signal, bool probed )
00487 {
00488     #ifdef DEBUG
00489     odebug << "decorating scanlist item " << type << " / "
00490            << essid << " / " << macaddr
00491            << "[" << channel << "]" << oendl;
00492     #endif
00493 
00494     // set icon for managed or adhoc mode
00495     QString name;
00496     name.sprintf( "wellenreiter/"+ type );
00497     setPixmap( col_type, Opie::Core::OResource::loadPixmap( name, Opie::Core::OResource::SmallIcon ) );
00498 
00499     // special case for probed networks FIXME: This is ugly at present
00500     if ( type == "network" && probed )
00501     {
00502         setPixmap( col_type, Opie::Core::OResource::loadPixmap( "wellenreiter/network-probed", Opie::Core::OResource::SmallIcon ) );
00503     }
00504 
00505     // set icon for wep (wireless encryption protocol)
00506     if ( wep )
00507         setPixmap( col_wep, Opie::Core::OResource::loadPixmap( "wellenreiter/cracked", Opie::Core::OResource::SmallIcon ) ); //FIXME: rename the pixmap!
00508 
00509     // set channel and signal text
00510 
00511     if ( signal != -1 )
00512         setText( col_sig, QString::number( signal ) );
00513     if ( channel != -1 )
00514         setText( col_channel, QString::number( channel ) );
00515 
00516     setText( col_firstseen, QTime::currentTime().toString() );
00517     //setText( col_lastseen, QTime::currentTime().toString() );
00518 
00519     listView()->triggerUpdate();
00520 
00521     this->type = type;
00522     _type = type;
00523     _essid = essid;
00524     _macaddr = macaddr;
00525     _channel = channel;
00526     _beacons = 1;
00527     _signal = 0;
00528 
00529     if ( WellenreiterConfigWindow::instance()->openTree->isChecked() )
00530     {
00531         listView()->ensureItemVisible( this );
00532     }
00533 
00534 }
00535 
00536 
00537 void MScanListItem::setManufacturer( const QString& manufacturer )
00538 {
00539     setText( col_manuf, manufacturer );
00540 }
00541 
00542 
00543 void MScanListItem::setLocation( const QString& location )
00544 {
00545     setText( col_location, location );
00546 }
00547 
00548 
00549 void MScanListItem::receivedBeacon()
00550 {
00551     _beacons++;
00552     #ifdef DEBUG
00553     odebug << "MScanListItem " << _macaddr << ": received beacon #" << _beacons << "" << oendl;
00554     #endif
00555     setText( col_sig, QString::number( _beacons ) );
00556     setText( col_lastseen, QTime::currentTime().toString() );
00557 
00558     MScanListItem* p = (MScanListItem*) parent();
00559     if ( p ) p->receivedBeacon();
00560 
00561 }
00562 
00563 QString MScanListItem::key( int id, bool b )const {
00564     QString str;
00565 
00566     /*
00567      * Pad the amount of received packages, number
00568      * of the channel.
00569      */
00570     switch( id ) {
00571     case col_sig:
00572         str = text(col_sig).rightJustify( 20, '0' );
00573         break;
00574     case col_channel:
00575         str = text(col_channel).rightJustify( 2, '0' );
00576         break;
00577     default:
00578         str = Opie::Ui::OListViewItem::key( id, b );
00579         break;
00580     }
00581 
00582     return str;
00583 }

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