~ubuntu-branches/ubuntu/trusty/kwlan/trusty

« back to all changes in this revision

Viewing changes to kwlan/kwlaninterface.cpp~

  • Committer: Bazaar Package Importer
  • Author(s): Fathi Boudra
  • Date: 2007-08-24 01:02:39 UTC
  • mfrom: (1.1.5 upstream) (0.1.3 lenny)
  • Revision ID: james.westby@ubuntu.com-20070824010239-e2xmgrrehh3n092w
Tags: 0.6.3-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* KwlanInterface defines a class for configuring and monitoring an interface
 
2
        Parts of it's implemtation are based on KNemo by Percy Leonhardt <percy@eris23.de>
 
3
        The scanning part is derived from wireless-tools ba Jean Tourrilhes <jt@hpl.hp.com>
 
4
   
 
5
        (c) 2006 by Thomas Michel <tom.michel@arcor.de>
 
6
 
 
7
        Kwlan is free software; you can redistribute it and/or modify
 
8
        it under the terms of the GNU Library General Public License as
 
9
        published by the Free Software Foundation; either version 2 of
 
10
        the License, or (at your option) any later version.
 
11
 
 
12
        Kwlan is distributed in the hope that it will be useful,
 
13
        but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
        GNU Library General Public License for more details.
 
16
 
 
17
        You should have received a copy of the GNU Library General Public License
 
18
        along with this library; see the file COPYING.LIB.  If not, write to
 
19
        the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
 
20
        Boston, MA 02110-1301, USA.
 
21
*/
 
22
 
 
23
#include <stdlib.h>
 
24
 
 
25
#include "kwlaninterface.h"        
 
26
 
 
27
#include "wlanlib.h"
 
28
#include "configuration.h"
 
29
#include "kstartsupplicantdlg.h"
 
30
#include "kwlansuprocess.h"
 
31
#include "keventhistorydlg.h"
 
32
#include "kprofileconfigdlg.h"
 
33
#include "kwlansettingsdlg.h"
 
34
#include "kscandlg.h"
 
35
#include "globals.h"
 
36
#include "kwlnetworklist.h"
 
37
 
 
38
#include <kmessagebox.h>
 
39
#include <ktempfile.h>
 
40
#include <kstandarddirs.h>
 
41
#include <klocale.h>
 
42
#include <dirent.h>
 
43
#include <qtimer.h>
 
44
#include <kdebug.h>
 
45
#include <kprocess.h>
 
46
#include <qregexp.h>
 
47
#include <kio/global.h>
 
48
#include <kstandarddirs.h>
 
49
#include <qdir.h>
 
50
#include <qcheckbox.h>
 
51
 
 
52
#include <linux/if.h>
 
53
#include <sys/ioctl.h>
 
54
 
 
55
 
 
56
KwlanInterface::KwlanInterface(KwlanMainWin *mainWin)
 
57
{
 
58
    // initialise variables
 
59
    //Notifier = NULL
 
60
    m_mainWin = mainWin;
 
61
    m_controlConnection = NULL;
 
62
    m_monitorConnection = NULL;
 
63
    m_controlInterfaceDir = strdup ("/var/run/wpa_supplicant");
 
64
    m_IpAddress = FALSE;
 
65
    m_associated = FALSE;
 
66
    m_wpaStarted = FALSE;
 
67
    m_userDataRequest = NULL;
 
68
    m_useDhclient = FALSE;
 
69
    m_useDhcpcd = FALSE;
 
70
    m_dhcpEnabled = TRUE;
 
71
    m_ifconfigProcess = 0L;
 
72
    m_iwconfigProcess = 0L;
 
73
    m_dhcpProcess = 0L;
 
74
    m_releaseProcess=0L;
 
75
    m_wpaWarned = FALSE;
 
76
    m_ipConfigured = FALSE;
 
77
    m_ssid = "";
 
78
    m_type = ETHERNET;
 
79
    m_configuration=0L;
 
80
    m_eventHistory = 0L;
 
81
    m_scanDlg = 0L;
 
82
    m_trayWin = 0L;
 
83
    m_fdSock = -1;
 
84
    m_state = DISABLED;
 
85
    m_isScanning = FALSE;
 
86
    m_isConfiguring = FALSE;
 
87
    KMessageBox::setDontShowAskAgainConfig(mainConfiguration().m_configuration);
 
88
    //get path to wpa_supplicant
 
89
    m_wpaPath = getPath("wpa_supplicant");
 
90
    if (m_wpaPath.isEmpty()){
 
91
        KMessageBox::error(0,i18n("Could not find wpa_supplicant binary. Without it Kwlan can't connect to encrypted networks.\n"
 
92
                "Please check your wpa_supplicant installation."));
 
93
    }
 
94
    //Check for dhcp client to use
 
95
    m_dhcpcdPath = getPath("dhcpcd");
 
96
    if (!m_dhcpcdPath.isEmpty()){
 
97
        m_useDhcpcd = TRUE;
 
98
    } else {
 
99
        m_dhclientPath = getPath("dhclient");
 
100
        if (!m_dhclientPath.isEmpty())
 
101
            m_useDhclient = TRUE;
 
102
    }
 
103
    if (! m_useDhclient && ! m_useDhcpcd)
 
104
        KMessageBox::sorry(0,i18n("Neither dhclient nor dhcpcd found. Dynamic IP configuration will not work."));
 
105
    // check for path to needed applications
 
106
    m_ifconfigPath = getPath("ifconfig");
 
107
    if (m_ifconfigPath.isEmpty())
 
108
        kdDebug() << i18n("ifconfig not found. Network statistics and static ip addresses will not work.") << endl;
 
109
    m_iwconfigPath = getPath("iwconfig");
 
110
    if (m_iwconfigPath.isEmpty())
 
111
        kdDebug() << i18n("iwconfig not found. Wireless statistics might not work.") << endl;
 
112
    m_timer = new QTimer(this);
 
113
 
 
114
}
 
115
 
 
116
void KwlanInterface::init(QString interface)
 
