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