热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

android上的WIFI模块

WIFI模块申屠家振修改1.2011年1月19日2.2011年1月27日对android平台的WIFI模块进行已经有段时间了,现在做一总结,以便以后查阅与修正。心得之作,如有异议,请斧正。什么是WIF
微笑
WIFI
模块
申屠家振

修改

1.2011119

2.2011127

android平台的WIFI模块进行已经有段时间了,现在做一总结,以便以后查阅与修正。

心得之作,如有异议,请斧正。


  1. 什么是WIFI

WIFI是一种无线连接技术,可用于PCPDA手机等终端。WIFI的目的是改善基于IEEE802.11标准的无线网络产品之间的互通性,也就是说WIFI是基于802.11标准的,但WIFI不等同无线网络。


  1. android平台下的WIFI模块

简单介绍一下,WIFI模块的基本功能:

  1. 开关WIFI

除了在WIFI设置界面可以开关WIFI,还有其他的入口可以开关,要查看这些开关状态是否一致。还有就是飞行模式对WIFI开关的影响,由于WIFI开和关都有一个时间过程,而飞行模式的开关瞬间完成,所以有时会出现冲突。

  1. 开关新可用网络提醒

新可用网络的定义是自WIFI模块开启后,从未发现过的,为加密的网络。只有满足了新可用网络的定义,才会有提醒。

  1. 连接断开网络

连接断开各种不同加密类型的网络(具体类型下文有详解)

  1. 手动添加网络

需要路由器关闭SIID广播。可手动输入SIID,网络加密类型,密码。对于OPAL手机来说,路由器隐藏了SSID,手动添加的网络是无法连接的。

  1. 搜索网络

手动点击搜索按钮可以搜索网络,也可以等待WIFI模块自动搜索网络。

  1. 休眠设置

由于WIFI模块是用电大户,所有为了省电,androidWIFI加了一个休眠策略,可以设置永远不断开,充电时不断开和锁屏时断开。要测试休眠设置是否有效,可以在路由器上PING手机的IPPING通就是连接状态。OPAL手机的休眠策略属于完全失效,现在的情况是无论选哪个都会一直保持连接,锁屏后15分钟再休眠。

  1. 设置静态IP

Android系统里对IP设置的输入限制很有问题,我一直认为这是弱智的限制。正常IP的范围在0-255之间,androidIP输入的限制是整数0到整数255之间,也就是说0000.000200.001.001这样一个IP都能合法输入。


  1. WIFI模块深入了解一点点

  1. WIFI的基本运行流程

【初始化】
1
SystemServer启动的时候,会生成一个ConnectivityService的实例

2ConnectivityService的构造函数会创建WifiService

3WifiStateTracker会创建WifiMonitor接收来自底层的事件,WifiServiceWifiMonitor是整个模块的核心。WifiService负责启动关闭wpa_supplicant、启动关闭WifiMonitor监视线程和把命令下发给wpa_supplicant,WifiMonitor则负责从wpa_supplicant接收事件通知。

【连接AP

1WirelessSettings在初始化的时候配置了由WifiEnabler来处理Wifi按钮

2当用户按下Wifi按钮后,Android会调用WifiEnableronPreferenceChange,再由WifiEnabler调用WifiManagersetWifiEnabled接口函数,通过AIDL,实际调用的是WifiServicesetWifiEnabled函数,WifiService接着向自身发送一条MESSAGE_ENABLE_WIFI消息,在处理该消息的代码中做真正的使能工作:首先装载WIFI内核模块(该模块的位置硬编码为"/system/lib/modules/wlan.ko"),然后 启 动wpa_supplicant(配置 文 件 硬 编 码 为"/data/misc/wifi/wpa_supplicant.conf")再通过WifiStateTracker来启动WifiMonitor中的监视线程

3当使能成功后,会广播发送WIFI_STATE_CHANGED_ACTION这个Intent通知外界WIFI已经 成 功 使 能 了 。WifiEnabler创建 的 时 候 就 会 向Android注册 接 收WIFI_STATE_CHANGED_ACTION,因此它会收到该Intent,从而开始扫描