117
{
 
118
    //char buf[10];
 
119
    //size_t len;
 
120
    if (!interface) return;
 
121
    m_sysClassPath="/sys/class/net/"+interface+"/";
 
122
    memset(&m_devInfo, 0, sizeof(m_devInfo));
 
123
    strcpy(m_devInfo.ifr_name, interface.latin1());
 
124
    m_confFile = QString("kwlanrc.") + interface;
 
125
    // find out if we have a wireless interface
 
126
    m_controlInterface = strdup(interface.ascii());
 
127
    QStringList wirelessInterfaces = getInterfaces();
 
128
    if (wirelessInterfaces.findIndex(m_controlInterface)!=-1)
 
129
        m_interfaceData.wirelessDevice = TRUE;
 
130
    else m_interfaceData.wirelessDevice = FALSE;
 
131
    // check for File existance to see wether interface is already configured
 
132
    QString tmpConf = KStandardDirs().findResource("config",m_confFile);
 
133
    m_configuration = new Configuration(m_confFile);
 
134
    // Check for interface type
 
135
    checkType();
 
136
    if ((tmpConf.isEmpty() || !hasProfiles() && m_type != PPP) && KMessageBox::shouldBeShownContinue("newinterfacewizard"))
 
137
    {
 
138
        // show wizard
 
139
        newInterfaceWizard(interface);
 
140
    }
 
141
    m_configureInterface = mainConfiguration().readConfigureInterface( interface);
 
142
    QStringList binDirs;
 
143
    if (m_type == ETHERNET)
 
144
    {
 
145
        // check if we have a custom wpa config file
 
146
        if (m_configuration && m_configuration->m_useCustomWpaConf)
 
147
        {
 
148
            m_wpaConf = m_configuration->m_customWpaConf;
 
149
        }
 
150
        else 
 
151
        {
 
152
            // check if wpa_config file for interface exists
 
153
            m_wpaConf = QString("kwlan.")+ interface; 
 
154
            if (locate("config",m_wpaConf).isEmpty())
 
155
            {
 
156
            //create a new config file containig the important global settings
 
157
                KConfig *conf= new KConfig(m_wpaConf,false,false,"config");
 
158
                conf->writeEntry("update_config","1");
 
159
                conf->writeEntry("ctrl_interface",m_controlInterfaceDir);
 
160
                conf->writeEntry("ctrl_interface_group","20");
 
161
                delete conf;
 
162
            }
 
163
            m_wpaConf = locate("config",m_wpaConf);
 
164
        }
 
165
    }
 
166
    // To avoid Getting an IP Address if interface already has one, check ip address
 
167
    // We set m_ipConfigured to true to avoid updateData getting an ip address
 
168
    // It's a little ugly and needs some rework
 
169
    m_ipConfigured = TRUE;
 
170
    updateData();
 
171
    if (m_interfaceData.ipAddress.isEmpty() ||  m_interfaceData.ipAddress=="0.0.0.0") m_ipConfigured = FALSE;
 
172
    else m_ipConfigured = TRUE;
 
173
    if (::debugOutput) kdDebug() << "IP Address " << m_interfaceData.ipAddress  << "M_ipconfigured " << m_ipConfigured << endl;
 
174
 
 
175
    //check for existing  WPA connection
 
176
    checkWpaConnection();
 
177
    //Start WPA Supplicant if configured and no connection is established
 
178
    if (m_configuration)
 
179
    {
 
180
        if (m_interfaceData.wirelessDevice)
 
181
        {
 
182
            if (!m_wpaStarted && m_configuration->m_startWpa && m_configureInterface){
 
183
                KStartSupplicantDlg *startSupplicant = new KStartSupplicantDlg();
 
184
                QString driver;
 
185
                m_configuration->readDriver(driver);
 
186
                if (startSupplicant ){
 
187
                    startSupplicant->setData(&interface,&driver);
 
188
                    if (m_configuration->m_startWpaNoQuestion&& !driver.isEmpty()){
 
189
                        startSupplicant->startSupplicant();
 
190
                    }
 
191
                    else {
 
192
                        startSupplicant->show();
 
193
                        startSupplicant->exec();
 
194
                    }
 
195
                    QString wpa_supplicant;
 
196
                    if (startSupplicant->m_start){
 
197
                        KwlanSuProcess *startWpa= new KwlanSuProcess(NULL,"Start WPA Supplicant");
 
198
                        *startWpa << m_wpaPath << QString("-i%1").arg(QString(m_controlInterface)) << QString ("-D%1").arg(startSupplicant->getDriver()) << QString("-c")+ m_wpaConf << "-B";
 
199
                        startWpa->setDescription(i18n("Start WPA Supplicant"));
 
200
                        startWpa->start();
 
201
                        m_configuration->writeDriver(startSupplicant->getDriver());
 
202
                    }
 
203
                    delete startSupplicant;
 
204
                    m_networkChange = true;
 
205
                }
 
206
            }
 
207
        }
 
208
        else {
 
209
            if ((!m_wpaStarted && m_configuration->m_startWpa && m_configureInterface)&&(m_type == ETHERNET )){
 
210
                //wired device, so drvier is wired
 
211
                KwlanSuProcess *startWpa= new KwlanSuProcess(NULL,"Start WPA Supplicant");
 
212
                *startWpa << m_wpaPath << QString("-i%1").arg(QString(m_controlInterface)) << QString ("-D%1").arg(QString("wired")) << QString("-c" ) + m_wpaConf <<"-B";
 
213
                startWpa->setDescription(i18n("Start WPA Supplicant"));
 
214
                startWpa->start();
 
215
            }
 
216
        }
 
217
    }
 
218
    // Set Status update timer
 
219
    if (m_type ==ETHERNET) 
 
220
    {
 
221
        if (m_configuration) m_configuration->readLastSsid(m_ssid);
 
222
    }
 
223
    getIpData();
 
224
    // Now check if we have to use static ip addressing 
 
225
    // If so, scheck whether interface address is equal to configured address
 
226
    if (!m_dhcpEnabled)
 
227
    {
 
228
        if (m_staticIpAddress!=m_interfaceData.ipAddress)
 
229
        {
 
230
            m_ipConfigured = FALSE;
 
231
            updateData();
 
232
        }
 
233
    }
 
234
    emit (networksChanged());
 
235
    slotScanAvailableNetworks();
 
236
    connect(this, SIGNAL(wpaStatusChanged( bool )), this, SLOT(slotWpaStatusChanged(bool)));
 
237
    m_timer = new QTimer(this);
 
238
    m_scanTimer = new QTimer(this);
 
239
    int timerInterval;
 
240
    timerInterval = 100;
 
241
    if (m_timer){
 
242
        connect (m_timer, SIGNAL(timeout()),SLOT(checkWpaConnection()));
 
243
        m_timer->start(timerInterval,FALSE);
 
244
    }
 
245
    if (m_scanTimer){
 
246
        connect (m_scanTimer, SIGNAL(timeout()),SLOT(slotScanAvailableNetworks()));
 
247
        m_scanTimer->start(3000,FALSE);
 
248
    }
 
249
 
 
250
}
 
251
        
 
252
KwlanInterface::~KwlanInterface()
 
253
{
 
254
    if (m_timer){
 
255
        m_timer->stop();
 
256
        delete (m_timer);
 
257
    } 
 
258
    if (m_ifconfigProcess) 
 
259
    {
 
260
        m_ifconfigProcess->kill();
 
261
        delete (m_ifconfigProcess);
 
262
    }
 
263
    if (m_iwconfigProcess) 
 
264
    {
 
265
        m_iwconfigProcess->kill();
 
266
        delete (m_iwconfigProcess);
 
267
    }
 
268
}
 
269
         
 
270
void KwlanInterface::slotWpaStatusChanged(bool status)
 
271
{
 
272
    if (status)
 
273
        profileActivate(m_ssid);
 
274
}
 
275
 
 
276
void KwlanInterface::cleanTemporaryFiles()
 
277
{
 
278
    resolvconf->unlink();
 
279
    if (resolvconf) {
 
280
        delete resolvconf;
 
281
        resolvconf = 0;
 
282
    }
 
283
}
 
284
        
 
285
int KwlanInterface::openControlConnection()
 
286
{
 
287
    bool tmpWpaStarted = m_wpaStarted;
 
288
    char *cfile;
 
289
    int flen;
 
290
 
 
291
    if ((m_controlInterface == NULL) || (m_type==PPP))
 
292
        return -1;
 
293
    //kdDebug() << "Trying to open control connection" << endl;
 
294
    flen = strlen(m_controlInterfaceDir) + strlen(m_controlInterface) + 2;
 
295
    cfile = (char *) malloc(flen);
 
296
    if (cfile == NULL)
 
297
        return -1;
 
298
    snprintf(cfile, flen, "%s/%s", m_controlInterfaceDir, m_controlInterface);
 
299
    
 
300
 
 
301
    if (m_controlConnection) {
 
302
        wpa_ctrl_close(m_controlConnection);
 
303
        m_controlConnection = NULL;
 
304
    }
 
305
 
 
306
    if (m_monitorConnection) {
 
307
        delete m_messageNotifier;
 
308
        m_messageNotifier = NULL;
 
309
        wpa_ctrl_detach(m_monitorConnection);
 
310
        wpa_ctrl_close(m_monitorConnection);
 
311
        m_monitorConnection = NULL;
 
312
    }
 
313
 
 
314
    //if (::debugOutput) kdDebug() << "Trying to connect to " <<  cfile << endl;
 
315
    m_controlConnection = wpa_ctrl_open(cfile);
 
316
    if (m_controlConnection == NULL) {
 
317
        //if (::debugOutput) kdDebug() << "Opening control connection failed" << endl;
 
318
        delete cfile;
 
319
        return -1;
 
320
    }
 
321
    m_wpaStarted = TRUE;
 
322
    if (!tmpWpaStarted)
 
323
    {
 
324
        if (debugOutput) kdDebug() << "Control connection established" << endl;
 
325
        // Set ap_scan value as new connection is established
 
326
        char buf[10];
 
327
        char command[100];
 
328
        size_t len;
 
329
        len = sizeof(buf)-1;
 
330
        snprintf(command,sizeof(command),"AP_SCAN %d",m_configuration->m_ap_scan);
 
331
        if (::debugOutput) kdDebug() << "Setting ap_scan value: " << command << endl;
 
332
        if (ctrlRequest(command,buf,&len) <0)
 
333
        {
 
334
            kdDebug() << "Setting ap_scan value failed!" << endl;
 
335
        }
 
336
        buf[len] = '\0';
 
337
        if (::debugOutput) kdDebug() << buf << endl;
 
338
        emit (wpaStatusChanged(m_wpaStarted));
 
339
        emit (networksChanged());
 
340
    }
 
341
    m_monitorConnection = wpa_ctrl_open(cfile);
 
342
    delete cfile;
 
343
    if (m_monitorConnection == NULL) {
 
344
        wpa_ctrl_close(m_controlConnection);
 
345
        if (::debugOutput) kdDebug() << "Could not establish monitor connection." << endl;
 
346
        return -1;
 
347
    }
 
348
    if (wpa_ctrl_attach(m_monitorConnection)) {
 
349
        printf("Failed to attach to wpa_supplicant\n");
 
350
        wpa_ctrl_close(m_monitorConnection);
 
351
        m_monitorConnection = NULL;
 
352
        wpa_ctrl_close(m_controlConnection);
 
353
        m_controlConnection = NULL;
 
354
        return -1;
 
355
    }
 
356
 
 
357
    m_messageNotifier = new QSocketNotifier(wpa_ctrl_get_fd(m_monitorConnection),QSocketNotifier::Read, this);
 
358
    if (m_messageNotifier)
 
359
        connect(m_messageNotifier, SIGNAL(activated(int)), SLOT(receiveMsgs()));
 
360
    else kdDebug() << "Could not create Message Notifier" << endl;
 
361
    return 0;
 
362
    
 
363
}
 
