zoukankan      html  css  js  c++  java
  • Hi3516如何连接Wifi(三)

    Hi3516如何连接Wifi(三)

        小伙伴们大家好,上一篇(Hi3516如何连接Wifi(二))介绍了用程序启动wap_supplicant,也就是Wifi的Daemon。下一步就是如何向Daemon发信息,我们可以参考//applications/sample/camera/communication/wpa_cli,他实现了连接Daemon、扫描热点、连接热点等功能。

        我们打开wpa_cli_sample.c文件,核心功能在于这几个函数:

    • InitControlInterface:初始化
    • TestScan:扫描周围热点
    • TestNetworkConfig:连接到指定热点

        首先看InitControlInterface函数,他先调用了wpa_ctrl_open函数,获取了用于发送命令的控制接口g_ctrlConn,是一个类型为struct wpa_ctrl的结构体。又调用一遍wpa_ctrl_open打开了一个用于事件监控的控制接口g_monitorConn。然后启动了事件监控的线程执行MonitorTask函数,这个监控线程不是必须,可以省略。

    int InitControlInterface()
    {
        g_ctrlConn = wpa_ctrl_open(WPA_IFACE_NAME); // create control interface for send cmd
        g_monitorConn = wpa_ctrl_open(WPA_IFACE_NAME); // create control interface for event monitor
        if (!g_ctrlConn || !g_monitorConn) {
            SAMPLE_ERROR("open wpa control interface failed.");
            return -1;
        }
        if (wpa_ctrl_attach(g_monitorConn) == 0) { // start monitor
            pthread_create(&g_wpaThreadId, NULL, MonitorTask, NULL); // create thread for read event
            return 0;
        }
        return -1;
    }
     

    然后我们来着重分析一下TestNetworkConfig函数。实际上就是一系列SendCtrlCommand向Daemon发送指令。

    static void TestNetworkConfig(void)
    {
        char networkId[20] = {0};
        size_t networkIdLen = sizeof(networkId);
        int ret = SendCtrlCommand("DISCONNECT", networkId, &networkIdLen);
        ret += SendCtrlCommand("ADD_NETWORK", networkId, &networkIdLen);
        if (ret != 0) {
            SAMPLE_ERROR("add network failed.");
            return;
        }
        SAMPLE_INFO("add network success, network id [%.*s]", networkIdLen, networkId);
        char reply[100] = {0};
        size_t replyLen = sizeof(reply);
        char cmd[200] = {0};
        sprintf_s(cmd, sizeof(cmd), "SET_NETWORK %.*s ssid "example"", networkIdLen, networkId);
        ret += SendCtrlCommand(cmd, reply, &replyLen);
        replyLen = sizeof(reply);
        sprintf_s(cmd, sizeof(cmd), "SET_NETWORK %.*s psk "012345678"", networkIdLen, networkId);
        ret += SendCtrlCommand(cmd, reply, &replyLen);
        replyLen = sizeof(reply);
        sprintf_s(cmd, sizeof(cmd), "ENABLE_NETWORK %.*s", networkIdLen, networkId);
        ret += SendCtrlCommand(cmd, reply, &replyLen);
        replyLen = sizeof(reply);
        ret += SendCtrlCommand("RECONNECT", reply, &replyLen);
        replyLen = sizeof(reply);
        if (ret == 0) {
            SAMPLE_INFO("network config success.");
            return;
        }
        sprintf_s(cmd, sizeof(cmd), "REMOVE_NETWORK %.*s", networkIdLen, networkId);
        SendCtrlCommand(cmd, reply, &replyLen);
        SAMPLE_ERROR("network config failed remove network [%.*s].", networkIdLen, networkId);
    }

    wpa_supplicant定义了许多命令,常见的有:

    • PING:心跳检测命令。客户端用它判断WPAS是否工作正常。WPAS收到”PING”命令后需要回复“PONG”。
    • MIB:客户端用该命令获取设备的MIB信息。
    • STATUS:客户端用该命令来获取WPAS的工作状态。
    • ADD_NETWORK:为WPAS添加一个新的无线网络。它将返回此新无线网络的id(从0开始)。注意:此network id非常重要,客户端后续将通过它来指明自己想操作的无线网络。
    • SET_NETWORK<network id> <variable> <value>:network id是无线网络的id。此命令用于设置指定无线网络的信息。其中variable为参数名,value为参数的值。
    • ENABLE_NETWORK<network id>:使能某个无线网络。此命令最终将促使WPAS发起一系列操作以加入该无线网络。
    • SCAN: 扫描附近AP
    • SCAN_RESULT:列出最近一次扫描的结果
    • LIST_NETWORKS: 列出添加的所有AP

        看完上边就很好理解了,先是DISCONNECT断开已有连接,ADD_NETWORK添加一个新的无线网络,SET_NETWORK设置ssid和psk,ENABLE_NETWORK使能这个无线网络,最后一个RECONNECT重新连接有点迷,去掉应该也没关系,不过本人没有尝试。

        TestScan函数就留给读者自行分析。

        了解了这些,我们就可以在自己的代码中去连接WIFI热点了,我是放在了ACE模块IDE自建module中,这样就可以在JS中调用了。还可以传递ssid和psk参数,连接指定的热点。如果需要,也可以增加扫描热点并获得热点列表的功能。

        在移植的过程中,需要注意的是,BUILD.gn文件需要增加相关配置,头文件目录增加:

        "//third_party/wpa_supplicant/wpa_supplicant-2.9/src/",

    依赖项deps增加:

        "//third_party/wpa_supplicant/wpa_supplicant-2.9:wpa_supplicant",

    ldflags选项增加"-lwpa_client"。

        这样应该就可以正常编译了。

        运行后观察日志输出,有点多:

    01-01 00:01:32.597 11 60 D 03B00/JS-3RD-APP: [Console Debug] Connecting to ap: huaweim20
    01-01 00:01:32.597 11 60 I 03900/ACE: ConnectToWifi invoked!
    01-01 00:01:32.597 11 60 I 03900/ACE: ssid: huaweim20
     WpaCliSample(DumpString:584):  SendCtrlCommand raw return dump start.
    OK
    
     WpaCliSample(DumpString:589):  SendCtrlCommand raw return dump end.
    01-01 00:01:32.597 11 60 I 03900/ACE: psk: huaweim20
     WpaCliSample(DumpString:584):  SendCtrlCommand raw return dump start.
    1
    
     WpaCliSample(DumpString:589):  SendCtrlCommand raw return dump end.
     WpaCliSample(ConnectToWifiInner:717):  add network success, network id [1
    ]
    01-01 00:01:32.597 11 60 I 03900/ACE: InitControlInterface
     WpaCliSample(DumpString:584):  SendCtrlCommand raw return dump start.
    OK
    
     WpaCliSample(DumpString:589):  SendCtrlCommand raw return dump end.
    01-01 00:01:32.623 11 60 I 03900/ACE: ConnectToWifiInner
     WpaCliSample(DumpString:584):  SendCtrlCommand raw return dump start.
    OK
    
     WpaCliSample(DumpString:589):  SendCtrlCommand raw return dump end.
     WpaCliSample(DumpString:584):  SendCtrlCommand raw return dump start.
    OK
    
     WpaCliSample(DumpString:589):  SendCtrlCommand raw return dump end.
     WpaCliSample(DumpString:584):  SendCtrlCommand raw return dump start.
    OK
    
     WpaCliSample(DumpString:589):  SendCtrlCommand raw return dump end.
     WpaCliSample(ConnectToWifiInner:733):  network config success.
    WIFI: Scan : (null) SSID : 0
    
    [HDF:I/HDF_LOG_TAG]WifiWpaCmdBlockSyncSend: cmd=15, ret=0
    [ERR][HDF:E/HDF_LOG_TAG]HdfWifiSendEvent event=5
    [ERR][HDF:E/HDF_LOG_TAG]HdfWifiSendEvent event=5
    [ERR][HDF:E/HDF_LOG_TAG]HdfWifiSendEvent event=5
    [ERR][HDF:E/HDF_LOG_TAG]HdfWifiSendEvent event=5
    [ERR][HDF:E/HDF_LOG_TAG]HdfWifiSendEvent event=5
    [ERR][HDF:E/HDF_LOG_TAG]HdfWifiSendEvent event=4
    WifiWpaDriverEventProcess event=5
    WifiWpaEventScanResultProcess: ie_len=248, beacon_ie_len=248
    WifiWpaEventScanResultProcess done
    WifiWpaDriverEventProcess event=5
    WifiWpaEventScanResultProcess: ie_len=310, beacon_ie_len=310
    WifiWpaEventScanResultProcess done
    WifiWpaDriverEventProcess event=5
    WifiWpaEventScanResultProcess: ie_len=226, beacon_ie_len=226
    WifiWpaEventScanResultProcess done
    WifiWpaDriverEventProcess event=5
    WifiWpaEventScanResultProcess: ie_len=243, beacon_ie_len=243
    WifiWpaEventScanResultProcess done
    WifiWpaDriverEventProcess event=5
    WifiWpaEventScanResultProcess: ie_len=198, beacon_ie_len=198
    WifiWpaEventScanResultProcess done
    WifiWpaDriverEventProcess event=4
    WifiWpaGetScanResults2 done
    WifiWpaEventScanDoneProcess done
    wlan0: Trying to associate with bc:e2:65:3c:19:70 (SSID='huaweim20' freq=2462 MHz)
    [97854][E:1786]{oal_sdio_transfer_scatt::write failed=-84}
    [E]oal_exception_submit, g_pst_exception_info is null
    [97859][E:1786]{oal_sdio_transfer_scatt::write failed=-84}
    [E]oal_exception_submit, g_pst_exception_info is null
    [HDF:I/HDF_LOG_TAG]WifiWpaCmdBlockSyncSend: cmd=17, ret=0
    WifiWpaAssociate done ret=0
    [97876][E:1786]{oal_sdio_transfer_scatt::write failed=-84}
    [E]oal_exception_submit, g_pst_exception_info is null
    [97887][E:1786]{oal_sdio_transfer_scatt::write failed=-84}
    [E]oal_exception_submit, g_pst_exception_info is null
    [97897][E:1786]{oal_sdio_transfer_scatt::write failed=-84}
    [E]oal_exception_submit, g_pst_exception_info is null
    [97907][E:1786]{oal_sdio_transfer_scatt::write failed=-84}
    [E]oal_exception_submit, g_pst_exception_info is null
    [97917][E:1786]{oal_sdio_transfer_scatt::write failed=-84}
    [E]oal_exception_submit, g_pst_exception_info is null
    [ERR][HDF:E/HDF_LOG_TAG]HdfWifiSendEvent event=13
    [97931][E:1786]{oal_sdio_transfer_scatt::write failed=-84}
    WifiWpaDriverEventProcess event=13[E]oal_exception_submit, g_pst_exception_info is null
    
    [97944][E:1786]{oal_sdio_transfer_scatt::write failed=-84}
    WifiWpaDriverEventEapolRecvProcess call[E]oal_exception_submit, g_pst_exception_info is null
    
    [ERR]
     l2_packet_receive1
     [HDF:E/HDF_LOG_TAG]HdfWifiSendEvent event=6
    
     l2_packet_receive2
     [HDF:I/HDF_LOG_TAG]WifiWpaCmdBlockSyncSend: cmd=6, ret=0
    
     l2_packet_receive3
    
     rx_callback
     WifiWpaReceiveEapol done
    WifiWpaDriverEventProcess event=6
    wlan0: Associated with bc:e2:65:3c:19:70
    [HDF:I/HDF_LOG_TAG]WifiWpaCmdBlockSyncSend: cmd=5, ret=0
    WifiWpaWpaSendEapol done ret=0
    wlan0: CTRL-EVENT-SUBNET-STATUS-UPDATE status=0
    WifiWpaEventConnectResultProcess done
    [ERR][HDF:E/HDF_LOG_TAG]HdfWifiSendEvent event=13
    WifiWpaDriverEventProcess event=13
    WifiWpaDriverEventEapolRecvProcess call
    
     l2_packet_receive1
    
     l2_packet_receive2
     [HDF:I/HDF_LOG_TAG]WifiWpaCmdBlockSyncSend: cmd=6, ret=0
    
     l2_packet_receive3
    
     rx_callback
     [HDF:I/HDF_LOG_TAG]WifiWpaCmdBlockSyncSend: cmd=5, ret=0
    WifiWpaWpaSendEapol done ret=0
    [HDF:I/HDF_LOG_TAG]WifiWpaCmdBlockSyncSend: cmd=1, ret=0
    [HDF:I/HDF_LOG_TAG]WifiWpaCmdBlockSyncSend: cmd=3, ret=0
    [HDF:I/HDF_LOG_TAG]WifiWpaCmdBlockSyncSend: cmd=1, ret=0
    wlan0: WPA: Key negotiation completed with bc:e2:65:3c:19:70 [PTK=CCMP GTK=CCMP]
    wlan0: CTRL-EVENT-CONNECTED - Connection to bc:e2:65:3c:19:70 completed [id=1 id_str=]
    WifiWpaReceiveEapol done
    [ERR][HDF:E/NetDeviceLite]LiteNetDhcpIsBound fail, ret = -5!
    [ERR][HDF:E/NetDeviceLite]LiteNetDhcpIsBound fail, ret = -5!

        能清楚的看到SendCtrlCommand的过程。最后看到wlan0: CTRL-EVENT-CONNECTED,就是连接成功了。同时手机热点已连接设备数显示为1。

        稍后,我会做一个带有界面的视频Demo,展示效果。

    作者:老船夫

    想了解更多内容,请访问51CTO和华为合作共建的鸿蒙社区:https://harmonyos.51cto.com

  • 相关阅读:
    2.4 自给自足的脚本:位于第一行的#!
    2.3 一个简单的脚本
    2.2 为什么要使用Shell脚本
    JSON 字符串 与 java 对象的转换
    ajax异步提交文件
    jquery选择器
    发现前端框架 bui-min.js
    学习hsf
    Git详解
    java学习材料
  • 原文地址:https://www.cnblogs.com/HarmonyOS/p/14620985.html
Copyright © 2011-2022 走看看