Qt 嵌入式 利用wpa_supplicant编写WIFI、有线网络管理器

来源:互联网 发布:税友软件怎么样 编辑:程序博客网 时间:2024/06/03 06:43

原文链接:http://blog.csdn.net/dr_abel/article/details/51335599

嵌入式linux系统中没有内置自动化程度高的管理程序,这个程序就完成根据有线插拔来判断是否启用无线的功能。

QTENetworkManager

qtenetworkmanager.h

#ifndef QTENETWORKMANAGER_H#define QTENETWORKMANAGER_H#include <QObject>#include <QTimer>#include <QList>#include "QTEDefine.h"#include <qthread.h>#include "QTEDefine.h"class QTENetworkClearThread : public QThread{    Q_OBJECTpublic:    QTENetworkClearThread(QObject* parent = 0) : QThread(parent) {    }signals:    void cleared();    void notcleared();    // QThread interfaceprotected:    void run();};class QTEDhcpThread : public QThread{    Q_OBJECTpublic:    QTEDhcpThread(QObject* parent = 0) : QThread(parent) {    }    void setnet(QString eth = "eth0") {net=eth;}signals:    void passed(QString);    // QThread interfaceprotected:    void run();private:    QString net;};// thread unsafeclass QTENetworkManager : public QObject{    Q_OBJECTpublic:    static QTENetworkManager *Instance(QObject* parent = 0);    QList<TWifi>& wifiList() { return m_wifiList; }    inline TWifi currentWifi(){ return m_curWifi; }    bool setCurrentWifi(QString bssid_mac, QString password = "");    void setRefresh(bool ref = true) { ref ? m_workTimer->start(5000) : m_workTimer->stop(); }    void setDHCP(bool bUse = false) { m_bUseDHCP = bUse; }    void configIPAddress(QString ip, QString mask, QString gw, QString dns);    QString currentNetName();    QTimer* workTimer() { return m_workTimer; }    void saveAddr(QString ip, QString mask, QString gw, QString dns);    void getAddr(QString& ip, QString& mask, QString& gw, QString& dns);signals:    //没有配置就会发送这个信号    void sigScanning();    //断开连接的状态    void sigDisConnected();    //正在连接的状态    void sigConnecting();    //连接成功的状态    void sigConnected();    //Wifi列表更新 之上状态改变会影响list中wifi的标志位。    void sigRefreshed();    //Wifi状态改变    void sigStatusChanged(QString status);    //有线连接上    void sigLanConnected();    //有线断开    void sigLanDisConnected();    //网络线路连接上    void sigNetworkClear();    //网络线路断开    void sigNetworkNotClear();private slots:    void refreshWifiList();    void refreshWifiStatus();    void checkLanConnection();    void DhcpPassed(QString netname);    void checkNetworkClear();private:    explicit QTENetworkManager(QObject *parent = 0);    void readStatus();    void restoreWifi();    bool restartWifi();    void saveScript();    void config();signals:public slots:private:    static QTENetworkManager* _instance;    QTimer* m_workTimer;    QList<TWifi> m_wifiList;    TWifi m_curWifi;    bool m_bUseDHCP;    QString m_netName;    QTEDhcpThread* m_thread;    QTENetworkClearThread* m_clearThread;    QString m_status;};#endif // QTENETWORKMANAGER_H
qtenetworkmanager.cpp