364
 
 
365
void KwlanInterface::checkWpaConnection()
 
366
{
 
367
    char buf[10];
 
368
    size_t len;
 
369
    QString status;
 
370
    len = sizeof(buf)-1;
 
371
    bool tmpWpaStarted = m_wpaStarted;
 
372
    if (m_type != PPP)
 
373
    {
 
374
        if (ctrlRequest("PING",buf,&len) <0)
 
375
        {
 
376
            m_wpaStarted=FALSE;
 
377
            if (tmpWpaStarted)
 
378
            {
 
379
                m_controlConnection=0L;
 
380
                m_monitorConnection=0L;
 
381
                emit wpaStatusChanged (FALSE);
 
382
            }
 
383
            // try to open the connection
 
384
            openControlConnection();
 
385
        }
 
386
        else {
 
387
            m_wpaStarted = TRUE;
 
388
            if (!tmpWpaStarted)
 
389
                emit wpaStatusChanged (TRUE);
 
390
        }
 
391
    }
 
392
    updateData();
 
393
}
 
394
 
 
395
int KwlanInterface::ctrlRequest(const char *command, char *buf, size_t *buflen)
 
396
{
 
397
    if (m_controlConnection == NULL)
 
398
        return -1;
 
399
    return wpa_ctrl_request(m_controlConnection, command, strlen(command), buf, buflen, kwlan_msg_cb);
 
400
}
 
401
 
 
402
 
 
403
QStringList KwlanInterface::listProfiles()
 
404
{
 
405
    QStringList wpaProfiles;
 
406
    if (m_type == PPP) return wpaProfiles;
 
407
    
 
408
    wpaProfiles = listWpaProfiles();
 
409
    //kdDebug() << "WPA PRofiles: " << wpaProfiles << endl;
 
410
    return wpaProfiles + listNonWpaProfiles(wpaProfiles);
 
411
}
 
412
        
 
413
QStringList KwlanInterface::listWpaProfiles()
 
414
{
 
415
    char buf[2048], *start, *end, *id, *ssid, *bssid, *flags;
 
416
    size_t len =sizeof(buf);
 
417
    QStringList networks;
 
418
    // Are we connected to wpa?
 
419
    if (!m_controlConnection) {
 
420
        //kdDebug() << "No control connection to list wpa profiles! "<< m_controlInterface << endl;
 
421
        return networks;
 
422
    }
 
423
    if (ctrlRequest("LIST_NETWORKS", buf, &len) < 0)
 
424
    {
 
425
        kdDebug() << "Could not list wpa profiles" << endl;
 
426
        return networks;
 
427
    }
 
428
    buf[len] = '\0';
 
429
    start = strchr(buf, '\n');
 
430
    if (start == NULL)
 
431
        return networks;
 
432
    start++;
 
433
    while (*start) {
 
434
        bool last = false;
 
435
        end = strchr(start, '\n');
 
436
        if (end == NULL) {
 
437
            last = true;
 
438
            end = start;
 
439
            while (end[0] && end[1])
 
440
                end++;
 
441
        }
 
442
        *end = '\0';
 
443
        
 
444
        id = start;
 
445
        ssid = strchr(id, '\t');
 
446
        if (ssid == NULL)
 
447
            break;
 
448
        *ssid++ = '\0';
 
449
        bssid = strchr(ssid, '\t');
 
450
        if (bssid == NULL)
 
451
            break;
 
452
        *bssid++ = '\0';
 
453
        flags = strchr(bssid, '\t');
 
454
        if (flags == NULL)
 
455
            break;
 
456
        *flags++ = '\0';
 
457
        
 
458
        QString tmpNetwork(ssid);
 
459
        networks.append (tmpNetwork);
 
460
        if (last)
 
461
            break;
 
462
        start = end + 1;
 
463
    }
 
464
 
 
465
    return networks;
 
466
}        
 
467
        
 
468
QStringList KwlanInterface::listNonWpaProfiles(QStringList wpaProfiles)
 
469
{
 
470
    QStringList profiles;
 
471
    if (!m_configuration) return profiles;
 
472
    profiles = m_configuration->getNetworks();
 
473
    // Now test if networks already exists from wpa config
 
474
    QStringList::Iterator it;
 
475
    it = profiles.begin();
 
476
    while (it !=profiles.end())
 
477
    {
 
478
        QStringList::Iterator index = wpaProfiles.find( *it );
 
479
        if ( !(*index).isEmpty() )
 
480
        {
 
481
            it = profiles.remove(it);
 
482
            continue;
 
483
        }
 
484
            // Check whether the Network can be used without encryption
 
485
        /*
 
486
        m_configuration->readEncryption(*it,encrypted);
 
487
        if (encrypted) {
 
488
            it = profiles.remove(it);
 
489
            continue;
 
490
        }
 
491
        */
 
492
        it++;
 
493
    }
 
494
    //kdDebug() << profiles << endl;
 
495
    return profiles;
 
496
}
 
497
 
 
498
bool KwlanInterface::hasProfiles()
 
499
{
 
500
    if (!m_configuration) return FALSE;
 
501
    QStringList profiles;
 
502
    profiles = m_configuration->getNetworks();
 
503
    if (profiles.isEmpty()) return FALSE;
 
504
    return TRUE;
 
505
}
 
506
 
 
507
int KwlanInterface::getWpaId(QString findSsid)
 
508
{
 
509
    char buf[2048], *start, *end, *id, *ssid, *bssid, *flags;
 
510
    size_t len = sizeof(buf);
 
511
    QStringList networks;
 
512
    // Are we connected to wpa?
 
513
    if (!m_controlConnection) {
 
514
        //kdDebug() << "No control connection! " <<  endl;
 
515
        return  -1;
 
516
    }
 
517
    if (ctrlRequest("LIST_NETWORKS", buf, &len) < 0)
 
518
    {
 
519
        kdDebug() << "Getting list of networks failed! " <<  endl;
 
520
        return -1;
 
521
    }
 
522
    
 
523
    buf[len] = '\0';
 
524
    start = strchr(buf, '\n');
 
525
    if (start == NULL)
 
526
        return -1;
 
527
    start++;
 
528
    while (*start) {
 
529
        bool last = false;
 
530
        end = strchr(start, '\n');
 
531
        if (end == NULL) {
 
532
            last = true;
 
533
            end = start;
 
534
            while (end[0] && end[1])
 
535
                end++;
 
536
        }
 
537
        *end = '\0';
 
538
        
 
539
        id = start;
 
540
        ssid = strchr(id, '\t');
 
541
        if (ssid == NULL)
 
542
            break;
 
543
        *ssid++ = '\0';
 
544
        bssid = strchr(ssid, '\t');
 
545
        if (bssid == NULL)
 
546
            break;
 
547
        *bssid++ = '\0';
 
548
        flags = strchr(bssid, '\t');
 
549
        if (flags == NULL)
 
550
            break;
 
551
        *flags++ = '\0';
 
552
        QString tmpSsid =QString(ssid); 
 
553
        if (tmpSsid==findSsid)
 
554
        {
 
555
            return QString(id).toInt();
 
556
        }
 
557
        if (last)
 
558
            break;
 
559
        start = end + 1;
 
560
    }
 
561
    return -1;
 
562
}
 
563
 
 
564
bool KwlanInterface::profileActivateNonWpa(QString ssid)
 
