1 /*
2 * Copyright (C) 2021 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 #include <stdlib.h>
16 #include <string.h>
17 #include <stddef.h>
18 #include <stdio.h>
19 #include <unistd.h>
20 #include <fcntl.h>
21 #include "mock_wpa_ctrl.h"
22 #include "wifi_hal_common_func.h"
23
24 static std::vector<int> gPipeFd;
25 static int gUsePipeFdNum = 0;
26 const int OncePipeFdNum = 2;
27 const int MaxExactCmdLength = 32;
28
29 static std::map<std::string, std::string> gSupportedCmd;
30
MockSetWpaExpectCmdResponse(const std::string & cmd,const std::string & response)31 void MockSetWpaExpectCmdResponse(const std::string &cmd, const std::string &response)
32 {
33 gSupportedCmd[cmd] = response;
34 }
35
MockEraseSupportedCmd(const std::string & cmd)36 void MockEraseSupportedCmd(const std::string &cmd)
37 {
38 gSupportedCmd.erase(cmd);
39 }
40
MockInitGlobalCmd(void)41 void MockInitGlobalCmd(void)
42 {
43 gSupportedCmd["INTERFACE_ADD"] = "OK";
44 gSupportedCmd["INTERFACE_REMOVE"] = "OK";
45 }
46
MockInitStaSupportedCmd(void)47 void MockInitStaSupportedCmd(void)
48 {
49 gSupportedCmd["STATUS"] = "OK";
50 gSupportedCmd["ADD_NETWORK"] = "OK";
51 gSupportedCmd["RECONNECT"] = "OK";
52 gSupportedCmd["REASSOCIATE"] = "OK";
53 gSupportedCmd["DISCONNECT"] = "OK";
54 gSupportedCmd["SAVE_CONFIG"] = "OK";
55 gSupportedCmd["SET_NETWORK"] = "OK";
56 gSupportedCmd["ENABLE_NETWORK"] = "OK";
57 gSupportedCmd["SELECT_NETWORK"] = "OK";
58 gSupportedCmd["DISABLE_NETWORK"] = "OK";
59 gSupportedCmd["REMOVE_NETWORK"] = "OK";
60 gSupportedCmd["GET_NETWORK"] = "OK";
61 gSupportedCmd["WPS_PBC"] = "OK";
62 gSupportedCmd["WPS_PIN"] = "OK";
63 gSupportedCmd["WPS_CANCEL"] = "OK";
64 gSupportedCmd["SET"] = "OK";
65 gSupportedCmd["GET"] = "OK";
66 gSupportedCmd["STA_AUTOCONNECT"] = "OK";
67 gSupportedCmd["RECONFIGURE"] = "OK";
68 gSupportedCmd["LIST_NETWORKS"] = "OK";
69 gSupportedCmd["SIGNAL_POLL"] = "OK";
70 return;
71 }
72
MockInitApSupportedCmd(void)73 void MockInitApSupportedCmd(void)
74 {
75 gSupportedCmd["ENABLE"] = "OK";
76 gSupportedCmd["SET"] = "OK";
77 gSupportedCmd["STATUS"] = "OK";
78 gSupportedCmd["DISABLE"] = "OK";
79 gSupportedCmd["DENY_ACL"] = "OK";
80 gSupportedCmd["STA-FIRST"] = "OK";
81 gSupportedCmd["STA-NEXT"] = "OK";
82 gSupportedCmd["RELOAD"] = "OK";
83 gSupportedCmd["DEAUTHENTICATE"] = "OK";
84 gSupportedCmd["DISASSOCIATE"] = "OK";
85 return;
86 }
87
MockInitP2pSupportedCmd(void)88 void MockInitP2pSupportedCmd(void)
89 {
90 gSupportedCmd["P2P_STOP_FIND"] = "OK";
91 gSupportedCmd["P2P_FIND"] = "OK";
92 gSupportedCmd["SET"] = "OK";
93 gSupportedCmd["STATUS"] = "OK";
94 gSupportedCmd["P2P_FLUSH"] = "OK";
95 gSupportedCmd["P2P_SERVICE_FLUSH"] = "OK";
96 gSupportedCmd["P2P_PROV_DISC"] = "OK";
97 gSupportedCmd["P2P_GROUP_ADD"] = "OK";
98 gSupportedCmd["SAVE_CONFIG"] = "OK";
99 gSupportedCmd["LIST_NETWORKS"] = "OK";
100 gSupportedCmd["P2P_PEER"] = "OK\n";
101 gSupportedCmd["P2P_SERV_DISC_RESP"] = "OK";
102 gSupportedCmd["P2P_SERV_DISC_EXTERNAL"] = "OK";
103 gSupportedCmd["DRIVER"] = "OK";
104 gSupportedCmd["P2P_SERV_DISC_CANCEL_REQ"] = "OK";
105 gSupportedCmd["P2P_SERV_DISC_REQ"] = "OK";
106 gSupportedCmd["P2P_SERVICE_ADD"] = "OK";
107 gSupportedCmd["P2P_SERVICE_DEL"] = "OK";
108 gSupportedCmd["P2P_INVITE"] = "OK";
109 gSupportedCmd["P2P_CANCEL"] = "OK";
110 gSupportedCmd["P2P_SET"] = "OK";
111 gSupportedCmd["P2P_EXT_LISTEN"] = "OK";
112 gSupportedCmd["WFD_SUBELEM_SET"] = "OK";
113 gSupportedCmd["REMOVE_NETWORK"] = "OK";
114 gSupportedCmd["P2P_GROUP_REMOVE"] = "OK";
115 gSupportedCmd["WPS_PBC"] = "OK";
116 gSupportedCmd["WPS_PIN"] = "OK";
117 gSupportedCmd["P2P_CONNECT"] = "OK";
118 return;
119 }
120
MockWpaCallback(struct wpa_ctrl * send,const char * message)121 void MockWpaCallback(struct wpa_ctrl *send, const char *message)
122 {
123 if (send == NULL || message == NULL) {
124 return;
125 }
126 write(send->s, message, strlen(message));
127 return;
128 }
129
SetNonBlock(int fd)130 static void SetNonBlock(int fd)
131 {
132 int flags = fcntl(fd, F_GETFL, 0);
133 if (flags < 0) {
134 return;
135 }
136 flags |= O_NONBLOCK;
137 fcntl(fd, F_SETFL, flags);
138 return;
139 }
140
wpa_ctrl_open(const char * ctrl_path)141 struct wpa_ctrl *wpa_ctrl_open(const char *ctrl_path)
142 {
143 (void)ctrl_path;
144 struct wpa_ctrl *ctrl = (struct wpa_ctrl *)calloc(1, sizeof(struct wpa_ctrl));
145 if (ctrl == NULL) {
146 return NULL;
147 }
148 if (gUsePipeFdNum % OncePipeFdNum == 0) {
149 int pipeFd[OncePipeFdNum] = {0};
150 pipe(pipeFd);
151 SetNonBlock(pipeFd[0]);
152 gPipeFd.push_back(pipeFd[0]);
153 gPipeFd.push_back(pipeFd[1]);
154 }
155 if (gUsePipeFdNum % OncePipeFdNum == 0) {
156 ctrl->s = gPipeFd[gUsePipeFdNum + 1];
157 } else {
158 ctrl->s = gPipeFd[gUsePipeFdNum - 1];
159 }
160 ++gUsePipeFdNum;
161 return ctrl;
162 }
163
wpa_ctrl_open2(const char * ctrl_path,const char * cli_path)164 struct wpa_ctrl * wpa_ctrl_open2(const char *ctrl_path, const char *cli_path)
165 {
166 (void)cli_path;
167 return wpa_ctrl_open(ctrl_path);
168 }
169
wpa_ctrl_close(struct wpa_ctrl * ctrl)170 void wpa_ctrl_close(struct wpa_ctrl *ctrl)
171 {
172 if (ctrl == NULL) {
173 return;
174 }
175 close(ctrl->s);
176 for (auto iter = gPipeFd.begin(); iter != gPipeFd.end(); ++iter) {
177 if (*iter == ctrl->s) {
178 gPipeFd.erase(iter);
179 break;
180 }
181 }
182 --gUsePipeFdNum;
183 free(ctrl);
184 return;
185 }
186
GetExactCmd(const char * cmd,char * out,int out_len)187 static void GetExactCmd(const char *cmd, char *out, int out_len)
188 {
189 if (cmd == NULL || out == NULL) {
190 return;
191 }
192 int i = 0;
193 int j = 0;
194 if (strncmp(cmd, "IFNAME=", strlen("IFNAME=")) == 0) {
195 const char *p = strchr(cmd, ' ');
196 if (p == NULL) {
197 return;
198 }
199 j = p - cmd + 1;
200 }
201 while (i < out_len - 1 && cmd[i + j] != '\0' && cmd[i + j] != ' ') {
202 out[i] = cmd[i + j];
203 ++i;
204 }
205 out[i] = '\0';
206 return;
207 }
208
CheckInputCmdArgs(const char * cmd)209 static int CheckInputCmdArgs(const char *cmd)
210 {
211 (void)cmd;
212 return 0;
213 }
214
wpa_ctrl_request(struct wpa_ctrl * ctrl,const char * cmd,size_t cmd_len,char * reply,size_t * reply_len,void (* msg_cb)(char * msg,size_t len))215 int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len, char *reply, size_t *reply_len,
216 void (*msg_cb)(char *msg, size_t len))
217 {
218 if (ctrl == NULL || cmd == NULL || reply == NULL || reply_len == NULL) {
219 return -1;
220 }
221 (void)cmd_len;
222 (void)msg_cb;
223 char exactCmd[MaxExactCmdLength] = {0};
224 GetExactCmd(cmd, exactCmd, MaxExactCmdLength);
225 std::map<std::string, std::string>::iterator iter = gSupportedCmd.find(std::string(exactCmd));
226 if (iter == gSupportedCmd.end()) {
227 StrSafeCopy(reply, *reply_len, "UNKNOWN COMMAND\n");
228 *reply_len = strlen(reply);
229 return -1;
230 }
231 if (CheckInputCmdArgs(cmd) < 0) {
232 StrSafeCopy(reply, *reply_len, "FAIL\n");
233 } else {
234 StrSafeCopy(reply, *reply_len, iter->second.c_str());
235 }
236 *reply_len = strlen(reply);
237 return 0;
238 }
239
wpa_ctrl_attach(struct wpa_ctrl * ctrl)240 int wpa_ctrl_attach(struct wpa_ctrl *ctrl)
241 {
242 (void)ctrl;
243 return 0;
244 }
245
wpa_ctrl_detach(struct wpa_ctrl * ctrl)246 int wpa_ctrl_detach(struct wpa_ctrl *ctrl)
247 {
248 (void)ctrl;
249 return 0;
250 }
251
wpa_ctrl_recv(struct wpa_ctrl * ctrl,char * reply,size_t * reply_len)252 int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len)
253 {
254 size_t pos = 0;
255 while (pos < *reply_len) {
256 int ret = read(ctrl->s, reply + pos, 1);
257 if (ret <= 0) {
258 break;
259 }
260 if (reply[pos] == '\n') {
261 break;
262 }
263 ++pos;
264 }
265 *reply_len = pos;
266 reply[pos] = '\0';
267 return 0;
268 }
269
wpa_ctrl_pending(struct wpa_ctrl * ctrl)270 int wpa_ctrl_pending(struct wpa_ctrl *ctrl)
271 {
272 (void)ctrl;
273 return 0;
274 }
275
wpa_ctrl_get_fd(struct wpa_ctrl * ctrl)276 int wpa_ctrl_get_fd(struct wpa_ctrl *ctrl)
277 {
278 if (ctrl != NULL) {
279 return ctrl->s;
280 }
281 return -1;
282 }