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