565
{
 
566
    if (m_interfaceData.wirelessDevice)
 
567
    {
 
568
        KwlanSuProcess *iwconfig = new KwlanSuProcess(this);
 
569
        *iwconfig << m_iwconfigPath << m_controlInterface << QString("essid") << ssid;
 
570
        iwconfig->setDescription(i18n("Configure wlan interface using iwconfig"));
 
571
        //iwconfig->start(SuProcessBase::Block);
 
572
        iwconfig->start();
 
573
    }
 
574
   // store in config
 
575
    if (m_configuration) m_configuration->writeLastSsid( ssid);
 
576
    m_ssid = ssid;
 
577
    // set ip data
 
578
    getIpData();
 
579
 
 
580
    return TRUE;
 
581
    
 
582
}
 
583
 
 
584
bool KwlanInterface::profileActivateWpa(QString ssid)
 
585
{
 
586
    if (m_isConfiguring) return TRUE;
 
587
        // select network using wpa_supplicant
 
588
    if (!m_wpaStarted) return FALSE;
 
589
    int ret;
 
590
    char reply[40], cmd[256];
 
591
    size_t reply_len = sizeof(reply);
 
592
    m_ssid = ssid;
 
593
    int id = getWpaId(ssid);
 
594
    if (id == -1 ){
 
595
        // Seems to be a new network, so configure it.
 
596
        m_isConfiguring = TRUE;
 
597
        for (kwlNetworkList::iterator it = m_availableNetworks.begin();it != m_availableNetworks.end();it++)
 
598
        {
 
599
            if ((*it).m_ssid == ssid)
 
600
            {
 
601
                KProfileConfigDlg *nc = new KProfileConfigDlg();
 
602
                if (nc == NULL)
 
603
                    return FALSE;
 
604
                nc->setInterface(this);
 
605
                nc->paramsFromScanResults((*it));
 
606
                kdDebug() << (*it).m_flags << endl;
 
607
                nc->show();
 
608
                nc->exec();
 
609
                m_isConfiguring = FALSE;
 
610
                return TRUE;
 
611
            }
 
612
        }
 
613
        //KMessageBox::sorry(0, i18n("Could not find network in wpa_supplicant\nconfiguration."));
 
614
        return FALSE;
 
615
    }
 
616
    snprintf(cmd, sizeof(cmd), "DISCONNECT");
 
617
    reply_len = sizeof(reply);
 
618
    ctrlRequest(cmd, reply, &reply_len);
 
619
 
 
620
    // Enable Network
 
621
    snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %d", id);
 
622
    reply_len = sizeof(reply);
 
623
    ret=ctrlRequest(cmd, reply, &reply_len);
 
624
    if (ret==-1) {
 
625
        KMessageBox::sorry(0,"No control connection!");
 
626
        return FALSE;
 
627
    }
 
628
    if (strncmp(reply, "OK", 2) != 0) {
 
629
        KMessageBox::sorry(0, i18n("Failed to enable network in wpa_supplicant\nconfiguration."));
 
630
        return FALSE;
 
631
    } 
 
632
    // Connect
 
633
    snprintf(cmd, sizeof(cmd), "REASSOCIATE");
 
634
    reply_len = sizeof(reply);
 
635
    ctrlRequest(cmd, reply, &reply_len);
 
636
    // store in config
 
637
    if (m_configuration) m_configuration->writeLastSsid( ssid);
 
638
    // set ip data
 
639
    getIpData();
 
640
    
 
641
    checkWpaConnection();
 
642
    return TRUE;   
 
643
}
 
644
 
 
645
bool KwlanInterface::profileActivate(QString ssid)
 
646
{
 
647
    if (!m_configureInterface) return FALSE;
 
648
    // release any existing ip address
 
649
    if (m_ipConfigured) releaseIpAddress();
 
650
    //m_interfaceData.available = FALSE;
 
651
    m_interfaceData.connected = FALSE;
 
652
    if (m_controlConnection){
 
653
        return profileActivateWpa(ssid);
 
654
    }
 
655
    else {
 
656
        // check if wpa_supplicant is needed for the network
 
657
        for (kwlNetworkList::iterator it = m_availableNetworks.begin();it != m_availableNetworks.end();it++)
 
658
        {
 
659
            if ((*it).m_ssid==ssid)
 
660
            {
 
661
                if ((*it).m_flags.contains("WPA") )
 
662
                {
 
663
                    int result = KMessageBox::questionYesNo(0,i18n("To activate this network, wpa_supplicant must be started. Do you want to start wpa_supplicant?"),
 
664
                                              "Kwlan");
 
665
                    if (result == KMessageBox::Yes)
 
666
                    {
 
667
                        KStartSupplicantDlg *startSupplicant = new KStartSupplicantDlg();
 
668
                        QString driver;
 
669
                        m_configuration->readDriver(driver);
 
670
                        if (startSupplicant )
 
671
                        {
 
672
                            QString iface = QString(m_controlInterface)
 
673
                            startSupplicant->setData(&iface,&driver);
 
674
                            startSupplicant->show();
 
675
                            startSupplicant->exec();
 
676
                            QString wpa_supplicant;
 
677
                            if (startSupplicant->m_start)
 
678
                            {
 
679
                                KwlanSuProcess *startWpa= new KwlanSuProcess(NULL,"Start WPA Supplicant");
 
680
                                *startWpa << m_wpaPath << QString("-i%1").arg(QString(m_controlInterface)) << QString ("-D%1").arg(startSupplicant->getDriver()) << QString("-c")+ m_wpaConf << "-B";
 
681
                                startWpa->setDescription(i18n("Start WPA Supplicant"));
 
682
                                startWpa->start();
 
683
                                m_configuration->writeDriver(startSupplicant->getDriver());
 
684
                                m_ssid = ssid;
 
685
                            }
 
686
                            delete startSupplicant;
 
687
                            m_networkChange = true;
 
688
                            return true;
 
689
                        }
 
690
                    }
 
691
                }
 
692
            }
 
693
        }
 
694
 
 
695
        // select network using iwconfig
 
696
        return profileActivateNonWpa(ssid);
 
697
    }
 
698
}
 
699
 
 
700
void KwlanInterface::releaseIpAddress()
 
701
{
 
702
    if (!m_controlInterface || (m_type == PPP) || !m_configureInterface)  return;
 
703
    if (m_releaseProcess) return;
 
704
    // Now start script before disconnect if configured
 
705
    QString script;
 
706
    bool useRoot;
 
707
    m_configuration->readScriptBeforeDisconnect( m_ssid,script, useRoot);
 
708
    if (::debugOutput) kdDebug() << "Now starting script before disconnect "<< script << endl;
 
709
    if (!script.isEmpty())
 
710
    {
 
711
        if (useRoot) {
 
712
            KwlanSuProcess *proc = new KwlanSuProcess();
 
713
            *proc << script;
 
714
            proc->setDescription( i18n("start script before disconnect"));
 
715
            proc->start();
 
716
        }
 
717
        else {
 
718
            KProcess *proc = new KProcess();
 
719
            *proc << script;
 
720
            proc->start();
 
721
        }
 
722
    }
 
723
 
 
724
    m_releaseProcess = new KwlanSuProcess(this);    
 
725
    if  (!m_dhcpEnabled) {
 
726
        *m_releaseProcess << "ifconfig" << m_controlInterface << "0.0.0.0";
 
727
    } else {
 
728
        if (m_useDhclient)
 
729
        {
 
730
            *m_releaseProcess << m_dhclientPath << "-r" << m_controlInterface;
 
731
        } else if (m_useDhcpcd){
 
732
            *m_releaseProcess << m_dhcpcdPath << "-k" << m_controlInterface;
 
733
        }
 
734
    }
 
735
    m_releaseProcess->setDescription(i18n("Release IP address"));
 
736
    connect (m_releaseProcess, SIGNAL(processExited(KwlanSuProcess*)), this, SLOT(releaseProcessExited(KwlanSuProcess*)));
 
737
    m_releaseProcess->start();
 
738
}
 
739
 
 
740
void KwlanInterface::setDnsSettings()
 