【查找AP

1扫描的入口函数是WifiServicestartScan,它其实也就是往wpa_supplicant发送SCAN命令。

2wpa_supplicant处理完SCAN命令后,它会向控制通道发送事件通知扫描完成,从而wifi_wait_for_event函数会接收到该事件,由此WifiMonitor中的MonitorThread会被执行来出来这个事件。

3WifiStateTracker则接着广播发送SCAN_RESULTS_AVAILABLE_ACTION这个Intent

4WifiLayer注册了接收SCAN_RESULTS_AVAILABLE_ACTION这个Intent,所以它的相关处理函数handleScanResultsAvailable会被调用,在该函数中,先会去拿到SCAN的结果(最终是往wpa_supplicant发送SCAN_RESULT命令并读取返回值来实现的),Listlist = mWifiManager.getScanResults();对每一个扫描返回的AP,WifiLayer会调用WifiSettingsonAccessPointSetChanged函数,从而最终把该AP加到GUI显示列表中。

【配置AP参数】

当用户在WifiSettings界面上选择了一个AP,会显示配置AP参数的一个对话框。

showAccessPointDialog(state,AccessPointDialog.MODE_INFO);

【连接】

当用户在AcessPointDialog中选择好加密方式和输入密钥之后,再点击连接按钮,Android就会去连接这个AP

1WifiLayer会先检测这个AP是不是之前被配置过,这个是通过向wpa_supplicant发送LIST_NETWORK命令并且比较返回值来实现的,

//NeedWifiConfiguration for the AP

WifiCOnfigurationconfig= findConfiguredNetwork(state);

如果wpa_supplicant没有这个AP的配置信息,则会向wpa_supplicant发送ADD_NETWORK命令来添加该AP

2ADD_NETWORK命令 会 返 回 一 个ID,WifiLayer再用 这 个 返 回 的ID作为参数向wpa_supplicant发送ENABLE_NETWORK命令,从而让wpa_supplicant去连接该AP

【配置IP地址】

1wpa_supplicant成功连接上AP之后,它会向控制通道发送事件通知连接上AP,从而wifi_wait_for_event函数会接收到该事件,由此WifiMonitor中的MonitorThread会被执行来出来这个事件

2WifiMonitor再调用WifiStateTrackernotifyStateChange,WifiStateTracker则接着会往自身发送EVENT_DHCP_START消息来启动DHCP去获取IP地址

3然后再广播发送NETWORK_STATE_CHANGED_ACTION这个Intent

4WifiLayer注册了接收NETWORK_STATE_CHANGED_ACTION这个Intent,所以它的相关处理函数handleNetworkStateChanged会被调用,DHCP拿到IP地址之后,会再发送EVENT_DHCP_SUCCEEDED消息

5WifiLayer处理EVENT_DHCP_SUCCEEDED消息,会再 次 广 播 发 送

至此为止,整个连接过程完成

2.wpa_supplicant

Android平台使用的WiFi控制框架是基于大名鼎鼎的wpa_supplicant,它是一个安全中间件,为各种无线网卡提供统一的安全机制,如下图所示:

对应上述结构,基于Android的手机中的WiFi控制分为三大组件:
1
)客户端程序,包括wpa_cli命令行或java图形界面程序,通过unix本地socket
wpa_supplicantdaemon
服务通信,发送命令并接收结果;
2
wpa_supplicantdaemon服务,对应上述中间部分,功能是“上传下达”。所有客户端通过它控制硬件网卡,通过发送字符串命令控制是否扫描AP,提取扫描结果和是否关联AP等操作,同时将驱动的执行状态发送给用户。该服务是设计支持多种无线网卡芯片,因此各个厂商共同提供了一个通用接口给wpa_supplicant调用;
3
)网卡驱动;


在手机内存的/etc/wpa_supplicant.conf中我们可以直接看到WIFI支持的网络类型,每种类型都有例子,比如:

