00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "scanlist.h"
00017 #include "configwindow.h"
00018 #include "logwindow.h"
00019
00020
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
00031 #include <qcursor.h>
00032 #include <qdatetime.h>
00033 #include <qpopupmenu.h>
00034 #include <qcheckbox.h>
00035
00036
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
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
00157
00158 network = item;
00159
00160 item = static_cast<MScanListItem*> ( item->firstChild() );
00161 assert( item );
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
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
00190
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
00227 #ifdef DEBUG
00228 odebug << "" << addr.toString(true) << " is a dupe - ignoring..." << oendl;
00229 #endif
00230 subitem->receivedBeacon();
00231 return;
00232 }
00233
00234
00235 MScanListItem* station = new MScanListItem( network, type, "", 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
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 )
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& , const OMacAddress& via )
00278 {
00279 QString s;
00280
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 )
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& , const OMacAddress& via )
00301 {
00302 QString s;
00303
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 )
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& , const OMacAddress& , const OMacAddress& )
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
00353
00354
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
00375 #ifdef DEBUG
00376 odebug << "" << name << " is a dupe - ignoring..." << oendl;
00377 #endif
00378 subitem->receivedBeacon();
00379 return;
00380 }
00381
00382
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
00406
00407 return;
00408 }
00409
00410
00411
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 );
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 );
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 ) );
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
00495 QString name;
00496 name.sprintf( "wellenreiter/"+ type );
00497 setPixmap( col_type, Opie::Core::OResource::loadPixmap( name, Opie::Core::OResource::SmallIcon ) );
00498
00499
00500 if ( type == "network" && probed )
00501 {
00502 setPixmap( col_type, Opie::Core::OResource::loadPixmap( "wellenreiter/network-probed", Opie::Core::OResource::SmallIcon ) );
00503 }
00504
00505
00506 if ( wep )
00507 setPixmap( col_wep, Opie::Core::OResource::loadPixmap( "wellenreiter/cracked", Opie::Core::OResource::SmallIcon ) );
00508
00509
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
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
00568
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 }