1e5b75505Sopenharmony_ci/*
2e5b75505Sopenharmony_ci * Driver interaction with hdf wifi
3e5b75505Sopenharmony_ci * Copyright (c) 2020 Huawei Device Co., Ltd.
4e5b75505Sopenharmony_ci *
5e5b75505Sopenharmony_ci * This software may be distributed under the terms of the BSD license.
6e5b75505Sopenharmony_ci * See README for more details.
7e5b75505Sopenharmony_ci */
8e5b75505Sopenharmony_ci
9e5b75505Sopenharmony_ci#include "wpa_hal.h"
10e5b75505Sopenharmony_ci#include "includes.h"
11e5b75505Sopenharmony_ci#include "utils/common.h"
12e5b75505Sopenharmony_ci#include "driver.h"
13e5b75505Sopenharmony_ci#include "ap/hostapd.h"
14e5b75505Sopenharmony_ci#include "l2_packet/l2_packet.h"
15e5b75505Sopenharmony_ci#include "eloop.h"
16e5b75505Sopenharmony_ci#include "securec.h"
17e5b75505Sopenharmony_ci#include <dirent.h>
18e5b75505Sopenharmony_ci
19e5b75505Sopenharmony_ci#ifdef __cplusplus
20e5b75505Sopenharmony_ci#if __cplusplus
21e5b75505Sopenharmony_ciextern "C" {
22e5b75505Sopenharmony_ci#endif
23e5b75505Sopenharmony_ci#endif
24e5b75505Sopenharmony_ci
25e5b75505Sopenharmony_ciWifiDriverData *g_wifiDriverData = NULL;
26e5b75505Sopenharmony_cienum WifiIfType g_wifiDriverType = WIFI_IFTYPE_UNSPECIFIED;
27e5b75505Sopenharmony_ci#define WAIT_LOAD_NETDEVICE 2500
28e5b75505Sopenharmony_ci#ifdef CONFIG_OHOS_P2P
29e5b75505Sopenharmony_ciuint8_t g_msgInit = TRUE;
30e5b75505Sopenharmony_ci#endif
31e5b75505Sopenharmony_ci
32e5b75505Sopenharmony_ciWifiDriverData *GetDrvData()
33e5b75505Sopenharmony_ci{
34e5b75505Sopenharmony_ci    return g_wifiDriverData;
35e5b75505Sopenharmony_ci}
36e5b75505Sopenharmony_ci
37e5b75505Sopenharmony_ci#ifdef CONFIG_OHOS_P2P
38e5b75505Sopenharmony_ci#define WPA_MAX_WIFI_DEV_NUM 3
39e5b75505Sopenharmony_ci
40e5b75505Sopenharmony_ciWifiDev* g_wifiDev[WPA_MAX_WIFI_DEV_NUM] = {NULL};
41e5b75505Sopenharmony_ci
42e5b75505Sopenharmony_ciWifiDev* GetWifiDevByName(const char *ifName)
43e5b75505Sopenharmony_ci{
44e5b75505Sopenharmony_ci    int32_t i;
45e5b75505Sopenharmony_ci    if (ifName == NULL) {
46e5b75505Sopenharmony_ci        return NULL;
47e5b75505Sopenharmony_ci    }
48e5b75505Sopenharmony_ci    for (i = 0; i < WPA_MAX_WIFI_DEV_NUM; i++) {
49e5b75505Sopenharmony_ci        if ((g_wifiDev[i] != NULL) && (strncmp(g_wifiDev[i]->ifName, ifName, strlen(ifName)) == 0)) {
50e5b75505Sopenharmony_ci            g_wifiDev[i]->networkId = i;
51e5b75505Sopenharmony_ci            return g_wifiDev[i];
52e5b75505Sopenharmony_ci        }
53e5b75505Sopenharmony_ci    }
54e5b75505Sopenharmony_ci    return NULL;
55e5b75505Sopenharmony_ci}
56e5b75505Sopenharmony_ci
57e5b75505Sopenharmony_ciint32_t SetWifiDev(WifiDev *wifiDev)
58e5b75505Sopenharmony_ci{
59e5b75505Sopenharmony_ci    int32_t i;
60e5b75505Sopenharmony_ci    if (wifiDev == NULL) {
61e5b75505Sopenharmony_ci        return -EFAIL;
62e5b75505Sopenharmony_ci    }
63e5b75505Sopenharmony_ci    for (i = 0; i < WPA_MAX_WIFI_DEV_NUM; i++) {
64e5b75505Sopenharmony_ci        if ((g_wifiDev[i] != NULL) && (strncmp(g_wifiDev[i]->ifName, wifiDev->ifName, strlen(wifiDev->ifName)) == 0)) {
65e5b75505Sopenharmony_ci            g_wifiDev[i] = wifiDev;
66e5b75505Sopenharmony_ci            return SUCC;
67e5b75505Sopenharmony_ci        } else if (g_wifiDev[i] == NULL) {
68e5b75505Sopenharmony_ci            g_wifiDev[i] = wifiDev;
69e5b75505Sopenharmony_ci            g_wifiDev[i]->networkId = i;
70e5b75505Sopenharmony_ci            return SUCC;
71e5b75505Sopenharmony_ci        }
72e5b75505Sopenharmony_ci    }
73e5b75505Sopenharmony_ci    return -EFAIL;
74e5b75505Sopenharmony_ci}
75e5b75505Sopenharmony_ci
76e5b75505Sopenharmony_civoid FreeWifiDev(WifiDev *wifiDev)
77e5b75505Sopenharmony_ci{
78e5b75505Sopenharmony_ci    int32_t i;
79e5b75505Sopenharmony_ci    if (wifiDev == NULL) {
80e5b75505Sopenharmony_ci        return;
81e5b75505Sopenharmony_ci    }
82e5b75505Sopenharmony_ci    for (i = 0; i < WPA_MAX_WIFI_DEV_NUM; i++) {
83e5b75505Sopenharmony_ci        if (g_wifiDev[i] == wifiDev) {
84e5b75505Sopenharmony_ci            g_wifiDev[i] = NULL;
85e5b75505Sopenharmony_ci            break;
86e5b75505Sopenharmony_ci        }
87e5b75505Sopenharmony_ci    }
88e5b75505Sopenharmony_ci    os_free(wifiDev);
89e5b75505Sopenharmony_ci    wifiDev = NULL;
90e5b75505Sopenharmony_ci}
91e5b75505Sopenharmony_ci
92e5b75505Sopenharmony_ciint32_t CountWifiDevInUse()
93e5b75505Sopenharmony_ci{
94e5b75505Sopenharmony_ci    int32_t i;
95e5b75505Sopenharmony_ci    int32_t count = 0;
96e5b75505Sopenharmony_ci    for (i = 0; i < WPA_MAX_WIFI_DEV_NUM; i++) {
97e5b75505Sopenharmony_ci        if (g_wifiDev[i] != NULL) {
98e5b75505Sopenharmony_ci            count++;
99e5b75505Sopenharmony_ci        }
100e5b75505Sopenharmony_ci    }
101e5b75505Sopenharmony_ci    return count;
102e5b75505Sopenharmony_ci}
103e5b75505Sopenharmony_ci#endif // CONFIG_OHOS_P2P
104e5b75505Sopenharmony_ci
105e5b75505Sopenharmony_cistatic int OnWpaWiFiEvents(uint32_t event, void *data, const char *ifName)
106e5b75505Sopenharmony_ci{
107e5b75505Sopenharmony_ci    WifiDriverData *drv = NULL;
108e5b75505Sopenharmony_ci#ifndef CONFIG_OHOS_P2P
109e5b75505Sopenharmony_ci    drv = GetDrvData();
110e5b75505Sopenharmony_ci#else
111e5b75505Sopenharmony_ci    WifiDev *wifiDev = NULL;
112e5b75505Sopenharmony_ci    wifiDev = GetWifiDevByName(ifName);
113e5b75505Sopenharmony_ci    if (wifiDev == NULL) {
114e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "OnWpaWiFiEvents wifiDev is null\n");
115e5b75505Sopenharmony_ci        return -EFAIL;
116e5b75505Sopenharmony_ci    }
117e5b75505Sopenharmony_ci    drv = wifiDev->priv;
118e5b75505Sopenharmony_ci#endif
119e5b75505Sopenharmony_ci    (void)ifName;
120e5b75505Sopenharmony_ci    wpa_printf(MSG_INFO, "OnWpaWiFiEvents event=%d", event);
121e5b75505Sopenharmony_ci    if (drv == NULL || data == NULL) {
122e5b75505Sopenharmony_ci        return -EFAIL;
123e5b75505Sopenharmony_ci    }
124e5b75505Sopenharmony_ci    switch (event) {
125e5b75505Sopenharmony_ci        case WIFI_EVENT_NEW_STA:
126e5b75505Sopenharmony_ci            WifiWpaNewStaProcess(drv, (WifiNewStaInfo *)data);
127e5b75505Sopenharmony_ci            break;
128e5b75505Sopenharmony_ci        case WIFI_EVENT_DEL_STA:
129e5b75505Sopenharmony_ci            WifiWpaDelStaProcess(drv, (uint8_t *)data);
130e5b75505Sopenharmony_ci            break;
131e5b75505Sopenharmony_ci        case WIFI_EVENT_RX_MGMT:
132e5b75505Sopenharmony_ci            WifiWpaRxMgmtProcess(drv, (WifiRxMgmt *)data);
133e5b75505Sopenharmony_ci            break;
134e5b75505Sopenharmony_ci        case WIFI_EVENT_TX_STATUS:
135e5b75505Sopenharmony_ci            WifiWpaTxStatusProcess(drv, (WifiTxStatus *)data);
136e5b75505Sopenharmony_ci            break;
137e5b75505Sopenharmony_ci        case WIFI_EVENT_SCAN_DONE:
138e5b75505Sopenharmony_ci            WifiWpaScanDoneProcess(drv, (uint32_t *)data);
139e5b75505Sopenharmony_ci            break;
140e5b75505Sopenharmony_ci        case WIFI_EVENT_SCAN_RESULT:
141e5b75505Sopenharmony_ci            WifiWpaScanResultProcess(drv, (WifiScanResult *)data);
142e5b75505Sopenharmony_ci            break;
143e5b75505Sopenharmony_ci        case WIFI_EVENT_CONNECT_RESULT:
144e5b75505Sopenharmony_ci            WifiWpaConnectResultProcess(drv, (WifiConnectResult *)data);
145e5b75505Sopenharmony_ci            break;
146e5b75505Sopenharmony_ci        case WIFI_EVENT_DISCONNECT:
147e5b75505Sopenharmony_ci            WifiWpaDisconnectProcess(drv, (WifiDisconnect *)data);
148e5b75505Sopenharmony_ci            break;
149e5b75505Sopenharmony_ci        case WIFI_EVENT_EAPOL_RECV:
150e5b75505Sopenharmony_ci            WifiWpaDriverEapolRecvProcess(drv, data);
151e5b75505Sopenharmony_ci            break;
152e5b75505Sopenharmony_ci        case WIFI_EVENT_REMAIN_ON_CHANNEL:
153e5b75505Sopenharmony_ci            WifiWpaRemainOnChannelProcess(drv, (WifiOnChannel *)data);
154e5b75505Sopenharmony_ci            break;
155e5b75505Sopenharmony_ci        case WIFI_EVENT_CANCEL_REMAIN_ON_CHANNEL:
156e5b75505Sopenharmony_ci            WifiWpaCancelRemainOnChannelProcess(drv, (WifiOnChannel *)data);
157e5b75505Sopenharmony_ci            break;
158e5b75505Sopenharmony_ci        default:
159e5b75505Sopenharmony_ci            break;
160e5b75505Sopenharmony_ci    }
161e5b75505Sopenharmony_ci
162e5b75505Sopenharmony_ci    return SUCC;
163e5b75505Sopenharmony_ci}
164e5b75505Sopenharmony_ci
165e5b75505Sopenharmony_cistatic int32_t WifiClientInit(const char *ifName)
166e5b75505Sopenharmony_ci{
167e5b75505Sopenharmony_ci    int32_t ret;
168e5b75505Sopenharmony_ci
169e5b75505Sopenharmony_ci    wpa_printf(MSG_INFO, "WifiClientInit enter.");
170e5b75505Sopenharmony_ci    ret = WifiDriverClientInit();
171e5b75505Sopenharmony_ci    if (ret != SUCC) {
172e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "WifiWpa init msg service failed");
173e5b75505Sopenharmony_ci        return ret;
174e5b75505Sopenharmony_ci    }
175e5b75505Sopenharmony_ci    ret = WifiRegisterEventCallback(OnWpaWiFiEvents, WIFI_KERNEL_TO_WPA_CLIENT, ifName);
176e5b75505Sopenharmony_ci    if (ret != SUCC) {
177e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "WifiWpa register event listener faild");
178e5b75505Sopenharmony_ci    }
179e5b75505Sopenharmony_ci    return ret;
180e5b75505Sopenharmony_ci}
181e5b75505Sopenharmony_ci
182e5b75505Sopenharmony_civoid WifiClientDeinit(const char *ifName)
183e5b75505Sopenharmony_ci{
184e5b75505Sopenharmony_ci    WifiUnregisterEventCallback(OnWpaWiFiEvents, WIFI_KERNEL_TO_WPA_CLIENT, ifName);
185e5b75505Sopenharmony_ci    WifiDriverClientDeinit();
186e5b75505Sopenharmony_ci}
187e5b75505Sopenharmony_ci
188e5b75505Sopenharmony_cistatic int32_t WifiWpaGetBssid(void *priv, uint8_t *bssid)
189e5b75505Sopenharmony_ci{
190e5b75505Sopenharmony_ci    WifiDriverData *drv = priv;
191e5b75505Sopenharmony_ci    errno_t rc;
192e5b75505Sopenharmony_ci    if ((priv == NULL) || (bssid == NULL)) {
193e5b75505Sopenharmony_ci        return -EFAIL;
194e5b75505Sopenharmony_ci    }
195e5b75505Sopenharmony_ci    if (drv->associated == WIFI_DISCONNECT) {
196e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s associated status error", __func__);
197e5b75505Sopenharmony_ci        return -EFAIL;
198e5b75505Sopenharmony_ci    }
199e5b75505Sopenharmony_ci
200e5b75505Sopenharmony_ci    rc = memcpy_s(bssid, ETH_ADDR_LEN, drv->bssid, ETH_ADDR_LEN);
201e5b75505Sopenharmony_ci    if (rc != EOK) {
202e5b75505Sopenharmony_ci        return -EFAIL;
203e5b75505Sopenharmony_ci    }
204e5b75505Sopenharmony_ci    return SUCC;
205e5b75505Sopenharmony_ci}
206e5b75505Sopenharmony_ci
207e5b75505Sopenharmony_cistatic int32_t WifiWpaGetSsid(void *priv, uint8_t *ssid)
208e5b75505Sopenharmony_ci{
209e5b75505Sopenharmony_ci    WifiDriverData *drv = priv;
210e5b75505Sopenharmony_ci    errno_t rc;
211e5b75505Sopenharmony_ci    if ((priv == NULL) || (ssid == NULL)) {
212e5b75505Sopenharmony_ci        return -EFAIL;
213e5b75505Sopenharmony_ci    }
214e5b75505Sopenharmony_ci    if (drv->associated == WIFI_DISCONNECT) {
215e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s associated status error", __func__);
216e5b75505Sopenharmony_ci        return -EFAIL;
217e5b75505Sopenharmony_ci    }
218e5b75505Sopenharmony_ci    rc = memcpy_s(ssid, MAX_SSID_LEN, drv->ssid, drv->ssidLen);
219e5b75505Sopenharmony_ci    if (rc != EOK) {
220e5b75505Sopenharmony_ci        return -EFAIL;
221e5b75505Sopenharmony_ci    }
222e5b75505Sopenharmony_ci    return drv->ssidLen;
223e5b75505Sopenharmony_ci}
224e5b75505Sopenharmony_ci
225e5b75505Sopenharmony_cistatic uint32_t WifiAlgToCipherSuite(enum wpa_alg alg, size_t keyLen)
226e5b75505Sopenharmony_ci{
227e5b75505Sopenharmony_ci    switch (alg) {
228e5b75505Sopenharmony_ci        case WPA_ALG_WEP:
229e5b75505Sopenharmony_ci            if (keyLen == WPA_WEP40_KEY_LEN) {
230e5b75505Sopenharmony_ci                return RSN_CIPHER_SUITE_WEP40;
231e5b75505Sopenharmony_ci            }
232e5b75505Sopenharmony_ci            return RSN_CIPHER_SUITE_WEP104;
233e5b75505Sopenharmony_ci        case WPA_ALG_TKIP:
234e5b75505Sopenharmony_ci            return RSN_CIPHER_SUITE_TKIP;
235e5b75505Sopenharmony_ci        case WPA_ALG_CCMP:
236e5b75505Sopenharmony_ci            return RSN_CIPHER_SUITE_CCMP;
237e5b75505Sopenharmony_ci        case WPA_ALG_GCMP:
238e5b75505Sopenharmony_ci            return RSN_CIPHER_SUITE_GCMP;
239e5b75505Sopenharmony_ci        case WPA_ALG_CCMP_256:
240e5b75505Sopenharmony_ci            return RSN_CIPHER_SUITE_CCMP_256;
241e5b75505Sopenharmony_ci        case WPA_ALG_GCMP_256:
242e5b75505Sopenharmony_ci            return RSN_CIPHER_SUITE_GCMP_256;
243e5b75505Sopenharmony_ci        case WPA_ALG_IGTK:
244e5b75505Sopenharmony_ci            return RSN_CIPHER_SUITE_AES_128_CMAC;
245e5b75505Sopenharmony_ci        case WPA_ALG_BIP_GMAC_128:
246e5b75505Sopenharmony_ci            return RSN_CIPHER_SUITE_BIP_GMAC_128;
247e5b75505Sopenharmony_ci        case WPA_ALG_BIP_GMAC_256:
248e5b75505Sopenharmony_ci            return RSN_CIPHER_SUITE_BIP_GMAC_256;
249e5b75505Sopenharmony_ci        case WPA_ALG_BIP_CMAC_256:
250e5b75505Sopenharmony_ci            return RSN_CIPHER_SUITE_BIP_CMAC_256;
251e5b75505Sopenharmony_ci        case WPA_ALG_SMS4:
252e5b75505Sopenharmony_ci            return RSN_CIPHER_SUITE_SMS4;
253e5b75505Sopenharmony_ci        case WPA_ALG_KRK:
254e5b75505Sopenharmony_ci            return RSN_CIPHER_SUITE_KRK;
255e5b75505Sopenharmony_ci        case WPA_ALG_NONE:
256e5b75505Sopenharmony_ci        case WPA_ALG_PMK:
257e5b75505Sopenharmony_ci            return 0;
258e5b75505Sopenharmony_ci        default:
259e5b75505Sopenharmony_ci            return 0;
260e5b75505Sopenharmony_ci    }
261e5b75505Sopenharmony_ci}
262e5b75505Sopenharmony_ci
263e5b75505Sopenharmony_cistatic inline int IsBroadcastAddr(const uint8_t *addr)
264e5b75505Sopenharmony_ci{
265e5b75505Sopenharmony_ci    // 0 1 2 3 4 5 are mac index
266e5b75505Sopenharmony_ci    return (addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) == 0xff;
267e5b75505Sopenharmony_ci}
268e5b75505Sopenharmony_ci
269e5b75505Sopenharmony_cistatic void WifiWpaInitAlg(WifiKeyExt *keyExt, enum wpa_alg alg, size_t keyLen)
270e5b75505Sopenharmony_ci{
271e5b75505Sopenharmony_ci    keyExt->cipher = WifiAlgToCipherSuite(alg, keyLen);
272e5b75505Sopenharmony_ci    if ((alg == WPA_ALG_IGTK) || (alg == WPA_ALG_BIP_GMAC_128) || (alg == WPA_ALG_BIP_GMAC_256) ||
273e5b75505Sopenharmony_ci        (alg == WPA_ALG_BIP_CMAC_256)) {
274e5b75505Sopenharmony_ci        keyExt->defMgmt = TRUE;
275e5b75505Sopenharmony_ci    } else {
276e5b75505Sopenharmony_ci        keyExt->def = TRUE;
277e5b75505Sopenharmony_ci    }
278e5b75505Sopenharmony_ci}
279e5b75505Sopenharmony_ci
280e5b75505Sopenharmony_cistatic int32_t WifiWpaInitAddr(WifiKeyExt *keyExt, const uint8_t *addr, const enum wpa_alg alg, const int32_t keyIdx,
281e5b75505Sopenharmony_ci    const int32_t setTx)
282e5b75505Sopenharmony_ci{
283e5b75505Sopenharmony_ci    keyExt->type = WIFI_KEYTYPE_BUTT;
284e5b75505Sopenharmony_ci    keyExt->defaultTypes = WIFI_KEY_DEFAULT_TYPE_INVALID;
285e5b75505Sopenharmony_ci    if (addr != NULL) {
286e5b75505Sopenharmony_ci        if (!IsBroadcastAddr(addr)) {
287e5b75505Sopenharmony_ci            keyExt->addr = (uint8_t *)os_zalloc(ETH_ADDR_LEN);
288e5b75505Sopenharmony_ci            if ((keyExt->addr == NULL) || (memcpy_s(keyExt->addr, ETH_ADDR_LEN, addr, ETH_ADDR_LEN) != EOK)) {
289e5b75505Sopenharmony_ci                return -EFAIL;
290e5b75505Sopenharmony_ci            }
291e5b75505Sopenharmony_ci            if ((alg != WPA_ALG_WEP) && (keyIdx != 0) && (setTx == 0)) {
292e5b75505Sopenharmony_ci                keyExt->type = WIFI_KEYTYPE_GROUP;
293e5b75505Sopenharmony_ci            }
294e5b75505Sopenharmony_ci            keyExt->defaultTypes = WIFI_KEY_DEFAULT_TYPE_UNICAST;
295e5b75505Sopenharmony_ci        } else {
296e5b75505Sopenharmony_ci            keyExt->addr = NULL;
297e5b75505Sopenharmony_ci            keyExt->defaultTypes = WIFI_KEY_DEFAULT_TYPE_MULTICAST;
298e5b75505Sopenharmony_ci        }
299e5b75505Sopenharmony_ci    }
300e5b75505Sopenharmony_ci    if (keyExt->type == WIFI_KEYTYPE_BUTT) {
301e5b75505Sopenharmony_ci        keyExt->type = (keyExt->addr != NULL) ? WIFI_KEYTYPE_PAIRWISE : WIFI_KEYTYPE_GROUP;
302e5b75505Sopenharmony_ci    }
303e5b75505Sopenharmony_ci    return SUCC;
304e5b75505Sopenharmony_ci}
305e5b75505Sopenharmony_ci
306e5b75505Sopenharmony_cistatic int32_t WifiWpaInitSeq(WifiKeyExt *keyExt, const uint8_t *seq, const size_t seqLen)
307e5b75505Sopenharmony_ci{
308e5b75505Sopenharmony_ci    keyExt->seqLen = seqLen;
309e5b75505Sopenharmony_ci    if ((seq != NULL) && (seqLen != 0)) {
310e5b75505Sopenharmony_ci        keyExt->seq = (uint8_t *)os_zalloc(seqLen);
311e5b75505Sopenharmony_ci        if ((keyExt->seq == NULL) || (memcpy_s(keyExt->seq, seqLen, seq, seqLen) != EOK)) {
312e5b75505Sopenharmony_ci            return -EFAIL;
313e5b75505Sopenharmony_ci        }
314e5b75505Sopenharmony_ci    }
315e5b75505Sopenharmony_ci    return SUCC;
316e5b75505Sopenharmony_ci}
317e5b75505Sopenharmony_ci
318e5b75505Sopenharmony_cistatic int32_t WifiWpaInitKey(WifiKeyExt *keyExt, const uint8_t *key, const size_t keyLen, const int32_t keyIdx,
319e5b75505Sopenharmony_ci    const enum wpa_alg alg)
320e5b75505Sopenharmony_ci{
321e5b75505Sopenharmony_ci    keyExt->keyLen = keyLen;
322e5b75505Sopenharmony_ci    keyExt->keyIdx = keyIdx;
323e5b75505Sopenharmony_ci    if ((alg != WPA_ALG_NONE) && (key != NULL) && (keyLen != 0)) {
324e5b75505Sopenharmony_ci        keyExt->key = (uint8_t *)os_zalloc(keyLen);
325e5b75505Sopenharmony_ci        if ((keyExt->key == NULL) || (memcpy_s(keyExt->key, keyLen, key, keyLen) != EOK)) {
326e5b75505Sopenharmony_ci            return -EFAIL;
327e5b75505Sopenharmony_ci        }
328e5b75505Sopenharmony_ci    }
329e5b75505Sopenharmony_ci    return SUCC;
330e5b75505Sopenharmony_ci}
331e5b75505Sopenharmony_ci
332e5b75505Sopenharmony_cistatic void WifiKeyExtFree(WifiKeyExt **key)
333e5b75505Sopenharmony_ci{
334e5b75505Sopenharmony_ci    if (key == NULL || *key == NULL) {
335e5b75505Sopenharmony_ci        return;
336e5b75505Sopenharmony_ci    }
337e5b75505Sopenharmony_ci
338e5b75505Sopenharmony_ci    if ((*key)->addr != NULL) {
339e5b75505Sopenharmony_ci        os_free((*key)->addr);
340e5b75505Sopenharmony_ci        (*key)->addr = NULL;
341e5b75505Sopenharmony_ci    }
342e5b75505Sopenharmony_ci    if ((*key)->seq != NULL) {
343e5b75505Sopenharmony_ci        os_free((*key)->seq);
344e5b75505Sopenharmony_ci        (*key)->seq = NULL;
345e5b75505Sopenharmony_ci    }
346e5b75505Sopenharmony_ci    if ((*key)->key != NULL) {
347e5b75505Sopenharmony_ci        os_free((*key)->key);
348e5b75505Sopenharmony_ci        (*key)->key = NULL;
349e5b75505Sopenharmony_ci    }
350e5b75505Sopenharmony_ci
351e5b75505Sopenharmony_ci    os_free(*key);
352e5b75505Sopenharmony_ci    *key = NULL;
353e5b75505Sopenharmony_ci}
354e5b75505Sopenharmony_ci
355e5b75505Sopenharmony_cistatic inline int32_t IsApInterface(int32_t mode)
356e5b75505Sopenharmony_ci{
357e5b75505Sopenharmony_ci    return ((mode) == WIFI_IFTYPE_AP || (mode) == WIFI_IFTYPE_P2P_GO);
358e5b75505Sopenharmony_ci}
359e5b75505Sopenharmony_ci
360e5b75505Sopenharmony_cistatic int32_t WifiWpaSetKey(const char *ifname, void *priv, enum wpa_alg alg, const uint8_t *addr, int32_t keyIdx,
361e5b75505Sopenharmony_ci    int32_t setTx, const uint8_t *seq, size_t seqLen, const uint8_t *key, size_t keyLen)
362e5b75505Sopenharmony_ci{
363e5b75505Sopenharmony_ci    int32_t ret;
364e5b75505Sopenharmony_ci    WifiKeyExt *keyExt = NULL;
365e5b75505Sopenharmony_ci    WifiDriverData *drv = priv;
366e5b75505Sopenharmony_ci
367e5b75505Sopenharmony_ci    if ((ifname == NULL) || (priv == NULL)) {
368e5b75505Sopenharmony_ci        return -EFAIL;
369e5b75505Sopenharmony_ci    }
370e5b75505Sopenharmony_ci    if (drv->mode == WIFI_IFTYPE_P2P_DEVICE) {
371e5b75505Sopenharmony_ci        return SUCC;
372e5b75505Sopenharmony_ci    }
373e5b75505Sopenharmony_ci
374e5b75505Sopenharmony_ci    keyExt = os_zalloc(sizeof(WifiKeyExt));
375e5b75505Sopenharmony_ci    if (keyExt == NULL) {
376e5b75505Sopenharmony_ci        return -EFAIL;
377e5b75505Sopenharmony_ci    }
378e5b75505Sopenharmony_ci
379e5b75505Sopenharmony_ci    WifiWpaInitAlg(keyExt, alg, keyLen);
380e5b75505Sopenharmony_ci    if (WifiWpaInitAddr(keyExt, addr, alg, keyIdx, setTx) != SUCC || WifiWpaInitSeq(keyExt, seq, seqLen) != SUCC ||
381e5b75505Sopenharmony_ci        WifiWpaInitKey(keyExt, key, keyLen, keyIdx, alg) != SUCC) {
382e5b75505Sopenharmony_ci        WifiKeyExtFree(&keyExt);
383e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "WifiWpaInitKey failed");
384e5b75505Sopenharmony_ci        return -EFAIL;
385e5b75505Sopenharmony_ci    }
386e5b75505Sopenharmony_ci
387e5b75505Sopenharmony_ci    if (alg == WPA_ALG_NONE) {
388e5b75505Sopenharmony_ci        ret = WifiCmdDelKey(ifname, keyExt);
389e5b75505Sopenharmony_ci    } else {
390e5b75505Sopenharmony_ci        ret = WifiCmdNewKey(ifname, keyExt);
391e5b75505Sopenharmony_ci        if ((ret != SUCC) || (setTx == 0) || (alg == WPA_ALG_NONE)) {
392e5b75505Sopenharmony_ci            WifiKeyExtFree(&keyExt);
393e5b75505Sopenharmony_ci            return ret;
394e5b75505Sopenharmony_ci        }
395e5b75505Sopenharmony_ci
396e5b75505Sopenharmony_ci        if ((IsApInterface(drv->mode)) && (keyExt->addr != NULL) && (!IsBroadcastAddr(keyExt->addr))) {
397e5b75505Sopenharmony_ci            WifiKeyExtFree(&keyExt);
398e5b75505Sopenharmony_ci            return ret;
399e5b75505Sopenharmony_ci        }
400e5b75505Sopenharmony_ci        ret = WifiCmdSetKey(ifname, keyExt);
401e5b75505Sopenharmony_ci    }
402e5b75505Sopenharmony_ci
403e5b75505Sopenharmony_ci    WifiKeyExtFree(&keyExt);
404e5b75505Sopenharmony_ci    return ret;
405e5b75505Sopenharmony_ci}
406e5b75505Sopenharmony_ci
407e5b75505Sopenharmony_cistatic void WifiWpaReceiveEapol(void *ctx, const uint8_t *srcAddr, const uint8_t *buf, size_t len)
408e5b75505Sopenharmony_ci{
409e5b75505Sopenharmony_ci    WifiDriverData *drv = ctx;
410e5b75505Sopenharmony_ci
411e5b75505Sopenharmony_ci    if ((ctx == NULL) || (srcAddr == NULL) || (buf == NULL) || (len < sizeof(struct l2_ethhdr))) {
412e5b75505Sopenharmony_ci        return;
413e5b75505Sopenharmony_ci    }
414e5b75505Sopenharmony_ci
415e5b75505Sopenharmony_ci    drv_event_eapol_rx(drv->ctx, srcAddr, buf + sizeof(struct l2_ethhdr), len - sizeof(struct l2_ethhdr));
416e5b75505Sopenharmony_ci    wpa_printf(MSG_INFO, "WifiWpaReceiveEapol done");
417e5b75505Sopenharmony_ci}
418e5b75505Sopenharmony_ci
419e5b75505Sopenharmony_cistatic void WifiWpaPreInit(const WifiDriverData *drv)
420e5b75505Sopenharmony_ci{
421e5b75505Sopenharmony_ci    WifiSetMode setMode;
422e5b75505Sopenharmony_ci    WifiSetNewDev info;
423e5b75505Sopenharmony_ci
424e5b75505Sopenharmony_ci    if (drv == NULL) {
425e5b75505Sopenharmony_ci        return;
426e5b75505Sopenharmony_ci    }
427e5b75505Sopenharmony_ci
428e5b75505Sopenharmony_ci    (void)memset_s(&setMode, sizeof(WifiSetMode), 0, sizeof(WifiSetMode));
429e5b75505Sopenharmony_ci    (void)memset_s(&info, sizeof(WifiSetNewDev), 0, sizeof(WifiSetNewDev));
430e5b75505Sopenharmony_ci
431e5b75505Sopenharmony_ci    if  (strncmp(drv->iface, "p2p-p2p0-", 9) == 0) {
432e5b75505Sopenharmony_ci        info.ifType = WIFI_IFTYPE_P2P_CLIENT;
433e5b75505Sopenharmony_ci        setMode.iftype = WIFI_IFTYPE_P2P_CLIENT;
434e5b75505Sopenharmony_ci    } else if (strncmp(drv->iface, "p2p0", 4) == 0) {
435e5b75505Sopenharmony_ci        info.ifType = WIFI_IFTYPE_P2P_DEVICE;
436e5b75505Sopenharmony_ci        setMode.iftype = WIFI_IFTYPE_P2P_DEVICE;
437e5b75505Sopenharmony_ci    } else {
438e5b75505Sopenharmony_ci        setMode.iftype = WIFI_IFTYPE_STATION;
439e5b75505Sopenharmony_ci        info.status = FALSE;
440e5b75505Sopenharmony_ci        info.ifType = WIFI_IFTYPE_STATION;
441e5b75505Sopenharmony_ci        info.mode = WIFI_PHY_MODE_11N;
442e5b75505Sopenharmony_ci        if (WifiCmdSetNetdev(drv->iface, &info) != SUCC) {
443e5b75505Sopenharmony_ci            wpa_printf(MSG_ERROR, "%s set netdev failed", __func__);
444e5b75505Sopenharmony_ci        }
445e5b75505Sopenharmony_ci        if (WifiCmdSetMode((char *)drv->iface, &setMode) != SUCC) {
446e5b75505Sopenharmony_ci            wpa_printf(MSG_ERROR, "%s set mode failed", __func__);
447e5b75505Sopenharmony_ci        }
448e5b75505Sopenharmony_ci    }
449e5b75505Sopenharmony_ci}
450e5b75505Sopenharmony_ci
451e5b75505Sopenharmony_ci#ifdef CONFIG_OPEN_HARMONY_PATCH
452e5b75505Sopenharmony_cistatic void CheckWifiIface(const char *ifName)
453e5b75505Sopenharmony_ci{
454e5b75505Sopenharmony_ci    DIR *dir;
455e5b75505Sopenharmony_ci    struct dirent *dent;
456e5b75505Sopenharmony_ci    while (TRUE) {
457e5b75505Sopenharmony_ci        dir = opendir("/sys/class/net");
458e5b75505Sopenharmony_ci        if (dir == 0) {
459e5b75505Sopenharmony_ci            return;
460e5b75505Sopenharmony_ci        }
461e5b75505Sopenharmony_ci        while ((dent = readdir(dir))) {
462e5b75505Sopenharmony_ci            if (dent->d_name[0] == '.') {
463e5b75505Sopenharmony_ci                continue;
464e5b75505Sopenharmony_ci            }
465e5b75505Sopenharmony_ci            if (strcmp(dent->d_name, ifName) == 0) {
466e5b75505Sopenharmony_ci                goto out;
467e5b75505Sopenharmony_ci            }
468e5b75505Sopenharmony_ci            usleep(WAIT_LOAD_NETDEVICE);
469e5b75505Sopenharmony_ci        }
470e5b75505Sopenharmony_ci    }
471e5b75505Sopenharmony_ciout:
472e5b75505Sopenharmony_ci    closedir(dir);
473e5b75505Sopenharmony_ci}
474e5b75505Sopenharmony_ci#endif
475e5b75505Sopenharmony_ci
476e5b75505Sopenharmony_cistatic void WifiWpaDeinit(void *priv)
477e5b75505Sopenharmony_ci{
478e5b75505Sopenharmony_ci    WifiDriverData *drv = NULL;
479e5b75505Sopenharmony_ci    WifiSetNewDev info;
480e5b75505Sopenharmony_ci
481e5b75505Sopenharmony_ci    if (priv == NULL) {
482e5b75505Sopenharmony_ci        return;
483e5b75505Sopenharmony_ci    }
484e5b75505Sopenharmony_ci
485e5b75505Sopenharmony_ci    drv = (WifiDriverData *)priv;
486e5b75505Sopenharmony_ci    info.status = FALSE;
487e5b75505Sopenharmony_ci    info.ifType = WIFI_IFTYPE_STATION;
488e5b75505Sopenharmony_ci    info.mode = WIFI_PHY_MODE_11N;
489e5b75505Sopenharmony_ci#ifdef CONFIG_OHOS_P2P
490e5b75505Sopenharmony_ci    if  (strncmp(drv->iface, "p2p-p2p0-", 9) == 0) {
491e5b75505Sopenharmony_ci        info.ifType = WIFI_IFTYPE_P2P_CLIENT;
492e5b75505Sopenharmony_ci    } else if (strncmp(drv->iface, "p2p0", 4) == 0) {
493e5b75505Sopenharmony_ci        info.ifType = WIFI_IFTYPE_P2P_DEVICE;
494e5b75505Sopenharmony_ci    }
495e5b75505Sopenharmony_ci    WifiDev *wifiDev = NULL;
496e5b75505Sopenharmony_ci    wifiDev = GetWifiDevByName(drv->iface);
497e5b75505Sopenharmony_ci    if (wifiDev == NULL) {
498e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s: GetWifiDevByName failed.\r\n.", __FUNCTION__);
499e5b75505Sopenharmony_ci    }
500e5b75505Sopenharmony_ci    FreeWifiDev(wifiDev);
501e5b75505Sopenharmony_ci#endif // CONFIG_OHOS_P2P
502e5b75505Sopenharmony_ci    eloop_cancel_timeout(WifiWpaScanTimeout, drv, drv->ctx);
503e5b75505Sopenharmony_ci    WifiCmdSetNetdev(drv->iface, &info);
504e5b75505Sopenharmony_ci
505e5b75505Sopenharmony_ci    if (drv->eapolSock != NULL) {
506e5b75505Sopenharmony_ci        l2_packet_deinit(drv->eapolSock);
507e5b75505Sopenharmony_ci    }
508e5b75505Sopenharmony_ci
509e5b75505Sopenharmony_ci#ifdef CONFIG_OHOS_P2P
510e5b75505Sopenharmony_ci    WifiUnregisterEventCallback(OnWpaWiFiEvents, WIFI_KERNEL_TO_WPA_CLIENT, drv->iface);
511e5b75505Sopenharmony_ci    if (CountWifiDevInUse() == 0) {
512e5b75505Sopenharmony_ci        g_msgInit = TRUE;
513e5b75505Sopenharmony_ci        os_free(g_wifiDriverData);
514e5b75505Sopenharmony_ci        g_wifiDriverData = NULL;
515e5b75505Sopenharmony_ci        (void)WifiClientDeinit(drv->iface);
516e5b75505Sopenharmony_ci    }
517e5b75505Sopenharmony_ci#else
518e5b75505Sopenharmony_ci    os_free(g_wifiDriverData);
519e5b75505Sopenharmony_ci    g_wifiDriverData = NULL;
520e5b75505Sopenharmony_ci    (void)WifiClientDeinit(drv->iface);
521e5b75505Sopenharmony_ci#endif //CONFIG_OHOS_P2P
522e5b75505Sopenharmony_ci
523e5b75505Sopenharmony_ci    wpa_printf(MSG_INFO, "WifiWpaDeinit done");
524e5b75505Sopenharmony_ci}
525e5b75505Sopenharmony_ci
526e5b75505Sopenharmony_cistatic void *WifiWpaInit(void *ctx, const char *ifName)
527e5b75505Sopenharmony_ci{
528e5b75505Sopenharmony_ci    int32_t ret;
529e5b75505Sopenharmony_ci    WifiSetNewDev info;
530e5b75505Sopenharmony_ci#ifdef CONFIG_OHOS_P2P
531e5b75505Sopenharmony_ci    WifiDev *wifiDev = NULL;
532e5b75505Sopenharmony_ci    errno_t rc;
533e5b75505Sopenharmony_ci#endif
534e5b75505Sopenharmony_ci
535e5b75505Sopenharmony_ci    if ((ctx == NULL) || (ifName == NULL)) {
536e5b75505Sopenharmony_ci        return NULL;
537e5b75505Sopenharmony_ci    }
538e5b75505Sopenharmony_ci
539e5b75505Sopenharmony_ci    wpa_printf(MSG_INFO, "%s enter, interface name:%s.", __FUNCTION__, ifName);
540e5b75505Sopenharmony_ci    (void)memset_s(&info, sizeof(WifiSetNewDev), 0, sizeof(WifiSetNewDev));
541e5b75505Sopenharmony_ci    WifiDriverData *drv = os_zalloc(sizeof(WifiDriverData));
542e5b75505Sopenharmony_ci    if (drv == NULL) {
543e5b75505Sopenharmony_ci        goto failed;
544e5b75505Sopenharmony_ci    }
545e5b75505Sopenharmony_ci
546e5b75505Sopenharmony_ci    drv->ctx = ctx;
547e5b75505Sopenharmony_ci    if (memcpy_s(drv->iface, sizeof(drv->iface), ifName, sizeof(drv->iface)) != EOK) {
548e5b75505Sopenharmony_ci        goto failed;
549e5b75505Sopenharmony_ci    }
550e5b75505Sopenharmony_ci#ifdef CONFIG_OHOS_P2P
551e5b75505Sopenharmony_ci    if (g_msgInit && (strncmp(drv->iface, "p2p0", 4) == 0)) {
552e5b75505Sopenharmony_ci        if (WifiClientInit(drv->iface) != SUCC) {
553e5b75505Sopenharmony_ci            goto failed;
554e5b75505Sopenharmony_ci        }
555e5b75505Sopenharmony_ci        g_msgInit = FALSE;
556e5b75505Sopenharmony_ci    }
557e5b75505Sopenharmony_ci#endif // CONFIG_OHOS_P2P
558e5b75505Sopenharmony_ci    if (strncmp(drv->iface, "wlan0", 5) == 0) {
559e5b75505Sopenharmony_ci        if (WifiClientInit(drv->iface) != SUCC) {
560e5b75505Sopenharmony_ci            goto failed;
561e5b75505Sopenharmony_ci        }
562e5b75505Sopenharmony_ci    }
563e5b75505Sopenharmony_ci#ifdef CONFIG_OPEN_HARMONY_PATCH
564e5b75505Sopenharmony_ci    CheckWifiIface(ifName);
565e5b75505Sopenharmony_ci#endif
566e5b75505Sopenharmony_ci    WifiWpaPreInit(drv);
567e5b75505Sopenharmony_ci
568e5b75505Sopenharmony_ci    info.status = TRUE;
569e5b75505Sopenharmony_ci    info.ifType = WIFI_IFTYPE_STATION;
570e5b75505Sopenharmony_ci    info.mode = WIFI_PHY_MODE_11N;
571e5b75505Sopenharmony_ci#ifdef CONFIG_OHOS_P2P
572e5b75505Sopenharmony_ci    if  (strncmp(drv->iface, "p2p-p2p0-", 9) == 0) {
573e5b75505Sopenharmony_ci        info.ifType = WIFI_IFTYPE_P2P_CLIENT;
574e5b75505Sopenharmony_ci    } else if (strncmp(drv->iface, "p2p0", 4) == 0) {
575e5b75505Sopenharmony_ci        info.ifType = WIFI_IFTYPE_P2P_DEVICE;
576e5b75505Sopenharmony_ci    }
577e5b75505Sopenharmony_ci#endif // CONFIG_OHOS_P2P
578e5b75505Sopenharmony_ci    ret = WifiCmdSetNetdev(drv->iface, &info);
579e5b75505Sopenharmony_ci    if (ret != SUCC) {
580e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "WifiWpaInit set netdev faild");
581e5b75505Sopenharmony_ci        goto failed;
582e5b75505Sopenharmony_ci    }
583e5b75505Sopenharmony_ci    drv->eapolSock = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL, WifiWpaReceiveEapol, drv, 1);
584e5b75505Sopenharmony_ci    if (drv->eapolSock == NULL) {
585e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "WifiWpaInit l2_packet_init faild");
586e5b75505Sopenharmony_ci        goto failed;
587e5b75505Sopenharmony_ci    }
588e5b75505Sopenharmony_ci
589e5b75505Sopenharmony_ci    if (l2_packet_get_own_addr(drv->eapolSock, drv->ownAddr)) {
590e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "l2_packet_get_own_addr faild");
591e5b75505Sopenharmony_ci        goto failed;
592e5b75505Sopenharmony_ci    }
593e5b75505Sopenharmony_ci
594e5b75505Sopenharmony_ci    g_wifiDriverType = WIFI_IFTYPE_STATION;
595e5b75505Sopenharmony_ci#ifdef CONFIG_OHOS_P2P
596e5b75505Sopenharmony_ci    wifiDev = (WifiDev *)os_zalloc(sizeof(WifiDev));
597e5b75505Sopenharmony_ci    if (wifiDev == NULL) {
598e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s wifiDev malloc failed.", __FUNCTION__);
599e5b75505Sopenharmony_ci        goto failed;
600e5b75505Sopenharmony_ci    }
601e5b75505Sopenharmony_ci    wifiDev->priv = drv;
602e5b75505Sopenharmony_ci    wifiDev->ifNameLen = sizeof(ifName);
603e5b75505Sopenharmony_ci    rc = memcpy_s(wifiDev->ifName, sizeof(wifiDev->ifName), drv->iface, sizeof(drv->iface));
604e5b75505Sopenharmony_ci    if (rc != EOK) {
605e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s could not copy wifi device name.", __FUNCTION__);
606e5b75505Sopenharmony_ci        goto failed;
607e5b75505Sopenharmony_ci    }
608e5b75505Sopenharmony_ci    wpa_printf(MSG_ERROR, "%s init done, ifName:%s.", __FUNCTION__, wifiDev->ifName);
609e5b75505Sopenharmony_ci    SetWifiDev(wifiDev);
610e5b75505Sopenharmony_ci#endif // CONFIG_OHOS_P2P
611e5b75505Sopenharmony_ci    g_wifiDriverData = drv;
612e5b75505Sopenharmony_ci    return drv;
613e5b75505Sopenharmony_ci
614e5b75505Sopenharmony_cifailed:
615e5b75505Sopenharmony_ci#ifdef CONFIG_OHOS_P2P
616e5b75505Sopenharmony_ci    FreeWifiDev(wifiDev);
617e5b75505Sopenharmony_ci#endif // CONFIG_OHOS_P2P
618e5b75505Sopenharmony_ci    WifiWpaDeinit(drv);
619e5b75505Sopenharmony_ci    return NULL;
620e5b75505Sopenharmony_ci}
621e5b75505Sopenharmony_ci
622e5b75505Sopenharmony_cistatic int32_t WifiWpaDeauthenticate(void *priv, const uint8_t *addr, uint16_t reasonCode)
623e5b75505Sopenharmony_ci{
624e5b75505Sopenharmony_ci    int32_t ret;
625e5b75505Sopenharmony_ci    WifiDriverData *drv = priv;
626e5b75505Sopenharmony_ci
627e5b75505Sopenharmony_ci    (void)addr;
628e5b75505Sopenharmony_ci    if (priv == NULL) {
629e5b75505Sopenharmony_ci        return -EFAIL;
630e5b75505Sopenharmony_ci    }
631e5b75505Sopenharmony_ci
632e5b75505Sopenharmony_ci    wpa_printf(MSG_INFO, "WifiWpaDeauthenticate reasonCode = %d", reasonCode);
633e5b75505Sopenharmony_ci    ret = WifiCmdDisconnet(drv->iface, reasonCode);
634e5b75505Sopenharmony_ci    if (ret == SUCC) {
635e5b75505Sopenharmony_ci        drv->associated = WIFI_DISCONNECT;
636e5b75505Sopenharmony_ci    }
637e5b75505Sopenharmony_ci    return ret;
638e5b75505Sopenharmony_ci}
639e5b75505Sopenharmony_ci
640e5b75505Sopenharmony_cistatic int32_t WifiWpaDriverAp(WifiDriverData *drv, struct wpa_driver_associate_params *params)
641e5b75505Sopenharmony_ci{
642e5b75505Sopenharmony_ci    int32_t ret;
643e5b75505Sopenharmony_ci    WifiSetMode setMode;
644e5b75505Sopenharmony_ci    errno_t rc;
645e5b75505Sopenharmony_ci
646e5b75505Sopenharmony_ci    if ((drv == NULL) || (params == NULL)) {
647e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s input NULL ptr.", __FUNCTION__);
648e5b75505Sopenharmony_ci        return -EFAIL;
649e5b75505Sopenharmony_ci    }
650e5b75505Sopenharmony_ci    rc = memset_s(&setMode, sizeof(WifiSetMode), 0, sizeof(WifiSetMode));
651e5b75505Sopenharmony_ci    if (rc != EOK) {
652e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s: memset failed.", __FUNCTION__);
653e5b75505Sopenharmony_ci        return -EFAIL;
654e5b75505Sopenharmony_ci    }
655e5b75505Sopenharmony_ci    if (params->p2p) {
656e5b75505Sopenharmony_ci        wpa_printf(MSG_INFO, "%s: Setup AP operations for P2P group.(GO).", __FUNCTION__);
657e5b75505Sopenharmony_ci        setMode.iftype = WIFI_IFTYPE_P2P_GO;
658e5b75505Sopenharmony_ci    } else {
659e5b75505Sopenharmony_ci        setMode.iftype = WIFI_IFTYPE_AP;
660e5b75505Sopenharmony_ci    }
661e5b75505Sopenharmony_ci    rc = memcpy_s(setMode.bssid, ETH_ADDR_LEN, drv->ownAddr, ETH_ADDR_LEN);
662e5b75505Sopenharmony_ci    if (rc != EOK) {
663e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s memcpy failed.", __FUNCTION__);
664e5b75505Sopenharmony_ci        return -EFAIL;
665e5b75505Sopenharmony_ci    }
666e5b75505Sopenharmony_ci    ret = WifiCmdSetMode(drv->iface, &setMode);
667e5b75505Sopenharmony_ci    if (ret != SUCC) {
668e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s: set mode failed.", __FUNCTION__);
669e5b75505Sopenharmony_ci        return -EFAIL;
670e5b75505Sopenharmony_ci    }
671e5b75505Sopenharmony_ci    return SUCC;
672e5b75505Sopenharmony_ci}
673e5b75505Sopenharmony_ci
674e5b75505Sopenharmony_cistatic int32_t WifiWpaAssocParamsSet(WifiDriverData *drv, struct wpa_driver_associate_params *params,
675e5b75505Sopenharmony_ci    WifiAssociateParams *assocParams)
676e5b75505Sopenharmony_ci{
677e5b75505Sopenharmony_ci    if (params->bssid != NULL) {
678e5b75505Sopenharmony_ci        assocParams->bssid = (uint8_t *)os_zalloc(ETH_ADDR_LEN);
679e5b75505Sopenharmony_ci        if (assocParams->bssid == NULL) {
680e5b75505Sopenharmony_ci            return -EFAIL;
681e5b75505Sopenharmony_ci        }
682e5b75505Sopenharmony_ci        if (memcpy_s(assocParams->bssid, ETH_ADDR_LEN, params->bssid, ETH_ADDR_LEN) != EOK) {
683e5b75505Sopenharmony_ci            return -EFAIL;
684e5b75505Sopenharmony_ci        }
685e5b75505Sopenharmony_ci    }
686e5b75505Sopenharmony_ci
687e5b75505Sopenharmony_ci    if (params->freq.freq != 0) {
688e5b75505Sopenharmony_ci        assocParams->freq = params->freq.freq;
689e5b75505Sopenharmony_ci    }
690e5b75505Sopenharmony_ci    if (params->ssid_len > MAX_SSID_LEN) {
691e5b75505Sopenharmony_ci        params->ssid_len = MAX_SSID_LEN;
692e5b75505Sopenharmony_ci    }
693e5b75505Sopenharmony_ci    if ((params->ssid != NULL) && (params->ssid_len != 0)) {
694e5b75505Sopenharmony_ci        assocParams->ssid = (uint8_t *)os_zalloc(params->ssid_len);
695e5b75505Sopenharmony_ci        if (assocParams->ssid == NULL) {
696e5b75505Sopenharmony_ci            return -EFAIL;
697e5b75505Sopenharmony_ci        }
698e5b75505Sopenharmony_ci        assocParams->ssidLen = params->ssid_len;
699e5b75505Sopenharmony_ci        if (memcpy_s(assocParams->ssid, assocParams->ssidLen, params->ssid, params->ssid_len) != EOK) {
700e5b75505Sopenharmony_ci            return -EFAIL;
701e5b75505Sopenharmony_ci        }
702e5b75505Sopenharmony_ci        if (memset_s(drv->ssid, MAX_SSID_LEN, 0, MAX_SSID_LEN) != EOK) {
703e5b75505Sopenharmony_ci            return -EFAIL;
704e5b75505Sopenharmony_ci        }
705e5b75505Sopenharmony_ci        if (memcpy_s(drv->ssid, MAX_SSID_LEN, params->ssid, params->ssid_len) != EOK) {
706e5b75505Sopenharmony_ci            return -EFAIL;
707e5b75505Sopenharmony_ci        }
708e5b75505Sopenharmony_ci        drv->ssidLen = params->ssid_len;
709e5b75505Sopenharmony_ci    }
710e5b75505Sopenharmony_ci
711e5b75505Sopenharmony_ci    if ((params->wpa_ie != NULL) && (params->wpa_ie_len != 0)) {
712e5b75505Sopenharmony_ci        assocParams->ie = (uint8_t *)os_zalloc(params->wpa_ie_len);
713e5b75505Sopenharmony_ci        if (assocParams->ie == NULL) {
714e5b75505Sopenharmony_ci            return -EFAIL;
715e5b75505Sopenharmony_ci        }
716e5b75505Sopenharmony_ci        assocParams->ieLen = params->wpa_ie_len;
717e5b75505Sopenharmony_ci        if (memcpy_s(assocParams->ie, assocParams->ieLen, params->wpa_ie, params->wpa_ie_len) != EOK) {
718e5b75505Sopenharmony_ci            return -EFAIL;
719e5b75505Sopenharmony_ci        }
720e5b75505Sopenharmony_ci    }
721e5b75505Sopenharmony_ci
722e5b75505Sopenharmony_ci    return SUCC;
723e5b75505Sopenharmony_ci}
724e5b75505Sopenharmony_ci
725e5b75505Sopenharmony_cistatic uint32_t WifiCipherToCipherSuite(uint32_t cipher)
726e5b75505Sopenharmony_ci{
727e5b75505Sopenharmony_ci    switch (cipher) {
728e5b75505Sopenharmony_ci        case WPA_CIPHER_CCMP_256:
729e5b75505Sopenharmony_ci            return RSN_CIPHER_SUITE_CCMP_256;
730e5b75505Sopenharmony_ci        case WPA_CIPHER_GCMP_256:
731e5b75505Sopenharmony_ci            return RSN_CIPHER_SUITE_GCMP_256;
732e5b75505Sopenharmony_ci        case WPA_CIPHER_CCMP:
733e5b75505Sopenharmony_ci            return RSN_CIPHER_SUITE_CCMP;
734e5b75505Sopenharmony_ci        case WPA_CIPHER_GCMP:
735e5b75505Sopenharmony_ci            return RSN_CIPHER_SUITE_GCMP;
736e5b75505Sopenharmony_ci        case WPA_CIPHER_TKIP:
737e5b75505Sopenharmony_ci            return RSN_CIPHER_SUITE_TKIP;
738e5b75505Sopenharmony_ci        case WPA_CIPHER_WEP104:
739e5b75505Sopenharmony_ci            return RSN_CIPHER_SUITE_WEP104;
740e5b75505Sopenharmony_ci        case WPA_CIPHER_WEP40:
741e5b75505Sopenharmony_ci            return RSN_CIPHER_SUITE_WEP40;
742e5b75505Sopenharmony_ci        case WPA_CIPHER_GTK_NOT_USED:
743e5b75505Sopenharmony_ci            return RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED;
744e5b75505Sopenharmony_ci        default:
745e5b75505Sopenharmony_ci            return 0;
746e5b75505Sopenharmony_ci    }
747e5b75505Sopenharmony_ci}
748e5b75505Sopenharmony_ci
749e5b75505Sopenharmony_cistatic int32_t WifiWpaAssocParamCryptoSet(const struct wpa_driver_associate_params *params,
750e5b75505Sopenharmony_ci    WifiAssociateParams *assocParams)
751e5b75505Sopenharmony_ci{
752e5b75505Sopenharmony_ci    uint32_t ver = 0;
753e5b75505Sopenharmony_ci    uint32_t akm_suites_num = 0;
754e5b75505Sopenharmony_ci    uint32_t ciphers_pairwise_num = 0;
755e5b75505Sopenharmony_ci    int32_t mgmt = RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X;
756e5b75505Sopenharmony_ci
757e5b75505Sopenharmony_ci    assocParams->crypto = (WifiCryptoSetting *)os_zalloc(sizeof(WifiCryptoSetting));
758e5b75505Sopenharmony_ci    if (assocParams->crypto == NULL) {
759e5b75505Sopenharmony_ci        return -EFAIL;
760e5b75505Sopenharmony_ci    }
761e5b75505Sopenharmony_ci
762e5b75505Sopenharmony_ci    if (params->wpa_proto != 0) {
763e5b75505Sopenharmony_ci        if (params->wpa_proto & WPA_PROTO_WPA) {
764e5b75505Sopenharmony_ci            ver |= WPA_VERSION_1;
765e5b75505Sopenharmony_ci        }
766e5b75505Sopenharmony_ci        if (params->wpa_proto & WPA_PROTO_RSN) {
767e5b75505Sopenharmony_ci            ver |= WPA_VERSION_2;
768e5b75505Sopenharmony_ci        }
769e5b75505Sopenharmony_ci        assocParams->crypto->wpaVersions = ver;
770e5b75505Sopenharmony_ci    }
771e5b75505Sopenharmony_ci
772e5b75505Sopenharmony_ci    if (params->pairwise_suite != WPA_CIPHER_NONE) {
773e5b75505Sopenharmony_ci        assocParams->crypto->ciphersPairwise[ciphers_pairwise_num++] = WifiCipherToCipherSuite(params->pairwise_suite);
774e5b75505Sopenharmony_ci        assocParams->crypto->nCiphersPairwise = ciphers_pairwise_num;
775e5b75505Sopenharmony_ci    }
776e5b75505Sopenharmony_ci
777e5b75505Sopenharmony_ci    if (params->group_suite != WPA_CIPHER_NONE) {
778e5b75505Sopenharmony_ci        assocParams->crypto->cipherGroup = WifiCipherToCipherSuite(params->group_suite);
779e5b75505Sopenharmony_ci    }
780e5b75505Sopenharmony_ci
781e5b75505Sopenharmony_ci    if (params->key_mgmt_suite == WPA_KEY_MGMT_PSK || params->key_mgmt_suite == WPA_KEY_MGMT_SAE ||
782e5b75505Sopenharmony_ci        params->key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256) {
783e5b75505Sopenharmony_ci        switch (params->key_mgmt_suite) {
784e5b75505Sopenharmony_ci            case WPA_KEY_MGMT_PSK_SHA256:
785e5b75505Sopenharmony_ci                mgmt = RSN_AUTH_KEY_MGMT_PSK_SHA256;
786e5b75505Sopenharmony_ci                break;
787e5b75505Sopenharmony_ci            case WPA_KEY_MGMT_SAE:
788e5b75505Sopenharmony_ci                mgmt = RSN_AUTH_KEY_MGMT_SAE;
789e5b75505Sopenharmony_ci                break;
790e5b75505Sopenharmony_ci            case WPA_KEY_MGMT_PSK: /* fall through */
791e5b75505Sopenharmony_ci            default:
792e5b75505Sopenharmony_ci                mgmt = RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X;
793e5b75505Sopenharmony_ci                break;
794e5b75505Sopenharmony_ci        }
795e5b75505Sopenharmony_ci        assocParams->crypto->akmSuites[akm_suites_num++] = mgmt;
796e5b75505Sopenharmony_ci        assocParams->crypto->nAkmSuites = akm_suites_num;
797e5b75505Sopenharmony_ci    }
798e5b75505Sopenharmony_ci
799e5b75505Sopenharmony_ci    return SUCC;
800e5b75505Sopenharmony_ci}
801e5b75505Sopenharmony_ci
802e5b75505Sopenharmony_cistatic void WifiWpaSetConnKeys(const struct wpa_driver_associate_params *wpa_params, WifiAssociateParams *params)
803e5b75505Sopenharmony_ci{
804e5b75505Sopenharmony_ci    int32_t loop;
805e5b75505Sopenharmony_ci    uint8_t privacy;
806e5b75505Sopenharmony_ci    errno_t rc;
807e5b75505Sopenharmony_ci
808e5b75505Sopenharmony_ci    if ((wpa_params == NULL) || (params == NULL)) {
809e5b75505Sopenharmony_ci        return;
810e5b75505Sopenharmony_ci    }
811e5b75505Sopenharmony_ci
812e5b75505Sopenharmony_ci    privacy = 0;
813e5b75505Sopenharmony_ci    for (loop = 0; loop < WEP_KEY_NUM; loop++) {
814e5b75505Sopenharmony_ci        if (wpa_params->wep_key[loop] == NULL) {
815e5b75505Sopenharmony_ci            continue;
816e5b75505Sopenharmony_ci        }
817e5b75505Sopenharmony_ci        privacy = 1;
818e5b75505Sopenharmony_ci        break;
819e5b75505Sopenharmony_ci    }
820e5b75505Sopenharmony_ci
821e5b75505Sopenharmony_ci    if ((wpa_params->wps == WPS_MODE_PRIVACY) ||
822e5b75505Sopenharmony_ci        ((wpa_params->pairwise_suite != 0) && (wpa_params->pairwise_suite != WPA_CIPHER_NONE))) {
823e5b75505Sopenharmony_ci        privacy = 1;
824e5b75505Sopenharmony_ci    }
825e5b75505Sopenharmony_ci    if (privacy == 0) {
826e5b75505Sopenharmony_ci        return;
827e5b75505Sopenharmony_ci    }
828e5b75505Sopenharmony_ci    params->privacy = privacy;
829e5b75505Sopenharmony_ci    for (loop = 0; loop < WEP_KEY_NUM; loop++) {
830e5b75505Sopenharmony_ci        if (wpa_params->wep_key[loop] == NULL) {
831e5b75505Sopenharmony_ci            continue;
832e5b75505Sopenharmony_ci        }
833e5b75505Sopenharmony_ci        params->keyLen = wpa_params->wep_key_len[loop];
834e5b75505Sopenharmony_ci        params->key = (uint8_t *)os_zalloc(params->keyLen);
835e5b75505Sopenharmony_ci        if (params->key == NULL) {
836e5b75505Sopenharmony_ci            return;
837e5b75505Sopenharmony_ci        }
838e5b75505Sopenharmony_ci
839e5b75505Sopenharmony_ci        rc = memcpy_s(params->key, params->keyLen, wpa_params->wep_key[loop], params->keyLen);
840e5b75505Sopenharmony_ci        if (rc != EOK) {
841e5b75505Sopenharmony_ci            os_free(params->key);
842e5b75505Sopenharmony_ci            params->key = NULL;
843e5b75505Sopenharmony_ci            return;
844e5b75505Sopenharmony_ci        }
845e5b75505Sopenharmony_ci        params->keyIdx = wpa_params->wep_tx_keyidx;
846e5b75505Sopenharmony_ci        break;
847e5b75505Sopenharmony_ci    }
848e5b75505Sopenharmony_ci
849e5b75505Sopenharmony_ci    return;
850e5b75505Sopenharmony_ci}
851e5b75505Sopenharmony_ci
852e5b75505Sopenharmony_cistatic void WifiWpaConnectFree(WifiAssociateParams **params)
853e5b75505Sopenharmony_ci{
854e5b75505Sopenharmony_ci    if (params == NULL || *params == NULL) {
855e5b75505Sopenharmony_ci        return;
856e5b75505Sopenharmony_ci    }
857e5b75505Sopenharmony_ci
858e5b75505Sopenharmony_ci    if ((*params)->ie != NULL) {
859e5b75505Sopenharmony_ci        os_free((*params)->ie);
860e5b75505Sopenharmony_ci        (*params)->ie = NULL;
861e5b75505Sopenharmony_ci    }
862e5b75505Sopenharmony_ci    if ((*params)->crypto != NULL) {
863e5b75505Sopenharmony_ci        os_free((*params)->crypto);
864e5b75505Sopenharmony_ci        (*params)->crypto = NULL;
865e5b75505Sopenharmony_ci    }
866e5b75505Sopenharmony_ci    if ((*params)->ssid != NULL) {
867e5b75505Sopenharmony_ci        os_free((*params)->ssid);
868e5b75505Sopenharmony_ci        (*params)->ssid = NULL;
869e5b75505Sopenharmony_ci    }
870e5b75505Sopenharmony_ci    if ((*params)->bssid != NULL) {
871e5b75505Sopenharmony_ci        os_free((*params)->bssid);
872e5b75505Sopenharmony_ci        (*params)->bssid = NULL;
873e5b75505Sopenharmony_ci    }
874e5b75505Sopenharmony_ci    if ((*params)->key != NULL) {
875e5b75505Sopenharmony_ci        os_free((*params)->key);
876e5b75505Sopenharmony_ci        (*params)->key = NULL;
877e5b75505Sopenharmony_ci    }
878e5b75505Sopenharmony_ci
879e5b75505Sopenharmony_ci    os_free(*params);
880e5b75505Sopenharmony_ci    *params = NULL;
881e5b75505Sopenharmony_ci}
882e5b75505Sopenharmony_ci
883e5b75505Sopenharmony_cistatic WifiAuthType WifiGetStaAuthType(const struct wpa_driver_associate_params *params)
884e5b75505Sopenharmony_ci{
885e5b75505Sopenharmony_ci    WifiAuthType type = WIFI_AUTHTYPE_BUTT;
886e5b75505Sopenharmony_ci    uint32_t algs = 0;
887e5b75505Sopenharmony_ci
888e5b75505Sopenharmony_ci    if ((uint32_t)(params->auth_alg) & WPA_AUTH_ALG_OPEN) {
889e5b75505Sopenharmony_ci        type = WIFI_AUTHTYPE_OPEN_SYSTEM;
890e5b75505Sopenharmony_ci        algs++;
891e5b75505Sopenharmony_ci    }
892e5b75505Sopenharmony_ci    if ((uint32_t)(params->auth_alg) & WPA_AUTH_ALG_SHARED) {
893e5b75505Sopenharmony_ci        type = WIFI_AUTHTYPE_SHARED_KEY;
894e5b75505Sopenharmony_ci        algs++;
895e5b75505Sopenharmony_ci    }
896e5b75505Sopenharmony_ci    if ((uint32_t)(params->auth_alg) & WPA_AUTH_ALG_LEAP) {
897e5b75505Sopenharmony_ci        type = WIFI_AUTHTYPE_EAP;
898e5b75505Sopenharmony_ci        algs++;
899e5b75505Sopenharmony_ci    }
900e5b75505Sopenharmony_ci
901e5b75505Sopenharmony_ci    if (algs > 1) {
902e5b75505Sopenharmony_ci        return WIFI_AUTHTYPE_AUTOMATIC;
903e5b75505Sopenharmony_ci    } else if (algs == 1) {
904e5b75505Sopenharmony_ci        return type;
905e5b75505Sopenharmony_ci    }
906e5b75505Sopenharmony_ci
907e5b75505Sopenharmony_ci    if ((uint32_t)params->auth_alg & WPA_AUTH_ALG_FT) {
908e5b75505Sopenharmony_ci        type = WIFI_AUTHTYPE_FT;
909e5b75505Sopenharmony_ci    }
910e5b75505Sopenharmony_ci    return type;
911e5b75505Sopenharmony_ci}
912e5b75505Sopenharmony_ci
913e5b75505Sopenharmony_cistatic int32_t WifiWpaTryConnect(WifiDriverData *drv, struct wpa_driver_associate_params *params)
914e5b75505Sopenharmony_ci{
915e5b75505Sopenharmony_ci    WifiAssociateParams *assocParams = NULL;
916e5b75505Sopenharmony_ci    int32_t ret = -EFAIL;
917e5b75505Sopenharmony_ci
918e5b75505Sopenharmony_ci    if ((drv == NULL) || (params == NULL)) {
919e5b75505Sopenharmony_ci        return -EFAIL;
920e5b75505Sopenharmony_ci    }
921e5b75505Sopenharmony_ci
922e5b75505Sopenharmony_ci    assocParams = (WifiAssociateParams *)os_zalloc(sizeof(WifiAssociateParams));
923e5b75505Sopenharmony_ci    if (assocParams == NULL) {
924e5b75505Sopenharmony_ci        return ret;
925e5b75505Sopenharmony_ci    }
926e5b75505Sopenharmony_ci    if (WifiWpaAssocParamsSet(drv, params, assocParams) != SUCC) {
927e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "WifiWpaTryConnect set assoc params faild");
928e5b75505Sopenharmony_ci        goto skip_auth_type;
929e5b75505Sopenharmony_ci    }
930e5b75505Sopenharmony_ci    if (WifiWpaAssocParamCryptoSet(params, assocParams) != SUCC) {
931e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "WifiWpaTryConnect set assoc crypto faild");
932e5b75505Sopenharmony_ci        goto skip_auth_type;
933e5b75505Sopenharmony_ci    }
934e5b75505Sopenharmony_ci    assocParams->mfp = params->mgmt_frame_protection;
935e5b75505Sopenharmony_ci    assocParams->authType = WifiGetStaAuthType(params);
936e5b75505Sopenharmony_ci
937e5b75505Sopenharmony_ci    WifiWpaSetConnKeys(params, assocParams);
938e5b75505Sopenharmony_ci    ret = WifiCmdAssoc(drv->iface, assocParams);
939e5b75505Sopenharmony_ci    if (ret != SUCC) {
940e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "WifiWpaTryConnect assoc faild");
941e5b75505Sopenharmony_ci    }
942e5b75505Sopenharmony_ci
943e5b75505Sopenharmony_ciskip_auth_type:
944e5b75505Sopenharmony_ci    WifiWpaConnectFree(&assocParams);
945e5b75505Sopenharmony_ci    return ret;
946e5b75505Sopenharmony_ci}
947e5b75505Sopenharmony_ci
948e5b75505Sopenharmony_cistatic int32_t WifiWpaDisconnet(WifiDriverData *drv, uint16_t reasonCode)
949e5b75505Sopenharmony_ci{
950e5b75505Sopenharmony_ci    int32_t ret;
951e5b75505Sopenharmony_ci
952e5b75505Sopenharmony_ci    if (drv == NULL) {
953e5b75505Sopenharmony_ci        return -EFAIL;
954e5b75505Sopenharmony_ci    }
955e5b75505Sopenharmony_ci    ret = WifiCmdDisconnet(drv->iface, reasonCode);
956e5b75505Sopenharmony_ci    if (ret == SUCC) {
957e5b75505Sopenharmony_ci        drv->associated = WIFI_DISCONNECT;
958e5b75505Sopenharmony_ci    }
959e5b75505Sopenharmony_ci    wpa_printf(MSG_INFO, "WifiWpaDisconnet done ret=%d", ret);
960e5b75505Sopenharmony_ci    return ret;
961e5b75505Sopenharmony_ci}
962e5b75505Sopenharmony_cistatic int WifiWpaAssociate(void *priv, struct wpa_driver_associate_params *params)
963e5b75505Sopenharmony_ci{
964e5b75505Sopenharmony_ci    int ret;
965e5b75505Sopenharmony_ci    WifiDriverData *drv = priv;
966e5b75505Sopenharmony_ci
967e5b75505Sopenharmony_ci    if ((drv == NULL) || (params == NULL)) {
968e5b75505Sopenharmony_ci        return -EFAIL;
969e5b75505Sopenharmony_ci    }
970e5b75505Sopenharmony_ci#ifdef CONFIG_OHOS_P2P
971e5b75505Sopenharmony_ci    if (params->mode == IEEE80211_MODE_AP) {
972e5b75505Sopenharmony_ci        return WifiWpaDriverAp(drv, params);
973e5b75505Sopenharmony_ci    }
974e5b75505Sopenharmony_ci#endif
975e5b75505Sopenharmony_ci    ret = WifiWpaTryConnect(drv, params);
976e5b75505Sopenharmony_ci    if (ret != SUCC) {
977e5b75505Sopenharmony_ci        if (WifiWpaDisconnet(drv, WLAN_REASON_PREV_AUTH_NOT_VALID)) {
978e5b75505Sopenharmony_ci            return -EFAIL;
979e5b75505Sopenharmony_ci        }
980e5b75505Sopenharmony_ci        ret = WifiWpaTryConnect(drv, params);
981e5b75505Sopenharmony_ci    }
982e5b75505Sopenharmony_ci    wpa_printf(MSG_INFO, "WifiWpaAssociate done ret=%d", ret);
983e5b75505Sopenharmony_ci    return ret;
984e5b75505Sopenharmony_ci}
985e5b75505Sopenharmony_ci
986e5b75505Sopenharmony_cistatic const uint8_t *WifiWpaGetMacAddr(void *priv)
987e5b75505Sopenharmony_ci{
988e5b75505Sopenharmony_ci    WifiDriverData *drv = priv;
989e5b75505Sopenharmony_ci
990e5b75505Sopenharmony_ci    if (priv == NULL) {
991e5b75505Sopenharmony_ci        return NULL;
992e5b75505Sopenharmony_ci    }
993e5b75505Sopenharmony_ci    return drv->ownAddr;
994e5b75505Sopenharmony_ci}
995e5b75505Sopenharmony_ci
996e5b75505Sopenharmony_ciint32_t WifiWpaWpaSendEapol(void *priv, const uint8_t *dest, uint16_t proto, const uint8_t *data, size_t dataLen)
997e5b75505Sopenharmony_ci{
998e5b75505Sopenharmony_ci    WifiDriverData *drv = priv;
999e5b75505Sopenharmony_ci    int32_t ret;
1000e5b75505Sopenharmony_ci    uint32_t frameLen;
1001e5b75505Sopenharmony_ci    uint8_t *frame = NULL;
1002e5b75505Sopenharmony_ci    uint8_t *payload = NULL;
1003e5b75505Sopenharmony_ci    struct l2_ethhdr *l2_ethhdr = NULL;
1004e5b75505Sopenharmony_ci    errno_t rc;
1005e5b75505Sopenharmony_ci
1006e5b75505Sopenharmony_ci    if ((priv == NULL) || (data == NULL) || (dest == NULL)) {
1007e5b75505Sopenharmony_ci        return -EFAIL;
1008e5b75505Sopenharmony_ci    }
1009e5b75505Sopenharmony_ci
1010e5b75505Sopenharmony_ci    frameLen = dataLen + sizeof(struct l2_ethhdr);
1011e5b75505Sopenharmony_ci    frame = os_zalloc(frameLen);
1012e5b75505Sopenharmony_ci    if (frame == NULL) {
1013e5b75505Sopenharmony_ci        return -EFAIL;
1014e5b75505Sopenharmony_ci    }
1015e5b75505Sopenharmony_ci
1016e5b75505Sopenharmony_ci    l2_ethhdr = (struct l2_ethhdr *)frame;
1017e5b75505Sopenharmony_ci    rc = memcpy_s(l2_ethhdr->h_dest, ETH_ADDR_LEN, dest, ETH_ADDR_LEN);
1018e5b75505Sopenharmony_ci    if (rc != EOK) {
1019e5b75505Sopenharmony_ci        os_free(frame);
1020e5b75505Sopenharmony_ci        frame = NULL;
1021e5b75505Sopenharmony_ci        return -EFAIL;
1022e5b75505Sopenharmony_ci    }
1023e5b75505Sopenharmony_ci    rc = memcpy_s(l2_ethhdr->h_source, ETH_ADDR_LEN, drv->ownAddr, ETH_ADDR_LEN);
1024e5b75505Sopenharmony_ci    if (rc != EOK) {
1025e5b75505Sopenharmony_ci        os_free(frame);
1026e5b75505Sopenharmony_ci        frame = NULL;
1027e5b75505Sopenharmony_ci        return -EFAIL;
1028e5b75505Sopenharmony_ci    }
1029e5b75505Sopenharmony_ci    l2_ethhdr->h_proto = host_to_be16(proto);
1030e5b75505Sopenharmony_ci
1031e5b75505Sopenharmony_ci    payload = (uint8_t *)(l2_ethhdr + 1);
1032e5b75505Sopenharmony_ci    rc = memcpy_s(payload, dataLen, data, dataLen);
1033e5b75505Sopenharmony_ci    if (rc != EOK) {
1034e5b75505Sopenharmony_ci        os_free(frame);
1035e5b75505Sopenharmony_ci        frame = NULL;
1036e5b75505Sopenharmony_ci        return -EFAIL;
1037e5b75505Sopenharmony_ci    }
1038e5b75505Sopenharmony_ci    ret = l2_packet_send(drv->eapolSock, dest, host_to_be16(proto), frame, frameLen);
1039e5b75505Sopenharmony_ci    os_free(frame);
1040e5b75505Sopenharmony_ci    frame = NULL;
1041e5b75505Sopenharmony_ci    wpa_printf(MSG_INFO, "WifiWpaWpaSendEapol done ret=%d", ret);
1042e5b75505Sopenharmony_ci    return ret;
1043e5b75505Sopenharmony_ci}
1044e5b75505Sopenharmony_ci
1045e5b75505Sopenharmony_cistatic void WifiWpaHwFeatureDataFree(struct hostapd_hw_modes **modes, uint16_t num)
1046e5b75505Sopenharmony_ci{
1047e5b75505Sopenharmony_ci    uint16_t loop;
1048e5b75505Sopenharmony_ci
1049e5b75505Sopenharmony_ci    if (modes == NULL || *modes == NULL) {
1050e5b75505Sopenharmony_ci        return;
1051e5b75505Sopenharmony_ci    }
1052e5b75505Sopenharmony_ci    for (loop = 0; loop < num; ++loop) {
1053e5b75505Sopenharmony_ci        if ((*modes)[loop].channels != NULL) {
1054e5b75505Sopenharmony_ci            os_free((*modes)[loop].channels);
1055e5b75505Sopenharmony_ci            (*modes)[loop].channels = NULL;
1056e5b75505Sopenharmony_ci        }
1057e5b75505Sopenharmony_ci        if ((*modes)[loop].rates != NULL) {
1058e5b75505Sopenharmony_ci            os_free((*modes)[loop].rates);
1059e5b75505Sopenharmony_ci            (*modes)[loop].rates = NULL;
1060e5b75505Sopenharmony_ci        }
1061e5b75505Sopenharmony_ci    }
1062e5b75505Sopenharmony_ci    os_free(*modes);
1063e5b75505Sopenharmony_ci    *modes = NULL;
1064e5b75505Sopenharmony_ci}
1065e5b75505Sopenharmony_ci
1066e5b75505Sopenharmony_cistatic struct hostapd_hw_modes *WifiWpaGetHwFeatureData(void *priv, uint16_t *numModes, uint16_t *flags, uint8_t *dfs)
1067e5b75505Sopenharmony_ci{
1068e5b75505Sopenharmony_ci    WifiModes modesData[] = {{IEEE80211G_RATES_NUM, HOSTAPD_MODE_IEEE80211G},
1069e5b75505Sopenharmony_ci        {IEEE80211B_RATES_NUM, HOSTAPD_MODE_IEEE80211B}, {IEEE80211A_RATES_NUM, HOSTAPD_MODE_IEEE80211A}};
1070e5b75505Sopenharmony_ci    size_t loop;
1071e5b75505Sopenharmony_ci    uint32_t index;
1072e5b75505Sopenharmony_ci    uint32_t iee80211band;
1073e5b75505Sopenharmony_ci    WifiHwFeatureData hwFeatureData;
1074e5b75505Sopenharmony_ci    WifiDriverData *drv = (WifiDriverData *)priv;
1075e5b75505Sopenharmony_ci    (void)dfs;
1076e5b75505Sopenharmony_ci    if ((priv == NULL) || (numModes == NULL) || (flags == NULL)) {
1077e5b75505Sopenharmony_ci        return NULL;
1078e5b75505Sopenharmony_ci    }
1079e5b75505Sopenharmony_ci    (void)memset_s(&hwFeatureData, sizeof(WifiHwFeatureData), 0, sizeof(WifiHwFeatureData));
1080e5b75505Sopenharmony_ci    *numModes = DEFAULT_NUM_MODES;
1081e5b75505Sopenharmony_ci    *flags = 0;
1082e5b75505Sopenharmony_ci
1083e5b75505Sopenharmony_ci    if (WifiCmdGetHwFeature(drv->iface, &hwFeatureData) != SUCC) {
1084e5b75505Sopenharmony_ci        return NULL;
1085e5b75505Sopenharmony_ci    }
1086e5b75505Sopenharmony_ci    if (hwFeatureData.bands[IEEE80211_BAND_5GHZ].channelNum != 0) {
1087e5b75505Sopenharmony_ci        *numModes = sizeof(modesData) / sizeof(WifiModes);
1088e5b75505Sopenharmony_ci    }
1089e5b75505Sopenharmony_ci    struct hostapd_hw_modes *modes = os_calloc(*numModes, sizeof(struct hostapd_hw_modes));
1090e5b75505Sopenharmony_ci    if (modes == NULL) {
1091e5b75505Sopenharmony_ci        return NULL;
1092e5b75505Sopenharmony_ci    }
1093e5b75505Sopenharmony_ci
1094e5b75505Sopenharmony_ci    for (loop = 0; loop < *numModes; ++loop) {
1095e5b75505Sopenharmony_ci        modes[loop].channels = NULL;
1096e5b75505Sopenharmony_ci        modes[loop].rates = NULL;
1097e5b75505Sopenharmony_ci    }
1098e5b75505Sopenharmony_ci
1099e5b75505Sopenharmony_ci    modes[0].ht_capab = hwFeatureData.htCapab;
1100e5b75505Sopenharmony_ci    iee80211band = IEEE80211_BAND_2GHZ;
1101e5b75505Sopenharmony_ci    for (index = 0; index < *numModes; index++) {
1102e5b75505Sopenharmony_ci        if (index >= DEFAULT_NUM_MODES) {
1103e5b75505Sopenharmony_ci            iee80211band = IEEE80211_BAND_5GHZ;
1104e5b75505Sopenharmony_ci        }
1105e5b75505Sopenharmony_ci        modes[index].mode = modesData[index].mode;
1106e5b75505Sopenharmony_ci        modes[index].num_channels = hwFeatureData.bands[iee80211band].channelNum;
1107e5b75505Sopenharmony_ci        modes[index].num_rates = modesData[index].numRates;
1108e5b75505Sopenharmony_ci        modes[index].channels = os_calloc(hwFeatureData.bands[iee80211band].channelNum, sizeof(struct hostapd_channel_data));
1109e5b75505Sopenharmony_ci        modes[index].rates = os_calloc(modes[index].num_rates, sizeof(uint32_t));
1110e5b75505Sopenharmony_ci        if ((modes[index].channels == NULL) || (modes[index].rates == NULL)) {
1111e5b75505Sopenharmony_ci            WifiWpaHwFeatureDataFree(&modes, *numModes);
1112e5b75505Sopenharmony_ci            return NULL;
1113e5b75505Sopenharmony_ci        }
1114e5b75505Sopenharmony_ci
1115e5b75505Sopenharmony_ci        for (loop = 0; loop < (size_t)hwFeatureData.bands[iee80211band].channelNum; loop++) {
1116e5b75505Sopenharmony_ci            modes[index].channels[loop].chan = hwFeatureData.bands[iee80211band].iee80211Channel[loop].channel;
1117e5b75505Sopenharmony_ci            modes[index].channels[loop].freq = hwFeatureData.bands[iee80211band].iee80211Channel[loop].freq;
1118e5b75505Sopenharmony_ci            modes[index].channels[loop].flag = hwFeatureData.bands[iee80211band].iee80211Channel[loop].flags;
1119e5b75505Sopenharmony_ci            modes[index].channels[loop].allowed_bw = HOSTAPD_CHAN_WIDTH_20 | HOSTAPD_CHAN_WIDTH_10;
1120e5b75505Sopenharmony_ci        }
1121e5b75505Sopenharmony_ci
1122e5b75505Sopenharmony_ci        for (loop = 0; loop < (size_t)modes[index].num_rates; loop++) {
1123e5b75505Sopenharmony_ci            if (index < DEFAULT_NUM_MODES) {
1124e5b75505Sopenharmony_ci                modes[index].rates[loop] = hwFeatureData.bitrate[loop];
1125e5b75505Sopenharmony_ci            } else {
1126e5b75505Sopenharmony_ci                modes[index].rates[loop] = hwFeatureData.bitrate[loop + IEEE80211B_RATES_NUM];
1127e5b75505Sopenharmony_ci            }
1128e5b75505Sopenharmony_ci        }
1129e5b75505Sopenharmony_ci    }
1130e5b75505Sopenharmony_ci
1131e5b75505Sopenharmony_ci    wpa_printf(MSG_INFO, "WifiWpaGetHwFeatureData done");
1132e5b75505Sopenharmony_ci    return modes;
1133e5b75505Sopenharmony_ci}
1134e5b75505Sopenharmony_ci
1135e5b75505Sopenharmony_cistatic int32_t WifiWpaSendMlme(void *priv, const uint8_t *data, size_t dataLen, int32_t noack, uint32_t freq,
1136e5b75505Sopenharmony_ci    const uint16_t *csaOffs, size_t csaOffsLen)
1137e5b75505Sopenharmony_ci{
1138e5b75505Sopenharmony_ci    int32_t ret;
1139e5b75505Sopenharmony_ci    WifiDriverData *drv = priv;
1140e5b75505Sopenharmony_ci    WifiMlmeData *mlme = NULL;
1141e5b75505Sopenharmony_ci    errno_t rc;
1142e5b75505Sopenharmony_ci
1143e5b75505Sopenharmony_ci    (void)freq;
1144e5b75505Sopenharmony_ci    (void)csaOffs;
1145e5b75505Sopenharmony_ci    (void)csaOffsLen;
1146e5b75505Sopenharmony_ci    (void)noack;
1147e5b75505Sopenharmony_ci    if ((priv == NULL) || (data == NULL)) {
1148e5b75505Sopenharmony_ci        return -EFAIL;
1149e5b75505Sopenharmony_ci    }
1150e5b75505Sopenharmony_ci    mlme = os_zalloc(sizeof(WifiMlmeData));
1151e5b75505Sopenharmony_ci    if (mlme == NULL) {
1152e5b75505Sopenharmony_ci        return -EFAIL;
1153e5b75505Sopenharmony_ci    }
1154e5b75505Sopenharmony_ci    mlme->data = NULL;
1155e5b75505Sopenharmony_ci    mlme->dataLen = dataLen;
1156e5b75505Sopenharmony_ci    mlme->cookie = &(drv->actionCookie);
1157e5b75505Sopenharmony_ci    if ((data != NULL) && (dataLen != 0)) {
1158e5b75505Sopenharmony_ci        mlme->data = (uint8_t *)os_zalloc(dataLen);
1159e5b75505Sopenharmony_ci        if (mlme->data == NULL) {
1160e5b75505Sopenharmony_ci            os_free(mlme);
1161e5b75505Sopenharmony_ci            mlme = NULL;
1162e5b75505Sopenharmony_ci            return -EFAIL;
1163e5b75505Sopenharmony_ci        }
1164e5b75505Sopenharmony_ci        rc = memcpy_s(mlme->data, dataLen, data, dataLen);
1165e5b75505Sopenharmony_ci        if (rc != EOK) {
1166e5b75505Sopenharmony_ci            os_free(mlme->data);
1167e5b75505Sopenharmony_ci            mlme->data = NULL;
1168e5b75505Sopenharmony_ci            os_free(mlme);
1169e5b75505Sopenharmony_ci            return -EFAIL;
1170e5b75505Sopenharmony_ci        }
1171e5b75505Sopenharmony_ci    }
1172e5b75505Sopenharmony_ci    ret = WifiCmdSendMlme(drv->iface, mlme);
1173e5b75505Sopenharmony_ci    os_free(mlme->data);
1174e5b75505Sopenharmony_ci    mlme->data = NULL;
1175e5b75505Sopenharmony_ci    os_free(mlme);
1176e5b75505Sopenharmony_ci    if (ret != SUCC) {
1177e5b75505Sopenharmony_ci        ret = -EFAIL;
1178e5b75505Sopenharmony_ci    }
1179e5b75505Sopenharmony_ci    wpa_printf(MSG_INFO, "WifiWpaSendMlme done ret=%d", ret);
1180e5b75505Sopenharmony_ci    return ret;
1181e5b75505Sopenharmony_ci}
1182e5b75505Sopenharmony_ci
1183e5b75505Sopenharmony_cistatic struct wpa_scan_results *WifiWpaGetScanResults2(void *priv)
1184e5b75505Sopenharmony_ci{
1185e5b75505Sopenharmony_ci    struct wpa_scan_results *results = NULL;
1186e5b75505Sopenharmony_ci    WifiDriverData *drv = priv;
1187e5b75505Sopenharmony_ci    uint32_t loop;
1188e5b75505Sopenharmony_ci    errno_t rc;
1189e5b75505Sopenharmony_ci
1190e5b75505Sopenharmony_ci    if (priv == NULL) {
1191e5b75505Sopenharmony_ci        return NULL;
1192e5b75505Sopenharmony_ci    }
1193e5b75505Sopenharmony_ci
1194e5b75505Sopenharmony_ci    results = (struct wpa_scan_results *)os_zalloc(sizeof(struct wpa_scan_results));
1195e5b75505Sopenharmony_ci    if (results == NULL) {
1196e5b75505Sopenharmony_ci        return NULL;
1197e5b75505Sopenharmony_ci    }
1198e5b75505Sopenharmony_ci
1199e5b75505Sopenharmony_ci    results->num = drv->scanNum;
1200e5b75505Sopenharmony_ci    if (results->num == 0) {
1201e5b75505Sopenharmony_ci        return results;
1202e5b75505Sopenharmony_ci    }
1203e5b75505Sopenharmony_ci    results->res = (struct wpa_scan_res **)os_zalloc(results->num * sizeof(struct wpa_scan_res *));
1204e5b75505Sopenharmony_ci    if (results->res == NULL) {
1205e5b75505Sopenharmony_ci        os_free(results);
1206e5b75505Sopenharmony_ci        results = NULL;
1207e5b75505Sopenharmony_ci        return NULL;
1208e5b75505Sopenharmony_ci    }
1209e5b75505Sopenharmony_ci    rc = memcpy_s(results->res, results->num * sizeof(struct wpa_scan_res *), drv->scanRes,
1210e5b75505Sopenharmony_ci        results->num * sizeof(struct wpa_scan_res *));
1211e5b75505Sopenharmony_ci    if (rc != EOK) {
1212e5b75505Sopenharmony_ci        os_free(results->res);
1213e5b75505Sopenharmony_ci        os_free(results);
1214e5b75505Sopenharmony_ci        results = NULL;
1215e5b75505Sopenharmony_ci        return NULL;
1216e5b75505Sopenharmony_ci    }
1217e5b75505Sopenharmony_ci    drv->scanNum = 0;
1218e5b75505Sopenharmony_ci    for (loop = 0; loop < SCAN_AP_LIMIT; loop++) {
1219e5b75505Sopenharmony_ci        drv->scanRes[loop] = NULL;
1220e5b75505Sopenharmony_ci    }
1221e5b75505Sopenharmony_ci    wpa_printf(MSG_INFO, "WifiWpaGetScanResults2 done");
1222e5b75505Sopenharmony_ci    return results;
1223e5b75505Sopenharmony_ci}
1224e5b75505Sopenharmony_ci
1225e5b75505Sopenharmony_cistatic void *WifiWpaInit2(void *ctx, const char *ifname, void *globalPriv)
1226e5b75505Sopenharmony_ci{
1227e5b75505Sopenharmony_ci    (void)globalPriv;
1228e5b75505Sopenharmony_ci    return WifiWpaInit(ctx, ifname);
1229e5b75505Sopenharmony_ci}
1230e5b75505Sopenharmony_ci
1231e5b75505Sopenharmony_cistatic int32_t WifiWpaScanProcessSsid(struct wpa_driver_scan_params *params, WifiScan *scan)
1232e5b75505Sopenharmony_ci{
1233e5b75505Sopenharmony_ci    errno_t rc;
1234e5b75505Sopenharmony_ci    size_t loop;
1235e5b75505Sopenharmony_ci    if (params->num_ssids == 0) {
1236e5b75505Sopenharmony_ci        return SUCC;
1237e5b75505Sopenharmony_ci    }
1238e5b75505Sopenharmony_ci
1239e5b75505Sopenharmony_ci    scan->numSsids = params->num_ssids;
1240e5b75505Sopenharmony_ci    scan->ssids = (WifiDriverScanSsid *)os_zalloc(sizeof(WifiDriverScanSsid) * params->num_ssids);
1241e5b75505Sopenharmony_ci    if (scan->ssids == NULL) {
1242e5b75505Sopenharmony_ci        return -EFAIL;
1243e5b75505Sopenharmony_ci    }
1244e5b75505Sopenharmony_ci
1245e5b75505Sopenharmony_ci    for (loop = 0; (loop < params->num_ssids) && (loop < WPAS_MAX_SCAN_SSIDS); loop++) {
1246e5b75505Sopenharmony_ci        wpa_printf(MSG_INFO, "WIFI: Scan : %s SSID : %zu\n", params->ssids[loop].ssid, params->ssids[loop].ssid_len);
1247e5b75505Sopenharmony_ci
1248e5b75505Sopenharmony_ci        if (params->ssids[loop].ssid_len > MAX_SSID_LEN) {
1249e5b75505Sopenharmony_ci            params->ssids[loop].ssid_len = MAX_SSID_LEN;
1250e5b75505Sopenharmony_ci        }
1251e5b75505Sopenharmony_ci        if (params->ssids[loop].ssid_len) {
1252e5b75505Sopenharmony_ci            rc = memcpy_s(scan->ssids[loop].ssid, MAX_SSID_LEN, params->ssids[loop].ssid, params->ssids[loop].ssid_len);
1253e5b75505Sopenharmony_ci            if (rc != EOK) {
1254e5b75505Sopenharmony_ci                return -EFAIL;
1255e5b75505Sopenharmony_ci            }
1256e5b75505Sopenharmony_ci        }
1257e5b75505Sopenharmony_ci        scan->ssids[loop].ssidLen = params->ssids[loop].ssid_len;
1258e5b75505Sopenharmony_ci    }
1259e5b75505Sopenharmony_ci
1260e5b75505Sopenharmony_ci    return SUCC;
1261e5b75505Sopenharmony_ci}
1262e5b75505Sopenharmony_ci
1263e5b75505Sopenharmony_cistatic int32_t WifiWpaScanProcessBssid(const struct wpa_driver_scan_params *params, WifiScan *scan)
1264e5b75505Sopenharmony_ci{
1265e5b75505Sopenharmony_ci    errno_t rc;
1266e5b75505Sopenharmony_ci    if (params->bssid != NULL) {
1267e5b75505Sopenharmony_ci        scan->bssid = (uint8_t *)os_zalloc(ETH_ADDR_LEN);
1268e5b75505Sopenharmony_ci        if (scan->bssid == NULL) {
1269e5b75505Sopenharmony_ci            return -EFAIL;
1270e5b75505Sopenharmony_ci        }
1271e5b75505Sopenharmony_ci        rc = memcpy_s(scan->bssid, ETH_ADDR_LEN, params->bssid, ETH_ADDR_LEN);
1272e5b75505Sopenharmony_ci        if (rc != EOK) {
1273e5b75505Sopenharmony_ci            return -EFAIL;
1274e5b75505Sopenharmony_ci        }
1275e5b75505Sopenharmony_ci    }
1276e5b75505Sopenharmony_ci    return SUCC;
1277e5b75505Sopenharmony_ci}
1278e5b75505Sopenharmony_ci
1279e5b75505Sopenharmony_cistatic int32_t WifiWpaScanProcessExtraIes(const struct wpa_driver_scan_params *params, WifiScan *scan)
1280e5b75505Sopenharmony_ci{
1281e5b75505Sopenharmony_ci    errno_t rc;
1282e5b75505Sopenharmony_ci    if ((params->extra_ies != NULL) && (params->extra_ies_len != 0)) {
1283e5b75505Sopenharmony_ci        scan->extraIes = (uint8_t *)os_zalloc(params->extra_ies_len);
1284e5b75505Sopenharmony_ci        if (scan->extraIes == NULL) {
1285e5b75505Sopenharmony_ci            return -EFAIL;
1286e5b75505Sopenharmony_ci        }
1287e5b75505Sopenharmony_ci
1288e5b75505Sopenharmony_ci        rc = memcpy_s(scan->extraIes, params->extra_ies_len, params->extra_ies, params->extra_ies_len);
1289e5b75505Sopenharmony_ci        if (rc != EOK) {
1290e5b75505Sopenharmony_ci            return -EFAIL;
1291e5b75505Sopenharmony_ci        }
1292e5b75505Sopenharmony_ci        scan->extraIesLen = params->extra_ies_len;
1293e5b75505Sopenharmony_ci    }
1294e5b75505Sopenharmony_ci    return SUCC;
1295e5b75505Sopenharmony_ci}
1296e5b75505Sopenharmony_ci
1297e5b75505Sopenharmony_cistatic int32_t WifiWpaScanProcessFreq(const struct wpa_driver_scan_params *params, WifiScan *scan)
1298e5b75505Sopenharmony_ci{
1299e5b75505Sopenharmony_ci    uint32_t numFreqs;
1300e5b75505Sopenharmony_ci    int32_t *freqs = NULL;
1301e5b75505Sopenharmony_ci    errno_t rc;
1302e5b75505Sopenharmony_ci
1303e5b75505Sopenharmony_ci    if (params->freqs != NULL) {
1304e5b75505Sopenharmony_ci        numFreqs = 0;
1305e5b75505Sopenharmony_ci        for (freqs = params->freqs; *freqs != 0; freqs++) {
1306e5b75505Sopenharmony_ci            numFreqs++;
1307e5b75505Sopenharmony_ci            if (numFreqs > 14) { // 14 is 2.4G channel num
1308e5b75505Sopenharmony_ci                return -EFAIL;
1309e5b75505Sopenharmony_ci            }
1310e5b75505Sopenharmony_ci        }
1311e5b75505Sopenharmony_ci
1312e5b75505Sopenharmony_ci        scan->numFreqs = numFreqs;
1313e5b75505Sopenharmony_ci        scan->freqs = (int32_t *)os_zalloc(numFreqs * (sizeof(int32_t)));
1314e5b75505Sopenharmony_ci        if (scan->freqs == NULL) {
1315e5b75505Sopenharmony_ci            return -EFAIL;
1316e5b75505Sopenharmony_ci        }
1317e5b75505Sopenharmony_ci        rc = memcpy_s(scan->freqs, numFreqs * (sizeof(int32_t)), params->freqs, numFreqs * (sizeof(int32_t)));
1318e5b75505Sopenharmony_ci        if (rc != EOK) {
1319e5b75505Sopenharmony_ci            return -EFAIL;
1320e5b75505Sopenharmony_ci        }
1321e5b75505Sopenharmony_ci    }
1322e5b75505Sopenharmony_ci    return SUCC;
1323e5b75505Sopenharmony_ci}
1324e5b75505Sopenharmony_ci
1325e5b75505Sopenharmony_cistatic void WifiWpaScanFree(WifiScan **scan)
1326e5b75505Sopenharmony_ci{
1327e5b75505Sopenharmony_ci    if (scan == NULL || *scan == NULL) {
1328e5b75505Sopenharmony_ci        return;
1329e5b75505Sopenharmony_ci    }
1330e5b75505Sopenharmony_ci
1331e5b75505Sopenharmony_ci    if ((*scan)->ssids != NULL) {
1332e5b75505Sopenharmony_ci        os_free((*scan)->ssids);
1333e5b75505Sopenharmony_ci        (*scan)->ssids = NULL;
1334e5b75505Sopenharmony_ci    }
1335e5b75505Sopenharmony_ci    if ((*scan)->bssid != NULL) {
1336e5b75505Sopenharmony_ci        os_free((*scan)->bssid);
1337e5b75505Sopenharmony_ci        (*scan)->bssid = NULL;
1338e5b75505Sopenharmony_ci    }
1339e5b75505Sopenharmony_ci
1340e5b75505Sopenharmony_ci    if ((*scan)->extraIes != NULL) {
1341e5b75505Sopenharmony_ci        os_free((*scan)->extraIes);
1342e5b75505Sopenharmony_ci        (*scan)->extraIes = NULL;
1343e5b75505Sopenharmony_ci    }
1344e5b75505Sopenharmony_ci
1345e5b75505Sopenharmony_ci    if ((*scan)->freqs != NULL) {
1346e5b75505Sopenharmony_ci        os_free((*scan)->freqs);
1347e5b75505Sopenharmony_ci        (*scan)->freqs = NULL;
1348e5b75505Sopenharmony_ci    }
1349e5b75505Sopenharmony_ci
1350e5b75505Sopenharmony_ci    os_free(*scan);
1351e5b75505Sopenharmony_ci    *scan = NULL;
1352e5b75505Sopenharmony_ci}
1353e5b75505Sopenharmony_ci
1354e5b75505Sopenharmony_civoid WifiWpaScanTimeout(void *eloop, void *ctx)
1355e5b75505Sopenharmony_ci{
1356e5b75505Sopenharmony_ci    (void)eloop;
1357e5b75505Sopenharmony_ci    if (ctx == NULL) {
1358e5b75505Sopenharmony_ci        return;
1359e5b75505Sopenharmony_ci    }
1360e5b75505Sopenharmony_ci    wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, NULL);
1361e5b75505Sopenharmony_ci}
1362e5b75505Sopenharmony_ci
1363e5b75505Sopenharmony_cistatic int32_t WifiWpaScan2(void *priv, struct wpa_driver_scan_params *params)
1364e5b75505Sopenharmony_ci{
1365e5b75505Sopenharmony_ci    WifiScan *scan = NULL;
1366e5b75505Sopenharmony_ci    WifiDriverData *drv = NULL;
1367e5b75505Sopenharmony_ci    int32_t timeout;
1368e5b75505Sopenharmony_ci    int32_t ret;
1369e5b75505Sopenharmony_ci
1370e5b75505Sopenharmony_ci    if ((priv == NULL) || (params == NULL) || (params->num_ssids > WPAS_MAX_SCAN_SSIDS)) {
1371e5b75505Sopenharmony_ci        return -EFAIL;
1372e5b75505Sopenharmony_ci    }
1373e5b75505Sopenharmony_ci    drv = (WifiDriverData *)priv;
1374e5b75505Sopenharmony_ci    scan = (WifiScan *)os_zalloc(sizeof(WifiScan));
1375e5b75505Sopenharmony_ci    if (scan == NULL) {
1376e5b75505Sopenharmony_ci        return -EFAIL;
1377e5b75505Sopenharmony_ci    }
1378e5b75505Sopenharmony_ci    if ((WifiWpaScanProcessSsid(params, scan) != SUCC) || (WifiWpaScanProcessBssid(params, scan) != SUCC) ||
1379e5b75505Sopenharmony_ci        (WifiWpaScanProcessExtraIes(params, scan) != SUCC) || (WifiWpaScanProcessFreq(params, scan) != SUCC)) {
1380e5b75505Sopenharmony_ci        WifiWpaScanFree(&scan);
1381e5b75505Sopenharmony_ci        return -EFAIL;
1382e5b75505Sopenharmony_ci    }
1383e5b75505Sopenharmony_ci
1384e5b75505Sopenharmony_ci    scan->fastConnectFlag = WPA_FLAG_OFF;
1385e5b75505Sopenharmony_ci    scan->prefixSsidScanFlag = WPA_FLAG_OFF;
1386e5b75505Sopenharmony_ci    ret = WifiCmdScan(drv->iface, scan);
1387e5b75505Sopenharmony_ci    WifiWpaScanFree(&scan);
1388e5b75505Sopenharmony_ci
1389e5b75505Sopenharmony_ci    timeout = SCAN_TIME_OUT;
1390e5b75505Sopenharmony_ci    eloop_cancel_timeout(WifiWpaScanTimeout, drv, drv->ctx);
1391e5b75505Sopenharmony_ci    eloop_register_timeout(timeout, 0, WifiWpaScanTimeout, drv, drv->ctx);
1392e5b75505Sopenharmony_ci
1393e5b75505Sopenharmony_ci    return ret;
1394e5b75505Sopenharmony_ci}
1395e5b75505Sopenharmony_ci
1396e5b75505Sopenharmony_cistatic void WifiSetApFreq(WifiApSetting *apsettings, const struct wpa_driver_ap_params *params)
1397e5b75505Sopenharmony_ci{
1398e5b75505Sopenharmony_ci    if (params->freq != NULL) {
1399e5b75505Sopenharmony_ci        apsettings->freqParams.mode = params->freq->mode;
1400e5b75505Sopenharmony_ci        apsettings->freqParams.freq = params->freq->freq;
1401e5b75505Sopenharmony_ci        apsettings->freqParams.channel = params->freq->channel;
1402e5b75505Sopenharmony_ci        apsettings->freqParams.htEnabled = params->freq->ht_enabled;
1403e5b75505Sopenharmony_ci        apsettings->freqParams.secChannelOffset = params->freq->sec_channel_offset;
1404e5b75505Sopenharmony_ci        apsettings->freqParams.centerFreq1 = params->freq->center_freq1;
1405e5b75505Sopenharmony_ci        apsettings->freqParams.bandwidth = params->freq->bandwidth;
1406e5b75505Sopenharmony_ci        if (params->freq->bandwidth == WPA_BANDWIDTH_20) {
1407e5b75505Sopenharmony_ci            apsettings->freqParams.bandwidth = WIFI_CHAN_WIDTH_20;
1408e5b75505Sopenharmony_ci        } else {
1409e5b75505Sopenharmony_ci            apsettings->freqParams.bandwidth = WIFI_CHAN_WIDTH_40;
1410e5b75505Sopenharmony_ci        }
1411e5b75505Sopenharmony_ci    }
1412e5b75505Sopenharmony_ci}
1413e5b75505Sopenharmony_ci
1414e5b75505Sopenharmony_cistatic void WifiSetApBand(WifiApSetting *apsettings, struct hostapd_data *hapd)
1415e5b75505Sopenharmony_ci{
1416e5b75505Sopenharmony_ci    if ((apsettings!= NULL) && (hapd!= NULL)) {
1417e5b75505Sopenharmony_ci        switch (hapd->conf->wps_rf_bands) {
1418e5b75505Sopenharmony_ci            case WPS_RF_24GHZ:
1419e5b75505Sopenharmony_ci                apsettings->freqParams.band = IEEE80211_BAND_2GHZ;
1420e5b75505Sopenharmony_ci                break;
1421e5b75505Sopenharmony_ci            case WPS_RF_50GHZ:
1422e5b75505Sopenharmony_ci                apsettings->freqParams.band = IEEE80211_BAND_5GHZ;
1423e5b75505Sopenharmony_ci                break;
1424e5b75505Sopenharmony_ci            default:
1425e5b75505Sopenharmony_ci                apsettings->freqParams.band = IEEE80211_BAND_2GHZ;
1426e5b75505Sopenharmony_ci                break;
1427e5b75505Sopenharmony_ci        }
1428e5b75505Sopenharmony_ci    }
1429e5b75505Sopenharmony_ci}
1430e5b75505Sopenharmony_ci
1431e5b75505Sopenharmony_cistatic int WifiSetApBeaconData(WifiApSetting *apsettings, const struct wpa_driver_ap_params *params)
1432e5b75505Sopenharmony_ci{
1433e5b75505Sopenharmony_ci    if ((params->head != NULL) && (params->head_len != 0)) {
1434e5b75505Sopenharmony_ci        apsettings->beaconData.headLen = params->head_len;
1435e5b75505Sopenharmony_ci        apsettings->beaconData.head = (uint8_t *)os_zalloc(apsettings->beaconData.headLen);
1436e5b75505Sopenharmony_ci        if (apsettings->beaconData.head == NULL) {
1437e5b75505Sopenharmony_ci            return -EFAIL;
1438e5b75505Sopenharmony_ci        }
1439e5b75505Sopenharmony_ci        if (memcpy_s(apsettings->beaconData.head, apsettings->beaconData.headLen, params->head, params->head_len) !=
1440e5b75505Sopenharmony_ci            EOK) {
1441e5b75505Sopenharmony_ci            return -EFAIL;
1442e5b75505Sopenharmony_ci        }
1443e5b75505Sopenharmony_ci    }
1444e5b75505Sopenharmony_ci
1445e5b75505Sopenharmony_ci    if ((params->tail != NULL) && (params->tail_len != 0)) {
1446e5b75505Sopenharmony_ci        apsettings->beaconData.tailLen = params->tail_len;
1447e5b75505Sopenharmony_ci        apsettings->beaconData.tail = (uint8_t *)os_zalloc(apsettings->beaconData.tailLen);
1448e5b75505Sopenharmony_ci        if (apsettings->beaconData.tail == NULL) {
1449e5b75505Sopenharmony_ci            return -EFAIL;
1450e5b75505Sopenharmony_ci        }
1451e5b75505Sopenharmony_ci        if (memcpy_s(apsettings->beaconData.tail, apsettings->beaconData.tailLen, params->tail, params->tail_len) !=
1452e5b75505Sopenharmony_ci            EOK) {
1453e5b75505Sopenharmony_ci            return -EFAIL;
1454e5b75505Sopenharmony_ci        }
1455e5b75505Sopenharmony_ci    }
1456e5b75505Sopenharmony_ci    return SUCC;
1457e5b75505Sopenharmony_ci}
1458e5b75505Sopenharmony_ci
1459e5b75505Sopenharmony_cistatic void WifiApSettingsFree(WifiApSetting **apsettings)
1460e5b75505Sopenharmony_ci{
1461e5b75505Sopenharmony_ci    if (apsettings == NULL || *apsettings == NULL) {
1462e5b75505Sopenharmony_ci        return;
1463e5b75505Sopenharmony_ci    }
1464e5b75505Sopenharmony_ci
1465e5b75505Sopenharmony_ci    if ((*apsettings)->meshSsid != NULL) {
1466e5b75505Sopenharmony_ci        os_free((*apsettings)->meshSsid);
1467e5b75505Sopenharmony_ci        (*apsettings)->meshSsid = NULL;
1468e5b75505Sopenharmony_ci    }
1469e5b75505Sopenharmony_ci
1470e5b75505Sopenharmony_ci    if ((*apsettings)->ssid != NULL) {
1471e5b75505Sopenharmony_ci        os_free((*apsettings)->ssid);
1472e5b75505Sopenharmony_ci        (*apsettings)->ssid = NULL;
1473e5b75505Sopenharmony_ci    }
1474e5b75505Sopenharmony_ci
1475e5b75505Sopenharmony_ci    if ((*apsettings)->beaconData.head != NULL) {
1476e5b75505Sopenharmony_ci        os_free((*apsettings)->beaconData.head);
1477e5b75505Sopenharmony_ci        (*apsettings)->beaconData.head = NULL;
1478e5b75505Sopenharmony_ci    }
1479e5b75505Sopenharmony_ci
1480e5b75505Sopenharmony_ci    if ((*apsettings)->beaconData.tail != NULL) {
1481e5b75505Sopenharmony_ci        os_free((*apsettings)->beaconData.tail);
1482e5b75505Sopenharmony_ci        (*apsettings)->beaconData.tail = NULL;
1483e5b75505Sopenharmony_ci    }
1484e5b75505Sopenharmony_ci
1485e5b75505Sopenharmony_ci    os_free(*apsettings);
1486e5b75505Sopenharmony_ci    *apsettings = NULL;
1487e5b75505Sopenharmony_ci}
1488e5b75505Sopenharmony_ci
1489e5b75505Sopenharmony_cistatic WifiAuthType WifiGetApAuthType(const struct wpa_driver_ap_params *params)
1490e5b75505Sopenharmony_ci{
1491e5b75505Sopenharmony_ci    WifiAuthType type;
1492e5b75505Sopenharmony_ci
1493e5b75505Sopenharmony_ci    if ((params->auth_algs & (WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED)) == (WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED)) {
1494e5b75505Sopenharmony_ci        type = WIFI_AUTHTYPE_AUTOMATIC;
1495e5b75505Sopenharmony_ci    } else if ((params->auth_algs & WPA_AUTH_ALG_SHARED) == WPA_AUTH_ALG_SHARED) {
1496e5b75505Sopenharmony_ci        type = WIFI_AUTHTYPE_SHARED_KEY;
1497e5b75505Sopenharmony_ci    } else {
1498e5b75505Sopenharmony_ci        type = WIFI_AUTHTYPE_OPEN_SYSTEM;
1499e5b75505Sopenharmony_ci    }
1500e5b75505Sopenharmony_ci    return type;
1501e5b75505Sopenharmony_ci}
1502e5b75505Sopenharmony_ci
1503e5b75505Sopenharmony_cistatic int32_t WifiWpaSetAp(void *priv, struct wpa_driver_ap_params *params)
1504e5b75505Sopenharmony_ci{
1505e5b75505Sopenharmony_ci    int32_t ret;
1506e5b75505Sopenharmony_ci    WifiApSetting *apsettings = NULL;
1507e5b75505Sopenharmony_ci    WifiDriverData *drv = (WifiDriverData *)priv;
1508e5b75505Sopenharmony_ci    if ((priv == NULL) || (params == NULL) || (params->freq == NULL)) {
1509e5b75505Sopenharmony_ci        return -EFAIL;
1510e5b75505Sopenharmony_ci    }
1511e5b75505Sopenharmony_ci    if ((params->freq->bandwidth != WPA_BANDWIDTH_20) && (params->freq->bandwidth != WPA_BANDWIDTH_40)) {
1512e5b75505Sopenharmony_ci        return -EFAIL;
1513e5b75505Sopenharmony_ci    }
1514e5b75505Sopenharmony_ci
1515e5b75505Sopenharmony_ci    apsettings = os_zalloc(sizeof(WifiApSetting));
1516e5b75505Sopenharmony_ci    if (apsettings == NULL) {
1517e5b75505Sopenharmony_ci        return -EFAIL;
1518e5b75505Sopenharmony_ci    }
1519e5b75505Sopenharmony_ci    apsettings->beaconInterval = params->beacon_int;
1520e5b75505Sopenharmony_ci    apsettings->dtimPeriod = params->dtim_period;
1521e5b75505Sopenharmony_ci    apsettings->hiddenSsid = params->hide_ssid;
1522e5b75505Sopenharmony_ci    apsettings->authType = WifiGetApAuthType(params);
1523e5b75505Sopenharmony_ci
1524e5b75505Sopenharmony_ci    if ((params->ssid != NULL) && (params->ssid_len != 0)) {
1525e5b75505Sopenharmony_ci        apsettings->ssidLen = params->ssid_len;
1526e5b75505Sopenharmony_ci        apsettings->ssid = (uint8_t *)os_zalloc(apsettings->ssidLen);
1527e5b75505Sopenharmony_ci        if ((apsettings->ssid == NULL) ||
1528e5b75505Sopenharmony_ci            (memcpy_s(apsettings->ssid, apsettings->ssidLen, params->ssid, params->ssid_len) != EOK)) {
1529e5b75505Sopenharmony_ci            goto failed;
1530e5b75505Sopenharmony_ci        }
1531e5b75505Sopenharmony_ci    }
1532e5b75505Sopenharmony_ci    WifiSetApFreq(apsettings, params);
1533e5b75505Sopenharmony_ci    WifiSetApBand(apsettings, drv->hapd);
1534e5b75505Sopenharmony_ci    if (WifiSetApBeaconData(apsettings, params) != SUCC) {
1535e5b75505Sopenharmony_ci        goto failed;
1536e5b75505Sopenharmony_ci    }
1537e5b75505Sopenharmony_ci    if (drv->beaconSet == TRUE) {
1538e5b75505Sopenharmony_ci        ret = WifiCmdChangeBeacon(drv->iface, apsettings);
1539e5b75505Sopenharmony_ci    } else {
1540e5b75505Sopenharmony_ci        ret = WifiCmdSetAp(drv->iface, apsettings);
1541e5b75505Sopenharmony_ci    }
1542e5b75505Sopenharmony_ci    if (ret == SUCC) {
1543e5b75505Sopenharmony_ci        drv->beaconSet = TRUE;
1544e5b75505Sopenharmony_ci    }
1545e5b75505Sopenharmony_ci    WifiApSettingsFree(&apsettings);
1546e5b75505Sopenharmony_ci    wpa_printf(MSG_INFO, "WifiWpaGetScanResults2 done ret=%d", ret);
1547e5b75505Sopenharmony_ci    return ret;
1548e5b75505Sopenharmony_ci
1549e5b75505Sopenharmony_cifailed:
1550e5b75505Sopenharmony_ci    WifiApSettingsFree(&apsettings);
1551e5b75505Sopenharmony_ci    return -EFAIL;
1552e5b75505Sopenharmony_ci}
1553e5b75505Sopenharmony_ci
1554e5b75505Sopenharmony_cistatic void WifiHapdPreInit(const WifiDriverData *drv)
1555e5b75505Sopenharmony_ci{
1556e5b75505Sopenharmony_ci    WifiSetNewDev info;
1557e5b75505Sopenharmony_ci
1558e5b75505Sopenharmony_ci    if (drv == NULL) {
1559e5b75505Sopenharmony_ci        return;
1560e5b75505Sopenharmony_ci    }
1561e5b75505Sopenharmony_ci    info.status = FALSE;
1562e5b75505Sopenharmony_ci    info.ifType = WIFI_IFTYPE_STATION;
1563e5b75505Sopenharmony_ci    info.mode = WIFI_PHY_MODE_11N;
1564e5b75505Sopenharmony_ci    int ret = WifiCmdSetNetdev(drv->iface, &info);
1565e5b75505Sopenharmony_ci
1566e5b75505Sopenharmony_ci    if (ret != SUCC) {
1567e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s set netdev failed ret = %d.", __func__, ret);
1568e5b75505Sopenharmony_ci    }
1569e5b75505Sopenharmony_ci}
1570e5b75505Sopenharmony_ci
1571e5b75505Sopenharmony_cistatic WifiDriverData *WifiDrvInit(void *ctx, const struct wpa_init_params *params)
1572e5b75505Sopenharmony_ci{
1573e5b75505Sopenharmony_ci    WifiDriverData *drv = NULL;
1574e5b75505Sopenharmony_ci    errno_t rc;
1575e5b75505Sopenharmony_ci    WifiSetNewDev info;
1576e5b75505Sopenharmony_ci    WifiSetMode setMode;
1577e5b75505Sopenharmony_ci    int32_t ret;
1578e5b75505Sopenharmony_ci#ifdef CONFIG_OHOS_P2P
1579e5b75505Sopenharmony_ci    WifiDev *wifiDev = NULL;
1580e5b75505Sopenharmony_ci#endif
1581e5b75505Sopenharmony_ci    if ((ctx == NULL) || (params == NULL)) {
1582e5b75505Sopenharmony_ci        return NULL;
1583e5b75505Sopenharmony_ci    }
1584e5b75505Sopenharmony_ci    drv = os_zalloc(sizeof(WifiDriverData));
1585e5b75505Sopenharmony_ci    if (drv == NULL) {
1586e5b75505Sopenharmony_ci        goto failed;
1587e5b75505Sopenharmony_ci    }
1588e5b75505Sopenharmony_ci
1589e5b75505Sopenharmony_ci    drv->ctx = ctx;
1590e5b75505Sopenharmony_ci    rc = memcpy_s(drv->iface, sizeof(drv->iface), params->ifname, sizeof(drv->iface));
1591e5b75505Sopenharmony_ci    if (rc != EOK) {
1592e5b75505Sopenharmony_ci        os_free(drv);
1593e5b75505Sopenharmony_ci        drv = NULL;
1594e5b75505Sopenharmony_ci        goto failed;
1595e5b75505Sopenharmony_ci    }
1596e5b75505Sopenharmony_ci#ifdef CONFIG_OHOS_P2P
1597e5b75505Sopenharmony_ci    wifiDev = (WifiDev *)os_zalloc(sizeof(WifiDev));
1598e5b75505Sopenharmony_ci    if (wifiDev == NULL)
1599e5b75505Sopenharmony_ci    {
1600e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s wifiDev malloc failed.", __FUNCTION__);
1601e5b75505Sopenharmony_ci        goto failed;
1602e5b75505Sopenharmony_ci    }
1603e5b75505Sopenharmony_ci    wifiDev->priv = drv;
1604e5b75505Sopenharmony_ci    wifiDev->ifNameLen = sizeof(params->ifname);
1605e5b75505Sopenharmony_ci    rc = memcpy_s(wifiDev->ifName, sizeof(wifiDev->ifName), drv->iface, sizeof(drv->iface));
1606e5b75505Sopenharmony_ci    if (rc != EOK) {
1607e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s wifiDev could not copy interface name.", __FUNCTION__);
1608e5b75505Sopenharmony_ci        goto failed;
1609e5b75505Sopenharmony_ci    }
1610e5b75505Sopenharmony_ci    wpa_printf(MSG_INFO, "%s init, interface name:%s.", __FUNCTION__, wifiDev->ifName);
1611e5b75505Sopenharmony_ci    SetWifiDev(wifiDev);
1612e5b75505Sopenharmony_ci#endif // CONFIG_OHOS_P2P
1613e5b75505Sopenharmony_ci    WifiHapdPreInit(drv);
1614e5b75505Sopenharmony_ci
1615e5b75505Sopenharmony_ci    setMode.iftype = WIFI_IFTYPE_AP;
1616e5b75505Sopenharmony_ci    ret = WifiCmdSetMode(drv->iface, &setMode);
1617e5b75505Sopenharmony_ci    if (ret != SUCC) {
1618e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "WifiWpaHapdInit set mode failed, iface = %s, ret = %d.", drv->iface, ret);
1619e5b75505Sopenharmony_ci        goto failed;
1620e5b75505Sopenharmony_ci    }
1621e5b75505Sopenharmony_ci    info.status = TRUE;
1622e5b75505Sopenharmony_ci    info.ifType = WIFI_IFTYPE_AP;
1623e5b75505Sopenharmony_ci    info.mode = WIFI_PHY_MODE_11N;
1624e5b75505Sopenharmony_ci    ret = WifiCmdSetNetdev(drv->iface, &info);
1625e5b75505Sopenharmony_ci    if (ret != SUCC) {
1626e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "WifiDrvInit set netdev failed");
1627e5b75505Sopenharmony_ci        goto failed;
1628e5b75505Sopenharmony_ci    }
1629e5b75505Sopenharmony_ci    wpa_printf(MSG_INFO, "WifiDrvInit done");
1630e5b75505Sopenharmony_ci    return drv;
1631e5b75505Sopenharmony_ci
1632e5b75505Sopenharmony_cifailed:
1633e5b75505Sopenharmony_ci    if (drv != NULL) {
1634e5b75505Sopenharmony_ci        info.status = FALSE;
1635e5b75505Sopenharmony_ci        info.ifType = WIFI_IFTYPE_STATION;
1636e5b75505Sopenharmony_ci        info.mode = WIFI_PHY_MODE_11N;
1637e5b75505Sopenharmony_ci        WifiCmdSetNetdev(drv->iface, &info);
1638e5b75505Sopenharmony_ci        os_free(drv);
1639e5b75505Sopenharmony_ci        drv = NULL;
1640e5b75505Sopenharmony_ci    }
1641e5b75505Sopenharmony_ci#ifdef CONFIG_OHOS_P2P
1642e5b75505Sopenharmony_ci    FreeWifiDev(wifiDev);
1643e5b75505Sopenharmony_ci#endif // CONFIG_OHOS_P2P
1644e5b75505Sopenharmony_ci    return NULL;
1645e5b75505Sopenharmony_ci}
1646e5b75505Sopenharmony_ci
1647e5b75505Sopenharmony_cistatic int32_t WifiWpaInitl2(struct wpa_init_params *params, WifiDriverData *drv)
1648e5b75505Sopenharmony_ci{
1649e5b75505Sopenharmony_ci    int32_t ret;
1650e5b75505Sopenharmony_ci    uint8_t addrTmp[ETH_ADDR_LEN] = {0};
1651e5b75505Sopenharmony_ci
1652e5b75505Sopenharmony_ci    drv->eapolSock = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL, WifiWpaReceiveEapol, drv, 1);
1653e5b75505Sopenharmony_ci    if (drv->eapolSock == NULL) {
1654e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "WifiDrvInit l2 packet init failed");
1655e5b75505Sopenharmony_ci        return -EFAIL;
1656e5b75505Sopenharmony_ci    }
1657e5b75505Sopenharmony_ci    if (l2_packet_get_own_addr(drv->eapolSock, addrTmp)) {
1658e5b75505Sopenharmony_ci        return -EFAIL;
1659e5b75505Sopenharmony_ci    }
1660e5b75505Sopenharmony_ci    ret = memcpy_s(params->own_addr, ETH_ADDR_LEN, addrTmp, ETH_ADDR_LEN);
1661e5b75505Sopenharmony_ci    if (ret != EOK) {
1662e5b75505Sopenharmony_ci        return -EFAIL;
1663e5b75505Sopenharmony_ci    }
1664e5b75505Sopenharmony_ci    ret = memcpy_s(drv->ownAddr, ETH_ADDR_LEN, addrTmp, ETH_ADDR_LEN);
1665e5b75505Sopenharmony_ci    if (ret != EOK) {
1666e5b75505Sopenharmony_ci        return -EFAIL;
1667e5b75505Sopenharmony_ci    }
1668e5b75505Sopenharmony_ci    return SUCC;
1669e5b75505Sopenharmony_ci}
1670e5b75505Sopenharmony_ci
1671e5b75505Sopenharmony_cistatic void *WifiWpaHapdInit(struct hostapd_data *hapd, struct wpa_init_params *params)
1672e5b75505Sopenharmony_ci{
1673e5b75505Sopenharmony_ci    WifiDriverData *drv = NULL;
1674e5b75505Sopenharmony_ci
1675e5b75505Sopenharmony_ci    int32_t ret;
1676e5b75505Sopenharmony_ci
1677e5b75505Sopenharmony_ci    if ((hapd == NULL) || (params == NULL) || (hapd->conf == NULL)) {
1678e5b75505Sopenharmony_ci        return NULL;
1679e5b75505Sopenharmony_ci    }
1680e5b75505Sopenharmony_ci
1681e5b75505Sopenharmony_ci    if (WifiClientInit(params->ifname) != SUCC) {
1682e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "Wifi client init failed");
1683e5b75505Sopenharmony_ci        return NULL;
1684e5b75505Sopenharmony_ci    }
1685e5b75505Sopenharmony_ci    drv = WifiDrvInit(hapd, params);
1686e5b75505Sopenharmony_ci    if (drv == NULL) {
1687e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "WifiWpaHapdInit drv init failed");
1688e5b75505Sopenharmony_ci        goto failed;
1689e5b75505Sopenharmony_ci    }
1690e5b75505Sopenharmony_ci    drv->hapd = hapd;
1691e5b75505Sopenharmony_ci
1692e5b75505Sopenharmony_ci    ret = WifiWpaInitl2(params, drv);
1693e5b75505Sopenharmony_ci    if (ret != SUCC) {
1694e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "WifiWpaInitI2 failed");
1695e5b75505Sopenharmony_ci        goto failed;
1696e5b75505Sopenharmony_ci    }
1697e5b75505Sopenharmony_ci
1698e5b75505Sopenharmony_ci    g_wifiDriverData = drv;
1699e5b75505Sopenharmony_ci    g_wifiDriverType = WIFI_IFTYPE_AP;
1700e5b75505Sopenharmony_ci    wpa_printf(MSG_INFO, "WifiWpaHapdInit done");
1701e5b75505Sopenharmony_ci    return (void *)drv;
1702e5b75505Sopenharmony_ci
1703e5b75505Sopenharmony_cifailed:
1704e5b75505Sopenharmony_ci    if (drv != NULL && drv->eapolSock != NULL) {
1705e5b75505Sopenharmony_ci        l2_packet_deinit(drv->eapolSock);
1706e5b75505Sopenharmony_ci    }
1707e5b75505Sopenharmony_ci    WifiWpaDeinit(drv);
1708e5b75505Sopenharmony_ci    return NULL;
1709e5b75505Sopenharmony_ci}
1710e5b75505Sopenharmony_ci
1711e5b75505Sopenharmony_cistatic void WifiWpaHapdDeinit(void *priv)
1712e5b75505Sopenharmony_ci{
1713e5b75505Sopenharmony_ci    int32_t ret;
1714e5b75505Sopenharmony_ci    WifiDriverData *drv = NULL;
1715e5b75505Sopenharmony_ci    WifiSetMode setMode;
1716e5b75505Sopenharmony_ci    WifiSetNewDev info;
1717e5b75505Sopenharmony_ci
1718e5b75505Sopenharmony_ci    if (priv == NULL) {
1719e5b75505Sopenharmony_ci        return;
1720e5b75505Sopenharmony_ci    }
1721e5b75505Sopenharmony_ci
1722e5b75505Sopenharmony_ci    (void)memset_s(&setMode, sizeof(WifiSetMode), 0, sizeof(WifiSetMode));
1723e5b75505Sopenharmony_ci    drv = (WifiDriverData *)priv;
1724e5b75505Sopenharmony_ci    setMode.iftype = WIFI_IFTYPE_STATION;
1725e5b75505Sopenharmony_ci    info.status = FALSE;
1726e5b75505Sopenharmony_ci    info.ifType = WIFI_IFTYPE_AP;
1727e5b75505Sopenharmony_ci    info.mode = WIFI_PHY_MODE_11N;
1728e5b75505Sopenharmony_ci
1729e5b75505Sopenharmony_ci    WifiCmdSetNetdev(drv->iface, &info);
1730e5b75505Sopenharmony_ci    ret = WifiCmdSetMode((char *)drv->iface, &setMode);
1731e5b75505Sopenharmony_ci    if (ret != SUCC) {
1732e5b75505Sopenharmony_ci        return;
1733e5b75505Sopenharmony_ci    }
1734e5b75505Sopenharmony_ci
1735e5b75505Sopenharmony_ci    if (drv->eapolSock != NULL) {
1736e5b75505Sopenharmony_ci        l2_packet_deinit(drv->eapolSock);
1737e5b75505Sopenharmony_ci    }
1738e5b75505Sopenharmony_ci    os_free(g_wifiDriverData);
1739e5b75505Sopenharmony_ci    g_wifiDriverData = NULL;
1740e5b75505Sopenharmony_ci    WifiClientDeinit(drv->iface);
1741e5b75505Sopenharmony_ci
1742e5b75505Sopenharmony_ci    wpa_printf(MSG_INFO, "WifiWpaHapdDeinit done");
1743e5b75505Sopenharmony_ci}
1744e5b75505Sopenharmony_ci
1745e5b75505Sopenharmony_cistatic int32_t WifiWpaHapdSendEapol(void *priv, const uint8_t *addr, const uint8_t *data, size_t dataLen, int encrypt,
1746e5b75505Sopenharmony_ci    const uint8_t *ownAddr, uint32_t flags)
1747e5b75505Sopenharmony_ci{
1748e5b75505Sopenharmony_ci    WifiDriverData *drv = priv;
1749e5b75505Sopenharmony_ci    int32_t ret;
1750e5b75505Sopenharmony_ci    uint32_t frameLen;
1751e5b75505Sopenharmony_ci    uint8_t *frameBuf = NULL;
1752e5b75505Sopenharmony_ci    uint8_t *payload = NULL;
1753e5b75505Sopenharmony_ci    struct l2_ethhdr *ethhdr = NULL;
1754e5b75505Sopenharmony_ci
1755e5b75505Sopenharmony_ci    (void)encrypt;
1756e5b75505Sopenharmony_ci    (void)flags;
1757e5b75505Sopenharmony_ci    if ((priv == NULL) || (addr == NULL) || (data == NULL) || (ownAddr == NULL)) {
1758e5b75505Sopenharmony_ci        return -EFAIL;
1759e5b75505Sopenharmony_ci    }
1760e5b75505Sopenharmony_ci
1761e5b75505Sopenharmony_ci    frameLen = dataLen + sizeof(struct l2_ethhdr);
1762e5b75505Sopenharmony_ci    frameBuf = os_zalloc(frameLen);
1763e5b75505Sopenharmony_ci    if (frameBuf == NULL) {
1764e5b75505Sopenharmony_ci        return -EFAIL;
1765e5b75505Sopenharmony_ci    }
1766e5b75505Sopenharmony_ci
1767e5b75505Sopenharmony_ci    ethhdr = (struct l2_ethhdr *)frameBuf;
1768e5b75505Sopenharmony_ci    if (memcpy_s(ethhdr->h_dest, ETH_ADDR_LEN, addr, ETH_ADDR_LEN) != EOK) {
1769e5b75505Sopenharmony_ci        os_free(frameBuf);
1770e5b75505Sopenharmony_ci        frameBuf = NULL;
1771e5b75505Sopenharmony_ci        return -EFAIL;
1772e5b75505Sopenharmony_ci    }
1773e5b75505Sopenharmony_ci    if (memcpy_s(ethhdr->h_source, ETH_ADDR_LEN, ownAddr, ETH_ADDR_LEN) != EOK) {
1774e5b75505Sopenharmony_ci        os_free(frameBuf);
1775e5b75505Sopenharmony_ci        frameBuf = NULL;
1776e5b75505Sopenharmony_ci        return -EFAIL;
1777e5b75505Sopenharmony_ci    }
1778e5b75505Sopenharmony_ci    ethhdr->h_proto = host_to_be16(ETH_P_PAE);
1779e5b75505Sopenharmony_ci    payload = (uint8_t *)(ethhdr + 1);
1780e5b75505Sopenharmony_ci    if (memcpy_s(payload, dataLen, data, dataLen) != EOK) {
1781e5b75505Sopenharmony_ci        os_free(frameBuf);
1782e5b75505Sopenharmony_ci        frameBuf = NULL;
1783e5b75505Sopenharmony_ci        return -EFAIL;
1784e5b75505Sopenharmony_ci    }
1785e5b75505Sopenharmony_ci    ret = l2_packet_send(drv->eapolSock, addr, ETH_P_EAPOL, frameBuf, frameLen);
1786e5b75505Sopenharmony_ci    os_free(frameBuf);
1787e5b75505Sopenharmony_ci    frameBuf = NULL;
1788e5b75505Sopenharmony_ci    wpa_printf(MSG_INFO, "WifiWpaHapdSendEapol done, ret=%d", ret);
1789e5b75505Sopenharmony_ci    return ret;
1790e5b75505Sopenharmony_ci}
1791e5b75505Sopenharmony_ci
1792e5b75505Sopenharmony_cistatic int32_t WifiWpaStaRemove(void *priv, const uint8_t *addr)
1793e5b75505Sopenharmony_ci{
1794e5b75505Sopenharmony_ci    WifiDriverData *drv = NULL;
1795e5b75505Sopenharmony_ci    int32_t ret;
1796e5b75505Sopenharmony_ci
1797e5b75505Sopenharmony_ci    if ((priv == NULL) || (addr == NULL)) {
1798e5b75505Sopenharmony_ci        return -EFAIL;
1799e5b75505Sopenharmony_ci    }
1800e5b75505Sopenharmony_ci    drv = (WifiDriverData *)priv;
1801e5b75505Sopenharmony_ci    ret = WifiCmdStaRemove(drv->iface, addr, ETH_ADDR_LEN);
1802e5b75505Sopenharmony_ci    if (ret != SUCC) {
1803e5b75505Sopenharmony_ci        return -EFAIL;
1804e5b75505Sopenharmony_ci    }
1805e5b75505Sopenharmony_ci    wpa_printf(MSG_INFO, "WifiWpaStaRemove done, ret=%d", ret);
1806e5b75505Sopenharmony_ci    return ret;
1807e5b75505Sopenharmony_ci}
1808e5b75505Sopenharmony_ci
1809e5b75505Sopenharmony_cistatic uint8_t *WifiDuplicateStr(const uint8_t *src, size_t len)
1810e5b75505Sopenharmony_ci{
1811e5b75505Sopenharmony_ci    uint8_t *res = NULL;
1812e5b75505Sopenharmony_ci
1813e5b75505Sopenharmony_ci    if (src == NULL) {
1814e5b75505Sopenharmony_ci        return NULL;
1815e5b75505Sopenharmony_ci    }
1816e5b75505Sopenharmony_ci    res = os_malloc(len + 1);
1817e5b75505Sopenharmony_ci    if (res == NULL) {
1818e5b75505Sopenharmony_ci        return NULL;
1819e5b75505Sopenharmony_ci    }
1820e5b75505Sopenharmony_ci    if (memcpy_s(res, len, src, len) != EOK) {
1821e5b75505Sopenharmony_ci        os_free(res);
1822e5b75505Sopenharmony_ci        return NULL;
1823e5b75505Sopenharmony_ci    }
1824e5b75505Sopenharmony_ci    res[len] = '\0';
1825e5b75505Sopenharmony_ci
1826e5b75505Sopenharmony_ci    return res;
1827e5b75505Sopenharmony_ci}
1828e5b75505Sopenharmony_ci
1829e5b75505Sopenharmony_cistatic void WifiActionDataBufFree(WifiActionData *actionData)
1830e5b75505Sopenharmony_ci{
1831e5b75505Sopenharmony_ci    if (actionData == NULL) {
1832e5b75505Sopenharmony_ci        return;
1833e5b75505Sopenharmony_ci    }
1834e5b75505Sopenharmony_ci    if (actionData->data != NULL) {
1835e5b75505Sopenharmony_ci        os_free(actionData->data);
1836e5b75505Sopenharmony_ci        actionData->data = NULL;
1837e5b75505Sopenharmony_ci    }
1838e5b75505Sopenharmony_ci}
1839e5b75505Sopenharmony_ci
1840e5b75505Sopenharmony_cistatic int32_t WifiWpaSendAction(void *priv, uint32_t freq, uint32_t wait, const uint8_t *dst, const uint8_t *src,
1841e5b75505Sopenharmony_ci    const uint8_t *bssid, const uint8_t *data, size_t dataLen, int32_t noCck)
1842e5b75505Sopenharmony_ci{
1843e5b75505Sopenharmony_ci    WifiActionData actionData = {
1844e5b75505Sopenharmony_ci        .dst = {0},
1845e5b75505Sopenharmony_ci        .src = {0},
1846e5b75505Sopenharmony_ci        .bssid = {0},
1847e5b75505Sopenharmony_ci        .data = NULL,
1848e5b75505Sopenharmony_ci        .dataLen = 0,
1849e5b75505Sopenharmony_ci        .freq = 0,
1850e5b75505Sopenharmony_ci        .wait = 0,
1851e5b75505Sopenharmony_ci        .noCck = 0,
1852e5b75505Sopenharmony_ci    };
1853e5b75505Sopenharmony_ci    WifiDriverData *drv = NULL;
1854e5b75505Sopenharmony_ci    int32_t ret;
1855e5b75505Sopenharmony_ci
1856e5b75505Sopenharmony_ci    if ((priv == NULL) || (data == NULL) || (dst == NULL) || (src == NULL) || (bssid == NULL)) {
1857e5b75505Sopenharmony_ci        return -EFAIL;
1858e5b75505Sopenharmony_ci    }
1859e5b75505Sopenharmony_ci    drv = (WifiDriverData *)priv;
1860e5b75505Sopenharmony_ci
1861e5b75505Sopenharmony_ci    if (memcpy_s(actionData.dst, ETH_ADDR_LEN, dst, ETH_ADDR_LEN) != EOK) {
1862e5b75505Sopenharmony_ci        return -EFAIL;
1863e5b75505Sopenharmony_ci    }
1864e5b75505Sopenharmony_ci    if (memcpy_s(actionData.src, ETH_ADDR_LEN, src, ETH_ADDR_LEN) != EOK) {
1865e5b75505Sopenharmony_ci        return -EFAIL;
1866e5b75505Sopenharmony_ci    }
1867e5b75505Sopenharmony_ci    if (memcpy_s(actionData.bssid, ETH_ADDR_LEN, bssid, ETH_ADDR_LEN) != EOK) {
1868e5b75505Sopenharmony_ci        return -EFAIL;
1869e5b75505Sopenharmony_ci    }
1870e5b75505Sopenharmony_ci
1871e5b75505Sopenharmony_ci    actionData.dataLen = dataLen;
1872e5b75505Sopenharmony_ci    actionData.freq = freq;
1873e5b75505Sopenharmony_ci    actionData.wait = wait;
1874e5b75505Sopenharmony_ci    actionData.noCck = noCck;
1875e5b75505Sopenharmony_ci    actionData.data = WifiDuplicateStr(data, dataLen);
1876e5b75505Sopenharmony_ci    if (actionData.data == NULL) {
1877e5b75505Sopenharmony_ci        return -EFAIL;
1878e5b75505Sopenharmony_ci    }
1879e5b75505Sopenharmony_ci    ret = WifiCmdSendAction(drv->iface, &actionData);
1880e5b75505Sopenharmony_ci    WifiActionDataBufFree(&actionData);
1881e5b75505Sopenharmony_ci    wpa_printf(MSG_INFO, "WifiWpaSendAction done, ret=%d", ret);
1882e5b75505Sopenharmony_ci    return ret;
1883e5b75505Sopenharmony_ci}
1884e5b75505Sopenharmony_ci
1885e5b75505Sopenharmony_ci__attribute__ ((visibility ("default"))) void DeinitWifiService()
1886e5b75505Sopenharmony_ci{
1887e5b75505Sopenharmony_ci    if (g_wifiDriverType == WIFI_IFTYPE_STATION) {
1888e5b75505Sopenharmony_ci        WifiWpaDeinit(g_wifiDriverData);
1889e5b75505Sopenharmony_ci    } else if (g_wifiDriverType == WIFI_IFTYPE_AP) {
1890e5b75505Sopenharmony_ci        WifiWpaHapdDeinit(g_wifiDriverData);
1891e5b75505Sopenharmony_ci    } else {
1892e5b75505Sopenharmony_ci        printf("no need to cleanup \n");
1893e5b75505Sopenharmony_ci    }
1894e5b75505Sopenharmony_ci}
1895e5b75505Sopenharmony_ci
1896e5b75505Sopenharmony_ci#ifdef CONFIG_OHOS_P2P
1897e5b75505Sopenharmony_cistatic int32_t WifiProbeReqReport(void *priv, int32_t report)
1898e5b75505Sopenharmony_ci{
1899e5b75505Sopenharmony_ci    WifiDriverData *drv = NULL;
1900e5b75505Sopenharmony_ci    wpa_printf(MSG_INFO, "%s enter.", __FUNCTION__);
1901e5b75505Sopenharmony_ci    if (priv == NULL) {
1902e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s input invalid.", __FUNCTION__);
1903e5b75505Sopenharmony_ci        return -EFAIL;
1904e5b75505Sopenharmony_ci    }
1905e5b75505Sopenharmony_ci    drv = (WifiDriverData *)priv;
1906e5b75505Sopenharmony_ci    return WifiCmdProbeReqReport(drv->iface, &report);
1907e5b75505Sopenharmony_ci}
1908e5b75505Sopenharmony_ci
1909e5b75505Sopenharmony_cistatic int32_t WifiRemainOnChannel(void *priv, uint32_t freq, uint32_t duration)
1910e5b75505Sopenharmony_ci{
1911e5b75505Sopenharmony_ci    int32_t ret;
1912e5b75505Sopenharmony_ci    WifiDriverData *drv = priv;
1913e5b75505Sopenharmony_ci    WifiOnChannel *onChannel = NULL;
1914e5b75505Sopenharmony_ci    if (priv == NULL) {
1915e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s input invalid.", __FUNCTION__);
1916e5b75505Sopenharmony_ci        return -EFAIL;
1917e5b75505Sopenharmony_ci    }
1918e5b75505Sopenharmony_ci    onChannel = (WifiOnChannel *)os_zalloc(sizeof(WifiOnChannel));
1919e5b75505Sopenharmony_ci    if (onChannel == NULL)
1920e5b75505Sopenharmony_ci    {
1921e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s failed to alloc channel.", __FUNCTION__);
1922e5b75505Sopenharmony_ci        return -EFAIL;
1923e5b75505Sopenharmony_ci    }
1924e5b75505Sopenharmony_ci    onChannel->freq = freq;
1925e5b75505Sopenharmony_ci    onChannel->duration = duration;
1926e5b75505Sopenharmony_ci
1927e5b75505Sopenharmony_ci    ret = WifiCmdRemainOnChannel(drv->iface, onChannel);
1928e5b75505Sopenharmony_ci
1929e5b75505Sopenharmony_ci    os_free(onChannel);
1930e5b75505Sopenharmony_ci    onChannel = NULL;
1931e5b75505Sopenharmony_ci
1932e5b75505Sopenharmony_ci    return ret;
1933e5b75505Sopenharmony_ci}
1934e5b75505Sopenharmony_ci
1935e5b75505Sopenharmony_cistatic int32_t WifiCancelRemainOnChannel(void *priv)
1936e5b75505Sopenharmony_ci{
1937e5b75505Sopenharmony_ci    WifiDriverData *drv = priv;
1938e5b75505Sopenharmony_ci    if (drv == NULL) {
1939e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s input invalid.", __FUNCTION__);
1940e5b75505Sopenharmony_ci        return -EFAIL;
1941e5b75505Sopenharmony_ci    }
1942e5b75505Sopenharmony_ci
1943e5b75505Sopenharmony_ci    return WifiCmdCancelRemainOnChannel(drv->iface);
1944e5b75505Sopenharmony_ci}
1945e5b75505Sopenharmony_ci
1946e5b75505Sopenharmony_cistatic int32_t WifiAddIf(void *priv, enum wpa_driver_if_type type, const char *ifName, const uint8_t *addr, void *bss_ctx,
1947e5b75505Sopenharmony_ci                         void **drv_priv, char *force_ifname, uint8_t *if_addr, const char *bridge, int32_t use_existing, int32_t setup_ap)
1948e5b75505Sopenharmony_ci{
1949e5b75505Sopenharmony_ci    WifiDriverData *drv = priv;
1950e5b75505Sopenharmony_ci    WifiIfAdd *ifAdd = NULL;
1951e5b75505Sopenharmony_ci    int32_t ret;
1952e5b75505Sopenharmony_ci    WifiDev *wifiDev = NULL;
1953e5b75505Sopenharmony_ci    if (priv == NULL) {
1954e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s input invalid.", __FUNCTION__);
1955e5b75505Sopenharmony_ci        return -EFAIL;
1956e5b75505Sopenharmony_ci    }
1957e5b75505Sopenharmony_ci    ifAdd = (WifiIfAdd *)os_zalloc(sizeof(WifiIfAdd));
1958e5b75505Sopenharmony_ci    if (ifAdd == NULL) {
1959e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s failed to alloc ifAdd.", __FUNCTION__);
1960e5b75505Sopenharmony_ci        return -EFAIL;
1961e5b75505Sopenharmony_ci    }
1962e5b75505Sopenharmony_ci    switch (type) {
1963e5b75505Sopenharmony_ci    case WPA_IF_STATION:
1964e5b75505Sopenharmony_ci        ifAdd->type = WIFI_IFTYPE_STATION;
1965e5b75505Sopenharmony_ci        break;
1966e5b75505Sopenharmony_ci    case WPA_IF_P2P_GROUP:
1967e5b75505Sopenharmony_ci    case WPA_IF_P2P_CLIENT:
1968e5b75505Sopenharmony_ci        ifAdd->type = WIFI_IFTYPE_P2P_CLIENT;
1969e5b75505Sopenharmony_ci        break;
1970e5b75505Sopenharmony_ci    case WPA_IF_AP_VLAN:
1971e5b75505Sopenharmony_ci        ifAdd->type = WIFI_IFTYPE_AP_VLAN;
1972e5b75505Sopenharmony_ci        break;
1973e5b75505Sopenharmony_ci    case WPA_IF_AP_BSS:
1974e5b75505Sopenharmony_ci        ifAdd->type = WIFI_IFTYPE_AP;
1975e5b75505Sopenharmony_ci        break;
1976e5b75505Sopenharmony_ci    case WPA_IF_P2P_GO:
1977e5b75505Sopenharmony_ci        ifAdd->type = WIFI_IFTYPE_P2P_GO;
1978e5b75505Sopenharmony_ci        break;
1979e5b75505Sopenharmony_ci    case WPA_IF_P2P_DEVICE:
1980e5b75505Sopenharmony_ci        ifAdd->type = WIFI_IFTYPE_P2P_DEVICE;
1981e5b75505Sopenharmony_ci        break;
1982e5b75505Sopenharmony_ci    case WPA_IF_MESH:
1983e5b75505Sopenharmony_ci        ifAdd->type = WIFI_IFTYPE_MESH_POINT;
1984e5b75505Sopenharmony_ci        break;
1985e5b75505Sopenharmony_ci    default:
1986e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s unsuportted interface type %d.", __FUNCTION__, type);
1987e5b75505Sopenharmony_ci    }
1988e5b75505Sopenharmony_ci
1989e5b75505Sopenharmony_ci    ret = WifiRegisterEventCallback(OnWpaWiFiEvents, WIFI_KERNEL_TO_WPA_CLIENT, ifName);
1990e5b75505Sopenharmony_ci    if (ret != SUCC) {
1991e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "WifiWpa register event listener faild");
1992e5b75505Sopenharmony_ci    }
1993e5b75505Sopenharmony_ci    ret = memcpy_s(ifAdd->ifName, IFNAMSIZ, ifName, IFNAMSIZ);
1994e5b75505Sopenharmony_ci    if (ret != SUCC) {
1995e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s memcpy_s ifName faild", __FUNCTION__);
1996e5b75505Sopenharmony_ci        return -EFAIL;
1997e5b75505Sopenharmony_ci    }
1998e5b75505Sopenharmony_ci
1999e5b75505Sopenharmony_ci    ret = WifiCmdAddIf(drv->iface, ifAdd);
2000e5b75505Sopenharmony_ci    if (ret == SUCC) {
2001e5b75505Sopenharmony_ci        wifiDev = (WifiDev *)os_zalloc(sizeof(WifiDev));
2002e5b75505Sopenharmony_ci        if (wifiDev == NULL) {
2003e5b75505Sopenharmony_ci            wpa_printf(MSG_ERROR, "%s failed to malloc wifiDev.", __FUNCTION__);
2004e5b75505Sopenharmony_ci            return -EFAIL;
2005e5b75505Sopenharmony_ci        }
2006e5b75505Sopenharmony_ci        wifiDev->priv = drv;
2007e5b75505Sopenharmony_ci        wifiDev->ifNameLen = sizeof(ifName);
2008e5b75505Sopenharmony_ci        errno_t rc = memcpy_s(wifiDev->ifName, sizeof(wifiDev->ifName), ifName, sizeof(drv->iface));
2009e5b75505Sopenharmony_ci        if (rc != EOK) {
2010e5b75505Sopenharmony_ci            wpa_printf(MSG_ERROR, "Could not copy wifi device name.");
2011e5b75505Sopenharmony_ci            FreeWifiDev(wifiDev);
2012e5b75505Sopenharmony_ci            return ret;
2013e5b75505Sopenharmony_ci        }
2014e5b75505Sopenharmony_ci        wpa_printf(MSG_INFO, "%s ifName:%s, type:%d", __FUNCTION__, wifiDev->ifName, ifAdd->type);
2015e5b75505Sopenharmony_ci        SetWifiDev(wifiDev);
2016e5b75505Sopenharmony_ci    }
2017e5b75505Sopenharmony_ci    os_free(ifAdd);
2018e5b75505Sopenharmony_ci    ifAdd = NULL;
2019e5b75505Sopenharmony_ci    return ret;
2020e5b75505Sopenharmony_ci}
2021e5b75505Sopenharmony_ci
2022e5b75505Sopenharmony_cistatic int32_t WifiRemoveIf(void *priv, enum wpa_driver_if_type type, const char *ifName)
2023e5b75505Sopenharmony_ci{
2024e5b75505Sopenharmony_ci    WifiDriverData *drv = priv;
2025e5b75505Sopenharmony_ci    WifiIfRemove ifRemove = {0};
2026e5b75505Sopenharmony_ci    int32_t ret;
2027e5b75505Sopenharmony_ci    errno_t rc;
2028e5b75505Sopenharmony_ci    WifiDev *wifiDev = NULL;
2029e5b75505Sopenharmony_ci    if (priv == NULL || ifName == NULL) {
2030e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s input invalid.", __FUNCTION__);
2031e5b75505Sopenharmony_ci        return -EFAIL;
2032e5b75505Sopenharmony_ci    }
2033e5b75505Sopenharmony_ci    if (os_strlen(ifName) > IFNAMSIZ) {
2034e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s ifName invalid:%s.", __FUNCTION__, ifName);
2035e5b75505Sopenharmony_ci        return -EFAIL;
2036e5b75505Sopenharmony_ci    }
2037e5b75505Sopenharmony_ci    rc = memcpy_s(ifRemove.ifName, IFNAMSIZ, ifName, IFNAMSIZ);
2038e5b75505Sopenharmony_ci    if (rc != EOK) {
2039e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s can not copy interface name.", __FUNCTION__);
2040e5b75505Sopenharmony_ci        return -EFAIL;
2041e5b75505Sopenharmony_ci    }
2042e5b75505Sopenharmony_ci
2043e5b75505Sopenharmony_ci    ret = WifiCmdRemoveIf(drv->iface, &ifRemove);
2044e5b75505Sopenharmony_ci    wifiDev = GetWifiDevByName(ifName);
2045e5b75505Sopenharmony_ci    if (wifiDev == NULL) {
2046e5b75505Sopenharmony_ci        wpa_printf(MSG_INFO, "%s: GetWifiDevByName is null, already free.", __FUNCTION__);
2047e5b75505Sopenharmony_ci        return SUCC;
2048e5b75505Sopenharmony_ci    }
2049e5b75505Sopenharmony_ci    FreeWifiDev(wifiDev);
2050e5b75505Sopenharmony_ci    return SUCC;
2051e5b75505Sopenharmony_ci}
2052e5b75505Sopenharmony_ci
2053e5b75505Sopenharmony_ciint32_t WifiSetApWpsP2pIe(void *priv, const struct wpabuf *beacon, const struct wpabuf *probresp, const struct wpabuf *assocresp)
2054e5b75505Sopenharmony_ci{
2055e5b75505Sopenharmony_ci    int32_t loops;
2056e5b75505Sopenharmony_ci    int32_t ret = SUCC;
2057e5b75505Sopenharmony_ci    WifiAppIe *appIe = NULL;
2058e5b75505Sopenharmony_ci    struct wpabuf *wpabufTmp = NULL;
2059e5b75505Sopenharmony_ci    WifiDriverData *drv = (WifiDriverData *)priv;
2060e5b75505Sopenharmony_ci    WifiCmd cmdAddr[4] = {{0x1, beacon}, {0x2, probresp}, {0x4, assocresp}, {-1, NULL}};
2061e5b75505Sopenharmony_ci    errno_t rc;
2062e5b75505Sopenharmony_ci    appIe = (WifiAppIe *)os_zalloc(sizeof(WifiAppIe));
2063e5b75505Sopenharmony_ci    if (appIe == NULL) {
2064e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s:failed to malloc WifiAppIe.", __FUNCTION__);
2065e5b75505Sopenharmony_ci        return -EFAIL;
2066e5b75505Sopenharmony_ci    }
2067e5b75505Sopenharmony_ci    for (loops = 0; cmdAddr[loops].cmd != -1; loops++) {
2068e5b75505Sopenharmony_ci        wpabufTmp = (struct wpabuf *)cmdAddr[loops].src;
2069e5b75505Sopenharmony_ci        if (wpabufTmp != NULL) {
2070e5b75505Sopenharmony_ci            appIe->appIeType = cmdAddr[loops].cmd;
2071e5b75505Sopenharmony_ci            appIe->ieLen = wpabuf_len(wpabufTmp);
2072e5b75505Sopenharmony_ci            if ((wpabufTmp->buf != NULL) && (appIe->ieLen != 0)) {
2073e5b75505Sopenharmony_ci                appIe->ie = os_zalloc(appIe->ieLen);
2074e5b75505Sopenharmony_ci                if (appIe->ie == NULL) {
2075e5b75505Sopenharmony_ci                    wpa_printf(MSG_ERROR, "%s appIe->ie malloc failed.", __FUNCTION__);
2076e5b75505Sopenharmony_ci                    os_free(appIe);
2077e5b75505Sopenharmony_ci                    return -EFAIL;
2078e5b75505Sopenharmony_ci                }
2079e5b75505Sopenharmony_ci                rc = memcpy_s(appIe->ie, appIe->ieLen, wpabuf_head(wpabufTmp), wpabuf_len(wpabufTmp));
2080e5b75505Sopenharmony_ci                if (rc != EOK) {
2081e5b75505Sopenharmony_ci                    wpa_printf(MSG_ERROR, "%s: ", __FUNCTION__);
2082e5b75505Sopenharmony_ci                    os_free(appIe->ie);
2083e5b75505Sopenharmony_ci                    os_free(appIe);
2084e5b75505Sopenharmony_ci                    return -EFAIL;
2085e5b75505Sopenharmony_ci                }
2086e5b75505Sopenharmony_ci            }
2087e5b75505Sopenharmony_ci            wpa_printf(MSG_INFO, "%s type %d, ie_len %d.", __FUNCTION__, appIe->appIeType, appIe->ieLen);
2088e5b75505Sopenharmony_ci
2089e5b75505Sopenharmony_ci            ret = WifiCmdSetApWpsP2pIe(drv->iface, appIe);
2090e5b75505Sopenharmony_ci            os_free(appIe->ie);
2091e5b75505Sopenharmony_ci            appIe->ie = NULL;
2092e5b75505Sopenharmony_ci            if (ret < 0) {
2093e5b75505Sopenharmony_ci                break;
2094e5b75505Sopenharmony_ci            }
2095e5b75505Sopenharmony_ci        }
2096e5b75505Sopenharmony_ci    }
2097e5b75505Sopenharmony_ci    os_free(appIe);
2098e5b75505Sopenharmony_ci    appIe = NULL;
2099e5b75505Sopenharmony_ci    return ret;
2100e5b75505Sopenharmony_ci}
2101e5b75505Sopenharmony_ci
2102e5b75505Sopenharmony_ciint32_t WifiWpaGetDrvFlags(void *priv, uint64_t *drvFlags)
2103e5b75505Sopenharmony_ci{
2104e5b75505Sopenharmony_ci    WifiDriverData *drv = NULL;
2105e5b75505Sopenharmony_ci    WifiGetDrvFlags *params = NULL;
2106e5b75505Sopenharmony_ci    int32_t ret;
2107e5b75505Sopenharmony_ci    if (priv == NULL || drvFlags == NULL)
2108e5b75505Sopenharmony_ci    {
2109e5b75505Sopenharmony_ci        return -EFAIL;
2110e5b75505Sopenharmony_ci    }
2111e5b75505Sopenharmony_ci    drv = (WifiDriverData *)priv;
2112e5b75505Sopenharmony_ci    params = (WifiGetDrvFlags *)os_zalloc(sizeof(WifiGetDrvFlags));
2113e5b75505Sopenharmony_ci    if (params == NULL)
2114e5b75505Sopenharmony_ci    {
2115e5b75505Sopenharmony_ci        return -EFAIL;
2116e5b75505Sopenharmony_ci    }
2117e5b75505Sopenharmony_ci    params->drvFlags = 0;
2118e5b75505Sopenharmony_ci    ret = WifiCmdGetDrvFlags(drv->iface, params);
2119e5b75505Sopenharmony_ci    if (ret != SUCC)
2120e5b75505Sopenharmony_ci    {
2121e5b75505Sopenharmony_ci        wpa_printf(MSG_ERROR, "%s WifiCmdGetDrvFlags failed, ret is %d.", __FUNCTION__, ret);
2122e5b75505Sopenharmony_ci        os_free(params);
2123e5b75505Sopenharmony_ci        return -EFAIL;
2124e5b75505Sopenharmony_ci    }
2125e5b75505Sopenharmony_ci    *drvFlags = params->drvFlags;
2126e5b75505Sopenharmony_ci    wpa_printf(MSG_INFO, "%s Get drvFlags done.", __FUNCTION__);
2127e5b75505Sopenharmony_ci    os_free(params);
2128e5b75505Sopenharmony_ci    return ret;
2129e5b75505Sopenharmony_ci}
2130e5b75505Sopenharmony_ci#endif // CONFIG_OHOS_P2P
2131e5b75505Sopenharmony_ci
2132e5b75505Sopenharmony_ciconst struct wpa_driver_ops g_wifiDriverOps = {
2133e5b75505Sopenharmony_ci    .name = "hdf wifi",
2134e5b75505Sopenharmony_ci    .desc = "wpa hdf adaptor layer",
2135e5b75505Sopenharmony_ci    .get_bssid = WifiWpaGetBssid,
2136e5b75505Sopenharmony_ci    .get_ssid = WifiWpaGetSsid,
2137e5b75505Sopenharmony_ci    .set_key = WifiWpaSetKey,
2138e5b75505Sopenharmony_ci    .scan2 = WifiWpaScan2,
2139e5b75505Sopenharmony_ci    .get_scan_results2 = WifiWpaGetScanResults2,
2140e5b75505Sopenharmony_ci    .deauthenticate = WifiWpaDeauthenticate,
2141e5b75505Sopenharmony_ci    .associate = WifiWpaAssociate,
2142e5b75505Sopenharmony_ci    .send_eapol = WifiWpaWpaSendEapol,
2143e5b75505Sopenharmony_ci    .init2 = WifiWpaInit2,
2144e5b75505Sopenharmony_ci    .deinit = WifiWpaDeinit,
2145e5b75505Sopenharmony_ci    .set_ap = WifiWpaSetAp,
2146e5b75505Sopenharmony_ci    .send_mlme = WifiWpaSendMlme,
2147e5b75505Sopenharmony_ci    .get_hw_feature_data = WifiWpaGetHwFeatureData,
2148e5b75505Sopenharmony_ci    .sta_remove = WifiWpaStaRemove,
2149e5b75505Sopenharmony_ci    .hapd_init = WifiWpaHapdInit,
2150e5b75505Sopenharmony_ci    .hapd_deinit = WifiWpaHapdDeinit,
2151e5b75505Sopenharmony_ci    .hapd_send_eapol = WifiWpaHapdSendEapol,
2152e5b75505Sopenharmony_ci    .send_action = WifiWpaSendAction,
2153e5b75505Sopenharmony_ci    .get_mac_addr = WifiWpaGetMacAddr,
2154e5b75505Sopenharmony_ci#ifdef CONFIG_OHOS_P2P
2155e5b75505Sopenharmony_ci    .remain_on_channel = WifiRemainOnChannel,
2156e5b75505Sopenharmony_ci    .cancel_remain_on_channel = WifiCancelRemainOnChannel,
2157e5b75505Sopenharmony_ci    .probe_req_report = WifiProbeReqReport,
2158e5b75505Sopenharmony_ci    .if_add = WifiAddIf,
2159e5b75505Sopenharmony_ci    .if_remove = WifiRemoveIf,
2160e5b75505Sopenharmony_ci    .set_ap_wps_ie = WifiSetApWpsP2pIe,
2161e5b75505Sopenharmony_ci#endif // CONFIG_OHOS_P2P
2162e5b75505Sopenharmony_ci};
2163e5b75505Sopenharmony_ci
2164e5b75505Sopenharmony_ci#ifdef __cplusplus
2165e5b75505Sopenharmony_ci#if __cplusplus
2166e5b75505Sopenharmony_ci}
2167e5b75505Sopenharmony_ci#endif
2168e5b75505Sopenharmony_ci#endif
2169