#BothWPA-PSK and WPA-EAP is accepted. Only CCMP is accepted as pairwiseand

#group cipher.

#network={

# ssid="example"

# bssid=00:11:22:33:44:55

# proto=WPARSN

# key_mgmt=WPA-PSKWPA-EAP

# pairwise=CCMP

# group=CCMP

# psk=06b4be19da289f475aa46a33cb793029d4ab3db7a23ee92382eb0106c72ac7bb

#}

不同类型的网络,不同的参数等等,应有尽有。

  1. WIFI模块的LOG了解多一点点

我们在上面已经知道WIFI的启动过程,在功能运行中也会输出相应的日志信息,下面就来详细了解一下。(请注意,WIFI开启后会更改电池状态等其他状态。关闭WIFI时,android的策略是卸载驱动来省电。如有缺失就是问题。不过下文删去了与WIFI无关的LOG!)

1.开启WIFI&自动搜索

E/WifiHW (1201): ==JOHN DEBUG==: [WIFI] Load Driver

加载驱动

D/SettingsWifiEnabler(1321): Received wifi state changed from Disabled to Enabling

接收到广播:WIFI正在开启

D/WifiService(1201): ACTION_BATTERY_CHANGED pluggedType: 2

电池状态改变

E/WifiHW(1201):==JOHNDEBUG==:moduleaddress:4b938008filename:/system/lib/modules/dhd.koargs:firmware_path=/system/wlan/broadcom/rtecdc.binnvram_path=/system/wlan/broadcom/nvram.txt

WIFI硬件:加载内核模块

I/wpa_supplicant(2490): CTRL-EVENT-STATE-CHANGE id=-1 state=2

wpa_supplicant发出事件通知

V/WifiMonitor(1201): Event [CTRL-EVENT-STATE-CHANGE id=-1 state=2]

WifiMonitorwpa_supplicant接收事件通知

I/wpa_supplicant(2490): CTRL-EVENT-SCAN-RESULTS Ready

wpa_supplicant发出事件通知:准备好开始搜索网络了

E/wpa_supplicant(2490): wpa_driver_priv_driver_cmd SCAN-ACTIVE len = 4096

wpa_supplicant发出事件通知:驱动命令行.主动搜索.LEN

E/wpa_supplicant(2490): wpa_driver_priv_driver_cmd SCAN-ACTIVE len = 0, 11

wpa_supplicant发出事件通知:驱动命令行.主动搜索.LEN

E/wpa_supplicant(2490): wpa_driver_priv_driver_cmd SCAN-PASSIVE len = 4096

wpa_supplicant发出事件通知:驱动命令行.被动搜索.LEN

E/wpa_supplicant(2490): wpa_driver_priv_driver_cmd SCAN-PASSIVE len = 0, 12

wpa_supplicant发出事件通知:驱动命令行.被动搜索.LEN=0.12

D/SettingsWifiEnabler(1321): Received wifi state changed from Enabling to Enabled

接收到广播:WIFI已经开启

E/wpa_supplicant(2490): wpa_driver_priv_driver_cmd RSSI len = 4096

wpa_supplicant发出事件通知:

E/wpa_supplicant(2490): wpa_driver_priv_driver_cmd RSSI len = 4, 4

wpa_supplicant发出事件通知:

E/wpa_supplicant(2490): wpa_driver_priv_driver_cmd LINKSPEED len = 4096

wpa_supplicant发出事件通知:

E/wpa_supplicant(2490): wpa_driver_priv_driver_cmd LinkSpeed 54 len = 12, 12

wpa_supplicant发出事件通知:

E/wpa_supplicant(2490): wpa_driver_priv_driver_cmd MACADDR len = 4096

wpa_supplicant发出事件通知:驱动命令行.MAC地址.LEN

E/wpa_supplicant(2490): wpa_driver_priv_driver_cmd Macaddr = 44:A4:2D:27:25:BE

wpa_supplicant发出事件通知:驱动命令行.MAC地址

