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 <poll.h>
17 #include <unistd.h>
18 #include <hdf_log.h>
19 #include <pthread.h>
20 #include "securec.h"
21 #include "hdi_wpa_hal.h"
22 #include "hdi_wpa_common.h"
23 #include "wpa_common_cmd.h"
24 #ifndef OHOS_EUPDATER
25 #include "wpa_client.h"
26 #endif
27
28 #undef LOG_TAG
29 #define LOG_TAG "HdiWpaHal"
30
31 #define WPA_TRY_CONNECT_TIMES 20
32 #define WPA_TRY_CONNECT_SLEEP_TIME (100 * 1000) /* 100ms */
33 #define WPA_CMD_BUF_LEN 256
34 #define WPA_CMD_REPLY_BUF_SMALL_LEN 64
35 #define P2P_SERVICE_INFO_FIRST_SECTION 1
36 #define P2P_SERVICE_INFO_SECOND_SECTION 2
37 #define P2P_SERVICE_INFO_THIRD_SECTION 3
38 #define P2P_SERVICE_DISC_REQ_ONE 1
39 #define P2P_SERVICE_DISC_REQ_TWO 2
40 #define P2P_SERVICE_DISC_REQ_THREE 3
41 #define P2P_SERVICE_DISC_REQ_FOUR 4
42 #define P2P_SERVICE_DISC_REQ_FIVE 5
43 #define WPA_CB_CONNECTED 1
44 #define WPA_CB_DISCONNECTED 2
45 #define WPA_CB_ASSOCIATING 3
46 #define WPA_CB_ASSOCIATED 4
47 #define WPS_EVENT_PBC_OVERLAP "WPS-OVERLAP-DETECTED PBC session overlap"
48 #define WPA_EVENT_BSSID_CHANGED "WPA-EVENT-BSSID-CHANGED "
49 #define WPA_EVENT_ASSOCIATING "Request association with "
50 #define WPA_EVENT_ASSOCIATED "Associated with "
51 #define REPLY_BUF_LENGTH 4096
52 #define CONNECTION_PWD_WRONG_STATUS 1
53 #define CONNECTION_FULL_STATUS 17
54 #define CONNECTION_REJECT_STATUS 37
55 #define WLAN_STATUS_AUTH_TIMEOUT 16
56 #define MAC_AUTH_RSP2_TIMEOUT 5201
57 #define MAC_AUTH_RSP4_TIMEOUT 5202
58 #define MAC_ASSOC_RSP_TIMEOUT 5203
59 #define SSID_EMPTY_LENGTH 1
60 static const int MAX_IFACE_LEN = 6;
61
62 #define WPA_CTRL_OPEN_IFNAME "@abstract:"CONFIG_ROOR_DIR"/sockets/wpa/wlan0"
63 #define P2P_NO_ADD_IFACE_NAME "p2p-dev-wlan0"
64
65 static WifiWpaInterface *g_wpaInterface = NULL;
66
WpaCliConnect(WifiWpaInterface * p)67 static int WpaCliConnect(WifiWpaInterface *p)
68 {
69 HDF_LOGI("Wpa connect start.");
70 if (p == NULL) {
71 HDF_LOGE("Wpa connect parameter error.");
72 return -1;
73 }
74 if (p->staCtrl.pSend != NULL && p->p2pCtrl.pSend != NULL && p->chbaCtrl.pSend != NULL &&
75 p->commonCtrl.pSend != NULL) {
76 HDF_LOGE("Wpa is already connected.");
77 return 0;
78 }
79 int count = WPA_TRY_CONNECT_TIMES;
80 while (count-- > 0) {
81 if (!InitWpaCtrl(&p->staCtrl, WPA_CTRL_OPEN_IFNAME) && !InitWpaCtrl(&p->p2pCtrl, WPA_CTRL_OPEN_IFNAME) &&
82 !InitWpaCtrl(&p->chbaCtrl, WPA_CTRL_OPEN_IFNAME) && !InitWpaCtrl(&p->commonCtrl, WPA_CTRL_OPEN_IFNAME)) {
83 HDF_LOGI("Global wpa interface connect successfully!");
84 break;
85 } else {
86 HDF_LOGE("Init wpaCtrl failed.");
87 }
88 usleep(WPA_TRY_CONNECT_SLEEP_TIME);
89 }
90 if (count <= 0) {
91 return -1;
92 }
93 p->threadRunFlag = 1;
94 HDF_LOGI("Wpa connect finish.");
95 return 0;
96 }
97
WpaCliClose(WifiWpaInterface * p)98 static void WpaCliClose(WifiWpaInterface *p)
99 {
100 HDF_LOGI("Wpa connect close.");
101 if (p->tid != 0) {
102 p->threadRunFlag = 0;
103 pthread_join(p->tid, NULL);
104 p->tid = 0;
105 }
106 ReleaseWpaCtrl(&p->staCtrl);
107 ReleaseWpaCtrl(&p->p2pCtrl);
108 ReleaseWpaCtrl(&p->chbaCtrl);
109 ReleaseWpaCtrl(&p->commonCtrl);
110 return;
111 }
112
WpaCliAddIface(WifiWpaInterface * p,const AddInterfaceArgv * argv,bool isWpaAdd)113 static int WpaCliAddIface(WifiWpaInterface *p, const AddInterfaceArgv *argv, bool isWpaAdd)
114 {
115 HDF_LOGI("enter WpaCliAddIface");
116 if (p == NULL || argv == NULL) {
117 return -1;
118 }
119 WpaIfaceInfo *info = p->ifaces;
120 while (info != NULL) {
121 if (strncmp(info->name, argv->name, MAX_IFACE_LEN) == 0) {
122 return 0;
123 }
124 info = info->next;
125 }
126 if (strncmp(argv->name, P2P_NO_ADD_IFACE_NAME, sizeof(argv->name)) == 0) {
127 HDF_LOGI("WpaCliAddIface: p2p name is p2p-dev-wlan0, no need add iface");
128 return 0;
129 }
130 info = (WpaIfaceInfo *)calloc(1, sizeof(WpaIfaceInfo));
131 if (info == NULL) {
132 return -1;
133 }
134 if (strcpy_s(info->name, sizeof(info->name), argv->name) != 0) {
135 HDF_LOGI("WpaCliAddIface strcpy_s fail");
136 free(info);
137 info = NULL;
138 return -1;
139 }
140 char cmd[WPA_CMD_BUF_LEN] = {0};
141 char buf[WPA_CMD_REPLY_BUF_SMALL_LEN] = {0};
142 HDF_LOGI("Add interface start.");
143 if (isWpaAdd && (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "INTERFACE_ADD %s\t%s",
144 argv->name, argv->confName) < 0 || WpaCliCmd(cmd, buf, sizeof(buf)) != 0)) {
145 free(info);
146 info = NULL;
147 HDF_LOGI("WpaCliAddIface failed, cmd: %{public}s, buf: %{public}s", cmd, buf);
148 return -1;
149 }
150 HDF_LOGI("Add interface finish, cmd: %{public}s, buf: %{public}s", cmd, buf);
151 info->next = p->ifaces;
152 p->ifaces = info;
153 return 0;
154 }
155
WpaCliRemoveIface(WifiWpaInterface * p,const char * name)156 static int WpaCliRemoveIface(WifiWpaInterface *p, const char *name)
157 {
158 HDF_LOGI("enter WpaCliRemoveIface.");
159 if (p == NULL || name == NULL) {
160 return -1;
161 }
162 WpaIfaceInfo *prev = NULL;
163 WpaIfaceInfo *info = p->ifaces;
164 while (info != NULL) {
165 if (strncmp(info->name, name, MAX_IFACE_LEN) == 0) {
166 break;
167 }
168 prev = info;
169 info = info->next;
170 }
171 if (info == NULL) {
172 HDF_LOGI("the WpaInterface info is null");
173 return 0;
174 }
175 char cmd[WPA_CMD_BUF_LEN] = {0};
176 char buf[WPA_CMD_REPLY_BUF_SMALL_LEN] = {0};
177 if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "INTERFACE_REMOVE %s", name) < 0 ||
178 WpaCliCmd(cmd, buf, sizeof(buf)) != 0) {
179 return -1;
180 }
181 if (prev == NULL) {
182 p->ifaces = info->next;
183 } else {
184 prev->next = info->next;
185 }
186 HDF_LOGI("Remove interface finish, cmd: %{public}s, buf: %{public}s", cmd, buf);
187 free(info);
188 info = NULL;
189 return 0;
190 }
191
WpaCliWpaTerminate(void)192 static int WpaCliWpaTerminate(void)
193 {
194 HDF_LOGI("enter WpaCliWpaTerminate.");
195 char cmd[WPA_CMD_BUF_LEN] = {0};
196 char buf[WPA_CMD_REPLY_BUF_SMALL_LEN] = {0};
197 if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "TERMINATE") < 0) {
198 HDF_LOGE("WpaCliWpaTerminate, snprintf err");
199 return -1;
200 }
201 return WpaCliCmd(cmd, buf, sizeof(buf));
202 }
203
InitWifiWpaGlobalInterface(void)204 void InitWifiWpaGlobalInterface(void)
205 {
206 HDF_LOGI("enter InitWifiWpaGlobalInterface.");
207 if (g_wpaInterface != NULL) {
208 return;
209 }
210 g_wpaInterface = (WifiWpaInterface *)calloc(1, sizeof(WifiWpaInterface));
211 if (g_wpaInterface == NULL) {
212 HDF_LOGE("Failed to create wpa interface!");
213 return;
214 }
215 g_wpaInterface->wpaCliConnect = WpaCliConnect;
216 g_wpaInterface->wpaCliClose = WpaCliClose;
217 g_wpaInterface->wpaCliAddIface = WpaCliAddIface;
218 g_wpaInterface->wpaCliRemoveIface = WpaCliRemoveIface;
219 g_wpaInterface->wpaCliTerminate = WpaCliWpaTerminate;
220 g_wpaInterface->ifaces = NULL;
221 }
222
GetWifiWpaGlobalInterface(void)223 WifiWpaInterface *GetWifiWpaGlobalInterface(void)
224 {
225 HDF_LOGI("enter GetWifiWpaGlobalInterface.");
226 return g_wpaInterface;
227 }
228
ReleaseWpaGlobalInterface(void)229 void ReleaseWpaGlobalInterface(void)
230 {
231 HDF_LOGI("enter ReleaseWpaGlobalInterface.");
232 if (g_wpaInterface == NULL) {
233 return;
234 }
235 WpaIfaceInfo *p = g_wpaInterface->ifaces;
236 while (p != NULL) {
237 WpaIfaceInfo *q = p->next;
238 free(p);
239 p = q;
240 }
241 WpaCliClose(g_wpaInterface);
242 free(g_wpaInterface);
243 g_wpaInterface = NULL;
244 }
245
GetStaCtrl(void)246 WpaCtrl *GetStaCtrl(void)
247 {
248 HDF_LOGI("enter GetStaCtrl");
249 if (g_wpaInterface == NULL) {
250 HDF_LOGE("GetStaCtrl g_wpaInterface = NULL!");
251 return NULL;
252 }
253 return &g_wpaInterface->staCtrl;
254 }
255
GetP2pCtrl(void)256 WpaCtrl *GetP2pCtrl(void)
257 {
258 HDF_LOGI("enter GetP2pCtrl");
259 if (g_wpaInterface == NULL) {
260 HDF_LOGE("GetP2pCtrl g_wpaInterface = NULL!");
261 return NULL;
262 }
263 return &g_wpaInterface->p2pCtrl;
264 }
265
GetChbaCtrl(void)266 WpaCtrl *GetChbaCtrl(void)
267 {
268 HDF_LOGI("enter GetChbaCtrl");
269 if (g_wpaInterface == NULL) {
270 HDF_LOGE("GetChbaCtrl g_wpaInterface = NULL!");
271 return NULL;
272 }
273 return &g_wpaInterface->chbaCtrl;
274 }
275
GetCommonCtrl(void)276 WpaCtrl *GetCommonCtrl(void)
277 {
278 HDF_LOGI("enter GetCommonCtrl");
279 if (g_wpaInterface == NULL) {
280 HDF_LOGE("GetCommonCtrl g_wpaInterface = NULL!");
281 return NULL;
282 }
283 return &g_wpaInterface->commonCtrl;
284 }
285
ReleaseIfaceCtrl(char * ifName,int len)286 void ReleaseIfaceCtrl(char *ifName, int len)
287 {
288 if (g_wpaInterface == NULL) {
289 return;
290 }
291 if (len < IFNAME_LEN_MIN || len > IFNAME_LEN_MAX) {
292 HDF_LOGE("ifname is invalid");
293 return;
294 }
295 if (strncmp(ifName, "wlan0", strlen("wlan0")) == 0) {
296 ReleaseWpaCtrl(&(g_wpaInterface->staCtrl));
297 ReleaseWpaCtrl(&(g_wpaInterface->p2pCtrl));
298 ReleaseWpaCtrl(&(g_wpaInterface->chbaCtrl));
299 #ifndef OHOS_EUPDATER
300 ReleaseEventCallback();
301 ClearHdfWpaRemoteObj();
302 #endif
303 }
304 }
305