10a7ce71fSopenharmony_ci/*
20a7ce71fSopenharmony_ci * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
30a7ce71fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
40a7ce71fSopenharmony_ci * you may not use this file except in compliance with the License.
50a7ce71fSopenharmony_ci * You may obtain a copy of the License at
60a7ce71fSopenharmony_ci *
70a7ce71fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
80a7ce71fSopenharmony_ci *
90a7ce71fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
100a7ce71fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
110a7ce71fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120a7ce71fSopenharmony_ci * See the License for the specific language governing permissions and
130a7ce71fSopenharmony_ci * limitations under the License.
140a7ce71fSopenharmony_ci */
150a7ce71fSopenharmony_ci
160a7ce71fSopenharmony_ci#include <unistd.h>
170a7ce71fSopenharmony_ci#include "hi_wifi_api.h"
180a7ce71fSopenharmony_ci#include "lwip/ip_addr.h"
190a7ce71fSopenharmony_ci#include "lwip/netifapi.h"
200a7ce71fSopenharmony_ci#include "app_demo_get_mac_addr.h"
210a7ce71fSopenharmony_ci#include "wifi_sta.h"
220a7ce71fSopenharmony_ci
230a7ce71fSopenharmony_ci#define APP_INIT_VAP_NUM    2
240a7ce71fSopenharmony_ci#define APP_INIT_USR_NUM    2
250a7ce71fSopenharmony_ci
260a7ce71fSopenharmony_cistatic struct netif *g_lwip_netif = NULL;
270a7ce71fSopenharmony_ci
280a7ce71fSopenharmony_ci/* clear netif's ip, gateway and netmask */
290a7ce71fSopenharmony_civoid hi_sta_reset_addr(const struct netif *pst_lwip_netif)
300a7ce71fSopenharmony_ci{
310a7ce71fSopenharmony_ci    ip4_addr_t st_gw;
320a7ce71fSopenharmony_ci    ip4_addr_t st_ipaddr;
330a7ce71fSopenharmony_ci    ip4_addr_t st_netmask;
340a7ce71fSopenharmony_ci
350a7ce71fSopenharmony_ci    if (pst_lwip_netif == NULL) {
360a7ce71fSopenharmony_ci        printf("hisi_reset_addr::Null param of netdev\r\n");
370a7ce71fSopenharmony_ci        return;
380a7ce71fSopenharmony_ci    }
390a7ce71fSopenharmony_ci
400a7ce71fSopenharmony_ci    IP4_ADDR(&st_gw, 0, 0, 0, 0);
410a7ce71fSopenharmony_ci    IP4_ADDR(&st_ipaddr, 0, 0, 0, 0);
420a7ce71fSopenharmony_ci    IP4_ADDR(&st_netmask, 0, 0, 0, 0);
430a7ce71fSopenharmony_ci
440a7ce71fSopenharmony_ci    netifapi_netif_set_addr(pst_lwip_netif, &st_ipaddr, &st_netmask, &st_gw);
450a7ce71fSopenharmony_ci}
460a7ce71fSopenharmony_ci
470a7ce71fSopenharmony_civoid wifi_wpa_event_cb(const hi_wifi_event *hisi_event)
480a7ce71fSopenharmony_ci{
490a7ce71fSopenharmony_ci    if (hisi_event == NULL)
500a7ce71fSopenharmony_ci        return;
510a7ce71fSopenharmony_ci
520a7ce71fSopenharmony_ci    switch (hisi_event->event) {
530a7ce71fSopenharmony_ci        case HI_WIFI_EVT_SCAN_DONE:
540a7ce71fSopenharmony_ci            printf("WiFi: Scan results available\n");
550a7ce71fSopenharmony_ci            break;
560a7ce71fSopenharmony_ci        case HI_WIFI_EVT_CONNECTED:
570a7ce71fSopenharmony_ci            printf("WiFi: Connected\n");
580a7ce71fSopenharmony_ci            netifapi_dhcp_start(g_lwip_netif);
590a7ce71fSopenharmony_ci            break;
600a7ce71fSopenharmony_ci        case HI_WIFI_EVT_DISCONNECTED:
610a7ce71fSopenharmony_ci            printf("WiFi: Disconnected\n");
620a7ce71fSopenharmony_ci            netifapi_dhcp_stop(g_lwip_netif);
630a7ce71fSopenharmony_ci            hi_sta_reset_addr(g_lwip_netif);
640a7ce71fSopenharmony_ci            break;
650a7ce71fSopenharmony_ci        case HI_WIFI_EVT_WPS_TIMEOUT:
660a7ce71fSopenharmony_ci            printf("WiFi: wps is timeout\n");
670a7ce71fSopenharmony_ci            break;
680a7ce71fSopenharmony_ci        default:
690a7ce71fSopenharmony_ci            break;
700a7ce71fSopenharmony_ci    }
710a7ce71fSopenharmony_ci}
720a7ce71fSopenharmony_ci
730a7ce71fSopenharmony_ciint hi_wifi_start_connect(void)
740a7ce71fSopenharmony_ci{
750a7ce71fSopenharmony_ci    int ret = 0;
760a7ce71fSopenharmony_ci    errno_t rc = 0;
770a7ce71fSopenharmony_ci    unsigned char *ssid = NULL;
780a7ce71fSopenharmony_ci    hi_wifi_assoc_request assoc_req = {0};
790a7ce71fSopenharmony_ci
800a7ce71fSopenharmony_ci    /* get Hi3861 mac addr */
810a7ce71fSopenharmony_ci    hi3816_get_mac_addr();
820a7ce71fSopenharmony_ci    ssid = GetSsid();
830a7ce71fSopenharmony_ci    /* copy SSID to assoc_req */
840a7ce71fSopenharmony_ci    rc = memcpy_s(assoc_req.ssid, HI_WIFI_MAX_SSID_LEN + 1, ssid, 20); /* 20:ssid length */
850a7ce71fSopenharmony_ci    if (rc != EOK) {
860a7ce71fSopenharmony_ci        return -1;
870a7ce71fSopenharmony_ci    }
880a7ce71fSopenharmony_ci
890a7ce71fSopenharmony_ci    /*
900a7ce71fSopenharmony_ci     * OPEN mode
910a7ce71fSopenharmony_ci     * for WPA2-PSK mode:
920a7ce71fSopenharmony_ci     * set assoc_req.auth as HI_WIFI_SECURITY_WPA2PSK,
930a7ce71fSopenharmony_ci     * then memcpy(assoc_req.key, "12345678", 8).
940a7ce71fSopenharmony_ci     */
950a7ce71fSopenharmony_ci    assoc_req.auth = HI_WIFI_SECURITY_OPEN;
960a7ce71fSopenharmony_ci
970a7ce71fSopenharmony_ci    ret = hi_wifi_sta_connect(&assoc_req);
980a7ce71fSopenharmony_ci    if (ret != HISI_OK) {
990a7ce71fSopenharmony_ci        return -1;
1000a7ce71fSopenharmony_ci    }
1010a7ce71fSopenharmony_ci
1020a7ce71fSopenharmony_ci    return 0;
1030a7ce71fSopenharmony_ci}
1040a7ce71fSopenharmony_ci
1050a7ce71fSopenharmony_ciint hi_wifi_start_sta(void)
1060a7ce71fSopenharmony_ci{
1070a7ce71fSopenharmony_ci    int ret;
1080a7ce71fSopenharmony_ci    char ifname[WIFI_IFNAME_MAX_SIZE + 1] = {0};
1090a7ce71fSopenharmony_ci    int len = sizeof(ifname);
1100a7ce71fSopenharmony_ci    const unsigned char wifi_vap_res_num = APP_INIT_VAP_NUM;
1110a7ce71fSopenharmony_ci    const unsigned char wifi_user_res_num = APP_INIT_USR_NUM;
1120a7ce71fSopenharmony_ci    unsigned int  num = WIFI_SCAN_AP_LIMIT;
1130a7ce71fSopenharmony_ci
1140a7ce71fSopenharmony_ci    ret = hi_wifi_init(wifi_vap_res_num, wifi_user_res_num);
1150a7ce71fSopenharmony_ci    if (ret != HISI_OK) {
1160a7ce71fSopenharmony_ci        return -1;
1170a7ce71fSopenharmony_ci    }
1180a7ce71fSopenharmony_ci
1190a7ce71fSopenharmony_ci    ret = hi_wifi_sta_start(ifname, &len);
1200a7ce71fSopenharmony_ci    if (ret != HISI_OK) {
1210a7ce71fSopenharmony_ci        return -1;
1220a7ce71fSopenharmony_ci    }
1230a7ce71fSopenharmony_ci
1240a7ce71fSopenharmony_ci    /* register call back function to receive wifi event, etc scan results event,
1250a7ce71fSopenharmony_ci     * connected event, disconnected event.
1260a7ce71fSopenharmony_ci     */
1270a7ce71fSopenharmony_ci    ret = hi_wifi_register_event_callback(wifi_wpa_event_cb);
1280a7ce71fSopenharmony_ci    if (ret != HISI_OK) {
1290a7ce71fSopenharmony_ci        printf("register wifi event callback failed\n");
1300a7ce71fSopenharmony_ci    }
1310a7ce71fSopenharmony_ci
1320a7ce71fSopenharmony_ci    /* acquire netif for IP operation */
1330a7ce71fSopenharmony_ci    g_lwip_netif = netifapi_netif_find(ifname);
1340a7ce71fSopenharmony_ci    if (g_lwip_netif == NULL) {
1350a7ce71fSopenharmony_ci        printf("%s: get netif failed\n", __FUNCTION__);
1360a7ce71fSopenharmony_ci        return -1;
1370a7ce71fSopenharmony_ci    }
1380a7ce71fSopenharmony_ci
1390a7ce71fSopenharmony_ci    /* start scan, scan results event will be received soon */
1400a7ce71fSopenharmony_ci    ret = hi_wifi_sta_scan();
1410a7ce71fSopenharmony_ci    if (ret != HISI_OK) {
1420a7ce71fSopenharmony_ci        return -1;
1430a7ce71fSopenharmony_ci    }
1440a7ce71fSopenharmony_ci
1450a7ce71fSopenharmony_ci    sleep(5);   /* sleep 5s, waiting for scan result. */
1460a7ce71fSopenharmony_ci
1470a7ce71fSopenharmony_ci    hi_wifi_ap_info *pst_results = malloc(sizeof(hi_wifi_ap_info) * WIFI_SCAN_AP_LIMIT);
1480a7ce71fSopenharmony_ci    if (pst_results == NULL) {
1490a7ce71fSopenharmony_ci        return -1;
1500a7ce71fSopenharmony_ci    }
1510a7ce71fSopenharmony_ci
1520a7ce71fSopenharmony_ci    ret = hi_wifi_sta_scan_results(pst_results, &num);
1530a7ce71fSopenharmony_ci    if (ret != HISI_OK) {
1540a7ce71fSopenharmony_ci        free(pst_results);
1550a7ce71fSopenharmony_ci        return -1;
1560a7ce71fSopenharmony_ci    }
1570a7ce71fSopenharmony_ci
1580a7ce71fSopenharmony_ci    for (unsigned int loop = 0; (loop < num) && (loop < WIFI_SCAN_AP_LIMIT); loop++) {
1590a7ce71fSopenharmony_ci        printf("SSID: %s\n", pst_results[loop].ssid);
1600a7ce71fSopenharmony_ci    }
1610a7ce71fSopenharmony_ci    free(pst_results);
1620a7ce71fSopenharmony_ci
1630a7ce71fSopenharmony_ci    /* if received scan results, select one SSID to connect */
1640a7ce71fSopenharmony_ci    ret = hi_wifi_start_connect();
1650a7ce71fSopenharmony_ci    if (ret != 0) {
1660a7ce71fSopenharmony_ci        return -1;
1670a7ce71fSopenharmony_ci    }
1680a7ce71fSopenharmony_ci
1690a7ce71fSopenharmony_ci    return 0;
1700a7ce71fSopenharmony_ci}
1710a7ce71fSopenharmony_ci
1720a7ce71fSopenharmony_civoid hi_wifi_stop_sta(void)
1730a7ce71fSopenharmony_ci{
1740a7ce71fSopenharmony_ci    int ret;
1750a7ce71fSopenharmony_ci
1760a7ce71fSopenharmony_ci    ret = hi_wifi_sta_stop();
1770a7ce71fSopenharmony_ci    if (ret != HISI_OK) {
1780a7ce71fSopenharmony_ci        printf("failed to stop sta\n");
1790a7ce71fSopenharmony_ci    }
1800a7ce71fSopenharmony_ci
1810a7ce71fSopenharmony_ci    ret = hi_wifi_deinit();
1820a7ce71fSopenharmony_ci    if (ret != HISI_OK) {
1830a7ce71fSopenharmony_ci        printf("failed to deinit wifi\n");
1840a7ce71fSopenharmony_ci    }
1850a7ce71fSopenharmony_ci
1860a7ce71fSopenharmony_ci    g_lwip_netif = NULL;
1870a7ce71fSopenharmony_ci}
188