xref: /OK3568_Linux_fs/app/forlinx/flapp/src/plugins/wifi/wpaclicmd.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 #include "wpaclicmd.h"
2 #include <QTimer>
3 #include <QDebug>
4 
5 #define CMD_SCAN "scan"
6 #define CMD_SCAN_RESULTS "scan_results"
7 #define CMD_STATUS "status"
8 #define CMD_ADD_NETWORK "add_network"
9 #define CMD_REMOVE_NETORK  "remove_network"
10 #define CMD_SET_NETOWRK_SSID  "set_network %1 ssid '\"%2\"'"
11 #define CMD_SET_NETOWRK_PSK   "set_network %1 psk '\"%2\"'"
12 #define CMD_SELECT_NETWORK "select_network %1"
13 #define CMD_REMOVE_NETWORK "remove_network %"
14 #define CMD_SAVE_CONFIG  "save_config"
15 #define CMD_DISCONNECT_CONNECT "disconnect"
16 #include "terminal.h"
17 
18 class WpaclicmdPrivate{
19 public:
20     QList<ScanInfo> scanResults;
21     QString ko;
22     QString cardName;
23     bool bWpa_supplicantStartFinish=false;
24     QString network=0;
25     QTimer *timer=Q_NULLPTR;
26     bool bRun =false;
27 
get(const QString & a,const QString & start,const QString & end)28     QString get(const QString &a, const QString &start, const QString &end)
29     {
30         //CTRL-EVENT-DISCONNECTED bssid=c2:5a:cd:8c:0f:f4 reason=3  //start ="bssid="  end="reaseo"    result ="c2:5a:cd:8c:0f:f4"
31         QByteArray data;
32         QString result;
33         for(int i=0; i<a.size(); i++){
34             data  +=a[i];
35             if(data.right(start.size()) == start){
36                 data.clear();
37             }else if(data.right(end.size()) == end)
38             {
39                 result = data.left(data.size() - end.size());
40                 result = result.trimmed();
41                 break;
42             }
43         }
44 
45         return result;
46     }
47 
pharseScanInfo(const QString & a)48     QList<ScanInfo> pharseScanInfo(const QString &a)
49     {
50         QStringList list = a.split('\n');
51         QList<ScanInfo>  wifiList;
52         QString wifiName;
53         for(int i=0; i<list.size(); i++){
54             QStringList l =list[i].split('\t');
55             l.removeAll("");
56             if(l.size() ==5){
57                 ScanInfo scan;
58                 scan.bssid = l[0];
59                 scan.frequency = l[1].toInt();
60                 scan.signalLevel = l[2].toInt();
61                 scan.flags = l[3];
62                 scan.ssid =l[4];
63                 if(!wifiList.contains(scan)/* && wifiName!= scan.ssid*/)
64                 {
65                     wifiList.append(scan);
66                     wifiName = scan.ssid;
67                 }
68             }
69         }
70 
71         auto moreThan =[=](const ScanInfo & t1, const ScanInfo & t2){
72             return t1.signalLevel > t2.signalLevel;
73         };
74         qSort(wifiList.begin(), wifiList.end(), moreThan);
75 
76         return wifiList;
77     }
78 
pharsStatusInfo(const QString & a,QMap<QString,QString> & maps)79     void pharsStatusInfo(const QString &a, QMap<QString, QString> &maps){
80         //    bssid=52:57:89:05:db:b9
81         //    freq=2412
82         //    ssid=wifi
83         //    id=0
84         //    mode=station
85         //    pairwise_cipher=CCMP
86         //    group_cipher=CCMP
87         //    key_mgmt=WPA2-PSK
88         //    wpa_state=COMPLETED
89         //    ip_address=192.168.43.236
90         //    p2p_device_address=30:95:87:7a:fb:48
91         //    address=30:95:87:7a:fb:48
92         //    uuid=1f7702ee-85b7-5974-9b6a-94b2ce28e72d
93         //    ieee80211ac=1
94         QStringList list =a.split('\n');
95         foreach (QString d, list) {
96             d +="###";
97             if(d.contains("bssid="))
98             {
99                 maps.insert("bssid", get(d, "bssid=", "###"));
100             }else if(d.contains("ip_address"))
101             {
102                 maps.insert("ip_address", get(d, "ip_address=", "###"));
103             }else if(d.contains("key_mgmt"))
104             {
105                 maps.insert("key_mgmt", get(d, "key_mgmt=", "###"));
106             }else if(d.contains("freq="))
107             {
108                 QString freq = get(d, "freq=", "###");
109                 if(freq.toInt()>=5000)
110                 {
111                     maps.insert("freq", "5 GHz");
112                 }else{
113                     maps.insert("freq", "2.4 GHz");
114                 }
115             }else if(d.contains("ssid"))
116             {
117                 maps.insert("ssid", get(d, "ssid=", "###"));
118             }else if(d.contains("wpa_state="))
119             {
120                 maps.insert("wpa_state", get(d, "wpa_state=", "###"));
121             }
122         }
123     }
124 };
125 
Wpaclicmd(QObject * parent)126 Wpaclicmd::Wpaclicmd(QObject *parent) :
127     QThread(parent),
128     m_d(new WpaclicmdPrivate)
129 {
130 
131     qRegisterMetaType<QList<ScanInfo>>("QList<ScanInfo>");
132 }
133 
~Wpaclicmd()134 Wpaclicmd::~Wpaclicmd()
135 {
136     delete m_d;
137 }
138 
startWpa_supplicant(const QString & ko,const QString & ModuleName,const QString & driverName,const QString & cardName)139 void Wpaclicmd::startWpa_supplicant(const QString &ko, const QString &ModuleName, const QString &driverName, const QString &cardName)
140 {
141     qDebug()<<"start startWpa_supplicant";
142     QString moudleIsExit =QString("lsmod | grep %1 | grep -v grep").arg(ModuleName);
143     m_d->ko = ko;
144     if(!Terminal::execCmd(moudleIsExit).contains(ModuleName))
145     {
146         qDebug() << Terminal::execCmd("insmod " + ko);
147         qDebug() << QString("insmod %1").arg(ko);
148     }else{
149         qDebug() << QString("driver: %1 already install").arg(ModuleName);
150     }
151 
152     //修改wifi配置文件.
153     Terminal::execCmd("echo \"#PSK/TKIP \nctrl_interface=/var/run/wpa_supplicant\" > /etc/wpa_supplicant.conf");
154 
155     auto driveInstallFinish = [=](){
156         Terminal::execCmd(QString("ifconfig %1 up").arg(cardName));
157         m_d->cardName = cardName;
158         //启动 wpa 服务.  //wpa_supplicant -D nl80211 -i wlan0 -c /etc/wpa_supplicant.conf -B
159         QString startSevrverCmd =QString("wpa_supplicant -D %1 -i %2 -c /etc/wpa_supplicant.conf -B")
160                 .arg(driverName)
161                 .arg(cardName);
162         if(!Terminal::execCmd("ps -ef | grep -v grep | grep wpa_supplicant").contains(startSevrverCmd))
163         {
164             qDebug()<<"start =" << Terminal::execCmd(startSevrverCmd);
165             qDebug()<<"start :"<< startSevrverCmd;
166         }else{
167             qDebug() <<"wpa_supplicant already start!";
168         }
169     };
170 
171     ///一秒后在启动服务,应为wifi网卡驱动可能没有安转好.
172     QTimer::singleShot(1000, this, [=](){
173         driveInstallFinish();
174         emit wpa_supplicantStartFinish();
175     });
176 }
177 
178 
setStart(bool bStart)179 void Wpaclicmd::setStart(bool bStart)
180 {
181     if(m_d->timer == Q_NULLPTR)
182     {
183         m_d->timer = new QTimer(this);
184         connect(m_d->timer, &QTimer::timeout, this, [=](){this->start();});
185     }
186 
187 
188     if(bStart)
189     {
190        m_d->timer->start(2000);
191        this->start();
192     }else{
193         m_d->timer->stop();
194         if(this->isRunning())
195         {
196             this->terminate();
197             this->wait();
198         }
199         m_d->scanResults.clear();
200         emit wifiScanResult(m_d->scanResults);
201     }
202 }
203 
connectWifi(const QString & ssid,const QString & psk)204 void Wpaclicmd::connectWifi(const QString &ssid, const QString &psk)
205 {
206     bool bOk;
207     m_d->network = addNetwork().trimmed();
208     m_d->network.toInt(&bOk);
209 //    qDebug()<<"addnetwork" << m_d->network <<"" << m_d->cardName;
210     if(bOk)
211     {
212         QString  result =setSSID(ssid);
213         if(!result.contains("OK"))
214         {
215             qDebug()<<"setssid: error";
216             return;
217         }
218 
219         result =  setPSK(psk);
220         if(!result.contains("OK"))
221         {
222              qDebug()<<"setPSK: error";
223             return;
224         }
225 
226         result =  selectNetwork(m_d->network);
227         if(!result.contains("OK"))
228         {
229             qDebug()<<"selectNetworks: error";
230             return;
231         }
232 
233 //        result =  saveConfig();
234 //        if(!result.contains("OK"))
235 //        {
236 //             qDebug()<<"saveConfig: error";
237 //            return;
238 //        }
239 
240         udhcpc(m_d->cardName);
241     }
242 }
243 
disconnectWifi()244 QString Wpaclicmd::disconnectWifi()
245 {
246     return execCmd(CMD_DISCONNECT_CONNECT);
247 }
248 
run()249 void Wpaclicmd::run()
250 {
251     QString scanInfo = this->scan();
252     if(scanInfo.contains("OK")){
253         QString scanInfo  = scanResults();
254         m_d->scanResults= m_d->pharseScanInfo(scanInfo);
255     }
256 
257     QString statusInfo = this->status();
258     QMap<QString, QString > info;
259     m_d->pharsStatusInfo(statusInfo, info);
260     emit wifiStatus(info);
261 
262     QString ssid = info.value("ssid");
263     QString wpa_state = info.value("wpa_state");
264     int connectIndex =-1;
265     for(int i=0; i<m_d->scanResults.size(); i++)
266     {
267         if(m_d->scanResults[i].ssid == ssid)
268         {
269             connectIndex = i;
270             m_d->scanResults[i].state =1;
271             if(wpa_state =="COMPLETED"){
272                 m_d->scanResults[i].state =2;
273             }
274             break;
275         }
276     }
277 
278     if(connectIndex >=0)
279     {
280         m_d->scanResults.swap(0, connectIndex);
281     }
282 
283     emit wifiScanResult(m_d->scanResults);
284 }
285 
scan()286 QString Wpaclicmd::scan()
287 {
288     return execCmd(CMD_SCAN);
289 }
290 
scanResults()291 QString Wpaclicmd::scanResults()
292 {
293     return  execCmd(CMD_SCAN_RESULTS);
294 }
295 
status()296 QString Wpaclicmd::status()
297 {
298     return execCmd(CMD_STATUS);
299 }
300 
addNetwork()301 QString Wpaclicmd::addNetwork()
302 {
303     return execCmd(CMD_ADD_NETWORK);
304 }
305 
removeNetWork()306 QString Wpaclicmd::removeNetWork()
307 {
308     return execCmd(CMD_REMOVE_NETORK);
309 }
310 
setSSID(const QString & ssid)311 QString Wpaclicmd::setSSID(const QString &ssid)
312 {
313     QString cmd= QString(CMD_SET_NETOWRK_SSID)
314             .arg(m_d->network)
315             .arg(ssid);
316     return execCmd(cmd);
317 }
318 
setPSK(const QString & psk)319 QString Wpaclicmd::setPSK(const QString &psk)
320 {
321     QString cmd = QString(CMD_SET_NETOWRK_PSK)
322             .arg(m_d->network)
323             .arg(psk);
324 
325     return execCmd(cmd);
326 }
327 
selectNetwork(const QString & network)328 QString Wpaclicmd::selectNetwork(const QString &network)
329 {
330     QString cmd = QString(CMD_SELECT_NETWORK)
331             .arg(network);
332     return execCmd(cmd);
333 }
334 
udhcpc(const QString & cardName)335 void Wpaclicmd::udhcpc(const QString &cardName)
336 {
337     static QString ucpcp = QString("udhcpc -i %1 -q &").arg(cardName);
338     Terminal::killProcess(ucpcp);
339     qDebug()<< ucpcp;
340     system(ucpcp.toLocal8Bit().constData());
341 }
342 
saveConfig()343 QString Wpaclicmd::saveConfig()
344 {
345     return execCmd(CMD_SAVE_CONFIG);
346 }
347 
execCmd(const QString & cmd)348 QString Wpaclicmd::execCmd(const QString &cmd)
349 {
350     return Terminal::execCmd(QString("wpa_cli %1 -i %2").arg(cmd).arg(m_d->cardName));
351 }
352