E/wpa_supplicant(2490): len = 28, 28

wpa_supplicant发出事件通知:

V/WifiStateTracker(1201): Connection to supplicant established, state=SCANNING

WIFI状态跟踪:连接请求确认,状态=搜索

D/NetworkStateTracker(1201): setDetailed state, ld =IDLE and new state=SCANNING

网络状态跟踪:更新显示为搜索状态

V/WifiStateTracker(1201): Changing supplicant state: SCANNING ==> INACTIVE

WIFI状态跟踪:更改请求状态:搜索中->不活动


2.点击连接&获取状态

E/WifiHW (1201): ==JOHN DEBUG==: [WIFI] Load Driver

WIFI硬件:加载驱动

D/SettingsWifiEnabler(1321): Received wifi state changed from Disabled to Enabling

收到广播,WIFI状态正在开启

E/WifiHW(1201):==JOHNDEBUG==:moduleaddress:4b938008filename:/system/lib/modules/dhd.koargs:firmware_path=/system/wlan/broadcom/rtecdc.binnvram_path=/system/wlan/broadcom/nvram.txt

WIFI硬件:加载内核模块

E/WifiHW (1201): ==JOHN DEBUG==: return of insmod : ret = 0, Unknown error: 0

WIFI硬件:返回装载模块报告:返回指令0,未知错误0

……

I/wpa_supplicant(2490): Trying to associate with 1c:bd:b9:f6:a7:9f (SSID='LosAngeles'freq=2412 MHz)

