• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "utils/includes.h"
17 #include "pthread.h"
18 #include "common/wpa_ctrl.h"
19 #include "securec.h"
20 
21 
22 #define WPA_IFACE_NAME "wlan0"
23 #define WIFI_AUTH_FAILED_REASON_STR "WRONG_KEY"
24 #define WIFI_AUTH_FAILED_REASON_CODE "reason=2"
25 #define WPA_CTRL_REQUEST_OK "OK"
26 #define WPA_CTRL_REQUEST_FAIL "FAIL"
27 
28 #define SAMPLE_INFO(format, args...) \
29     do { \
30         fprintf(stderr, "\033[1;32m WpaCliSample(%s:%d):\t\033[0m" format, __func__, __LINE__, ##args); \
31         printf("\n"); \
32     } while (0)
33 
34 #define SAMPLE_ERROR(format, args...) \
35     do { \
36         fprintf(stderr, "\033[1;31m WpaCliSample(%s:%d):\t\033[0m" format, __func__, __LINE__, ##args); \
37         printf("\n"); \
38     } while (0)
39 
40 
41 static struct wpa_ctrl *g_monitorConn;
42 static struct wpa_ctrl *g_ctrlConn;
43 static pthread_t g_wpaThreadId;
44 static int g_scanAvailable = 0;
45 
DumpString(const char * buf,int len,const char * tag)46 static void DumpString(const char *buf, int len, const char *tag)
47 {
48     SAMPLE_INFO("%s dump start.", tag);
49     for (int i = 0; i < len; i++) {
50         printf("%c", buf[i]);
51     }
52     printf("\n");
53     SAMPLE_INFO("%s dump end.", tag);
54 }
55 
StrMatch(const char * a,const char * b)56 static int StrMatch(const char *a, const char *b)
57 {
58     return strncmp(a, b, strlen(b)) == 0;
59 }
60 
WifiEventHandler(char * rawEvent,int len)61 static void WifiEventHandler(char *rawEvent, int len)
62 {
63     char *pos = rawEvent;
64     if (*pos == '<') {
65         pos = strchr(pos, '>');
66         if (pos) {
67             pos++;
68         } else {
69             pos = rawEvent;
70         }
71     }
72     if (StrMatch(pos, WPA_EVENT_CONNECTED)) {
73         SAMPLE_INFO("WIFI_EVENT_CONNECTED");
74         return;
75     }
76     if (StrMatch(pos, WPA_EVENT_SCAN_RESULTS)) {
77         SAMPLE_INFO("WIFI_EVENT_SCAN_DONE");
78         g_scanAvailable = 1;
79         return;
80     }
81     if (StrMatch(pos, WPA_EVENT_TEMP_DISABLED) && strstr(pos, WIFI_AUTH_FAILED_REASON_STR)) {
82         SAMPLE_INFO("WIFI_EVENT_WRONG_KEY");
83         return;
84     }
85     if (StrMatch(pos, WPA_EVENT_DISCONNECTED) && !strstr(pos, WIFI_AUTH_FAILED_REASON_CODE)) {
86         SAMPLE_INFO("WIFI_EVENT_DISCONNECTED");
87         return;
88     }
89 }
90 
CliRecvPending(void)91 static void CliRecvPending(void)
92 {
93     while (wpa_ctrl_pending(g_monitorConn)) {
94         char buf[4096];
95         size_t len = sizeof(buf) - 1;
96         if (wpa_ctrl_recv(g_monitorConn, buf, &len) == 0) {
97             buf[len] = '\0';
98             SAMPLE_INFO("event received %s", buf);
99             WifiEventHandler(buf, len);
100         } else {
101             SAMPLE_INFO("could not read pending message.");
102             break;
103         }
104     }
105 }
106 
MonitorTask(void * args)107 static void* MonitorTask(void *args)
108 {
109     (void)args;
110     int fd, ret;
111     fd_set rfd;
112     while (1) {
113         fd = wpa_ctrl_get_fd(g_monitorConn);
114         FD_ZERO(&rfd);
115         FD_SET(fd, &rfd);
116         ret = select(fd + 1, &rfd, NULL, NULL, NULL);
117         if (ret <= 0) {
118             SAMPLE_INFO("select failed ret = %d\n", ret);
119             break;
120         }
121         CliRecvPending();
122         sleep(1);
123     }
124     return NULL;
125 }
126 
SendCtrlCommand(const char * cmd,char * reply,size_t * replyLen)127 static int SendCtrlCommand(const char *cmd, char *reply, size_t *replyLen)
128 {
129     size_t len = *replyLen - 1;
130     wpa_ctrl_request(g_ctrlConn, cmd, strlen(cmd), reply, &len, 0);
131     DumpString(reply, len, "SendCtrlCommand raw return");
132     if (len != 0 && !StrMatch(reply, WPA_CTRL_REQUEST_FAIL)) {
133         *replyLen = len;
134         return 0;
135     }
136     SAMPLE_ERROR("send ctrl request [%s] failed.", cmd);
137     return -1;
138 }
139 
TestNetworkConfig(void)140 static void TestNetworkConfig(void)
141 {
142     char networkId[20] = {0};
143     size_t networkIdLen = sizeof(networkId);
144     int ret = SendCtrlCommand("DISCONNECT", networkId, &networkIdLen);
145     ret += SendCtrlCommand("ADD_NETWORK", networkId, &networkIdLen);
146     if (ret != 0) {
147         SAMPLE_ERROR("add network failed.");
148         return;
149     }
150     SAMPLE_INFO("add network success, network id [%.*s]", networkIdLen, networkId);
151     char reply[100] = {0};
152     size_t replyLen = sizeof(reply);
153     char cmd[200] = {0};
154     sprintf_s(cmd, sizeof(cmd), "SET_NETWORK %.*s ssid \"example\"", networkIdLen, networkId);
155     ret += SendCtrlCommand(cmd, reply, &replyLen);
156     replyLen = sizeof(reply);
157     sprintf_s(cmd, sizeof(cmd), "SET_NETWORK %.*s psk \"012345678\"", networkIdLen, networkId);
158     ret += SendCtrlCommand(cmd, reply, &replyLen);
159     replyLen = sizeof(reply);
160     sprintf_s(cmd, sizeof(cmd), "ENABLE_NETWORK %.*s", networkIdLen, networkId);
161     ret += SendCtrlCommand(cmd, reply, &replyLen);
162     replyLen = sizeof(reply);
163     ret += SendCtrlCommand("RECONNECT", reply, &replyLen);
164     replyLen = sizeof(reply);
165     if (ret == 0) {
166         SAMPLE_INFO("network config success.");
167         return;
168     }
169     sprintf_s(cmd, sizeof(cmd), "REMOVE_NETWORK %.*s", networkIdLen, networkId);
170     SendCtrlCommand(cmd, reply, &replyLen);
171     SAMPLE_ERROR("network config failed remove network [%.*s].", networkIdLen, networkId);
172 }
173 
TestCliConnection(void)174 static void TestCliConnection(void)
175 {
176     char reply[100] = {0};
177     size_t replyLen = sizeof(reply);
178     int ret = SendCtrlCommand("PING", reply, &replyLen);
179     if (ret == 0 && StrMatch(reply, "PONG")) {
180         SAMPLE_INFO("connect to wpa success.");
181         return;
182     }
183     SAMPLE_INFO("connect to wpa failed, err = %s.", reply);
184 }
185 
TestScan()186 static void TestScan()
187 {
188     char reply[100] = {0};
189     size_t replyLen = sizeof(reply);
190     g_scanAvailable = 0;
191     SendCtrlCommand("SCAN", reply, &replyLen);
192     while (1) {
193         sleep(1);
194         if (g_scanAvailable == 1) {
195             SAMPLE_INFO("scan result received.");
196             break;
197         }
198         SAMPLE_INFO("waiting scan result.");
199     }
200     char scanResult[4096] = {0};
201     size_t scanLen = sizeof(scanResult);
202     int ret = SendCtrlCommand("SCAN_RESULTS", scanResult, &scanLen);
203     if (ret != 0) {
204         SAMPLE_ERROR("request scan results failed.");
205         return;
206     }
207     DumpString(scanResult, scanLen, "scan results");
208 }
209 
StartTest()210 static void StartTest()
211 {
212     TestCliConnection(); // test if wpa control interface connected successfully
213     TestScan(); // test scan and get scan results
214     TestNetworkConfig(); // test config network and connect
215 }
216 
InitControlInterface()217 int InitControlInterface()
218 {
219     g_ctrlConn = wpa_ctrl_open(WPA_IFACE_NAME); // create control interface for send cmd
220     g_monitorConn = wpa_ctrl_open(WPA_IFACE_NAME); // create control interface for event monitor
221     if (!g_ctrlConn || !g_monitorConn) {
222         SAMPLE_ERROR("open wpa control interface failed.");
223         return -1;
224     }
225     if (wpa_ctrl_attach(g_monitorConn) == 0) { // start monitor
226         pthread_create(&g_wpaThreadId, NULL, MonitorTask, NULL); // create thread for read event
227         return 0;
228     }
229     return -1;
230 }
231 
main()232 int main()
233 {
234     if (InitControlInterface() != 0) {
235         SAMPLE_ERROR("control interface init failed, exit client.");
236         return -1;
237     }
238     SAMPLE_INFO("control interface init success.");
239     StartTest();
240     pthread_join(g_wpaThreadId, NULL);
241     SAMPLE_INFO("test finished, exit client.");
242 }
243