1 /*
2 * Copyright (C) 2024 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 "hdi_wpa_common.h"
17 #include <hdf_log.h>
18 #include <string.h>
19 #include "common/wpa_ctrl.h"
20 #include "hdi_wpa_hal.h"
21 #include "wpa_common_cmd.h"
22
23 #undef LOG_TAG
24 #define LOG_TAG "HdiHalWpaCommon"
25
26 #define HEX_TO_DEC_MOVING 4
27 #define DEC_MAX_SCOPE 10
28 #define WPA_CMD_RETURN_TIMEOUT (-2)
29
Hex2Dec(const char * str)30 int Hex2Dec(const char *str)
31 {
32 if (str == NULL || strncasecmp(str, "0x", strlen("0x")) != 0) {
33 return 0;
34 }
35 int result = 0;
36 const char *tmp = str + strlen("0x");
37 while (*tmp != '\0') {
38 result <<= HEX_TO_DEC_MOVING;
39 if (*tmp >= '0' && *tmp <= '9') {
40 result += *tmp - '0';
41 } else if (*tmp >= 'A' && *tmp <= 'F') {
42 result += *tmp - 'A' + DEC_MAX_SCOPE;
43 } else if (*tmp >= 'a' && *tmp <= 'f') {
44 result += *tmp - 'a' + DEC_MAX_SCOPE;
45 } else {
46 result = 0;
47 break;
48 }
49 ++tmp;
50 }
51 return result;
52 }
53
TrimQuotationMark(char * str,char c)54 void TrimQuotationMark(char *str, char c)
55 {
56 if (str == NULL) {
57 return;
58 }
59 int len = strlen(str);
60 if (len == 0) {
61 return;
62 }
63 if (str[len - 1] == c) {
64 str[len - 1] = '\0';
65 --len;
66 }
67 if (str[0] == c) {
68 for (int i = 0; i < len - 1; ++i) {
69 str[i] = str[i + 1];
70 }
71 str[len - 1] = '\0';
72 }
73 return;
74 }
75
ReleaseWpaCtrl(WpaCtrl * pCtrl)76 void ReleaseWpaCtrl(WpaCtrl *pCtrl)
77 {
78 if (pCtrl == NULL) {
79 return;
80 }
81 if (pCtrl->pSend != NULL) {
82 wpa_ctrl_close(pCtrl->pSend);
83 pCtrl->pSend = NULL;
84 }
85 if (pCtrl->pRecv != NULL) {
86 wpa_ctrl_close(pCtrl->pRecv);
87 pCtrl->pRecv = NULL;
88 }
89 return;
90 }
91
InitWpaCtrl(WpaCtrl * pCtrl,const char * ifname)92 int InitWpaCtrl(WpaCtrl *pCtrl, const char *ifname)
93 {
94 if (pCtrl == NULL || ifname == NULL) {
95 return -1;
96 }
97 int flag = 0;
98 do {
99 pCtrl->pSend = wpa_ctrl_open(ifname);
100 if (pCtrl->pSend == NULL) {
101 HDF_LOGE("open wpa control send interface failed!");
102 break;
103 }
104 flag += 1;
105 } while (0);
106 if (!flag) {
107 ReleaseWpaCtrl(pCtrl);
108 return -1;
109 }
110 return 0;
111 }
112
StaCliCmd(WpaCtrl * ctrl,const char * cmd,char * buf,size_t bufLen)113 static int StaCliCmd(WpaCtrl *ctrl, const char *cmd, char *buf, size_t bufLen)
114 {
115 HDF_LOGI("enter StaCliCmd");
116 if (ctrl == NULL || ctrl->pSend == NULL || cmd == NULL || buf == NULL || bufLen == 0) {
117 HDF_LOGE("StaCliCmd, invalid parameters!");
118 return -1;
119 }
120 size_t len = bufLen - 1;
121 HDF_LOGD("wpa_ctrl_request -> cmd: %{private}s", cmd);
122 int ret = wpa_ctrl_request(ctrl->pSend, cmd, strlen(cmd), buf, &len, NULL);
123 if (ret == WPA_CMD_RETURN_TIMEOUT) {
124 HDF_LOGE("[%{private}s] command timed out.", cmd);
125 return WPA_CMD_RETURN_TIMEOUT;
126 } else if (ret < 0) {
127 HDF_LOGE("[%{private}s] command failed.", cmd);
128 return -1;
129 }
130 buf[len] = '\0';
131 HDF_LOGD("wpa_ctrl_request -> buf: %{private}s", buf);
132 if (strncmp(buf, "FAIL\n", strlen("FAIL\n")) == 0 ||
133 strncmp(buf, "UNKNOWN COMMAND\n", strlen("UNKNOWN COMMAND\n")) == 0) {
134 HDF_LOGE("%{private}s request success, but response %{public}s", cmd, buf);
135 return -1;
136 }
137 return 0;
138 }
139
P2pCliCmd(WpaCtrl * ctrl,const char * cmd,char * buf,size_t bufLen)140 static int P2pCliCmd(WpaCtrl *ctrl, const char *cmd, char *buf, size_t bufLen)
141 {
142 HDF_LOGI("enter P2pCliCmd");
143 if (ctrl == NULL || ctrl->pSend == NULL || cmd == NULL || buf == NULL || bufLen == 0) {
144 HDF_LOGE("P2pCliCmd, invalid parameters!");
145 return -1;
146 }
147 size_t len = bufLen - 1;
148 HDF_LOGD("wpa_ctrl_request -> cmd: %{private}s", cmd);
149 int ret = wpa_ctrl_request(ctrl->pSend, cmd, strlen(cmd), buf, &len, NULL);
150 if (ret == WPA_CMD_RETURN_TIMEOUT) {
151 HDF_LOGE("[%{private}s] command timed out.", cmd);
152 return WPA_CMD_RETURN_TIMEOUT;
153 } else if (ret < 0) {
154 HDF_LOGE("[%{private}s] command failed.", cmd);
155 return -1;
156 }
157 buf[len] = '\0';
158 HDF_LOGD("wpa_ctrl_request -> buf: %{private}s", buf);
159 if (strncmp(buf, "FAIL\n", strlen("FAIL\n")) == 0 ||
160 strncmp(buf, "UNKNOWN COMMAND\n", strlen("UNKNOWN COMMAND\n")) == 0) {
161 HDF_LOGE("%{private}s request success, but response %{public}s", cmd, buf);
162 return -1;
163 }
164 return 0;
165 }
166
ChbaCliCmd(WpaCtrl * ctrl,const char * cmd,char * buf,size_t bufLen)167 static int ChbaCliCmd(WpaCtrl *ctrl, const char *cmd, char *buf, size_t bufLen)
168 {
169 HDF_LOGI("enter ChbaCliCmd");
170 if (ctrl == NULL || ctrl->pSend == NULL || cmd == NULL || buf == NULL || bufLen == 0) {
171 HDF_LOGE("ChbaCliCmd, invalid parameters!");
172 return -1;
173 }
174 size_t len = bufLen - 1;
175 HDF_LOGD("wpa_ctrl_request -> cmd: %{private}s", cmd);
176 int ret = wpa_ctrl_request(ctrl->pSend, cmd, strlen(cmd), buf, &len, NULL);
177 if (ret == WPA_CMD_RETURN_TIMEOUT) {
178 HDF_LOGE("[%{private}s] command timed out.", cmd);
179 return WPA_CMD_RETURN_TIMEOUT;
180 } else if (ret < 0) {
181 HDF_LOGE("[%{private}s] command failed.", cmd);
182 return -1;
183 }
184 buf[len] = '\0';
185 HDF_LOGD("wpa_ctrl_request -> buf: %{private}s", buf);
186 if (strncmp(buf, "FAIL\n", strlen("FAIL\n")) == 0 ||
187 strncmp(buf, "UNKNOWN COMMAND\n", strlen("UNKNOWN COMMAND\n")) == 0) {
188 HDF_LOGE("%{private}s request success, but response %{public}s", cmd, buf);
189 return -1;
190 }
191 return 0;
192 }
193
CommonCliCmd(WpaCtrl * ctrl,const char * cmd,char * buf,size_t bufLen)194 static int CommonCliCmd(WpaCtrl *ctrl, const char *cmd, char *buf, size_t bufLen)
195 {
196 HDF_LOGI("enter CommonCliCmd");
197 if (ctrl == NULL || ctrl->pSend == NULL || cmd == NULL || buf == NULL || bufLen == 0) {
198 HDF_LOGE("CommonCliCmd, invalid parameters!");
199 return -1;
200 }
201 size_t len = bufLen - 1;
202 HDF_LOGD("wpa_ctrl_request -> cmd: %{private}s", cmd);
203 int ret = wpa_ctrl_request(ctrl->pSend, cmd, strlen(cmd), buf, &len, NULL);
204 if (ret == WPA_CMD_RETURN_TIMEOUT) {
205 HDF_LOGE("[%{private}s] command timed out.", cmd);
206 return WPA_CMD_RETURN_TIMEOUT;
207 } else if (ret < 0) {
208 HDF_LOGE("[%{private}s] command failed.", cmd);
209 return -1;
210 }
211 buf[len] = '\0';
212 HDF_LOGD("wpa_ctrl_request -> buf: %{private}s", buf);
213 if (strncmp(buf, "FAIL\n", strlen("FAIL\n")) == 0 ||
214 strncmp(buf, "UNKNOWN COMMAND\n", strlen("UNKNOWN COMMAND\n")) == 0) {
215 HDF_LOGE("%{private}s request success, but response %{public}s", cmd, buf);
216 return -1;
217 }
218 return 0;
219 }
220
221
WpaCliCmd(const char * cmd,char * buf,size_t bufLen)222 int WpaCliCmd(const char *cmd, char *buf, size_t bufLen)
223 {
224 int ret = -1;
225 HDF_LOGI("enter WpaCliCmd");
226 if (cmd == NULL || buf == NULL || bufLen == 0) {
227 HDF_LOGE("WpaCliCmd, invalid parameters!");
228 return ret;
229 }
230 char *ifName = NULL;
231 if (strncmp(cmd, "IFNAME=", strlen("IFNAME=")) == 0) {
232 ifName = (char *)cmd + strlen("IFNAME=");
233 } else if (strncmp(cmd, "INTERFACE_ADD ", strlen("INTERFACE_ADD ")) == 0) {
234 ifName = (char *)cmd + strlen("INTERFACE_ADD ");
235 } else if (strncmp(cmd, "INTERFACE_REMOVE ", strlen("INTERFACE_REMOVE ")) == 0) {
236 ifName = (char *)cmd + strlen("INTERFACE_REMOVE ");
237 } else {
238 ifName = "common";
239 }
240
241 if (strncmp(ifName, "wlan", strlen("wlan")) == 0) {
242 ret = StaCliCmd(GetStaCtrl(), cmd, buf, bufLen);
243 } else if (strncmp(ifName, "p2p", strlen("p2p")) == 0) {
244 ret = P2pCliCmd(GetP2pCtrl(), cmd, buf, bufLen);
245 } else if (strncmp(ifName, "chba", strlen("chba")) == 0) {
246 ret = ChbaCliCmd(GetChbaCtrl(), cmd, buf, bufLen);
247 } else if (strncmp(ifName, "common", strlen("common")) == 0) {
248 ret = CommonCliCmd(GetCommonCtrl(), cmd, buf, bufLen);
249 } else {
250 HDF_LOGE("WpaCliCmd, ifName is unknow!");
251 }
252 if (ret == 0 && ifName != NULL &&
253 strncmp(cmd, "INTERFACE_REMOVE ", strlen("INTERFACE_REMOVE ")) == 0) {
254 int nameLen = strlen(ifName);
255 ReleaseIfaceCtrl(ifName, nameLen);
256 }
257 if (strncmp(cmd, "TERMINATE", strlen("TERMINATE")) == 0) {
258 ReleaseWpaGlobalInterface();
259 HDF_LOGI("%{public}s: call ReleaseWpaGlobalInterface finish", __func__);
260 }
261 return ret;
262 }
263
IsSockRemoved(const char * ifName,int len)264 int IsSockRemoved(const char *ifName, int len)
265 {
266 int ret = -1;
267 if (len < IFNAME_LEN_MIN || len > IFNAME_LEN_MAX) {
268 HDF_LOGE("ifname is invalid");
269 return ret;
270 }
271 if (strncmp(ifName, "wlan", strlen("wlan")) == 0) {
272 if (GetStaCtrl() == NULL) {
273 ret = 0;
274 }
275 } else if (strncmp(ifName, "p2p", strlen("p2p")) == 0) {
276 if (GetP2pCtrl() == NULL) {
277 ret = 0;
278 }
279 } else if (strncmp(ifName, "chba", strlen("chba")) == 0) {
280 if (GetChbaCtrl() == NULL) {
281 ret = 0;
282 }
283 }
284 return ret;
285 }
286