wpa_supplicant发出事件通知:尝试连接,(SSID='LosAngeles'频段=2412MHz

V/WifiMonitor(1201):Event[Trying to associate with 1c:bd:b9:f6:a7:9f(SSID='LosAngeles' freq=2412 MHz)]

WifiMonitor接收wpa_supplicant的事件

V/WifiMonitor(1201): Event [CTRL-EVENT-STATE-CHANGE id=-1 state=3]

WifiMonitor接收事件

V/WifiStateTracker(1201): Changing supplicant state: SCANNING ==> ASSOCIATING

WIFI状态跟踪:更改请求状态:搜索中->匹配中

D/NetworkStateTracker(1201): setDetailed state, ld =SCANNING and new state=CONNECTING

网络状态跟踪:更新显示为正在连接状态

D/ConnectivityService(1201): ConnectivityChange for WIFI: CONNECTING/CONNECTING

连接管理服务:改变WIFI连接状态:正在连接/正在连接

V/WifiStateTracker(1201): Changing supplicant state: ASSOCIATING ==> ASSOCIATED

WIFI状态跟踪:更改请求状态:匹配中->已匹配

D/NetworkStateTracker(1201): setDetailed state, ld =CONNECTING and new state=CONNECTING

网络状态跟踪:更新显示为正在连接状态

I/wpa_supplicant(2490): Associated with 1c:bd:b9:f6:a7:9f

wpa_supplicant发出事件通知:已和1c:bd:b9:f6:a7:9f匹配

V/WifiMonitor(1201): Event [Associated with 1c:bd:b9:f6:a7:9f]

WifiMonitor接收wpa_supplicant的事件

V/WifiStateTracker(1201): Changing supplicant state: ASSOCIATED ==>FOUR_WAY_HANDSHAKE

WIFI状态跟踪:更改请求状态:已匹配->TCP中断连接

D/NetworkStateTracker(1201): setDetailed state, ld =CONNECTING and newstate=AUTHENTICATING

网络状态跟踪:更新显示为鉴定中

D/ConnectivityService(1201): Dropping ConnectivityChange for WIFI:CONNECTING/AUTHENTICATING

连接管理服务:抛出WIFI连接状态改变:已连接/鉴定中

V/WifiStateTracker(1201): Changing supplicant state: FOUR_WAY_HANDSHAKE ==>GROUP_HANDSHAKE

WIFI状态跟踪:更改请求状态:TCP中断连接->确认标志位

D/NetworkStateTracker(1201): setDetailed state, ld =AUTHENTICATING and newstate=AUTHENTICATING

网络状态跟踪:更新显示为鉴定中

I/wpa_supplicant(2490): WPA: Key negotiation completed with 1c:bd:b9:f6:a7:9f[PTK=CCMP GTK=TKIP]

wpa_supplicant发出事件通知:WPA:1c:bd:b9:f6:a7:9f确定标志位

I/wpa_supplicant(2490): CTRL-EVENT-STATE-CHANGE id=0 state=7

wpa_supplicant发出事件通知:

I/wpa_supplicant(2490): CTRL-EVENT-CONNECTED - Connection to 1c:bd:b9:f6:a7:9fcompleted (auth) [id=0 id_str=]

wpa_supplicant发出事件通知:连接完成

V/WifiMonitor(1201): Event [WPA: Key negotiation completed with 1c:bd:b9:f6:a7:9f[PTK=CCMP GTK=TKIP]]

WifiMonitor接收wpa_supplicant事件

V/WifiMonitor(1201): Event [CTRL-EVENT-STATE-CHANGE id=0 state=7]

WifiMonitor接收wpa_supplicant事件

V/WifiMonitor(1201): Event [CTRL-EVENT-CONNECTED - Connection to 1c:bd:b9:f6:a7:9fcompleted (auth) [id=0 id_str=]]

WifiMonitor接收wpa_supplicant事件

V/WifiStateTracker(1201): Changing supplicant state: GROUP_HANDSHAKE ==> COMPLETED

WIFI状态跟踪:更改请求状态:确认标志位->完成

V/WifiStateTracker(1201): New network state is CONNECTED

WIFI状态跟踪:新网络状态为已连接

D/NetworkStateTracker(1201): setDetailed state, ld =AUTHENTICATING and newstate=OBTAINING_IPADDR

网络状态跟踪:更新显示为获取IP地址

D/ConnectivityService(1201): Dropping ConnectivityChange for WIFI:CONNECTING/OBTAINING_IPADDR

连接管理服务:抛出WIFI



微笑

http://blog.csdn.net/stevenliyong/article/details/5396336

Android 下使用wpa_cli 连接 wifi

# cp /media/sd8686.bin /lib/firmware/sd8686.bin
# cp /media/sd8686_helper.bin /lib/firmware/sd8686_helper.bin
# dpkg -i kernel-smartq5-modules_2.6.24.7-smartq5-050509_all.deb

 

# insmod sd8686.ko 

 

# ifconfig -a

 

# chmod 0660 /data/misc/wifi/wpa_supplicant.conf

 

* The content of wpa_supplicant.conf

----

update_cOnfig=1

ctrl_interface=DIR=/data/system/wpa_supplicant GROUP=1010

----


# /system/bin/wpa_supplicant -Dwext -iwlan0 -c /data/misc/wifi/wpa_supplicant.conf

# /system/bin/wpa_cli -i wlan0 -p /data/system/wpa_supplicant
 > status
 INACTIVE
 > help
 > add_network
 > set_network 0 ssid "NETGEAR"
 > set_network 0 key_mgmt NONE
 > set_network 0 priority 0
 > list_network
 > save_config
 > enable_network 0
 
bssid=00:24:b2:5b:5b:0a
ssid=NETGEAR
….
wpa_state=COMPLETED



http://hi.baidu.com/xyp86/blog/item/d371a1d78d4162d7a144dfd3.html

Android平台上无线网卡自动扫描并关联AP的实现 2009-12-09 21:34http://hi.baidu.com/xyp86/blog/item/d371a1d78d4162d7a144dfd3.html

最近为了验证一个算法的能耗,研究了在开源的Android平台上如何实现无线网卡的自动开启和基于wpa_supplicant的AP自动扫描和关联,记录且共享之。

目标:


自动打开无线网卡,扫描指定的信道列表,并在发现合适的AP时自动关联。

1. Android平台的WiFi框架

Android平台使用的WiFi控制框架是基于大名鼎鼎的wpa_supplicant,它是一个安全中间件,为各种无线网卡提供统一的安全机制,如下图所示:


图1:Android平台WiFi框架


对应上述结构,基于Android 的G1手机中的WiFi控制分为三大组件:
1)客户端程序,包括wpa_cli命令行或java图形界面程序,通过unix本地socket与
wpa_supplicant daemon服务通信,发送命令并接收结果;
2)wpa_supplicant daemon服务,对应上述中间部分,功能是“上传下达”。所有客户端通过它控制硬件网卡,通过发送字符串命令控制是否扫描AP,提取扫描结果和是否关联AP等操作,同时将驱动的执行状态发送给用户。该服务是设计支持多种无线网卡芯片,因此各个厂商共同提供了一个通用接口给wpa_supplicant调用,其中G1用的是TI的芯片;
3)网卡驱动,本文中可以不涉及。

