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 来控制复位。

  1. kernel里控制sd power 的gpio,其实是根据padmux里的MDRV_PUSE_SDIO0_PWR来找到对应哪个gpio口的,dts里的slot-pwr-gpios在padmux存在情况下,是没有作用的。

  2. 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参考:

wifi.tar.gz

wlan.json