#include "QTENetworkManager.h"#include "hnlinux.h"#include "QTEDefine.h"QTENetworkManager* QTENetworkManager::_instance = NULL;QTENetworkManager *QTENetworkManager::Instance(QObject *parent){    if(_instance)        return _instance;    _instance = new QTENetworkManager(parent);    return _instance;}bool QTENetworkManager::setCurrentWifi(QString bssid_mac, QString password){    for(QList<TWifi>::Iterator it = m_wifiList.begin();        it != m_wifiList.end(); it++)    {        TWifi wifi = *it;        if(bssid_mac == wifi[ESSID_BSSID])        {            m_status = "";            m_curWifi = wifi;            m_curWifi[ESSID_PASS] = password;            break;        }    }    restoreWifi();    if(!restartWifi())        return false;    return true;}void QTENetworkManager::configIPAddress(QString ip, QString mask, QString gw, QString dns){    saveAddr(ip, mask, gw, dns);    saveScript();    config();}QString QTENetworkManager::currentNetName(){    if("eth0" == m_netName)        return "Wired Lan";    if("wlan0" == m_netName)        if("COMPLETED" == m_status)            return m_curWifi[ESSID_NAME];    return "";}void QTENetworkManager::readStatus(){    //从 status 中读取    char result[MAX_LEN];    char key[MAX_LEN]; //设置一个合适的长度,以存储每一行输出    char value[MAX_LEN]; //设置一个合适的长度,以存储每一行输出    bzero(result, MAX_LEN);    bzero(key, MAX_LEN);    bzero(value, MAX_LEN);    FILE *pp = popen("wpa_cli -iwlan0 status", "r"); //建立管道    if (!pp)        return;    while( fgets(result, sizeof(result), pp) != NULL)    {        sscanf(result, "%[^=]=%s", key, value);        //如果这里不用QString包含,会对比地址        if(QString("wpa_state") == QString(key)) {            m_curWifi[ESSID_STATUS] = value;        } else if(QString("bssid") == QString(key)) {            m_curWifi[ESSID_BSSID] = value;        } else if(QString("ssid") == QString(key)) {            m_curWifi[ESSID_NAME] = value;        }    }    pclose(pp);    return;}void QTENetworkManager::refreshWifiList(){    static int scanid = 0;    if(scanid == 12)        scanid = 0, system("wpa_cli -iwlan0 scan");    scanid ++;    FILE *pp = popen("wpa_cli -iwlan0 scan_r", "r"); //建立管道    if (!pp)        return;    char cmdresult[MAX_LEN]; //设置一个合适的长度,以存储每一行输出    fgets(cmdresult, sizeof(cmdresult), pp) ; //""    char bssid[MAX_PATH];    char frequency[MAX_PATH];    char signal[MAX_PATH];    char flag[MAX_PATH];    char ssid[MAX_PATH];    m_wifiList.clear();    while( fgets(cmdresult, sizeof(cmdresult), pp) != NULL)    {        sscanf(cmdresult, "%s\t%s\t%s\t%s\t%s\n", bssid, frequency, signal, flag, ssid);        TWifi wifi;        wifi[ESSID_NAME] = ssid;        if( strstr(flag, "WPA"))            wifi[ESSID_TYPE] = "WPA";        else            wifi[ESSID_TYPE] = "WEP";        if(strstr(flag, "WPA") || strstr(flag, "WEP"))            wifi[ESSID_ENCRYP] = "YES";        else            wifi[ESSID_ENCRYP] = "NO";        wifi[ESSID_PASS] = "";        wifi[ESSID_BSSID] = bssid;        wifi[ESSID_FREQ] = frequency;        wifi[ESSID_SIGNAL] = signal;        wifi[ESSID_FLAG] = flag;        if(wifi[ESSID_BSSID] == m_curWifi[ESSID_BSSID])            wifi[ESSID_STATUS] = m_curWifi[ESSID_STATUS];        else            wifi[ESSID_STATUS] = "";        m_wifiList.push_back(wifi);        //pline() << ssid << frequency << signal << flag << bssid << wifi[ESSID_STATUS];    }    //pline() << m_wifiList.size();    pclose(pp); //关闭管道    emit sigRefreshed();}void QTENetworkManager::refreshWifiStatus(){    readStatus();    if(m_status == m_curWifi[ESSID_STATUS])        return;    pline() << m_curWifi[ESSID_BSSID] << m_curWifi[ESSID_NAME] << m_curWifi[ESSID_STATUS];    m_status = m_curWifi[ESSID_STATUS];    emit sigStatusChanged(m_status);    if("COMPLETED" == m_status)        emit sigConnected();    else if("SCANNING" == m_status)        emit sigScanning();    else if("ASSOCIATING" == m_status)        emit sigConnecting();    else if("INACTIVE" == m_status)        emit sigDisConnected();    else if("4WAY_HANDSHAKE" == m_status)        emit sigDisConnected();    else if("DISCONNECTED" == m_status)        emit sigDisConnected();}void QTENetworkManager::checkLanConnection(){    char cmdbuf[MAX_PATH];    char cmdresult[MAX_PATH]; //设置一个合适的长度,以存储每一行输出    bzero(cmdbuf, MAX_PATH);    bzero(cmdresult, MAX_PATH);    sprintf(cmdbuf, "cat /sys/class/net/eth0/carrier");    FILE *pp = popen(cmdbuf, "r"); //建立管道    fgets(cmdresult, sizeof(cmdresult), pp); //""    pclose(pp);    QString netName = m_netName;    if(strstr(cmdresult, "0"))        m_netName = "wlan0";    else        m_netName = "eth0";    if(netName != m_netName)    {        config();        if("wlan0" == m_netName)            emit sigLanDisConnected();        else            emit sigLanConnected();    }    return;}void QTENetworkManager::DhcpPassed(QString netname){    int sockfd;    struct ifreq ifr;    struct sockaddr_in sin;    sockfd = socket(AF_INET, SOCK_DGRAM, 0);    if (sockfd == -1)    {        perror("socket");        return;    }    strncpy(ifr.ifr_name, netname.toAscii().data(), IFNAMSIZ);    ifr.ifr_name[IFNAMSIZ - 1] = 0;    //ip    if(ioctl(sockfd, SIOCGIFADDR, &ifr) <0)        perror("ioctl");    memcpy(&sin, &ifr.ifr_addr, sizeof(sin));    QString ip = QString(inet_ntoa(sin.sin_addr));    //mask    if (ioctl(sockfd, SIOCGIFNETMASK, &ifr) < 0)        perror("ioctl");    memcpy(&sin, &ifr.ifr_addr, sizeof(sin));    QString mask = QString(inet_ntoa(sin.sin_addr));    //mac    if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0)        perror("ioctl");    memcpy(&sin, &ifr.ifr_addr, sizeof(sin));    QString mac = QString(inet_ntoa(sin.sin_addr));    close(sockfd);    //gw    FILE *fp;    char buf[MAX_PATH];    char gateway[MAX_PATH];    bzero(buf, MAX_PATH);    bzero(gateway, MAX_PATH);    fp = popen("ip route", "r");    while(fgets(buf, sizeof(buf), fp) != NULL)    {        if(strstr(buf, "default via"))        {            sscanf(buf, "%*s%*s%s", gateway);            break;        }    }    pclose(fp);    QString gw = gateway;    //dns    QFile file("/etc/resolv.conf");    file.open(QFile::ReadOnly);    QByteArray nameserver = file.readLine();    nameserver[nameserver.size()-1] = '\0';    QList<QByteArray> namelist = nameserver.split(' ');    QString dns = namelist.size() > 1 ? namelist[1] : gw;    file.close();    //pt    pline() << netname << ip << mask << gw << dns;    saveAddr(ip, mask, gw, dns);    saveScript();}void QTENetworkManager::checkNetworkClear(){    return;    m_clearThread->start();}QTENetworkManager::QTENetworkManager(QObject *parent) :    QObject(parent){    m_bUseDHCP = false;    m_clearThread = new QTENetworkClearThread(this);    connect(m_clearThread, SIGNAL(cleared()), this, SIGNAL(sigNetworkClear()));    connect(m_clearThread, SIGNAL(notcleared()), this, SIGNAL(sigNetworkNotClear()));    m_thread = new QTEDhcpThread(this);    connect(m_thread, SIGNAL(passed(QString)), this, SLOT(DhcpPassed(QString)));    //检查网线    //搜索热点    //刷新连接状态    m_workTimer = new QTimer(this);    m_workTimer->setSingleShot(false);    connect(m_workTimer, SIGNAL(timeout()), this, SLOT(refreshWifiList()));    connect(m_workTimer, SIGNAL(timeout()), this, SLOT(refreshWifiStatus()));    connect(m_workTimer, SIGNAL(timeout()), this, SLOT(checkLanConnection()));    connect(m_workTimer, SIGNAL(timeout()), this, SLOT(checkNetworkClear()));#ifdef __MIPS_LINUX__    m_workTimer->start(5000);    //更新一次,以后一直调用scan_r 5-6s    system("wpa_cli -iwlan0 scan");#endif}void QTENetworkManager::restoreWifi(){    QString name = m_curWifi[ESSID_NAME];    QString password = m_curWifi[ESSID_PASS];    QString encryt = m_curWifi[ESSID_ENCRYP];    QString type = m_curWifi[ESSID_TYPE];    char cmdbuf[MAX_PATH];    char cmdresult[MAX_PATH];    FILE* fp=fopen("/etc/wpa_supplicant.conf", "wb");    fprintf(fp, "ctrl_interface=/var/run/wpa_supplicant\nctrl_interface_group=0\nap_scan=1\n\n");    if("NO" == encryt)    {        pline() << "None Encryption";        fprintf(fp, "network={\n\tssid=%s\n\tkey_mgmt=NONE\n\tpriority=5\n}\n", name.toAscii().data());    }    else if("WEP" == type)    {        pline() << "WEP Encryption";        fprintf(fp, "network={\n\tssid=\"%s\"\n\tkey_mgmt=NONE\n\twep_key0=%s\n\twep_tx_keyidx=0\n\tpriority=5\n\tauth_alg=SHARED\n}\n",                name.toAscii().data(), password.toAscii().data());    }    else if("WPA" == type)    {        pline() << "WPA Encryption";        bzero(cmdbuf, MAX_PATH);        bzero(cmdresult, MAX_PATH);#if 0        sprintf(cmdbuf, "wpa_passphrase %s %s | awk 'NR==4{print $1}'", name.toAscii().data(), wifiPassword.toAscii().data());        FILE *pp = popen(cmdbuf, "r"); //建立管道        fgets(cmdresult, sizeof(cmdresult), pp) ; //""        pclose(pp);        fprintf(fp, "network={\n\tssid=\"%s\"\n\tkey_mgmt=WPA-PSK\n\tgroup=TKIP\n\tpairwise=CCMP\n\tproto=WPA\n\t#psk=\"%s\"\n\t%s\tpriority=5\n}\n",                name, wifiPassword, cmdresult);#else        sprintf(cmdbuf, "wpa_passphrase %s %s", name.toAscii().data(), password.toAscii().data());        FILE *pp = popen(cmdbuf, "r"); //建立管道        while(fgets(cmdresult, sizeof(cmdresult), pp))  //""        {            fputs(cmdresult, fp);        }        pclose(pp);#endif    }    fclose(fp);}bool QTENetworkManager::restartWifi(){    char cmdbuf[MAX_PATH];    char cmdresult[MAX_PATH]; //设置一个合适的长度,以存储每一行输出    bzero(cmdbuf, MAX_PATH);    bzero(cmdresult, MAX_PATH);    sprintf(cmdbuf, "wpa_cli -iwlan0 reconf");    FILE *pp = popen(cmdbuf, "r"); //建立管道    fgets(cmdresult, sizeof(cmdresult), pp); //""    pclose(pp);    if(strstr(cmdresult, "FAIL"))        return false;    return true;}void QTENetworkManager::saveScript(){    QString ip, mask, gw, dns;    getAddr(ip, mask, gw, dns);    QFile script("./net.sh");    script.open(QFile::WriteOnly);    char cmdbuf[MAX_PATH];    bzero(cmdbuf, MAX_PATH);    sprintf(cmdbuf, "#!/bin/sh\n\n");    script.write(cmdbuf);    bzero(cmdbuf, MAX_PATH);    sprintf(cmdbuf, "ifconfig eth0 %s netmask %s up\n",            ip.toAscii().data(),            mask.toAscii().data());    script.write(cmdbuf);    bzero(cmdbuf, MAX_PATH);    sprintf(cmdbuf, "ifconfig wlan0 %s netmask %s up\n",            ip.toAscii().data(),            mask.toAscii().data());    script.write(cmdbuf);    bzero(cmdbuf, MAX_PATH);    sprintf(cmdbuf, "route add default gw %s netmask 0.0.0.0 dev eth0\n",            gw.toAscii().data());    script.write(cmdbuf);    bzero(cmdbuf, MAX_PATH);    sprintf(cmdbuf, "route add default gw %s netmask 0.0.0.0 dev wlan0\n",            gw.toAscii().data());    script.write(cmdbuf);    bzero(cmdbuf, MAX_PATH);    sprintf(cmdbuf, "echo nameserver %s > /etc/resolv.conf\n", dns.toAscii().data());    script.write(cmdbuf);    bzero(cmdbuf, MAX_PATH);    sprintf(cmdbuf, "wpa_supplicant -B -Dwext -iwlan0 -c/etc/wpa_supplicant.conf\n");    script.write(cmdbuf);    script.close();    bzero(cmdbuf, MAX_PATH);    sprintf(cmdbuf, "chmod +x ./net.sh");    system(cmdbuf);}void QTENetworkManager::config(){    char cmdbuf[MAX_PATH];    bzero(cmdbuf, MAX_PATH);    sprintf(cmdbuf, "ip route | awk '{print $1}' | while read line; do ip route del $line; done");    system(cmdbuf);    //system("route");    if(m_bUseDHCP)    {        m_thread->setnet(m_netName);        m_thread->start();        return;    }    QString ip, mask, gw, dns;    getAddr(ip, mask, gw, dns);    pline() << m_netName << ip << mask << gw << dns;    // add .0 route    bzero(cmdbuf, MAX_PATH);    sprintf(cmdbuf, "ifconfig %s 0.0.0.0 up", m_netName.toAscii().data());    system(cmdbuf);    bzero(cmdbuf, MAX_PATH);    sprintf(cmdbuf, "ifconfig %s %s netmask %s",            m_netName.toAscii().data(),            ip.toAscii().data(),            mask.toAscii().data());    system(cmdbuf);    QStringList sl = gw.split(".");    if(sl.size() < 3) { sl.clear(); sl << "0" << "0" << "0" << "0";}    QString net = QString("%1.%2.%3.0").arg(sl[0]).arg(sl[1]).arg(sl[2]);#if 0    //dhcp后 ifconfig up 引发了添加这条route    //ifconfig 0.0.0.0 也能引发添加这条route    bzero(cmdbuf, MAX_PATH);    sprintf(cmdbuf, "route add -net %s netmask %s dev %s",            net.toAscii().data(),            mask.toAscii().data(),            m_netName.toAscii().data());    system(cmdbuf);#endif    bzero(cmdbuf, MAX_PATH);    sprintf(cmdbuf, "route add default gw %s netmask 0.0.0.0 dev %s",            gw.toAscii().data(),            m_netName.toAscii().data());    system(cmdbuf);    //system("route");    bzero(cmdbuf, MAX_PATH);    sprintf(cmdbuf, "echo nameserver %s > /etc/resolv.conf", dns.toAscii().data());    system(cmdbuf);}void QTENetworkManager::saveAddr(QString ip, QString mask, QString gw, QString dns){    QSettings netSet;    netSet.setValue("/Network/IP", ip);    netSet.setValue("/Network/Gateway", gw);    netSet.setValue("/Network/Mask", mask);    netSet.setValue("/Network/DNS", dns);    netSet.sync();}void QTENetworkManager::getAddr(QString &ip, QString &mask, QString &gw, QString &dns){    QSettings netSet;    ip = netSet.value("/Network/IP").toString();    mask = netSet.value("/Network/Mask").toString();    gw = netSet.value("/Network/Gateway").toString();    dns = netSet.value("/Network/DNS").toString();}void QTEDhcpThread::run(){    char cmdbuf[MAX_PATH];    bzero(cmdbuf, MAX_PATH);    sprintf(cmdbuf, "udhcpc -i %s", net.toAscii().data());    system(cmdbuf);    emit passed(net);}void QTENetworkClearThread::run(){    static bool _bclear = false;    bool bclear = false;    char cmdbuf[MAX_PATH];    char cmdresult[MAX_PATH]; //设置一个合适的长度,以存储每一行输出    bzero(cmdbuf, MAX_PATH);    bzero(cmdresult, MAX_PATH);    sprintf(cmdbuf, "ping 222.175.114.244 -w 2 -c 1");    FILE *pp = popen(cmdbuf, "r"); //建立管道    while(fgets(cmdresult, sizeof(cmdresult), pp))    {        if(strstr(cmdresult, "1 packets transmitted, 1 packets received, 0% packet loss"))            bclear = true;        break;    }    pclose(pp);    if(_bclear != bclear)    {        if(bclear)            emit cleared();        else            emit notcleared();        _bclear = bclear;    }    return;}



0 0