2.    自动打开网卡并启动wpa_supplicant
图形界面可以正常启动网卡并开始AP扫描,但通过命令行wpa_cli无法启动,为此修改wpa_supplicant程序,输出所有argv参数,然后通过图形界面的设置来启动AP扫描,设置->无线接口->启动WiFi,输出如下参数:
1257946571.827087: /system/bin/wpa_supplicant
1257946571.827453: -Dtiwlan0
1257946571.827545: -itiwlan0
1257946571.827636: -c/data/misc/wifi/wpa_supplicant.conf
手工输入 wpa_supplicant -Dtiwlan0 -itiwlan0 -c/data/misc/wifi/wpa_supplicant.conf 还是启动失败。通过跟踪图形界面的java代码,定位android/packages/apps/Settings/src/com/android/settings/wifi下的java文件,确定是WifiEnabler.java,调用路径为:WifiEnabler->WifiManager.setWifiEnabled 接口函数,通过AIDL->WifiServic.setWifiEnabled函数,它向自身发送一条 MESSAGE_ENABLE_WIFI 消息, 处理代码handleMessage中调用setWifiEnabledBlocking,该函数代码如下:

if (enable) {
if (!WifiNative.loadDriver()) {}
if (!WifiNative.startSupplicant()) {}
..... } else {
if (!WifiNative.stopSupplicant()) {}     
if (!WifiNative.unloadDriver()) { }

}
}
WifiNative.java使用JNI机制,对应的c文件是android/hardware/libhardware_legacy/wifi/wifi.c, 其中包括以下核心函数:
int wifi_load_driver();
int wifi_unload_driver();
int wifi_start_supplicant();
int wifi_stop_supplicant();

It’s great! 将该文件静态链接到我们的代码中就可以自动加载网卡和启动wpa_supplicant。

3.    自动扫描指定的信道,并关联给定的AP

现有的wpa_cli是一个交互式命令环境,在连接到wpa_supplicant服务后,通过请求-响应的方式工作。因此我们需要重写一个客户端wpa_myclient,并通过前述wifi.c代码自动打开网卡并启动wpa_supplicant,涉及代码文件包括:
android/external/wpa_supplicant/
android/system/wlan/ti/wpa_supplicant_lib/:是由TI公司提供给wpa_supplicant的统一接口

1)    分析wpa_cli的工作原理,确定通过手工命令如何关联AP
术语networks是指由当前网卡已记忆的WLAN网络,与windows无线接口设置中的“首选网络”概念类似,该网络也可以通过wpa_supplicant.conf手工配置
术语scan_results是指当前网卡扫描发现的AP。
网卡通过需要使用下列命令序列来关联一个网络:
scan
scan_results %获得扫描结果,包括ssid和信号强度等信息
add_network %必须先创建一个网络,得到一个新的网络号id
set_network id ssid “***” %将网络与想关联AP的SSID对应
set_network id key_mgmt NONE %设置安全信息,这里是针对Open System
set_network id pairwise NONE
select_network id %激活该网络,此时开始关联过程

