• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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