741
{
 
742
    if (m_type == PPP) return;
 
743
    if (m_staticDns1.isEmpty() && m_staticDns2.isEmpty() && m_domain.isEmpty() && m_dnsSearchlist.isEmpty())
 
744
        return;
 
745
    if (!m_dontOverrideDns || !hasNameserver()) {
 
746
         // Create temporary file containing DNS configuration      
 
747
        resolvconf = new KTempFile(locateLocal("tmp", "resolv"), ".conf", 0644);
 
748
        if (!m_staticDns1.isEmpty())
 
749
            *(resolvconf->textStream()) << QString("nameserver %1").arg(m_staticDns1) << endl;
 
750
        if (!m_staticDns2.isEmpty())
 
751
            *(resolvconf->textStream()) << QString("nameserver %1").arg(m_staticDns2) << endl;
 
752
        if (!m_domain.isEmpty())
 
753
            *(resolvconf->textStream()) << QString("domain %1").arg(m_domain) << endl;
 
754
        if (!m_dnsSearchlist.isEmpty())
 
755
        {
 
756
            *(resolvconf->textStream()) << QString("search ");
 
757
            for (QStringList::iterator it = m_dnsSearchlist.begin(); it != m_dnsSearchlist.end(); it++)
 
758
                *(resolvconf->textStream()) << *it << " ";
 
759
            *(resolvconf->textStream()) << endl;
 
760
        }
 
761
        resolvconf->close();
 
762
        KwlanSuProcess * setNetwork = new KwlanSuProcess();
 
763
        connect(setNetwork, SIGNAL( destroyed() ), this, SLOT( cleanTemporaryFiles() ));
 
764
 
 
765
        // And copy it to /etc fixing permissions (moving wont work if /etc/resolv.conf is a symlink)
 
766
        *setNetwork << getPath("cp") << resolvconf->name() << "/etc/resolv.conf";           
 
767
        *setNetwork << ";";
 
768
        *setNetwork << getPath("chown") << "root:root" << "/etc/resolv.conf";
 
769
        setNetwork->setDescription(i18n("Set network settings"));
 
770
        setNetwork->start();
 
771
    }
 
772
}
 
773
 
 
774
void KwlanInterface::checkType()
 
775
{
 
776
    // check Interface type
 
777
    int type = readInterfaceNumValue( "type");
 
778
    if ( type==1)
 
779
    {
 
780
        m_type = ETHERNET;
 
781
    }
 
782
    else
 
783
    {
 
784
        m_type = PPP;
 
785
    }
 
786
}
 
787
 
 
788
void KwlanInterface::getIpAddress()
 
789
{
 
790
    if ((m_type == PPP)||(m_ssid.isEmpty()) || !m_configureInterface || m_isConfiguring) return;
 
791
    if (m_dhcpProcess) 
 
792
    {
 
793
        // We are already running
 
794
        return;
 
795
    }
 
796
    m_dhcpProcess = new KwlanSuProcess(this);
 
797
    if (!m_dhcpEnabled){
 
798
        if (m_staticIpAddress.isEmpty()) return;
 
799
        
 
800
        m_dhcpProcess->setDescription(i18n("Configure the network"));   
 
801
        *m_dhcpProcess << m_ifconfigPath << m_controlInterface << m_staticIpAddress.ascii();    
 
802
        
 
803
        if (!m_staticNetmask.isEmpty())
 
804
            *m_dhcpProcess << "netmask" << m_staticNetmask.ascii();
 
805
 
 
806
        // We can to set up our new route if there is no route (hasGateway()==false) or we have but m_ovrgw is true ()
 
807
        bool m_hasGateway = hasGateway();
 
808
        if (!m_staticGateway.isEmpty() && (!m_dontOverrideGw || !m_hasGateway)) {
 
809
            *m_dhcpProcess << ";";
 
810
            
 
811
            // Delete default route if we already have one
 
812
            if (m_hasGateway)
 
813
                *m_dhcpProcess << getPath("route") << "del" << "default" << ";";
 
814
                
 
815
            *m_dhcpProcess << getPath("route") << "add" << "default" << "gw" << m_staticGateway.ascii();
 
816
        }    
 
817
    }
 
818
    else {
 
819
        
 
820
        if (m_useDhclient)
 
821
        {
 
822
            *m_dhcpProcess << m_dhclientPath <<  m_controlInterface;
 
823
        } else if (m_useDhcpcd){
 
824
            *m_dhcpProcess << m_dhcpcdPath << "-nd" << m_controlInterface;
 
825
        }
 
826
        say(i18n("%1 is requesting\nan IP address").arg(m_controlInterface));
 
827
        m_dhcpProcess->setDescription(i18n("Obtain IP address dynamically"));
 
828
        m_dhcpProcess->setRestart(true);
 
829
    }
 
830
    connect (m_dhcpProcess,SIGNAL(processExited(KwlanSuProcess*)), this, SLOT(dhcpProcessExited(KwlanSuProcess*)));
 
831
    //m_dhcpProcess->start(SuProcessBase::Block);
 
832
    m_dhcpProcess->start();
 
833
 
 
834
}
 
835
 
 
836
void KwlanInterface::processWpaMessage(char *message)
 
837
{
 
838
    char *pos = message, *pos2;
 
839
    int priority = 2;
 
840
    if (*pos == '<') {
 
841
        /* skip priority */
 
842
        pos++;
 
843
        priority = atoi(pos);
 
844
        pos = strchr(pos, '>');
 
845
        if (pos)
 
846
            pos++;
 
847
        else
 
848
            pos = message;
 
849
    }
 
850
 
 
851
    WpaMsg wm(pos, priority);
 
852
    emit wpaEvent(wm);
 
853
    m_messages.append(wm);
 
854
    while (m_messages.count() > 100)
 
855
        m_messages.pop_front();
 
856
    
 
857
    /* Update last message with truncated version of the event */
 
858
    if (strncmp(pos, "CTRL-", 5) == 0) {
 
859
        pos2 = strchr(pos, str_match(pos, WPA_CTRL_REQ) ? ':' : ' ');
 
860
        if (pos2)
 
861
            pos2++;
 
862
        else
 
863
            pos2 = pos;
 
864
    } else
 
865
        pos2 = pos;
 
866
        QString lastmsg = pos2;
 
867
        lastmsg.truncate(40);
 
868
        m_networkChange = true;
 
869
    
 
870
        if (str_match(pos, WPA_CTRL_REQ))
 
871
            processCtrlReq(pos + strlen(WPA_CTRL_REQ));
 
872
        if (str_match(pos,WPA_EVENT_CONNECTED)){
 
873
            m_associated = true;
 
874
        }
 
875
        if (str_match(pos,WPA_EVENT_DISCONNECTED)){
 
876
            m_associated = false;
 
877
        }
 
878
}
 
879
 
 
880
void KwlanInterface::receiveMsgs()
 
881
{
 
882
    char buf[256];
 
883
    size_t len;
 
884
    if (!m_monitorConnection) return;
 
885
    while (wpa_ctrl_pending(m_monitorConnection)) {
 
886
        len = sizeof(buf) - 1;
 
887
        if (wpa_ctrl_recv(m_monitorConnection, buf, &len) == 0) {
 
888
            buf[len] = '\0';
 
889
            processWpaMessage(buf);
 
890
        }
 
891
    }
 
892
}
 
893
 
 
894
void KwlanInterface::processCtrlReq( const char * request )
 
895
{
 
896
    // processe control request, for example ask for password for private key file.
 
897
    if (m_userDataRequest) {
 
898
        m_userDataRequest->close();
 
899
        delete m_userDataRequest;
 
900
    }
 
901
    m_userDataRequest = new KUserDataRequestDlg();
 
902
    if (m_userDataRequest == NULL)
 
903
        return;
 
904
    if (m_userDataRequest->setParams(this, request) < 0) {
 
905
        delete  m_userDataRequest;
 
906
        m_userDataRequest = NULL;
 
907
        return;
 
908
    }
 
909
    m_userDataRequest->show();
 
910
    m_userDataRequest->exec();
 
911
}
 
912
 
 
913
void KwlanInterface::startWpa(QString driver)
 
914
{
 
915
    if (m_wpaStarted) {
 
916
        kdDebug() << "wpa_supplicant is already started!" << endl;
 
917
        return;
 
918
    }
 
919
    if (m_configuration) 
 
920
    {
 
921
        if (m_configuration->m_useCustomWpaConf)
 
922
            m_wpaConf = m_configuration->m_customWpaConf;
 
923
        else {
 
924
            m_wpaConf = QString("kwlan.")+ m_controlInterface; 
 
925
            m_wpaConf = locate("config",m_wpaConf);
 
926
        }
 
927
    }
 
928
    KwlanSuProcess *startWpa = new KwlanSuProcess(this);
 
929
    *startWpa << m_wpaPath << QString("-i%1").arg(QString(m_controlInterface)) << QString ("-D%1").arg(driver) << QString("-c") +m_wpaConf << "-B";
 
930
    startWpa->setDescription(i18n("Start WPA Supplicant"));
 
931
    startWpa->start();
 
932
    //remember last interface driver
 
933
    if (m_configuration) m_configuration->writeDriver(driver);
 
934
    emit (networksChanged());
 
935
}
 
