Diffstat (limited to 'noncore/net/opiestumbler/opiestumbler.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/net/opiestumbler/opiestumbler.cpp | 348 |
1 files changed, 348 insertions, 0 deletions
diff --git a/noncore/net/opiestumbler/opiestumbler.cpp b/noncore/net/opiestumbler/opiestumbler.cpp new file mode 100644 index 0000000..8dedd67 --- a/dev/null +++ b/noncore/net/opiestumbler/opiestumbler.cpp | |||
@@ -0,0 +1,348 @@ | |||
1 | #include <cstdlib> | ||
2 | |||
3 | #include <qmenubar.h> | ||
4 | #include <qaction.h> | ||
5 | #include <qlistview.h> | ||
6 | #include <qstring.h> | ||
7 | //#include <qapplication.h> | ||
8 | #include <qdatetime.h> | ||
9 | #include <qpopupmenu.h> | ||
10 | #include <qstatusbar.h> | ||
11 | #include <qlayout.h> | ||
12 | #include <qwhatsthis.h> | ||
13 | #include <qtimer.h> | ||
14 | |||
15 | #include <qpe/resource.h> | ||
16 | #include <qpe/config.h> | ||
17 | //#include <qpe/global.h> | ||
18 | #include <qpe/qcopenvelope_qws.h> | ||
19 | #include <qpe/qpeapplication.h> | ||
20 | |||
21 | #include <opie2/odebug.h> | ||
22 | #include <opie2/ostation.h> | ||
23 | #include <opie2/omanufacturerdb.h> | ||
24 | #include <opie2/onetwork.h> | ||
25 | #include <opie2/oprocess.h> | ||
26 | |||
27 | #include "stumbler.h" | ||
28 | #include "opiestumbler.h" | ||
29 | #include "stumblersettings.h" | ||
30 | #include "stationviewitem.h" | ||
31 | #include "stumblerstation.h" | ||
32 | #include "stationinfo.h" | ||
33 | |||
34 | |||
35 | using Opie::Net::OWirelessNetworkInterface; | ||
36 | using Opie::Net::ONetwork; | ||
37 | |||
38 | |||
39 | QString OpieStumbler::appCaption() { | ||
40 | return QObject::tr("OpieStumbler"); | ||
41 | } | ||
42 | |||
43 | OpieStumbler::OpieStumbler(QWidget *parent, const char *name, WFlags) | ||
44 | :QMainWindow(parent, name, WStyle_ContextHelp), | ||
45 | m_listCurrent(new QListView(this)), m_listHistory(new QListView(this)), | ||
46 | m_stationsCurrent(new QList<Opie::Net::OStation>), | ||
47 | m_popupCurrent(new QPopupMenu(this)), | ||
48 | m_popupHistory(new QPopupMenu(this)), | ||
49 | m_db(NULL), m_proc(NULL) | ||
50 | { | ||
51 | |||
52 | if ( QCopChannel::isRegistered("QPE/OpieStumbler") ) { | ||
53 | QCopEnvelope e("QPE/OpieStumbler", "show()"); | ||
54 | exit(EXIT_SUCCESS); | ||
55 | } | ||
56 | |||
57 | QGridLayout *grid = new QGridLayout( this, 1, 1, 3, 0, "grid"); | ||
58 | QVBoxLayout *lay = new QVBoxLayout( NULL, 0, 5, "lay" ); | ||
59 | QSpacerItem *spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Fixed ); | ||
60 | lay->addItem(spacer); | ||
61 | lay->addWidget(m_listCurrent); | ||
62 | lay->addWidget(m_listHistory); | ||
63 | grid->addLayout(lay, 0, 0); | ||
64 | |||
65 | m_stationsCurrent->setAutoDelete(TRUE); | ||
66 | |||
67 | m_channel = new QCopChannel( "QPE/OpieStumbler", this ); | ||
68 | connect(m_channel, SIGNAL(received(const QCString &, const QByteArray &)), | ||
69 | this, SLOT(slotMessageReceived( const QCString &, const QByteArray &)) ); | ||
70 | |||
71 | //setCaption(appCaption()); | ||
72 | //setCentralWidget(grid); | ||
73 | setToolBarsMovable(FALSE); | ||
74 | |||
75 | |||
76 | QPopupMenu *fileMenu = new QPopupMenu(this); | ||
77 | QPopupMenu *configMenu = new QPopupMenu(this); | ||
78 | QPopupMenu *scanMenu = new QPopupMenu(this); | ||
79 | |||
80 | fileMenu->insertItem( tr("Exit"), this, SLOT(close()) ); | ||
81 | configMenu->insertItem( tr("Configure"), this, SLOT(slotConfigure()) ); | ||
82 | scanMenu->insertItem( tr("Start"), this, SLOT(slotStartScanning()) ); | ||
83 | scanMenu->insertItem( tr("Stop"), this, SLOT(slotStopScanning()) ); | ||
84 | |||
85 | m_popupCurrent->insertItem( tr("Show details"), this, SLOT(slotShowDetails()) ); | ||
86 | m_popupCurrent->insertItem( tr("Join Network"), this, SLOT(slotJoinNetwork()) ); | ||
87 | |||
88 | menuBar()->insertItem(tr("File"), fileMenu); | ||
89 | menuBar()->insertItem(tr("Settings"), configMenu); | ||
90 | menuBar()->insertItem(tr("Scanning"), scanMenu); | ||
91 | |||
92 | QPEApplication::setStylusOperation(m_listCurrent->viewport(), QPEApplication::RightOnHold); | ||
93 | QPEApplication::setStylusOperation(m_listHistory->viewport(), QPEApplication::RightOnHold); | ||
94 | |||
95 | m_listCurrent->addColumn(tr("SSID")); | ||
96 | m_listCurrent->addColumn(tr("Chan")); | ||
97 | m_listCurrent->addColumn(tr("Signal")); | ||
98 | m_listCurrent->addColumn(tr("Enc")); | ||
99 | m_listCurrent->setSelectionMode( QListView::Extended ); | ||
100 | |||
101 | m_listHistory->addColumn(tr("SSID")); | ||
102 | m_listHistory->addColumn(tr("Chan")); | ||
103 | m_listHistory->addColumn(tr("Max Sig")); | ||
104 | m_listHistory->addColumn(tr("Enc")); | ||
105 | m_listHistory->addColumn(tr("Vendor")); | ||
106 | |||
107 | connect(m_listCurrent, SIGNAL(mouseButtonPressed (int, QListViewItem*, const QPoint&, int)), | ||
108 | this, SLOT(slotCurrentMousePressed (int, QListViewItem*, const QPoint&, int))); | ||
109 | |||
110 | connect(m_listHistory, SIGNAL(mouseButtonPressed (int, QListViewItem*, const QPoint&, int)), | ||
111 | this, SLOT(slotHistoryMousePressed (int, QListViewItem*, const QPoint&, int))); | ||
112 | |||
113 | for(int i = CURCHAN; i <= CURENC; ++i) { | ||
114 | m_listCurrent->setColumnAlignment( i, Qt::AlignHCenter ); | ||
115 | m_listHistory->setColumnAlignment( i, Qt::AlignHCenter ); | ||
116 | } | ||
117 | |||
118 | loadConfig(); | ||
119 | m_stumbler = new Stumbler(m_interface, this); | ||
120 | connect(m_stumbler, SIGNAL(newdata()), this, SLOT(slotUpdateStations())); | ||
121 | |||
122 | QTimer::singleShot(1000, this, SLOT(slotLoadManufacturers()) ); | ||
123 | |||
124 | slotStartScanning(); | ||
125 | } | ||
126 | |||
127 | void OpieStumbler::slotConfigure() | ||
128 | { | ||
129 | StumblerSettings settings(this, "Settings", TRUE); | ||
130 | if (settings.exec() == QDialog::Accepted) | ||
131 | loadConfig(); | ||
132 | } | ||
133 | |||
134 | void OpieStumbler::loadConfig() | ||
135 | { | ||
136 | Config cfg("OpieStumbler", Config::User); | ||
137 | cfg.setGroup("General"); | ||
138 | m_interface = cfg.readEntry("interface", "wlan0"); | ||
139 | } | ||
140 | |||
141 | void OpieStumbler::slotStartScanning() | ||
142 | { | ||
143 | setCaption(appCaption() + " (" + tr("Scanning") + ")"); | ||
144 | m_stumbler->start(); | ||
145 | } | ||
146 | |||
147 | void OpieStumbler::slotStopScanning() | ||
148 | { | ||
149 | setCaption(appCaption()); | ||
150 | m_stumbler->stop(); | ||
151 | } | ||
152 | |||
153 | void OpieStumbler::slotUpdateStations() | ||
154 | { | ||
155 | m_stationsCurrent->clear(); | ||
156 | |||
157 | m_stationsCurrent = m_stumbler->stations(); | ||
158 | if (m_stationsCurrent) { | ||
159 | QListIterator<Opie::Net::OStation> it(*m_stationsCurrent); | ||
160 | for(; it.current(); ++it) { | ||
161 | Opie::Net::OStation *station = it.current(); | ||
162 | QListIterator<StumblerStation> itr(m_stationsHistory); | ||
163 | for( ; itr.current(); ++itr) { | ||
164 | if (itr.current()->st->macAddress.toString() == station->macAddress.toString()) { | ||
165 | break; | ||
166 | } | ||
167 | } | ||
168 | if (!itr.current()) { | ||
169 | //We need to copy the date because m_statiosCurrent has autodelete enabled | ||
170 | m_stationsHistory.append(new StumblerStation(new Opie::Net::OStation, QDateTime::currentDateTime())); | ||
171 | *(m_stationsHistory.last()->st) = (*station); | ||
172 | } | ||
173 | else { | ||
174 | if ( itr.current()->st->level < station->level ) | ||
175 | itr.current()->st->level = station->level; | ||
176 | |||
177 | itr.current()->lastTimeSeen = QDateTime::currentDateTime(); | ||
178 | } | ||
179 | } | ||
180 | } | ||
181 | displayStations(); | ||
182 | } | ||
183 | |||
184 | void OpieStumbler::displayStations() | ||
185 | { | ||
186 | m_listCurrent->clear(); | ||
187 | for(QListIterator<Opie::Net::OStation> it(*m_stationsCurrent); it.current(); ++it) | ||
188 | new StationViewItem( m_listCurrent, it.current()->ssid, QString::number(it.current()->channel), | ||
189 | QString::number(it.current()->level), it.current()->encrypted ? "Y": "N", it.current()->macAddress.toString() ); | ||
190 | |||
191 | m_listHistory->clear(); | ||
192 | for(QListIterator<StumblerStation> it(m_stationsHistory); it.current(); ++it) | ||
193 | new StationViewItem( m_listHistory, it.current()->st->ssid, QString::number(it.current()->st->channel), | ||
194 | QString::number(it.current()->st->level), it.current()->st->encrypted ? "Y": "N", | ||
195 | manufacturer(it.current()->st->macAddress.toString()), it.current()->st->macAddress.toString() ); | ||
196 | } | ||
197 | |||
198 | void OpieStumbler::slotMessageReceived( const QCString &message, const QByteArray ¶meters) | ||
199 | { | ||
200 | Q_UNUSED(const_cast<QByteArray &>(parameters)) | ||
201 | |||
202 | if ( message == "show()" ) | ||
203 | show(); | ||
204 | } | ||
205 | |||
206 | void OpieStumbler::slotCurrentMousePressed(int button, QListViewItem * item, const QPoint &point, int c) | ||
207 | { | ||
208 | Q_UNUSED(c) | ||
209 | |||
210 | if ( 2 == button ) { | ||
211 | m_mac = item->text(CURENC + 1); | ||
212 | m_popupCurrent->popup(point); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | |||
217 | void OpieStumbler::slotHistoryMousePressed(int button, QListViewItem * item, const QPoint &point, int c) | ||
218 | { | ||
219 | Q_UNUSED(c) | ||
220 | |||
221 | if ( 2 == button ) { | ||
222 | m_mac = item->text(HISVENDOR + 1); | ||
223 | m_popupHistory->popup(point); | ||
224 | } | ||
225 | } | ||
226 | |||
227 | void OpieStumbler::slotShowDetails() | ||
228 | { | ||
229 | QListIterator<StumblerStation> it(m_stationsHistory); | ||
230 | for(; it.current() && it.current()->st->macAddress.toString() != m_mac; ++it ); | ||
231 | |||
232 | if( it.current() ) { | ||
233 | StationInfo info(it.current()->st->ssid, it.current()->st->type, QString::number(it.current()->st->channel), | ||
234 | QString::number(it.current()->st->rates.last()/1000000), QString::number(it.current()->st->level), | ||
235 | it.current()->st->encrypted ? "WEP": "No", | ||
236 | it.current()->st->macAddress.toString(), manufacturer(it.current()->st->macAddress.toString(), TRUE), | ||
237 | it.current()->lastTimeSeen.toString() ,this, "", TRUE); | ||
238 | info.exec(); | ||
239 | } | ||
240 | |||
241 | } | ||
242 | |||
243 | void OpieStumbler::slotLoadManufacturers() | ||
244 | { | ||
245 | m_db = Opie::Net::OManufacturerDB::instance(); | ||
246 | } | ||
247 | |||
248 | QString OpieStumbler::manufacturer( const QString &mac, bool extended ) | ||
249 | { | ||
250 | QString retval; | ||
251 | if ( m_db ) | ||
252 | if ( extended ) | ||
253 | retval = m_db->lookupExt(mac); | ||
254 | else | ||
255 | retval = m_db->lookup(mac); | ||
256 | |||
257 | if ( retval.isEmpty() ) | ||
258 | retval = tr("Unknown"); | ||
259 | |||
260 | return retval; | ||
261 | } | ||
262 | |||
263 | void OpieStumbler::slotJoinNetwork() | ||
264 | { | ||
265 | slotStopScanning(); | ||
266 | |||
267 | OWirelessNetworkInterface *wiface = static_cast<OWirelessNetworkInterface*>(ONetwork::instance()->interface(m_interface)); | ||
268 | |||
269 | if( !wiface ) | ||
270 | return; | ||
271 | |||
272 | QListIterator<StumblerStation> it(m_stationsHistory); | ||
273 | |||
274 | for(; it.current() && it.current()->st->macAddress.toString() != m_mac; ++it ); | ||
275 | |||
276 | if( !it.current() ) | ||
277 | return; | ||
278 | |||
279 | Opie::Net::OStation *station = it.current()->st; | ||
280 | |||
281 | odebug << "Bringing interface down" << oendl; | ||
282 | wiface->setUp(FALSE); | ||
283 | |||
284 | odebug << "Setting mode to " << (station->type == "adhoc" ? "adhoc" : "managed") << oendl; | ||
285 | wiface->setMode(station->type == "adhoc" ? "adhoc" : "managed" ); | ||
286 | |||
287 | odebug << "Setting channel to " << station->channel << oendl; | ||
288 | wiface->setChannel(station->channel); | ||
289 | |||
290 | odebug << "Setting SSID to " << station->ssid << oendl; | ||
291 | wiface->setSSID(station->ssid); | ||
292 | |||
293 | wiface->commit(); | ||
294 | |||
295 | odebug << "Bringing interface up" << oendl; | ||
296 | wiface->setUp(TRUE); | ||
297 | //Wait 5 sec for association | ||
298 | QTimer::singleShot(5000, this, SLOT(slotAssociated())); | ||
299 | } | ||
300 | |||
301 | void OpieStumbler::slotAssociated() | ||
302 | { | ||
303 | OWirelessNetworkInterface *wiface = static_cast<OWirelessNetworkInterface*>(ONetwork::instance()->interface(m_interface)); | ||
304 | |||
305 | if( !wiface ) | ||
306 | return; | ||
307 | |||
308 | if (!wiface->isAssociated()) { | ||
309 | Global::statusMessage(tr("Could not Join")); | ||
310 | return; | ||
311 | } | ||
312 | |||
313 | Global::statusMessage(tr("Joined")); | ||
314 | |||
315 | if(m_proc) { | ||
316 | m_proc->kill(); | ||
317 | delete m_proc; | ||
318 | } | ||
319 | |||
320 | m_proc = new Opie::Core::OProcess(this); | ||
321 | |||
322 | *m_proc << "udhcpc" << "-f" << "-n" << "-i" << m_interface; | ||
323 | m_proc->start(Opie::Core::OProcess::DontCare); | ||
324 | QTimer::singleShot(5000, this, SLOT(slotCheckDHCP())); | ||
325 | } | ||
326 | |||
327 | void OpieStumbler::slotCheckDHCP() | ||
328 | { | ||
329 | if(!m_proc->isRunning()) { | ||
330 | Global::statusMessage(tr("Could not Obtain an Address")); | ||
331 | delete m_proc; | ||
332 | m_proc = NULL; | ||
333 | return; | ||
334 | } | ||
335 | m_listCurrent->show(); | ||
336 | |||
337 | |||
338 | OWirelessNetworkInterface *wiface = static_cast<OWirelessNetworkInterface*>(ONetwork::instance()->interface(m_interface)); | ||
339 | Global::statusMessage(tr("Obtained IP ") + wiface->ipV4Address()); | ||
340 | } | ||
341 | |||
342 | |||
343 | |||
344 | |||
345 | |||
346 | |||
347 | |||
348 | |||