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
64 static WifiWpaInterface *g_wpaInterface = NULL;
65
WpaCliConnect(WifiWpaInterface * p)66 static int WpaCliConnect(WifiWpaInterface *p)
67 {
68 HDF_LOGI("Wpa connect start.");
69 if (p == NULL) {
70 HDF_LOGE("Wpa connect parameter error.");
71 return -1;
72 }
73 if (p->staCtrl.pSend != NULL && p->p2pCtrl.pSend != NULL && p->chbaCtrl.pSend != NULL &&
74 p->commonCtrl.pSend != NULL) {
75 HDF_LOGE("Wpa is already connected.");
76 return 0;
77 }
78 int count = WPA_TRY_CONNECT_TIMES;
79 while (count-- > 0) {
80 if (!InitWpaCtrl(&p->staCtrl, WPA_CTRL_OPEN_IFNAME) && !InitWpaCtrl(&p->p2pCtrl, WPA_CTRL_OPEN_IFNAME) &&
81 !InitWpaCtrl(&p->chbaCtrl, WPA_CTRL_OPEN_IFNAME) && !InitWpaCtrl(&p->commonCtrl, WPA_CTRL_OPEN_IFNAME)) {
82 HDF_LOGI("Global wpa interface connect successfully!");
83 break;
84 } else {
85 HDF_LOGE("Init wpaCtrl failed.");
86 }
87 usleep(WPA_TRY_CONNECT_SLEEP_TIME);
88 }
89 if (count <= 0) {
90 return -1;
91 }
92 p->threadRunFlag = 1;
93 HDF_LOGI("Wpa connect finish.");
94 return 0;
95 }
96
WpaCliClose(WifiWpaInterface * p)97 static void WpaCliClose(WifiWpaInterface *p)
98 {
99 HDF_LOGI("Wpa connect close.");
100 if (p->tid != 0) {
101 p->threadRunFlag = 0;
102 pthread_join(p->tid, NULL);
103 p->tid = 0;
104 }
105 ReleaseWpaCtrl(&p->staCtrl);
106 ReleaseWpaCtrl(&p->p2pCtrl);
107 ReleaseWpaCtrl(&p->chbaCtrl);
108 ReleaseWpaCtrl(&p->commonCtrl);
109 return;
110 }
111
WpaCliAddIface(WifiWpaInterface * p,const AddInterfaceArgv * argv,bool isWpaAdd)112 static int WpaCliAddIface(WifiWpaInterface *p, const AddInterfaceArgv *argv, bool isWpaAdd)
113 {
114 HDF_LOGI("enter WpaCliAddIface");
115 if (p == NULL || argv == NULL) {
116 return -1;
117 }
118 WpaIfaceInfo *info = p->ifaces;
119 while (info != NULL) {
120 if (strncmp(info->name, argv->name, MAX_IFACE_LEN) == 0) {
121 return 0;
122 }
123 info = info->next;
124 }
125 info = (WpaIfaceInfo *)calloc(1, sizeof(WpaIfaceInfo));
126 if (info == NULL) {
127 return -1;
128 }
129 if (strcpy_s(info->name, sizeof(info->name), argv->name) != 0) {
130 HDF_LOGI("WpaCliAddIface strcpy_s fail");
131 free(info);
132 info = NULL;
133 return -1;
134 }
135 char cmd[WPA_CMD_BUF_LEN] = {0};
136 char buf[WPA_CMD_REPLY_BUF_SMALL_LEN] = {0};
137 HDF_LOGI("Add interface start.");
138 if (isWpaAdd && (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "INTERFACE_ADD %s\t%s",
139 argv->name, argv->confName) < 0 || WpaCliCmd(cmd, buf, sizeof(buf)) != 0)) {
140 free(info);
141 info = NULL;
142 HDF_LOGI("WpaCliAddIface failed, cmd: %{public}s, buf: %{public}s", cmd, buf);
143 return -1;
144 }
145 HDF_LOGI("Add interface finish, cmd: %{public}s, buf: %{public}s", cmd, buf);
146 info->next = p->ifaces;
147 p->ifaces = info;
148 return 0;
149 }
150
WpaCliRemoveIface(WifiWpaInterface * p,const char * name)151 static int WpaCliRemoveIface(WifiWpaInterface *p, const char *name)
152 {
153 HDF_LOGI("enter WpaCliRemoveIface.");
154 if (p == NULL || name == NULL) {
155 return -1;
156 }
157 WpaIfaceInfo *prev = NULL;
158 WpaIfaceInfo *info = p->ifaces;
159 while (info != NULL) {
160 if (strncmp(info->name, name, MAX_IFACE_LEN) == 0) {
161 break;
162 }
163 prev = info;
164 info = info->next;
165 }
166 if (info == NULL) {
167 HDF_LOGI("the WpaInterface info is null");
168 return 0;
169 }
170 char cmd[WPA_CMD_BUF_LEN] = {0};
171 char buf[WPA_CMD_REPLY_BUF_SMALL_LEN] = {0};
172 if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "INTERFACE_REMOVE %s", name) < 0 ||
173 WpaCliCmd(cmd, buf, sizeof(buf)) != 0) {
174 return -1;
175 }
176 if (prev == NULL) {
177 p->ifaces = info->next;
178 } else {
179 prev->next = info->next;
180 }
181 HDF_LOGI("Remove interface finish, cmd: %{public}s, buf: %{public}s", cmd, buf);
182 free(info);
183 info = NULL;
184 return 0;
185 }
186
WpaCliWpaTerminate(void)187 static int WpaCliWpaTerminate(void)
188 {
189 HDF_LOGI("enter WpaCliWpaTerminate.");
190 char cmd[WPA_CMD_BUF_LEN] = {0};
191 char buf[WPA_CMD_REPLY_BUF_SMALL_LEN] = {0};
192 if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "TERMINATE") < 0) {
193 HDF_LOGE("WpaCliWpaTerminate, snprintf err");
194 return -1;
195 }
196 return WpaCliCmd(cmd, buf, sizeof(buf));
197 }
198
InitWifiWpaGlobalInterface(void)199 void InitWifiWpaGlobalInterface(void)
200 {
201 HDF_LOGI("enter InitWifiWpaGlobalInterface.");
202 if (g_wpaInterface != NULL) {
203 return;
204 }
205 g_wpaInterface = (WifiWpaInterface *)calloc(1, sizeof(WifiWpaInterface));
206 if (g_wpaInterface == NULL) {
207 HDF_LOGE("Failed to create wpa interface!");
208 return;
209 }
210 g_wpaInterface->wpaCliConnect = WpaCliConnect;
211 g_wpaInterface->wpaCliClose = WpaCliClose;
212 g_wpaInterface->wpaCliAddIface = WpaCliAddIface;
213 g_wpaInterface->wpaCliRemoveIface = WpaCliRemoveIface;
214 g_wpaInterface->wpaCliTerminate = WpaCliWpaTerminate;
215 g_wpaInterface->ifaces = NULL;
216 }
217
GetWifiWpaGlobalInterface(void)218 WifiWpaInterface *GetWifiWpaGlobalInterface(void)
219 {
220 HDF_LOGI("enter GetWifiWpaGlobalInterface.");
221 return g_wpaInterface;
222 }
223
ReleaseWpaGlobalInterface(void)224 void ReleaseWpaGlobalInterface(void)
225 {
226 HDF_LOGI("enter ReleaseWpaGlobalInterface.");
227 if (g_wpaInterface == NULL) {
228 return;
229 }
230 WpaIfaceInfo *p = g_wpaInterface->ifaces;
231 while (p != NULL) {
232 WpaIfaceInfo *q = p->next;
233 free(p);
234 p = q;
235 }
236 WpaCliClose(g_wpaInterface);
237 free(g_wpaInterface);
238 g_wpaInterface = NULL;
239 }
240
GetStaCtrl(void)241 WpaCtrl *GetStaCtrl(void)
242 {
243 HDF_LOGI("enter GetStaCtrl");
244 if (g_wpaInterface == NULL) {
245 HDF_LOGE("GetStaCtrl g_wpaInterface = NULL!");
246 return NULL;
247 }
248 return &g_wpaInterface->staCtrl;
249 }
250
GetP2pCtrl(void)251 WpaCtrl *GetP2pCtrl(void)
252 {
253 HDF_LOGI("enter GetP2pCtrl");
254 if (g_wpaInterface == NULL) {
255 HDF_LOGE("GetP2pCtrl g_wpaInterface = NULL!");
256 return NULL;
257 }
258 return &g_wpaInterface->p2pCtrl;
259 }
260
GetChbaCtrl(void)261 WpaCtrl *GetChbaCtrl(void)
262 {
263 HDF_LOGI("enter GetChbaCtrl");
264 if (g_wpaInterface == NULL) {
265 HDF_LOGE("GetChbaCtrl g_wpaInterface = NULL!");
266 return NULL;
267 }
268 return &g_wpaInterface->chbaCtrl;
269 }
270
GetCommonCtrl(void)271 WpaCtrl *GetCommonCtrl(void)
272 {
273 HDF_LOGI("enter GetCommonCtrl");
274 if (g_wpaInterface == NULL) {
275 HDF_LOGE("GetCommonCtrl g_wpaInterface = NULL!");
276 return NULL;
277 }
278 return &g_wpaInterface->commonCtrl;
279 }
280
ReleaseIfaceCtrl(char * ifName,int len)281 void ReleaseIfaceCtrl(char *ifName, int len)
282 {
283 if (g_wpaInterface == NULL) {
284 return;
285 }
286 if (len < IFNAME_LEN_MIN || len > IFNAME_LEN_MAX) {
287 HDF_LOGE("ifname is invalid");
288 return;
289 }
290 if (strncmp(ifName, "wlan0", strlen("wlan0")) == 0) {
291 ReleaseWpaCtrl(&(g_wpaInterface->staCtrl));
292 ReleaseWpaCtrl(&(g_wpaInterface->p2pCtrl));
293 ReleaseWpaCtrl(&(g_wpaInterface->chbaCtrl));
294 #ifndef OHOS_EUPDATER
295 ReleaseEventCallback();
296 ClearHdfWpaRemoteObj();
297 #endif
298 }
299 }