936
 
 
937
void KwlanInterface::stopWpa()
 
938
{
 
939
    char reply[100];
 
940
    size_t reply_len;
 
941
    if (!m_wpaStarted) {
 
942
        kdDebug() << "wpa_supplicant is not started!" << endl;
 
943
        return;
 
944
    }
 
945
    if (::debugOutput) kdDebug() << "Releasing IP address" << endl;
 
946
    releaseIpAddress();
 
947
    reply_len = sizeof(reply);
 
948
    if (::debugOutput) kdDebug() << "Stopping wpa_supplicant" << endl;
 
949
    ctrlRequest("TERMINATE", reply, &reply_len);
 
950
    if (strncmp(reply,"OK",2) != 0) {
 
951
        KMessageBox::sorry(0,  i18n("Could not terminate WPA_Supplicant!"));
 
952
        return;
 
953
    }
 
954
    if (::debugOutput) kdDebug() << "wpa_supplicant stopped" << endl;
 
955
    emit (networksChanged());
 
956
}
 
957
 
 
958
QString KwlanInterface::getInterfaceName()
 
959
{
 
960
    return QString(m_controlInterface);
 
961
}
 
962
 
 
963
 
 
964
void KwlanInterface::profileAdded()
 
965
{
 
966
    emit (networksChanged());
 
967
}
 
968
 
 
969
void KwlanInterface::updateData()
 
970
{
 
971
    //bool tmpAvailable = m_interfaceData.available;
 
972
    bool tmpUp = m_interfaceData.up;
 
973
    //bool tmpConnected = m_interfaceData.connected;
 
974
    FILE* flags_fp = fopen((m_sysClassPath+"flags").latin1(), "r");
 
975
    bool currentStatus;
 
976
    if (!flags_fp)
 
977
    {
 
978
        // Interface seems to have gone away
 
979
        emit (interfaceGone(this));
 
980
        deleteLater();
 
981
        return;
 
982
    }
 
983
    else {
 
984
        int flags;
 
985
        fscanf(flags_fp, "%Xu", &flags);
 
986
        fclose(flags_fp);
 
987
        currentStatus = IFF_UP & flags;
 
988
    }
 
989
    if (!currentStatus) { // interface down...
 
990
        // Interface is down and was up before -> set status variables
 
991
        m_interfaceData.up = FALSE;
 
992
        m_interfaceData.connected = FALSE;
 
993
        m_state = DISABLED;
 
994
    } else if (currentStatus) {
 
995
        // Interface is up, so check for connection status
 
996
        m_interfaceData.up = TRUE;
 
997
        // Now get connection status
 
998
        FILE* carrier_fp = fopen((m_sysClassPath+"carrier").latin1(), "r");
 
999
        char carrierFlag = '1';
 
1000
        if (carrier_fp) {
 
1001
            carrierFlag = fgetc(carrier_fp);
 
1002
            fclose(carrier_fp);
 
1003
        }
 
1004
        if (carrierFlag == '0') { // carrier down
 
1005
            // Interface is not connected
 
1006
            m_state=NOTCONNECTED;
 
1007
            if (m_interfaceData.connected) {
 
1008
                m_interfaceData.connected = FALSE;
 
1009
                say(i18n("%1 is disconnected").arg(m_controlInterface));
 
1010
            }
 
1011
        } else if (!m_interfaceData.connected) { 
 
1012
            // Interface is connected
 
1013
            m_interfaceData.connected = TRUE;
 
1014
            if (m_ipConfigured)
 
1015
            {
 
1016
                m_state=CONFIGURED;
 
1017
                say(i18n("%1 is connected").arg(m_controlInterface));
 
1018
            }
 
1019
            else {
 
1020
                m_state=CONNECTED;
 
1021
            }
 
1022
        }
 
1023
        if (m_interfaceData.wirelessDevice)
 
1024
        {
 
1025
            long retval = readInterfaceNumValue("device/power/state");
 
1026
            if (retval==0)
 
1027
                m_wirelessData.radioOff = FALSE;
 
1028
            else m_wirelessData.radioOff = TRUE;
 
1029
        }
 
1030
        if (m_interfaceData.connected)
 
1031
        {
 
1032
        // Now get interface data
 
1033
            unsigned long currentRxBytes =  readInterfaceNumValue("statistics/rx_bytes");
 
1034
            if ( currentRxBytes < m_interfaceData.prevRxBytes )
 
1035
            {
 
1036
            // there was an overflow
 
1037
                m_interfaceData.rxBytes = currentRxBytes;
 
1038
                m_interfaceData.prevRxBytes = 0L;
 
1039
            }
 
1040
            if ( m_interfaceData.rxBytes == 0L )
 
1041
            {
 
1042
            // on startup set to currently received bytes
 
1043
                m_interfaceData.rxBytes = currentRxBytes;
 
1044
                m_interfaceData.prevRxBytes = currentRxBytes;
 
1045
            }
 
1046
            else
 
1047
            // afterwards only add difference to previous number of bytes
 
1048
            {
 
1049
                m_interfaceData.prevRxBytes = m_interfaceData.rxBytes;
 
1050
                m_interfaceData.rxBytes = currentRxBytes;
 
1051
            }
 
1052
 
 
1053
            m_interfaceData.rxString = KIO::convertSize( m_interfaceData.rxBytes );
 
1054
        
 
1055
            unsigned long currentTxBytes = readInterfaceNumValue("statistics/tx_bytes");
 
1056
            if ( currentTxBytes < m_interfaceData.prevTxBytes )
 
1057
            {
 
1058
            // there was an overflow
 
1059
                m_interfaceData.txBytes = currentTxBytes;
 
1060
                m_interfaceData.prevTxBytes = 0L;
 
1061
            }
 
1062
            if ( m_interfaceData.txBytes == 0L )
 
1063
            {
 
1064
            // on startup set to currently transmitted bytes
 
1065
                m_interfaceData.txBytes = currentTxBytes;
 
1066
                m_interfaceData.prevTxBytes = currentTxBytes;
 
1067
            }
 
1068
            else
 
1069
            {
 
1070
                m_interfaceData.prevTxBytes = m_interfaceData.txBytes;
 
1071
                m_interfaceData.txBytes = currentTxBytes;
 
1072
            }
 
1073
 
 
1074
            m_interfaceData.txString = KIO::convertSize( m_interfaceData.txBytes );
 
1075
 
 
1076
            m_interfaceData.rxPackets = readInterfaceNumValue("statistics/rx_packets");
 
1077
            m_interfaceData.txPackets = readInterfaceNumValue("statistics/tx_packets");
 
1078
            // Now get IP Address
 
1079
            if (!((m_fdSock == -1) && !openFdSocket()))
 
1080
            {
 
1081
                memset(&m_devInfo, 0, sizeof(m_devInfo));
 
1082
                strcpy(m_devInfo.ifr_name, m_controlInterface);
 
1083
                ioctl(m_fdSock, SIOCGIFADDR, &m_devInfo);
 
1084
                sockaddr_in sin = ((sockaddr_in&)m_devInfo.ifr_addr);
 
1085
                m_interfaceData.ipAddress = inet_ntoa(sin.sin_addr);
 
1086
                ioctl(m_fdSock, SIOCGIFNETMASK, &m_devInfo);
 
1087
                sockaddr_in mask = ((sockaddr_in&)m_devInfo.ifr_netmask);
 
1088
                m_interfaceData.subnetMask = inet_ntoa(mask.sin_addr);
 
1089
                ioctl(m_fdSock, SIOCGIFBRDADDR, &m_devInfo);
 
1090
                sockaddr_in broadcast = ((sockaddr_in&)m_devInfo.ifr_broadaddr);
 
1091
                m_interfaceData.broadcastAddress = inet_ntoa(broadcast.sin_addr);
 
1092
 
 
1093
            }
 
1094
            else {
 
1095
                m_interfaceData.ipAddress = "";
 
1096
                m_interfaceData.subnetMask="";
 
1097
                m_interfaceData.broadcastAddress="";
 
1098
            }
 
1099
       //Now get wireless data
 
1100
            if (m_interfaceData.wirelessDevice)
 
1101
            {
 
1102
                QString filename = m_sysClassPath+"device/bssinfo";
 
1103
                QFile bssFile (filename);
 
1104
                if (bssFile.open(IO_ReadOnly))
 
1105
                {
 
1106
                    QTextStream stream (&bssFile);
 
1107
                    QString line="";
 
1108
                    while (!stream.atEnd() && !line.isNull())
 
1109
                    {
 
1110
                        line = stream.readLine();
 
1111
                        if (!line.isNull())
 
1112
                        {
 
1113
                            QRegExp regExp;
 
1114
                            regExp.setPattern( "ESSID: (\\w*)" );
 
1115
                            if ( regExp.search( line ) > -1 )
 
1116
                                m_wirelessData.essid= regExp.cap( 1 );
 
1117
                            regExp.setPattern( "Channel: (\\d*)" );
 
1118
                            if ( regExp.search( line ) > -1 )
 
1119
                                m_wirelessData.channel = regExp.cap( 1 );
 
1120
                        }
 
1121
                    }
 
1122
                    bssFile.close();
 
1123
                }
 
1124
                unsigned long link = readInterfaceNumValue( "wireless/link");
 
1125
                m_wirelessData.linkQuality = QString("%1/100").arg(link);
 
1126
                m_wirelessData.linkQualityNum = link;
 
1127
            }
 
1128
        }
 
1129
    }
 
1130
    if (tmpUp != m_interfaceData.up)
 
1131
    {
 
1132
        emit (interfaceUp(m_interfaceData.up ));
 
1133
    }
 
1134
    if (m_interfaceData.up && m_interfaceData.connected)
 
1135
    {
 
1136
        if (!m_ipConfigured)
 
1137
        {
 
1138
            getIpAddress();
 
1139
        }
 
1140
    }
 
1141
}
 
