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 "wifi_device.h"
170a7ce71fSopenharmony_ci#include "cmsis_os2.h"
180a7ce71fSopenharmony_ci
190a7ce71fSopenharmony_ci#include "lwip/netifapi.h"
200a7ce71fSopenharmony_ci#include "lwip/api_shell.h"
210a7ce71fSopenharmony_ci
220a7ce71fSopenharmony_ci#define OS_SLEEP_10MS (10)
230a7ce71fSopenharmony_ci#define OS_SLEEP_100MS (100)
240a7ce71fSopenharmony_ci
250a7ce71fSopenharmony_cistatic void PrintLinkedInfo(const WifiLinkedInfo* info)
260a7ce71fSopenharmony_ci{
270a7ce71fSopenharmony_ci    if (!info) return;
280a7ce71fSopenharmony_ci
290a7ce71fSopenharmony_ci    static char macAddress[32] = {0};
300a7ce71fSopenharmony_ci    unsigned char* mac = info->bssid;
310a7ce71fSopenharmony_ci    if (snprintf_s(macAddress, sizeof(macAddress) + 1, sizeof(macAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
320a7ce71fSopenharmony_ci        mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]) < 0) { /* mac地址从0,1,2,3,4,5位 */
330a7ce71fSopenharmony_ci            return;
340a7ce71fSopenharmony_ci    }
350a7ce71fSopenharmony_ci}
360a7ce71fSopenharmony_ci
370a7ce71fSopenharmony_cistatic volatile int g_connected = 0;
380a7ce71fSopenharmony_ci
390a7ce71fSopenharmony_cistatic void OnWifiConnectionChanged(int state, const WifiLinkedInfo* info)
400a7ce71fSopenharmony_ci{
410a7ce71fSopenharmony_ci    if (!info) return;
420a7ce71fSopenharmony_ci
430a7ce71fSopenharmony_ci    printf("%s %d, state = %d, info = \r\n", __FUNCTION__, __LINE__, state);
440a7ce71fSopenharmony_ci    PrintLinkedInfo(info);
450a7ce71fSopenharmony_ci
460a7ce71fSopenharmony_ci    if (state == WIFI_STATE_AVAILABLE) {
470a7ce71fSopenharmony_ci        g_connected = 1;
480a7ce71fSopenharmony_ci    } else {
490a7ce71fSopenharmony_ci        g_connected = 0;
500a7ce71fSopenharmony_ci    }
510a7ce71fSopenharmony_ci}
520a7ce71fSopenharmony_ci
530a7ce71fSopenharmony_cistatic void OnWifiScanStateChanged(int state, int size)
540a7ce71fSopenharmony_ci{
550a7ce71fSopenharmony_ci    printf("%s %d, state = %X, size = %d\r\n", __FUNCTION__, __LINE__, state, size);
560a7ce71fSopenharmony_ci}
570a7ce71fSopenharmony_ci
580a7ce71fSopenharmony_cistatic WifiEvent g_defaultWifiEventListener = {
590a7ce71fSopenharmony_ci    .OnWifiConnectionChanged = OnWifiConnectionChanged,
600a7ce71fSopenharmony_ci    .OnWifiScanStateChanged = OnWifiScanStateChanged
610a7ce71fSopenharmony_ci};
620a7ce71fSopenharmony_ci
630a7ce71fSopenharmony_cistatic struct netif* g_iface = NULL;
640a7ce71fSopenharmony_ci
650a7ce71fSopenharmony_cierr_t netifapi_set_hostname(struct netif *netif, char *hostname, u8_t namelen);
660a7ce71fSopenharmony_ci
670a7ce71fSopenharmony_ciint ConnectToHotspot(const WifiDeviceConfig*  apConfig)
680a7ce71fSopenharmony_ci{
690a7ce71fSopenharmony_ci    WifiErrorCode errCode;
700a7ce71fSopenharmony_ci    int netId = -1;
710a7ce71fSopenharmony_ci
720a7ce71fSopenharmony_ci    errCode = RegisterWifiEvent(&g_defaultWifiEventListener);
730a7ce71fSopenharmony_ci    printf("RegisterWifiEvent: %d\r\n", errCode);
740a7ce71fSopenharmony_ci
750a7ce71fSopenharmony_ci    errCode = EnableWifi();
760a7ce71fSopenharmony_ci    printf("EnableWifi: %d\r\n", errCode);
770a7ce71fSopenharmony_ci
780a7ce71fSopenharmony_ci    errCode = AddDeviceConfig(apConfig, &netId);
790a7ce71fSopenharmony_ci    printf("AddDeviceConfig: %d\r\n", errCode);
800a7ce71fSopenharmony_ci
810a7ce71fSopenharmony_ci    g_connected = 0;
820a7ce71fSopenharmony_ci    errCode = ConnectTo(netId);
830a7ce71fSopenharmony_ci    printf("ConnectTo(%d): %d\r\n", netId, errCode);
840a7ce71fSopenharmony_ci
850a7ce71fSopenharmony_ci    while (!g_connected) { // wait until connect to AP
860a7ce71fSopenharmony_ci        osDelay(OS_SLEEP_10MS);
870a7ce71fSopenharmony_ci    }
880a7ce71fSopenharmony_ci    printf("g_connected: %d\r\n", g_connected);
890a7ce71fSopenharmony_ci
900a7ce71fSopenharmony_ci    g_iface = netifapi_netif_find("wlan0");
910a7ce71fSopenharmony_ci    if (g_iface) {
920a7ce71fSopenharmony_ci        err_t ret;
930a7ce71fSopenharmony_ci        char* hostname = "hispark";
940a7ce71fSopenharmony_ci        ret = netifapi_set_hostname(g_iface, hostname, strlen(hostname));
950a7ce71fSopenharmony_ci        printf("netifapi_set_hostname: %d\r\n", ret);
960a7ce71fSopenharmony_ci
970a7ce71fSopenharmony_ci        ret = netifapi_dhcp_start(g_iface);
980a7ce71fSopenharmony_ci        printf("netifapi_dhcp_start: %d\r\n", ret);
990a7ce71fSopenharmony_ci
1000a7ce71fSopenharmony_ci        osDelay(OS_SLEEP_100MS); // wait DHCP server give me IP
1010a7ce71fSopenharmony_ci#if 1
1020a7ce71fSopenharmony_ci        ret = netifapi_netif_common(g_iface, dhcp_clients_info_show, NULL);
1030a7ce71fSopenharmony_ci        printf("netifapi_netif_common: %d\r\n", ret);
1040a7ce71fSopenharmony_ci#else
1050a7ce71fSopenharmony_ci        // 下面这种方式也可以打印 IP、网关、子网掩码信息
1060a7ce71fSopenharmony_ci        ip4_addr_t ip = {0};
1070a7ce71fSopenharmony_ci        ip4_addr_t netmask = {0};
1080a7ce71fSopenharmony_ci        ip4_addr_t gw = {0};
1090a7ce71fSopenharmony_ci        ret = netifapi_netif_get_addr(g_iface, &ip, &netmask, &gw);
1100a7ce71fSopenharmony_ci        if (ret == ERR_OK) {
1110a7ce71fSopenharmony_ci            printf("ip = %s\r\n", ip4addr_ntoa(&ip));
1120a7ce71fSopenharmony_ci            printf("netmask = %s\r\n", ip4addr_ntoa(&netmask));
1130a7ce71fSopenharmony_ci            printf("gw = %s\r\n", ip4addr_ntoa(&gw));
1140a7ce71fSopenharmony_ci        }
1150a7ce71fSopenharmony_ci        printf("netifapi_netif_get_addr: %d\r\n", ret);
1160a7ce71fSopenharmony_ci#endif
1170a7ce71fSopenharmony_ci    }
1180a7ce71fSopenharmony_ci    return netId;
1190a7ce71fSopenharmony_ci}
1200a7ce71fSopenharmony_ci
1210a7ce71fSopenharmony_civoid DisconnectWithHotspot(int netId)
1220a7ce71fSopenharmony_ci{
1230a7ce71fSopenharmony_ci    if (g_iface) {
1240a7ce71fSopenharmony_ci        err_t ret = netifapi_dhcp_stop(g_iface);
1250a7ce71fSopenharmony_ci        printf("netifapi_dhcp_stop: %d\r\n", ret);
1260a7ce71fSopenharmony_ci    }
1270a7ce71fSopenharmony_ci
1280a7ce71fSopenharmony_ci    WifiErrorCode errCode = Disconnect(); // disconnect with your AP
1290a7ce71fSopenharmony_ci    printf("Disconnect: %d\r\n", errCode);
1300a7ce71fSopenharmony_ci
1310a7ce71fSopenharmony_ci    errCode = UnRegisterWifiEvent(&g_defaultWifiEventListener);
1320a7ce71fSopenharmony_ci    printf("UnRegisterWifiEvent: %d\r\n", errCode);
1330a7ce71fSopenharmony_ci
1340a7ce71fSopenharmony_ci    RemoveDevice(netId); // remove AP config
1350a7ce71fSopenharmony_ci    printf("RemoveDevice: %d\r\n", errCode);
1360a7ce71fSopenharmony_ci
1370a7ce71fSopenharmony_ci    errCode = DisableWifi();
1380a7ce71fSopenharmony_ci    printf("DisableWifi: %d\r\n", errCode);
1390a7ce71fSopenharmony_ci}
1400a7ce71fSopenharmony_ci#define OS_SLEEP_1000MS (1000)
1410a7ce71fSopenharmony_civoid WifiStaReadyWait(void)
1420a7ce71fSopenharmony_ci{
1430a7ce71fSopenharmony_ci    ip4_addr_t ipAddr;
1440a7ce71fSopenharmony_ci    ip4_addr_t ipAny;
1450a7ce71fSopenharmony_ci    IP4_ADDR(&ipAny, 0, 0, 0, 0);
1460a7ce71fSopenharmony_ci    IP4_ADDR(&ipAddr, 0, 0, 0, 0);
1470a7ce71fSopenharmony_ci    ConnectToHotspot();
1480a7ce71fSopenharmony_ci
1490a7ce71fSopenharmony_ci    while (memcmp(&ipAddr, &ipAny, sizeof(ip4_addr_t)) == 0) {
1500a7ce71fSopenharmony_ci        IOT_LOG_DEBUG("Wait the DHCP READY");
1510a7ce71fSopenharmony_ci        hi_sleep(OS_SLEEP_1000MS);
1520a7ce71fSopenharmony_ci        netifapi_netif_get_addr(gLwipNetif, &ipAddr, NULL, NULL);
1530a7ce71fSopenharmony_ci    }
1540a7ce71fSopenharmony_ci    wifi_first_connecting = WIFI_CONNECT_STATUS;
1550a7ce71fSopenharmony_ci    printf("wifi first connecting status = %d\r\n", wifi_first_connecting);
1560a7ce71fSopenharmony_ci    IOT_LOG_DEBUG("wifi sta dhcp done");
1570a7ce71fSopenharmony_ci
1580a7ce71fSopenharmony_ci    return;
1590a7ce71fSopenharmony_ci}
160