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 "wifi_wpa_common.h"
16 #include <string.h>
17 #include "wifi_wpa_hal.h"
18 #include "wifi_hal_common_func.h"
19 #include "wifi_common_hal.h"
20
21 #ifndef __UT__
22 #include "wifi_log.h"
23 #endif
24
25 #ifdef __UT__
26 #define static
27 #define LOGI(...) ;
28 #define LOGD(...) ;
29 #define LOGE(...) ;
30 #endif
31
32 #undef LOG_TAG
33 #define LOG_TAG "WifiHalWpaCommon"
34
35 #define HEX_TO_DEC_MOVING 4
36 #define DEC_MAX_SCOPE 10
37 #define WPA_CMD_RETURN_TIMEOUT (-2)
38 #define POS_SECOND 2
39 #define POS_FOURTH 4
40 #define POS_EIGHT 8
41 #define POS_TEN 10
42
GetStrKeyVal(char * src,const char * split,WpaKeyValue * out)43 void GetStrKeyVal(char *src, const char *split, WpaKeyValue *out)
44 {
45 if (src == NULL || split == NULL || out == NULL) {
46 return;
47 }
48 char *p = strstr(src, split);
49 if (p == NULL) {
50 StrSafeCopy(out->key, sizeof(out->key), src);
51 return;
52 }
53 *p = '\0';
54 StrSafeCopy(out->key, sizeof(out->key), src);
55 p += strlen(split);
56 StrSafeCopy(out->value, sizeof(out->value), p);
57 return;
58 }
59
Hex2Dec(const char * str)60 int Hex2Dec(const char *str)
61 {
62 if (str == NULL || strncasecmp(str, "0x", strlen("0x")) != 0) {
63 return 0;
64 }
65 int result = 0;
66 const char *tmp = str + strlen("0x");
67 while (*tmp != '\0') {
68 result <<= HEX_TO_DEC_MOVING;
69 if (*tmp >= '0' && *tmp <= '9') {
70 result += *tmp - '0';
71 } else if (*tmp >= 'A' && *tmp <= 'F') {
72 result += *tmp - 'A' + DEC_MAX_SCOPE;
73 } else if (*tmp >= 'a' && *tmp <= 'f') {
74 result += *tmp - 'a' + DEC_MAX_SCOPE;
75 } else {
76 result = 0;
77 break;
78 }
79 ++tmp;
80 }
81 return result;
82 }
83
TrimQuotationMark(char * str,char c)84 void TrimQuotationMark(char *str, char c)
85 {
86 if (str == NULL) {
87 return;
88 }
89 int len = strlen(str);
90 if (len == 0) {
91 return;
92 }
93 if (str[len - 1] == c) {
94 str[len - 1] = '\0';
95 --len;
96 }
97 if (str[0] == c) {
98 for (int i = 0; i < len - 1; ++i) {
99 str[i] = str[i + 1];
100 }
101 str[len - 1] = '\0';
102 }
103 return;
104 }
105
ReleaseWpaCtrl(WpaCtrl * pCtrl)106 void ReleaseWpaCtrl(WpaCtrl *pCtrl)
107 {
108 if (pCtrl == NULL) {
109 return;
110 }
111 if (pCtrl->pSend != NULL) {
112 wpa_ctrl_close(pCtrl->pSend);
113 pCtrl->pSend = NULL;
114 }
115 if (pCtrl->pRecv != NULL) {
116 wpa_ctrl_close(pCtrl->pRecv);
117 pCtrl->pRecv = NULL;
118 }
119 return;
120 }
121
InitWpaCtrl(WpaCtrl * pCtrl,const char * ifname)122 int InitWpaCtrl(WpaCtrl *pCtrl, const char *ifname)
123 {
124 if (pCtrl == NULL || ifname == NULL) {
125 return -1;
126 }
127 int flag = 0;
128 do {
129 #ifdef WPA_CTRL_IFACE_UNIX
130 pCtrl->pRecv = wpa_ctrl_open(ifname);
131 #else
132 pCtrl->pRecv = wpa_ctrl_open("global");
133 #endif
134 if (pCtrl->pRecv == NULL) {
135 LOGE("open wpa control recv interface failed!");
136 break;
137 }
138 if (wpa_ctrl_attach(pCtrl->pRecv) != 0) {
139 LOGE("attach monitor interface failed!");
140 break;
141 }
142 #ifdef WPA_CTRL_IFACE_UNIX
143 pCtrl->pSend = wpa_ctrl_open(ifname);
144 #else
145 pCtrl->pSend = wpa_ctrl_open("global");
146 #endif
147 if (pCtrl->pSend == NULL) {
148 LOGE("open wpa control send interface failed!");
149 break;
150 }
151 flag += 1;
152 } while (0);
153 if (!flag) {
154 ReleaseWpaCtrl(pCtrl);
155 return -1;
156 }
157 return 0;
158 }
159
WpaCliCmd(const char * cmd,char * buf,size_t bufLen)160 int WpaCliCmd(const char *cmd, char *buf, size_t bufLen)
161 {
162 if (cmd == NULL || buf == NULL || bufLen <= 0) {
163 return -1;
164 }
165 WpaCtrl *ctrl = GetWpaCtrl();
166 if (ctrl == NULL || ctrl->pSend == NULL) {
167 return -1;
168 }
169 size_t len = bufLen - 1;
170 LOGD("wpa_ctrl_request -> cmd: %{private}s", cmd);
171 int ret = wpa_ctrl_request(ctrl->pSend, cmd, strlen(cmd), buf, &len, NULL);
172 if (ret == WPA_CMD_RETURN_TIMEOUT) {
173 LOGE("[%{private}s] command timed out.", cmd);
174 return WPA_CMD_RETURN_TIMEOUT;
175 } else if (ret < 0) {
176 LOGE("[%{private}s] command failed.", cmd);
177 return -1;
178 }
179 buf[len] = '\0';
180 LOGD("wpa_ctrl_request -> buf: %{private}s", buf);
181 if (strncmp(buf, "FAIL\n", strlen("FAIL\n")) == 0 ||
182 strncmp(buf, "UNKNOWN COMMAND\n", strlen("UNKNOWN COMMAND\n")) == 0) {
183 LOGE("%{private}s request success, but response %{public}s", cmd, buf);
184 return -1;
185 }
186 return 0;
187 }
188
Hex2num(char c)189 static int Hex2num(char c)
190 {
191 if (c >= '0' && c <= '9') {
192 return c - '0';
193 }
194 if (c >= 'a' && c <= 'f') {
195 return c - 'a' + POS_TEN;
196 }
197 if (c >= 'A' && c <= 'F') {
198 return c - 'A' + POS_TEN;
199 }
200 return -1;
201 }
202
Hex2byte(const char * hex)203 static int Hex2byte(const char *hex)
204 {
205 int a = Hex2num(*hex++);
206 if (a < 0) {
207 return -1;
208 }
209 int b = Hex2num(*hex++);
210 if (b < 0) {
211 return -1;
212 }
213 return (a << POS_FOURTH) | b;
214 }
215
DealDigital(u8 * buf,const char ** pos,size_t * len)216 static void DealDigital(u8 *buf, const char **pos, size_t *len)
217 {
218 int val;
219 switch (**pos) {
220 case '0':
221 case '1':
222 case '2':
223 case '3':
224 case '4':
225 case '5':
226 case '6':
227 case '7':
228 val = **pos++ - '0';
229 if (**pos >= '0' && **pos <= '7') {
230 val = val * POS_EIGHT + (**pos++ - '0');
231 }
232 if (**pos >= '0' && **pos <= '7') {
233 val = val * POS_EIGHT + (**pos++ - '0');
234 }
235 buf[(*len)++] = val;
236 return;
237 default:
238 return;
239 }
240 }
241
DealSymbol(u8 * buf,const char ** pos,size_t * len)242 static void DealSymbol(u8 *buf, const char **pos, size_t *len)
243 {
244 int val;
245 switch (**pos) {
246 case '\\':
247 buf[(*len)++] = '\\';
248 (*pos)++;
249 return;
250 case '"':
251 buf[(*len)++] = '"';
252 (*pos)++;
253 return;
254 case 'n':
255 buf[(*len)++] = '\n';
256 (*pos)++;
257 return;
258 case 'r':
259 buf[(*len)++] = '\r';
260 (*pos)++;
261 return;
262 case 't':
263 buf[(*len)++] = '\t';
264 (*pos)++;
265 return;
266 case 'e':
267 buf[(*len)++] = '\033';
268 (*pos)++;
269 return;
270 case 'x':
271 (*pos)++;
272 val = Hex2byte(*pos);
273 if (val < 0) {
274 val = Hex2num(**pos);
275 if (val < 0) {
276 return;
277 }
278 buf[(*len)++] = val;
279 (*pos)++;
280 } else {
281 buf[(*len)++] = val;
282 (*pos) += POS_SECOND;
283 }
284 return;
285 default:
286 DealDigital(buf, pos, len);
287 return;
288 }
289 }
290
PrintfDecode(u8 * buf,size_t maxlen,const char * str)291 size_t PrintfDecode(u8 *buf, size_t maxlen, const char *str)
292 {
293 const char *pos = str;
294 size_t len = 0;
295
296 while (*pos) {
297 if (len + 1 >= maxlen) {
298 break;
299 }
300 switch (*pos) {
301 case '\\':
302 pos++;
303 DealSymbol(buf, &pos, &len);
304 break;
305 default:
306 buf[len++] = *pos++;
307 break;
308 }
309 }
310 if (maxlen > len) {
311 buf[len] = '\0';
312 }
313 return len;
314 }
315