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