2)    分析wpa_cli与supplicant的通信协议,添加一个新的命令MYSCAN能按指定信道列表扫描,并修改核心数据结构struct wpa_supplicant加入一个成员保存待扫描的信道列表,主要修改文件包括:ctrl_iface.c和wpa_supplicant_i.h
3)    由wpa_supplicant.c的wpa_supplicant_scan()->driver_ti.c的wpa_driver_tista_scan-> ti_init_scan_params()初始化扫描参数,将pScanParams->channelEntry设置为指定的信道列表;
4)    扫描结束后,驱动程序通过driver_ti.c的wpa_driver_tista_receive_driver_event()通知调用程序,该事件通过逐级传递到events.c 的wpa_supplicant_event()事件分发接口, 并通过wpa_supplicant_event_scan_results()通知wpa_cli客户端,指示用户可以使用scan_results命令获取扫描结果;此外在该处理函数中如果发现扫描结果包括用户的首选网络networks,则会自动启动关联过程(windows也是这种方式)。
5)    修改events.c 的wpa_supplicant_event_scan_results()来模拟用户首选网络,首先利用    wpa_config_remove_network方法删除wpa_s->conf->ssid 中的所有首选网络,并根据一个规则从wpa_s->scan_results[]中选择一个最合适的,然后通过wpa_config_add_network和wpa_config_set按照上述手工命令格式设置该network,然后它将自动按照正常流程关联。

Hints and Tips:
1)    在android根目录执行命令,. build/envsetup.sh,然后就可以使用mm TARGET_PRODUCT=htc_dream命令加速编译
2)    实现命令set_network id ssid “***”,不能少了SSID的双引号
3)    为了实现将输出调试信息到文件,需要在.config中打开编译开关CONFIG_DEBUG_FILE,同时在main.c中初始化params.wpa_debug_file_path为一个文件(我的是/sdcard/wpadbg),最后自定义一个wpa_printf的消息优先级,并打开wpa_debug_print_timestamp,输出时戳


