• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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