1142
 
 
1143
 
 
1144
void KwlanInterface::dhcpProcessExited(KwlanSuProcess *process)
 
1145
{
 
1146
    if (process == m_dhcpProcess)
 
1147
    {
 
1148
        delete m_dhcpProcess;    
 
1149
        // check if the process returned an Error
 
1150
        if (m_dhcpProcess->exitStatus()==0)
 
1151
        {
 
1152
            say(i18n("%1 is connected").arg(m_controlInterface));
 
1153
            if (::debugOutput) kdDebug() << "Now starting script after connect" << endl;
 
1154
            // set Network settings like DNS etc
 
1155
            setDnsSettings();
 
1156
            //start script after connect
 
1157
            startScriptAfterConnect();
 
1158
        }
 
1159
        m_ipConfigured = TRUE;
 
1160
        m_state=CONFIGURED;
 
1161
        m_dhcpProcess =0L;
 
1162
    }
 
1163
}
 
1164
 
 
1165
void KwlanInterface::releaseProcessExited(KwlanSuProcess *process)
 
1166
{
 
1167
    if (process == m_releaseProcess)
 
1168
    {
 
1169
        delete m_releaseProcess;    
 
1170
        m_ipConfigured = FALSE;
 
1171
        m_releaseProcess =0L;
 
1172
    }
 
1173
}
 
1174
 
 
1175
 
 
1176
void KwlanInterface::logViewer()
 
1177
{
 
1178
    //kdDebug()<<"Log Viewer called" << endl;
 
1179
    if (m_eventHistory) {
 
1180
        m_eventHistory->close();
 
1181
        delete m_eventHistory;
 
1182
    }
 
1183
 
 
1184
    m_eventHistory = new KEventHistoryDlg();
 
1185
    if (m_eventHistory == NULL)
 
1186
        return;
 
1187
    connect (this, SIGNAL (wpaEvent(WpaMsg)), m_eventHistory,SLOT (addEvent(WpaMsg)));
 
1188
    connect (this, SIGNAL (wpaEvents(WpaMsgList)), m_eventHistory,SLOT (addEvents(WpaMsgList)));
 
1189
    emit (wpaEvents( m_messages));
 
1190
    m_eventHistory->show();
 
1191
    m_eventHistory->exec();
 
1192
}
 
1193
 
 
1194
void KwlanInterface::getIpData()
 
1195
{
 
1196
    if (!m_configuration) return;
 
1197
    QString ipAddress,netmask,dns1,dns2,gateway, domain;
 
1198
    QStringList dnsSearchlist;
 
1199
    bool dontOverrideGw,dontOverrideDns, dhcpEnabled;
 
1200
    int ret;
 
1201
    ret = m_configuration->readIpSettings(m_ssid,dhcpEnabled, ipAddress, netmask, gateway, dns1, dns2,domain,dontOverrideGw,dontOverrideDns,dnsSearchlist);
 
1202
    if (ret != 0){
 
1203
        m_dhcpEnabled = true; //default will be dhcp
 
1204
        m_staticIpAddress="";
 
1205
        m_staticNetmask = "";
 
1206
        m_staticGateway="";
 
1207
        m_staticDns1 = "";
 
1208
        m_staticDns2="";
 
1209
        m_dontOverrideDns=TRUE;
 
1210
        m_dontOverrideGw=TRUE;
 
1211
        m_domain = "";
 
1212
        m_dnsSearchlist.clear();
 
1213
    }
 
1214
    else {
 
1215
        m_dhcpEnabled = dhcpEnabled;
 
1216
        m_staticIpAddress= ipAddress;
 
1217
        m_staticNetmask = netmask;
 
1218
        m_staticGateway=gateway;
 
1219
        m_staticDns1 = dns1;
 
1220
        m_staticDns2=dns2;
 
1221
        m_dontOverrideGw=dontOverrideGw;
 
1222
        m_dontOverrideDns=dontOverrideDns;
 
1223
        m_domain=domain;
 
1224
        m_dnsSearchlist = dnsSearchlist;
 
1225
    }
 
1226
}
 
1227
 
 
1228
void KwlanInterface::enableInterface( bool enable)
 
1229
{
 
1230
    if (!m_controlInterface || !m_configureInterface) return;
 
1231
    KwlanSuProcess *ifup = new KwlanSuProcess();
 
1232
    if (enable) {
 
1233
        *ifup << m_ifconfigPath << m_controlInterface  << "up";
 
1234
        ifup->setDescription( i18n("Enable interface"));
 
1235
        //ifup->start(SuProcessBase::Block );
 
1236
        ifup->start();
 
1237
    }
 
1238
    else if (m_type != PPP){
 
1239
        //releaseIpAddress(); // Don't release IP Address as it will reenable the interface if 
 
1240
        // it is run after setting the interface to down state.
 
1241
        // TODO: Release IP Address and connect processExited with function to set interface down
 
1242
        *ifup << m_ifconfigPath << m_controlInterface << "down";
 
1243
        ifup->setDescription( i18n("Disable interface"));
 
1244
        //ifup->start( SuProcessBase::Block );
 
1245
        ifup->start();
 
1246
    }
 
1247
}
 
1248
 
 
1249
 
 
1250
void KwlanInterface::slotNewProfile()
 
1251
{
 
1252
    KProfileConfigDlg *profileDlg = new KProfileConfigDlg();
 
1253
    if (!profileDlg) return;
 
1254
    profileDlg->setInterface(this);
 
1255
    profileDlg->newNetwork();
 
1256
    profileDlg->show();
 
1257
    profileDlg->exec();
 
1258
    emit (networksChanged());
 
1259
    //updateNetworks();
 
1260
}
 
1261
 
 
1262
void KwlanInterface::slotEditProfile(QString profile)
 
1263
{
 
1264
    
 
1265
    //int wpaId = getWpaId( profile);    
 
1266
    
 
1267
    // Open Config Dialog
 
1268
    KProfileConfigDlg *profileDlg = new KProfileConfigDlg();
 
1269
    if (!profileDlg) return;
 
1270
    profileDlg->setInterface(this);
 
1271
    profileDlg->paramsFromConfig(this, profile);
 
1272
    //profileDlg->show();
 
1273
    profileDlg->exec();
 
1274
}
 
1275
 
 
1276
void KwlanInterface::slotDeleteProfile(QString profile)
 
