SSD_WLAN使用参考
1. 内核配置说明¶
1.1. 配置WEXT¶
Wext是Wireless Extension,是内核中WIFI驱动和用户态进程的标准接口,iwpriv命令依赖这个配置。
1.2. 配置CFG80211¶
CFG80211是内核中WIFI驱动和用户态进程的标准接口,在CFG80211出现之前是WEXT,现在越来越多的使用CFG80211。
1.3. SDIO WIFI (SSW102B)配置¶
不支持SDIO wifi热插拔。
infinity2m.dtsi dts配置:
如果是跳线验证,信号较差可以将clk改成12M来验证,改动如下:
额外注意一点:
如果有使用wifi reset脚,需要检查reset脚的配置情况。如果没有额外gpio控制reset脚,可以忽略如下内容。
在demo板上使用gpio0来控制sd的power enable脚位。 有可能在新的设计图纸上,将GPIO0用来控制reset。
需要在infinity2m-ssc011a-s01a-padmux-display.dtsi中屏蔽
//<PAD_GPIO0 PINMUX_FOR_GPIO_MODE MDRV_PUSE_SDIO0_PWR >,
然后再uboot上添加:gpio out 0 0 和 gpio out 0 1 来控制复位。
-
kernel里控制sd power 的gpio,其实是根据padmux里的MDRV_PUSE_SDIO0_PWR来找到对应哪个gpio口的,dts里的slot-pwr-gpios在padmux存在情况下,是没有作用的。
-
power不是硬件长供电的情况下,作为SDIO使用时候,如果发生初始化的时候发生错误,注意要修改如下时间为30
2. 工具使用¶
2.1. wap_supplicant使用¶
wpa_supplicant是一个独立运行的守护进程,用来启动无线网络后台服务,在消息循环中处理WPA状态机、控制命令、驱动事件、配置信息等。
常用命令参数如下:
-I <ifname> // 网络接口名称 -c <conf> // 配置文件名称 -C <ctrl_intf> // 控制接口名称 -D<driver> // 驱动类型名称 -p <driver_param> // 驱动参数 -b <br_ifname> // 桥接口名称 -d // 增加调试信息
使用样例:
/config/wifi/wpa_supplicant -Dnl80211 -i wlan0 -c /customer/wpa_supplicant.conf -d &
启动无线网络服务,驱动类型为nl80211,使用网络端口名称为wlan0,配置文件路径为/customer/wpa_supplicant.conf。若配置文件中有保存热点信息,则发起连接。
2.2. wpa_cli使用¶
wpa_cli是客户端程序,与wpa_supplicant通信,搜索、设置和连接网络。
常用命令参数如下(如当前网络接口为wlan0):
wpa_cli –i wlan0 scan // 扫描附近的热点 wpa_cli –i wlan0 scan_result // 显示扫描结果 wpa_cli –I wlan0 status // 查看当前连接信息 wpa_cli –I wlan0 add_network // 新建一个链接,返回network id wpa_cli –I wlan0 set_network <network id> <variable> <value> // 设置网络参数,如ssid,psk,keymgmt wpa_cli –I wlan0 select_network <network id> // 选择指定的网络(会断开其它的连接) wpa_cli –I wlan0 enable_network <network id> // 使能指定网络 wpa_cli –I wlan0 disable_network <network id> // 禁用指定网络 wpa_cli –I wlan0 save_config // 保持连接信息至wpa_supplicant.conf
2.3. iwlist使用¶
iwlist用于对/proc/net/wireless文件进行分析,得出无线网卡相关信息。
常用命令参数如下(如当前网络接口为wlan0):
iwlist wlan0 scanning // 扫描当前无线网络 iwlist wlan0 frequen // 显示频道信息 iwlist wlan0 rate // 显示连接速度 iwlist wlan0 power // 显示电源模式
2.4. udhcpc使用¶
udhcpc作为dhcp客户端,动态获取ip。
常用命令参数如下:
-i <ifname> // 网络接口名称 -s <script> // udhcpc script -a // 使用arping验证提供的地址 -t <count> // 发送数据包次数 -T <time> // 数据包间时间间隔(默认是3s) -f // 前台执行 -b // 后台执行 -n // 租约获取失败时退出 -q // 获取到租约后退出
使用样例:
udhcpc -q -i wlan0 -s /etc/init.d/udhcpc.script &
2.5. hostapd使用¶
hostapd用来将当前设备作为热点,允许其它网络设备接入。
使用样例:
hostapd -B /config/wifi/hostapd.conf // -B:在后台执行守护进程
2.6. dnsmasq使用¶
dnsmasq是一个轻量级的,易于配置的DNS转发器和DHCP服务器。它的目的是给一个小网络提供DNS和可选的DHCP。
常用命令参数如下:
-i <ifname> // 网络接口名称 -C <path> // 指定配置文件路径(默认为/etc/dnsmasq.conf) --no-daemon // 非后台执行
使用样例:
dnsmasq -i p2p0 --no-daemon -C /config/wifi/dnsmasq.conf &
2.7. hostapd_cli使用¶
hostapd_cli作为hostapd的客户端,使用时,首先需要先启动hostapd主程序。hostapd启动后,运行cli客户端时,会自动去连接当前正在工作的hostapd进程,连接成功后,cli客户端就可以对hostapd应用程序进行参数的获取和控制。
常用命令参数如下:
-i <ifname> // 网络接口名称 -p <path> // 控制套接字路径(默认为/var/run/hostapd) -B // 后台执行守护进程
使用样例:
/config/wifi/hostapd_cli -I p2p0 –p /var/run/hostapd all_sta &
3. WIFI功能测试¶
3.1. 加载WIFI驱动¶
先insmod加载WIFI驱动,以ssw101b为例,对应驱动是ssw101b_wifi_HT40_usb.ko。执行insmod ssw101b_wifi_HT40_usb.ko,使用ifconfig –a查看,可以看到新生成wlan0节点和p2p0节点:
3.2. STA模式测试¶
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib:/lib:/config/wifi mkdir -p /tmp/wifi/run chmod 777 /tmp/wifi/run ifconfig wlan0 up
创建wpa_supplicant.conf文件,编辑如下,使用测试热点为”WiFi_test”,密码为“12345678”。
测试连接:
/config/wifi/wpa_supplicant -Dnl80211 -i wlan0 -c /appconfigs/wpa_supplicant.conf -d &
获取IP:
udhcpc -q -i wlan0 -s /etc/init.d/udhcpc.script &
查看wlan0信息:
扫描热点:
/config/wifi/iwlist wlan0 scan | grep Cell -A 5
可以看到,当前连接的热点“WiFi_test”信道为1。
3.3. AP模式测试¶
mkdir -p /var/run/hostapd mkdir -p /var/wifi/misc mkdir -p /var/lib/misc ifconfig p2p0 up ifconfig p2p0 192.168.1.100 netmask 255.255.255.0
hostapd配置文件在/config/wifi/hostapd.conf,其中ssid为当前设备的热点名称,wpa_passphrase为设备的连接密码。可修改此文件变更设备名称和密码。
开启热点:
/config/wifi/hostapd -B /config/wifi/hostapd.conf /config/wifi/dnsmasq -i p2p0 --no-daemon -C /config/wifi/dnsmasq.conf &
网络设备可以搜索到热点“ssw101bap”,使用手机连接该热点:
查看设备连接信息:
/config/wifi/hostapd_cli -i p2p0 -p /var/run/hostapd all_sta &
可以看到接入数量为 1,接入设备mac与手机mac一致。
3.4. 桥接模式测试¶
WIFI同时开启STA和AP的情况下,在wlan0和p2p0之间建立桥接。
Kernel配置添加网络桥接支持,编译kernel在kernel/modules目录会生成llc.ko,stp.ko,bridge.ko。网络桥接前依次加载这三个驱动。注:Kernel网络相关配置变化,wifi驱动可能需要重新编译。
建立桥接还需要需编辑/config/wifi/hostapd.conf,添加bridge字段,并修改channel,使之与STA模式接入热点的信道相同。
编译kernel和wifi驱动后,按3.1节加载wifi驱动,再按3.2节和3.3节的步骤启用STA模式接入测试热点“WiFi_test”,并启用AP模式开启热点。
建立桥接:
brctl addbr br0 brctl addif br0 wlan0 brctl addif br0 p2p0 ifconfig br0 up
使用测试手机接入热点“ssw101bap”。在“WiFi_test”接入外网的情况下,测试手机可正常访问外网。
查看br0信息:
4. MI_WLAN使用示例¶
4.1. MI_WLAN在STA模式下连接热点¶
本地设备连接AP示例:
1. static WLAN_HANDLE g_wlanHdl = -1; 2. static MI_WLAN_InitParams_t g_stParam = {"/config/wifi/wlan.json"}; 3. static MI_WLAN_OpenParams_t g_stOpenParam = {E_MI_WLAN_NETWORKTYPE_INFRA}; 4. static MI_WLAN_ConnectParam_t g_stConnectParam = { 5. E_MI_WLAN_SECURITY_WPA, 6. "WiFi_test", 7. "12345678", 8. 5000 9. }; 10. 11. static bool g_bConnected = false; 12. static pthread_t g_ptConn = NULL; 13. static bool g_bThreadRun = false; 14. 15. void *_ConnectWorkThread(void *args) 16. { 17. int nTimeoutCnt = 50; // timeout 10s 18. MI_WLAN_Status_t status; 19. MI_WLAN_ConnectParam_t *pstConnParam = (MI_WLAN_ConnectParam_t*)args; 20. MI_WLAN_Connect(&g_wlanHdl, pstConnParam); 21. printf("current conn info: handle=%d, ssid=%s, passwd=%s\n", g_wlanHdl, (char*)pstConnParam->au8SSId, (char*)pstConnParam->au8Password); 22. 23. while (1) 24. { 25. if (!g_bThreadRun) 26. break; 27. 28. if (nTimeoutCnt-- <= 0) 29. { 30. printf("connect failed, timeout\n"); 31. break; 32. } 33. 34. static int i = 0; 35. MI_WLAN_GetStatus(g_wlanHdl, &status); 36. printf("MI_WLAN_GetStatus: count %d\n", i++); 37. 38. if (status.stStaStatus.state == WPA_COMPLETED) 39. { 40. g_bConnected = true; 41. printf("connect success: ssid=%s, ip=%s\n", (char*)status.stStaStatus.ssid, (char*)status.stStaStatus.ip_address); 42. break; 43. } 44. 45. usleep(100000); 46. } 47. 48. return NULL; 49. } 50. 51. int main(int argc, char **argv) 52. { 53. MI_WLAN_ScanResult_t scanResult; 54. char ch = 0; 55. 56. // init wlan module 57. if (MI_WLAN_Init(&g_stParam)) 58. { 59. printf("Wlan init failed, please ensure wlan module is enabled.\n"); 60. return -1; 61. } 62. 63. if (MI_WLAN_Open(&g_stOpenParam)) 64. { 65. printf("wlan open failed\n"); 66. break; 67. } 68. 69. g_bThreadRun = true; 70. pthread_create(&g_ptConn, NULL, _ConnectWorkThread, &g_stConnectParam); 71. 72. while ((ch = getchar()) != 'q') 73. { 74. if (ch == 's') 75. { 76. memset(&scanResult, 0, sizeof(MI_WLAN_ScanResult_t)); 77. MI_WLAN_Scan(NULL, &scanResult); 78. 79. if (scanResult.u8APNumber > 0) 80. { 81. printf("Scan result:\n"); 82. 83. for (int i = 0; i < scanResult.u8APNumber; i++) 84. { 85. char *pSsid = (char*)scanResult.stAPInfo[i].au8SSId; 86. if (pSsid && strcmp(pSsid, "\"\"")) 87. { 88. char trimSsid[36]; 89. memset(trimSsid, 0, sizeof(trimSsid)); 90. strncpy(trimSsid, pSsid+1, strlen(pSsid)); 91. printf("SSID: %s\n", trimSsid); 92. printf("MAC: %s\n", (char*)scanResult.stAPInfo[i].au8Mac); 93. printf("encrypt: %s\n", scanResult.stAPInfo[i].bEncryptKey?"true":"false"); 94. printf("signalSTR: %d db\n", scanResult.stAPInfo[i].stQuality.signalSTR); 95. printf("frequency: %f GHz\n", scanResult.stAPInfo[i].fFrequency); 96. printf("bitrate: %f Mb/s\n", scanResult.stAPInfo[i].fBitRate); 97. printf("channel: %d\n", scanResult.stAPInfo[i].u8Channel); 98. printf("channel: %d\n", scanResult.stAPInfo[i].u16CellId); 99. printf("\n"); 100. } 101. } 102. } 103. } 104. } 105. 106. g_bThreadRun = false; 107. pthread_join(g_ptConn, NULL); 108. 109. if (g_bConnected) 110. { 111. MI_WLAN_Disconnect(g_wlanHdl); 112. g_bConnected = false; 113. } 114. 115. MI_WLAN_Close(&g_stOpenParam); 116. MI_WLAN_DeInit(); 117. 118. return 0; 119. }
4.2. MI_WLAN在AP模式下开启热点¶
本地设备作为host示例:
1. static WLAN_HANDLE g_apHdl = AP_HANDLE; 2. static MI_WLAN_OpenParams_t g_stOpenParam = {E_MI_WLAN_NETWORKTYPE_AP}; 3. static MI_WLAN_InitParams_t g_stParam = {"/config/wifi/wlan.json"}; 4. static MI_WLAN_Status_t g_stStatus; 5. static bool g_bConnected = false; 6. 7. int main(int argc, char **argv) 8. { 9. // init wlan module 10. if (MI_WLAN_Init(&g_stParam)) 11. { 12. printf("Wlan init failed, please ensure wlan module is enabled.\n"); 13. return -1; 14. } 15. 16. if (MI_WLAN_Open(&g_stOpenParam)) 17. { 18. printf("wlan open failed\n"); 19. break; 20. } 21. 22. if (MI_SUCCESS == MI_WLAN_Connect(&g_apHdl, NULL)) 23. g_bConnected = true; 24. 25. while ((ch = getchar()) != 'q') 26. { 27. if (ch == 's') 28. { 29. MI_WLAN_GetStatus(AP_HANDLE, &g_stStatus); 30. if (g_stStatus.stApStatus.u16HostNum > 0) 31. { 32. printf("Access port:\n"); 33. 34. for (int i = 0; i < g_stStatus.stApStatus.u16HostNum; i++) 35. { 36. printf("HostName: %s\n", g_stStatus.stApStatus.astHosts[i].hostname); 37. printf("IP: %s\n", (char*)g_stStatus.stApStatus.astHosts[i].ipaddr); 38. printf("MAC: %s\n", (char*)g_stStatus.stApStatus.astHosts[i].macaddr); 39. printf("Connected time: %lld\n", g_stStatus.stApStatus.astHosts[i].connectedtime); 40. printf("\n"); 41. } 42. } 43. } 44. } 45. 46. if (g_bConnected) 47. { 48. MI_WLAN_Disconnect(g_apHdl); 49. g_bConnected = false; 50. } 51. 52. MI_WLAN_Close(&g_stOpenParam); 53. MI_WLAN_DeInit(); 54. 55. return 0; 56. 57. }
5. DEMO参考¶
MI_WLAN DemoCode参考: