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