1277
{
 
1278
    char cmd[256],reply[100];
 
1279
    size_t reply_len = sizeof(reply);
 
1280
    if (!m_controlConnection && !m_wpaStarted) {
 
1281
        int result = KMessageBox::questionYesNo(0,"wpa_supplicant is not started. Only the non-wpa related network settings will be deleted.\n"
 
1282
                "Do you want to delete these settings?");
 
1283
        if (result == KMessageBox::Yes){
 
1284
            m_configuration->deleteNetwork( profile);
 
1285
        }
 
1286
        return; 
 
1287
    }
 
1288
    int id = getWpaId(profile);
 
1289
    snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %i", id);
 
1290
    reply_len = sizeof(reply);
 
1291
    ctrlRequest(cmd, reply, &reply_len);
 
1292
    if (strncmp(reply, "OK", 2) != 0) {
 
1293
        KMessageBox::sorry(0, i18n("Failed to remove network from wpa_supplicant\nconfiguration."));
 
1294
    } else {
 
1295
        reply_len = sizeof(reply);
 
1296
        ctrlRequest("SAVE_CONFIG", reply, &reply_len);
 
1297
        if (strncmp(reply,"OK",2) != 0) {
 
1298
            KMessageBox::sorry(0, "Failed to save the  wpa_supplicant configuration.\nIs update_config=1 defined in wpa_supplicant.conf?");
 
1299
        }
 
1300
    }
 
1301
    m_configuration->deleteNetwork( profile);
 
1302
    emit (networksChanged());
 
1303
}
 
1304
 
 
1305
void KwlanInterface::startScriptAfterConnect()
 
1306
{
 
1307
    // Now start script after connect if configured
 
1308
    QString script;
 
1309
    bool useRoot;
 
1310
    m_configuration->readScriptAfterConnect( m_ssid,script, useRoot);
 
1311
    if (::debugOutput) kdDebug() << "Now starting script after connect "<< script << endl;
 
1312
    if (!script.isEmpty())
 
1313
    {
 
1314
        if (useRoot) {
 
1315
            KwlanSuProcess *proc = new KwlanSuProcess();
 
1316
            *proc << script;
 
1317
            proc->setDescription( i18n("start script after connect"));
 
1318
            proc->start( );
 
1319
        }
 
1320
        else {
 
1321
            KProcess *proc = new KProcess();
 
1322
            *proc << script;
 
1323
            proc->start();
 
1324
        }
 
1325
    }
 
1326
}
 
1327
 
 
1328
unsigned long KwlanInterface::readInterfaceNumValue(const char* name) 
 
1329
{
 
1330
    // stdio functions appear to be more fast than QFile?
 
1331
    FILE* fp = fopen((m_sysClassPath+name).latin1(), "r");
 
1332
    if (!fp) return 0;
 
1333
    long retval;
 
1334
    fscanf(fp, "%lu", &retval);
 
1335
    fclose(fp);
 
1336
    return retval;
 
1337
}
 
1338
 
 
1339
bool KwlanInterface::openFdSocket() {
 
1340
    if (m_fdSock > 0)
 
1341
        return TRUE;
 
1342
    if ((m_fdSock = socket(AF_INET, SOCK_DGRAM, 0)) > 0)
 
1343
        return TRUE;
 
1344
    return FALSE;
 
1345
}
 
1346
 
 
1347
void KwlanInterface::say(QString message) {
 
1348
    emit sigMessage(message);
 
1349
}
 
1350
 
 
1351
 
 
1352
void KwlanInterface::newInterfaceWizard(QString interface)
 
1353
{
 
1354
    int res = KMessageBox::warningContinueCancel(0,QString(i18n("New interface found!\n%1\n Click Continue to configure it now.")).arg(interface),"Kwlan",
 
1355
            KStdGuiItem::cont(),"newinterfacewizard");
 
1356
    if (res == KMessageBox::Continue)
 
1357
    {
 
1358
        //User wants to configure interface
 
1359
        int result = KMessageBox::questionYesNo(0, i18n("Do you want to start wpa_supplicant for this interface?"));
 
1360
        if (result == KMessageBox::Yes)
 
1361
        {
 
1362
            KStartSupplicantDlg *startSupplicant = new KStartSupplicantDlg();
 
1363
            QString driver;
 
1364
            if (m_interfaceData.wirelessDevice) driver = "wext";
 
1365
            else driver = "wired";
 
1366
            if (startSupplicant ){
 
1367
                startSupplicant->setData(&interface,&driver);
 
1368
//                    startSupplicant->show();
 
1369
                startSupplicant->exec();
 
1370
            }
 
1371
            QString wpa_supplicant;
 
1372
            if (startSupplicant->m_start){
 
1373
                KwlanSuProcess *startWpa= new KwlanSuProcess(NULL,"Start WPA Supplicant");
 
1374
                *startWpa << m_wpaPath << QString("-i%1").arg(QString(m_controlInterface)) << QString ("-D%1").arg(startSupplicant->getDriver()) << QString("-c")+ m_wpaConf << "-B";
 
1375
                startWpa->setDescription(i18n("Start WPA Supplicant"));
 
1376
                startWpa->start();
 
1377
                m_configuration->writeDriver(startSupplicant->getDriver());
 
1378
            }
 
1379
            delete startSupplicant;
 
1380
            // show wpa settings
 
1381
            KwlanSettingsDlg *settings = new KwlanSettingsDlg();
 
1382
            settings->setConfiguraton( m_configuration);
 
1383
 
 
1384
            if (!settings) return;
 
1385
            settings->setCaption(QString(i18n("Settings for %1")).arg(interface));
 
1386
            //settings->show();
 
1387
            settings->exec();
 
1388
        }
 
1389
            // Now add a default profile
 
1390
        if (!hasProfiles())
 
1391
            slotNewProfile();
 
1392
        m_networkChange = true;
 
1393
    }
 
1394
}
 
1395
void KwlanInterface::slotEnableConfigureInterface(QString interface, bool enable)
 
1396
{
 
1397
    if (interface != QString(m_controlInterface)) return;
 
1398
    m_configureInterface = enable;
 
1399
}
 
1400
 
 
1401
void KwlanInterface::slotScan()
 
1402
{
 
1403
    if (m_scanDlg) {
 
1404
        m_scanDlg->close();
 
1405
        delete m_scanDlg;
 
1406
    }
 
1407
 
 
1408
    m_scanDlg = new KScanDlg();
 
1409
    if (m_scanDlg == NULL)
 
1410
        return;
 
1411
    m_scanDlg->setInterface(this);
 
1412
    m_scanDlg->show();
 
1413
    m_scanDlg->exec();
 
1414
}
 
1415
 
 
1416
void KwlanInterface::slotScanAvailableNetworks()
 
1417
{
 
1418
    //avoid mulitple scans due timeout of scann being longer than scan interval
 
1419
    if (m_isScanning | (!m_interfaceData.wirelessDevice)) return;
 
1420
    m_isScanning = TRUE;
 
1421
    QStringList configuredProfiles = listProfiles();
 
1422
    char buf[2048]; QString signal;
 
1423
    m_availableNetworks.clear();
 
1424
    size_t len =sizeof(buf);
 
1425
    // Are we connected to wpa? If so, send scan request
 
1426
    // We are not using the results but without it the iwlib functions 
 
1427
    // will not return any network;
 
1428
    if (m_controlConnection) {
 
1429
        if (ctrlRequest("SCAN", buf, &len) < 0)
 
1430
        {
 
1431
            kdDebug() << "Could not scan for wpa available networks" << endl;
 
1432
        }
 
1433
    }
 
1434
    
 
1435
    kwireless_scan(m_availableNetworks,m_controlInterface);
 
1436
    // check if found networks are already configured
 
1437
    for (kwlNetworkList::iterator it = m_availableNetworks.begin();it != m_availableNetworks.end();it++)
 
1438
    {
 
1439
        QStringList::Iterator index = configuredProfiles.find((*it).m_ssid);
 
1440
        if ((*index).isEmpty())
 
1441
        {
 
1442
            (*it).m_isConfigured = FALSE;
 
1443
        } else (*it).m_isConfigured = TRUE;
 
1444
   
 
1445
    }
 
1446
    m_isScanning = FALSE;
 
1447
    return;
 
1448
 
 
1449
}
 
1450
 
 
1451
kwlNetworkList KwlanInterface::getAvailableProfiles()
 
1452
{
 
1453
    QStringList profiles = listProfiles();
 
1454
    if ( !m_interfaceData.wirelessDevice )
 
1455
    {
 
1456
        kwlNetworkList tmpList;
 
1457
        for (QStringList::Iterator it = profiles.begin(); it != profiles.end();it++)
 
1458
        {
 
1459
            tmpList.append(kwlNetwork(*it));
 
1460
        }
 
1461
        return tmpList;
 
1462
    }
 
1463
    return m_availableNetworks;
 
1464
}
 
1465
 
 
1466
 
 
1467