更多内容请访问:https://harmonyos.51cto.com,与华为官方共同打造的鸿蒙技术社区连接Wifi(二))介绍程序使用启动wap_supplicant,它是Wifi的守护进程。下一步是如何向Daemon发送信息。我们可以参考//applications/sample/camera/communication/wpa_cli,它实现了连接Daemon、扫描热点、连接热点等功能。我们打开wpa_cli_sample.c文件,核心功能就在这几个函数:发送命令g_ctrlConn是一个structwpa_ctrl类型的结构。再次调用wpa_ctrl_open打开一个控制接口g_monitorConn进行事件监听。然后启动事件监听线程执行MonitorTask函数。这个监控线程不是必须的,可以省略。intInitControlInterface(){g_ctrlConn=wpa_ctrl_open(WPA_IFACE_NAME);//createcontrolinterfaceforsendcmdg_monitorConn=wpa_ctrl_open(WPA_IFACE_NAME);//createcontrolinterfaceforeventmonitorif(!g_ctrlConn||!g_monitorConn){SAMPLE_ERROR("openwpacontrolinterfacewattl_attachfailed.");(returnpacontrolinterfacewattl_nctl_Connach(returnpacontrol_connectorconn);})==0){//startmonitorpthread_create(&g_wpaThreadId,NULL,MonitorTask,NULL);//createthreadforreadeventreturn0;}return-1;}然后我们关注一下TestNetworkConfig函数。其实就是一系列的SendCtrlCommand向Daemon发送指令。staticvoidTestNetworkConfig(void){charnetworkId[20]={0};size_tnetworkIdLen=sizeof(networkId);intret=SendCtrlCommand("DISCONNECT",networkId,&networkIdLen);ret+=SendCtrlCommand("ADD_NETWORK",networkId,&networkIdLen);if(ret!=0){SAMPLE_ERROR("addnetworkfailed.");return;}SAMPLE_INFO("addnetworksuccess,networkid[%.*s]",networkIdLen,networkId);charreply[100]={0};size_treplyLen=sizeof(回复);charcmd[200]={0};sprintf_s(cmd,sizeof(cmd),"SET_NETWORK%.*sssid\"example\"",networkIdLen,networkId);ret+=SendCtrlCommand(cmd,reply,&replyLen);replyLen=sizeof(回复);sprintf_s(cmd,sizeof(cmd),"SET_NETWORK%.*spsk\"012345678\"",networkIdLen,networkId);ret+=SendCtrlCommand(cmd,reply,&replyLen);replyLen=sizeof(回复);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("networkconfigsuccess.");return;}sprintf_s(cmd,sizeof(cmd),"REMOVE_NETWORK%.*s",networkIdLen,networkId);SendCtrlCommand(cmd,reply,&replyLen);SAMPLE_ERROR("networkconfigfailedremovenetwork[%.*s].",networkIdLen,networkId);}wpa_supplicant定义了很多命令,常见的有:PING:heartbeatdetection命令用于客户端判断WPAS是否正常工作。WPAS收到“PING”命令后需要回复“PONG”。MIB:客户端使用该命令获取设备的MIB信息。STATUS:客户端使用该命令获取WPAS的工作状态。ADD_NETWORK:为WPAS添加一个新的无线网络。它将返回这个新无线网络的ID(从0开始)。注意:这个网络id很重要,客户端会用它来表示自己要操作的无线网络。SET_NETWORK:networkid是无线网络的id。该命令用于设置指定无线网络的信息。其中variable是参数名,value是参数的值。ENABLE_NETWORK:启用某个无线网络。该命令最终会导致WPAS发起一系列操作以加入无线网络。SCAN:扫描附近的APSCAN_RESULT:列出最近一次扫描的结果LIST_NETWORKS:列出所有添加的AP。看完上面的内容就很容易理解了。首先DISCONNECT断开现有连接,ADD_NETWORK添加新的无线网络,SET_NETWORK设置ssid和psk,ENABLE_NETWORK启用这个无线网络,最后RECONNECT重连有点乱,去掉应该没问题,不过我没有试过了。TestScan函数留给读者自己分析。知道了这些,我们就可以在自己的代码中连接WIFI热点了。我把它放在了ACE模块IDE自建模块中,这样在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-0100:01:32.5971160D03B00/JS-3RD-APP:[ConsoleDebug]Connectingtoap:huaweim2001-0100:01:32.5971160I03900/ACE:ConnectToWifiinvoked!01-0100:01:32.5971160I03900/ACE:ssid:huaweim20WpaCliSample(DumpString:584):SendCtrlCommandrawreturndumpstart.OKWpaCliSample(DumpString:589):SendCtrlCommandrawreturndumpend.01-0100:01:32.5971160I03900/ACE:psk:huaweim20WpaCliSample(DumpString:584):SendCtrlCommandrawreturndumpstart.1WpaCliSample(DumpString:589):SendCtrlCommandrawreturndumpend.WpaCliSample(ConnectToWifiInner:717):addnetworksuccess,networkid[1]01-0100:01:32.5971160I03900/ACE:InitControlInterfaceWpaCliSample(DumpString:584):SendCtrlCommandrawreturndumpstart.OKWpaCliSample(DumpString:589):SendCtrlCommandrawreturndumpend.01-0100:01:32.6231160I03900/ACE:ConnectToWifiInnerWpaCliSample(DumpString:584):SendCtrlCommandrawreturndumpstart.OKWpaCliSample(DumpString:589):SendCtrlCommandrawreturndumpend.WpaCliSample(DumpString:584):SendCtrlCommandrawreturndumpstart.OKWpaCliSample(DumpString:589):SendCtrlCommandrawreturndumpend.WpaCliSample(DumpString:584):SendCtrlCommandrawreturndumpstart.OKWpaCliSample(DumpString:589):SendCtrlCommandrawreturndumpend.WpaCliSample(ConnectToWifiInner:733:networkIDSScanf.success):I/HDF_LOG_TAG]WifiWpaCmdBlockSyncSend:cmd=15,ret=0[ERR][HDF:E/HDF_LOG_TAG]HdfWifiSendEventevent=5[ERR][HDF:E/HDF_LOG_TAG]HdfWifiSendEventevent=5[ERR][HDF:E/HDF_LOG_TAG]HdfWifiSendEventevent=5[ERR][HDF:E/HDF_LOG_TAG]HdfWifiSendEventevent=5[ERR][HDF:E/HDF_LOG_TAG]HdfWifiSendEventevent=5[ERR][HDF:E/HDF_LOG_TAG]HdfWifiSendEventevent=4WifiWpaDriverEventProcessevent=5WifiWpaEventScanResultProcess:ie_len=248,beacon_ie_len=248WifiWpaEventScanResultProcessdoneWifiWpaDriverEventProcessevent=5WifiWpaEventScanResultProcess:ie_len=310,beacon_ie_len=310WifiWpaEventScanResultProcessdoneWifiWpaDriverEventProcessevent=5WifiWpaEventScanResultProcess:ie_len=226,beacon_ieWiflenWpaEventScanResultProcessdoneWifiWpaDriverEventProcessevent=5WifiWpaEventScanResultProcess:ie_len=243,beacon_ie_len=243WifiWpaEventScanResultProcessdoneWifiWpaDriverEventProcessevent=5WifiWpaEventScanResultProcess:ie_len=198,beacon_ie_len=198WifiWpaEventScanResultProcessdoneWifiWpaDriverEventProcessevent=4WifiWpaGetScanResults2doneWifiWpaEventScanDoneProcessdonewlan0:Tryingtoassociatewithbc:e2:65:3c:19:70(SSID='huaweim20'freq=2462MHz)[97854][E:1786]{oal_sdio_transfer_scatt::writefailed=-84}[E]oal_exception_submit,g_pst_exception_infoisnull[97859][E:1786]{oal_sdio_transfer_scatt::writefailed=-84}[E]oal_exception_submit,g_pst_exception_infoisnull[HDF_WendifTAGMlock]cmd=17,ret=0WifiWpaAssociatedoneret=0[97876][E:1786]{oal_sdio_transfer_scatt::writefailed=-84}[E]oal_exception_submit,g_pst_exception_infoisnull[97887][E:1786]{oal_sdio_transfer_scatt::writefailed=-84}E]oal_exception_submit,g_pst_exception_infoisnull[97897][E:1786]{oal_sdio_transfer_scatt::writefailed=-84}[E]oal_exception_submit,g_pst_exception_infoisnull[97907][E:1786]{oal_sdio_transfer_scatt::writefailed=-84}[E]oal_exception_submit,g_pst_exception_infoisnull[97917][E:17_86]{oal_sdio_transfer_scatt::writestransfer:=-84}[E]oal_exception_submit,g_pst_exception_infoisnull[ERR][HDF:E/HDF_LOG_TAG]HdfWifiSendEventevent=13[97931][E:1786]{oal_sdio_transfer_scatt::writefailed=-84}WifiWpaDriverEventProcessevent=13[E]oal_gexceptionpsexception事件=1397944][E:1786]{oal_sdio_transfer_scatt::writefailed=-84}WifiWpaDriverEventEapolRecvProcesscall[E]oal_exception_submit,g_pst_exception_infoisnull[ERR]l2_packet_receive1[HDF:E/HDF_LOG_TAG]HdfWifiSendEventevent=6l2_packet_receive2[HDF:I/HDF_LOG_TAG]WifiWpaCmdBlockSyncSend:cmd=6,ret=0l2_packet_receive3rx_callbackWifiWpaReceiveEapoldoneWifiWpaDriverEventProcessevent=6wlan0:Associatedwithbc:e2:65:3c:19:70[HDF:I/HDF_LOG_TAG]WifiWpaCmdBlockSyncSend:cmd=5,ret=0WifiWpaWpaSendEapoldoneret=0wlan0:CTRL-EVENT-SUBNET-STATUS-UPDATEstatus=0WifiWpaEventConnectResultProcessdone[ERR][HDF:E/HDF_LOG_TAG]HdfWifiSendEventevent=13WifiWpaDriverEventProcessevent=13WifiWpaDriverEventEapolRecvProcesscalll2_packet_receive1l2_packet_receive2[HDF:I/HDF_LOG_TAG]WifiWpaCmdBlockSyncSend:cmd=6,ret=0l2_packet_receive3rx_callback[HDF:I/HDF_LOG_TAG]WifiWpaCmdBlockSyncSend:cmd=5,ret=0WifiWpaWpaSendEapoldoneret=0[HDF:I/HDF_LOG_TAG]WifiWpaCmdBlockSyncSend:cmd=1,ret=0[HDF:I/HDF_LOG_TAG]WifiWpaCmdBlockSyncSend:cmd=3,ret_TA_TA[/GDF]WifiWpaCmdBlockSyncSend:cmd=1,ret=0wlan0:WPA:Keynegotiationcompletedwithbc:e2:65:3c:19:70[PTK=CCMPGTK=CCMP]wlan0:CTRL-EVENT-CONNECTED-Connectiontobc:e2:65:3c:19:70completed[id=1id_str=]WifiWpaReceiveEapoldone[ERR][HDF:E/NetDeviceLite]LiteNetDhcpIsBoundfail,ret=-5![ERR][HDF:E/NetDeviceLite]LiteNetDhcpIsBoundfail,ret=-5!可以清楚的看到SendCtrlCommand过程结束时,看到wlan0:CTRL-EVENT-CONNECTED,表示连接成功。同时移动热点连接的设备数显示为1。后面我会做一个带有界面的视频demo来展示一下效果。更多信息请访问:Harmonyos.51cto.com,与华为官方合作打造的鸿蒙技术社区