推荐阅读
  • 服务器部署中的安全策略实践与优化
    服务器部署中的安全策略实践与优化 ... [详细]
  • 体积小巧的vsftpd与pureftpd Docker镜像在Unraid系统中的详细配置指南:支持TLS加密及IPv6协议
    本文详细介绍了如何在Unraid系统中配置体积小巧的vsftpd和Pure-FTPd Docker镜像,以支持TLS加密和IPv6协议。通过这些配置,用户可以实现安全、高效的文件传输服务,适用于各种网络环境。配置过程包括镜像的选择、环境变量的设置以及必要的安全措施,确保了系统的稳定性和数据的安全性。 ... [详细]
  • 【Linux】CentOS 7 远程连接指南:高效安全的远程管理方法
    在 CentOS 7 中实现高效且安全的远程管理,本文详细介绍了如何检查和安装配置 OpenSSH。首先,通过 `yum list installed` 命令检查系统是否已安装 OpenSSH,若未安装,则使用 `yum install openssh-server` 进行安装。随后,配置 SSH 服务以确保其安全性和稳定性,包括修改默认端口、禁用 root 登录等关键步骤。此外,还提供了常见问题的解决方案,帮助用户顺利进行远程连接。 ... [详细]
  • 在日常的Android开发过程中,真机调试是一项必不可少的任务。然而,有时会遇到公司电脑配置较低或USB接口故障,导致无法通过数据线连接手机进行调试。为此,本文将介绍一款名为ADB WiFi的无线调试工具,帮助开发者轻松实现远程调试,彻底摆脱数据线的束缚。该工具不仅操作简便,还能显著提高开发效率,尤其适用于需要频繁切换设备或进行远程协作的场景。 ... [详细]
  • 【前端开发】深入探讨 RequireJS 与性能优化策略
    随着前端技术的迅速发展,RequireJS虽然不再像以往那样吸引关注,但其在模块化加载方面的优势仍然值得深入探讨。本文将详细介绍RequireJS的基本概念及其作为模块加载工具的核心功能,并重点分析其性能优化策略,帮助开发者更好地理解和应用这一工具,提升前端项目的加载速度和整体性能。 ... [详细]
  • 从用户转型为开发者:一场思维升级的旅程 | 专访 StarRocks Committer 周威
    从用户转变为开发者,不仅是一次角色的转换,更是一场深刻的思维升级之旅。本次专访中,StarRocks Committer 周威分享了他如何在这一过程中逐步提升技术能力与思维方式,为开源社区贡献自己的力量。 ... [详细]
  • 本文介绍了如何利用 Delphi 中的 IdTCPServer 和 IdTCPClient 控件实现高效的文件传输。这些控件在默认情况下采用阻塞模式,并且服务器端已经集成了多线程处理,能够支持任意大小的文件传输,无需担心数据包大小的限制。与传统的 ClientSocket 相比,Indy 控件提供了更为简洁和可靠的解决方案,特别适用于开发高性能的网络文件传输应用程序。 ... [详细]
  • Squaretest:自动生成功能测试代码的高效插件
    本文将介绍一款名为Squaretest的高效插件,该工具能够自动生成功能测试代码。使用这款插件的主要原因是公司近期加强了代码质量的管控,对各项目进行了严格的单元测试评估。Squaretest不仅提高了测试代码的生成效率,还显著提升了代码的质量和可靠性。 ... [详细]
  • TCP三次握手过程详解与图示解析
    本文详细解析了TCP三次握手的过程,并通过图示清晰展示了各个状态的变化。同时,文章还介绍了四次挥手的图解,解释了在TIME_WAIT状态中,客户端最后一次发送的ACK包的作用和重要性。 ... [详细]
  • HBase Java API 进阶:过滤器详解与应用实例
    本文详细探讨了HBase 1.2.6版本中Java API的高级应用,重点介绍了过滤器的使用方法和实际案例。首先,文章对几种常见的HBase过滤器进行了概述,包括列前缀过滤器(ColumnPrefixFilter)和时间戳过滤器(TimestampsFilter)。此外,还详细讲解了分页过滤器(PageFilter)的实现原理及其在大数据查询中的应用场景。通过具体的代码示例,读者可以更好地理解和掌握这些过滤器的使用技巧,从而提高数据处理的效率和灵活性。 ... [详细]
  • CentOS 7环境下Jenkins的安装与前后端应用部署详解
    CentOS 7环境下Jenkins的安装与前后端应用部署详解 ... [详细]
  • Linux入门教程第七课:基础命令与操作详解
    在本课程中,我们将深入探讨 Linux 系统中的基础命令与操作,重点讲解网络配置的相关知识。首先,我们会介绍 IP 地址的概念及其在网络协议中的作用,特别是 IPv4(Internet Protocol Version 4)的具体应用和配置方法。通过实际操作和示例,帮助初学者更好地理解和掌握这些基本技能。 ... [详细]
  • Win11无线网络图标消失解决方案及恢复技巧
    Win11无线网络图标消失解决方案及恢复技巧 ... [详细]
  • ROS主机与从机之间的通信原理及机制分析
    本文深入探讨了ROS(Robot Operating System)主机与从机之间的通信原理及机制。通过分析ROS网络架构,详细阐述了节点间的通信方式、消息传递流程以及数据同步机制。此外,还介绍了ROS中常用的通信模式,如发布/订阅、服务调用和参数服务器,为开发者提供了全面的技术指导。 ... [详细]
  • 机顶盒,即数字电视机顶盒(Digital TV Set-Top Box,简称STB),是一种放置在电视机旁的设备。它主要用于将数字信号转换为电视能够识别的模拟信号,从而实现高质量的视频和音频播放。机顶盒不仅支持基本的电视节目接收功能,还具备多种增值服务,如互动点播、网络浏览等。随着技术的发展,现代机顶盒集成了更多的智能功能,成为家庭娱乐的重要组成部分。 ... [详细]
author-avatar
qiqianan
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有