来自Wi-Fi专家的声音

 

SX-580为台灯的无线化赋能 (2)

撰写于:2014年8月27日
作者:silex Wi-Fi专家

在上一篇文章中,我们整理了使用SX-580 SDK开发SX-580-2700DM固件的环境。在本文中,我们将介绍启动SX-580-2700DM的Wi-Fi为AP模式,并与iPhone连接的步骤。
要将iPhone与SX-580-2700DM通过Wi-Fi连接,可以考虑两种方式:(1) 两者都连接到同一个接入点(AP);(2) 让SX-580-2700DM作为简易AP运行,并连接iPhone。两种方式都有其优缺点:(1) 适用于已经有AP且正在运行的环境(可以保持网络连接进行操作),(2) 更适合没有AP的独立环境。这次我们选择(2)的方式,尝试让SX-580-2700DM以AP模式运行。

尝试运行AP模式
在连接有线Ethernet的状态下启动SX-580 SDK,并以"root"身份登录。如果无法连接有线Ethernet,请在登录后执行以下命令:


# killall wpa_supplicant
# ifconfig ath0 up
来重置Wi-Fi模式(稍后将对此进行详细说明)。

SX-580 SDK的软件手册中记录了AP模式的设置方法。要在Linux上运行AP模式,需要使用名为hostapd的辅助程序,以及名为hostapd.conf的配置文件。在SX-580-2700DM的默认构建状态下,/etc/hostapd.conf中已经包含了一个示例配置文件,我们将对此文件进行一行修改(因为我们不使用与有线LAN的桥接功能,所以将bridge=br0注释掉)并使用它。


#
# 这是一个hostapd的示例配置文件。
#
interface=ath0
# bridge=br0
driver=ar6000
ssid=SX-IMAPP-SDK
channel_num=11
ignore_broadcast_ssid=0
auth_algs=1
ctrl_interface=/var/run/hostapd


启动hostapd时,需要将hostapd.conf的路径作为参数传递给它


# hostapd -B /etc/hostapd.conf
这里的-B选项表示在后台运行。如果运行不顺利或者无法看到SSID,可以去掉-B选项启动,这样会在前台运行并显示各种消息。(如果加上-d或-dd选项,会显示更多的消息,但如果没有一定的知识,可能难以理解)


# hostapd ./hostapd.conf
Configuration file: ./hostapd.conf
Delete Filter 0 = 33:33:00:00:00:01
Delete Filter 1 = 01:00:5e:00:00:01
Delete Filter 2 = 33:33:ff:5b:34:ec
Add Filter 0 = 01:00:5e:00:00:01
ADDRCONF(NETDEV_UP): ath0: link is not ready
channel hint set to 2462
Using interface ath0 with hwaddr 00:80:9ADDRCONF(NETDEV_CHANGE): ath0: link becomes ready
2:5b:34:ec and ssid 'SX-IMAPP-SDK'


从iPhone查看WiFi列表时,确认可以看到名为“SX-IMAPP-SDK”的SSID。点击它尝试连接...


 SSID可见的状态
但是,它一直在转圈圈,但就是无法完成连接。


不停地显示“正在连接”的旋转图标
但是,在SX-580端使用“hostapd_cli”命令进行检查,可以看到iPhone的MAC地址。 
# hostapd_cli all_sta
Selected interface 'ath0'
60:fa:cd:**:**:**


说白了,要使iPhone连接到WiFi需要

-通过DHCP能够获得IP地址
- DHCP选项中包含默认网关


这些条件是必需的。即使没有DHCP服务器响应,如果等待大约3分钟,会自动分配169.254.x.x的AutoIP地址,但是不能等待3分钟(※注)。另外,虽然也可以在iPhone的设置中分配一个固定的地址,但那很麻烦。
(※注)原本AutoIP是作为“Zeroconf”项目的一部分,而Zeroconf是一个旨在让世界上的设备能够自由相互连接的标准。苹果公司实现的Zeroconf协议变成了Bonjour。AutoIP的目标是无论何时何地,无论是否有DHCP服务器,都能够使用的链路本地地址,但由于IETF的精英们对其进行了严厉的批评,并将重试间隔不合理地延长,结果变成了“无论何时何地都不能用”的东西。


static设置的例子
也就是说,要使iPhone能够连接的"AP设备",仅仅作为一个接入点(AP)功能是不够的,还需要具备"DHCP服务器"的功能。

busybox的定制
SX-580使用的是“busybox”。busybox是一个集成了多种功能的“工具箱”,它将shell、ls、cat、ps等传统的Unix命令作为一个大的执行文件的一部分来实现,而不是作为单独的执行文件。
busybox也实现了DHCP服务器的功能,但在SX-580 SDK的默认设置中并未开启。因此,需要改变busybox的配置并更新rootfs(根文件系统)。在虚拟机上开发环境中


sxdevel@silex:~/sx580sdk/snapshot$ make buildroot-busybox-config


通过执行以上命令来进行busybox的设置。打开"Networking Utilities",并将"udhcp server (udhcpd)"的设置改为ON ([*])。由于之后也会使用WEB服务器,因此也需要将"httpd"设置为开启状态,不过在SX-580 SDK中,默认就已经是开启的了。


 BusyBox menuconfig 的画面。


 udhcpd server选项设置为选中状态[*]。


 确认httpd已被选中。

好了,修改了busybox配置后,选择退出,并在提示"Do you wish to save your new configuration?"时选择,然后在snapshot目录下执行make命令...咦?看起来并没有重新编译busybox。使用ls -l staging/build/busybox-1.19.4/busybox查看时,文件日期还是之前构建时的日期。但是,使用ls -l staging/build/busybox-1.19.4/.config查看时,配置文件的日期确实已经改变了。


sxdevel@silex:~/sx580sdk/snapshot$ ls -l staging/build/busybox-1.19.4/busybox
-rwxr-xr-x 1 sxdevel sxdevel 8149362014-08-05 19:16 staging/build/busybox-1.19.4/busybox

sxdevel@silex:~/sx580sdk/snapshot$ ls -l staging/build/busybox-1.19.4/.config
-rw-r--r-- 1 sxdevel sxdevel 27125 2014-08-13 10:31 staging/build/busybox-1.19.4/.config
这是因为snapshot/Makefile中的依赖关系描述不充分,导致busybox的.config文件更新与busybox的重新编译没有正确关联。虽然有些麻烦,但请手动删除staging/target/bin/busybox,然后执行make命令。这次应该会显示">>> busybox 1.19.4 Building"的消息,表明busybox正在编译中。


sxdevel@silex:~/sx580sdk/snapshot$ rm staging/target/bin/busybox
sxdevel@silex:~/sx580sdk/snapshot$ make


编译完成后,请将staging/images/rootfs.jffs2复制到/tftp目录,并从U-Boot更新rootfs。这次不需要更新内核。

busybox DHCP服务器的行为是通过conf文件设置的。有关conf文件语法的详细信息,请参阅http://git.busybox.net/busybox/tree/examples/udhcp/udhcpd.conf这次我们使用最基本的设置:


start 192.168.99.100
end 192.168.99.199
interface ath0
opt router 192.168.99.1
创建这个文件为/etc/udhcpd.conf。
像往常一样,从 /etc/hostapd.conf 中移除 bridge=br0 设置,然后在 /etc/hostapd.conf 中设置


# hostapd -B /etc/hostapd.conf
# ifconfig ath0 192.168.99.1
# udhcpd /etc/udhcpd.conf
按照上述命令启动接入点(AP),为AP的接口配置IP地址192.168.99.1,并启动DHCP服务器。在这种状态下,如果从iPhone连接,这次应该不会持续显示“正在连接”的旋转图标,而应该显示表示“连接完成”的勾选标记。


WiFi 连接完成
通过以上步骤,我们已经能够让SX-580-2700DM以AP模式运行,并且能够让iPhone连接上AP。但是,在传输rootfs之后,还需要手动编辑hostapd.conf、添加udhcpd.conf,以及手动启动hostapd和udhcpd,这些操作都比较繁琐。接下来,我将介绍自动化这些步骤的方法。

init进程和init.d脚本
Linux的初始化过程是由名为init的进程执行的。init按照什么顺序进行哪些初始化操作因Linux版本或发行版而异,但在SX-580 SDK中,启动步骤记录在/etc/inittab中,从那里调用的初始化脚本实现为/etc/init.d/rcS和/etc/init.d/rcW。


#启动系统
null::sysinit:/etc/init.d/rcS
null::sysinit:/etc/init.d/rcW

#在串行端口上执行getty
::respawn:/sbin/getty -L ttyAM0 115200 vt100 # GENERIC_SERIAL

#重启前要做的事情
null::shutdown:/etc/init.d/rcD
null::shutdown:/bin/umount -r /


rcS 是执行与网络无关的初始化处理,rcW 负责执行网络初始化处理。rcW 是根据/etc/init.d/ipconfig 中的设置来运行的。默认的 ipconfig 文件内容如下所示。


#
HOSTNAME=
IPV4METHOD=auto
IPTRIES=3
IPV4ADDR=169.254.111.111
IPV4MASK=255.255.0.0
IPV4ROUTER=0.0.0.0
IPV4DNS1=0.0.0.0
IPV4DNS2=0.0.0.0
#
USETFTP=1
USETELNET=1
#
WIFIMODE=AD-HOC
APCOUNTRY=JP
REGCODE=0x406A


设置 IPV4METHOD=static(小写)和 WIFIMODE=AP(大写),系统将作为接入点(AP)模式启动。不过,在默认rcW下,以太网eth0会自动初始化为网桥模式,udhcpd不会自动启动。

网桥和 DHCP 服务器
AP 的网桥模式与 DHCP 服务器配合使用时可能会有问题。 在网桥模式下,无线局域网和有线局域网会以透明方式连接。从无线局域网收到的 DHCP 请求会转发到有线局域网,并由连接在有线网络上(应该是)的DHCP服务器分配IP地址。如果在AP上运行DHCP服务器,而有线网络上已经有DHCP服务器在运行,那么AP上的DHCP服务器可能会与之发生冲突。
为了避免这个问题,家用无线路由器通常会将无线网络作为一个独立的网络来处理,并使用 NAT(Network Address Translation) 将无线局域网转发到有线局域网。不过,光是设置 NAT 就够写一整章了,所以这次我们就简单地 “关闭网桥功能,让无线局域网作为独立的无线局域网环境运行”。

修改 init.d/rcW(部分)
 
#
# AP模式或客户端模式
#
if [ ${WIFIMODE} = "ap" ] ; then
        #
        # Add bridge interface
        #
#        brctl addbr br0
#        brctl addif br0 eth0
#        brctl setfd br0 2

#        ifconfig br0 up
#        actif=br0
         actif=ath0

        if [ -e /sys/class/net/ath0 ] ; then
                #
                # Start up the hostapd
                #
                if [ -x /etc/init.d/wireless.sh ]; then
                        /etc/init.d/wireless.sh start ath0 ${WIFIMODE} ${APCOUNTRY}
                fi
#                brctl addif br0 ath0
        fi

.
.
.
/etc/init.d/startip.sh ${actif}

# Start DHCP server
if [ -e /etc/udhcpd.conf ] ; then
        udhcpd /etc/udhcpd.conf
fi
设置actif=ath0的原因是让 startip.sh在无线AP的接口ath0上设置IP地址。因为DHCP服务器需要在IP地址设置之后才能启动,所以udhcpd的启动会在调用startip.sh之后进行。

rootfs 映像及其模板
SX-580-2700DM目标设备的rcW文件当然位于/etc/init.d目录下,但在开发环境中(虚拟机上)却在不同的位置。绝不能错误地编辑/etc/init.d目录下的文件!那里存放的是Ubuntu Linux的初始化文件。
在开发环境中,会在snapshot/staging/target目录下创建一个本应“传输到目标设备”的rootfs副本,这个目录的内容会被整体转换成rootfs.jffs2格式。然而,snapshot/staging/target目录的内容每次执行"make rootfs-build"时都会半自动地生成,而像init.d这样的文件的“原型”则位于另一个目录,即snapshot/staging/skeleton下。(※注)
(※注) rootfs原型或模板目录的布局和命名在不同的Linux开发环境中会有很大差异。即使是同一家公司的产品,随着BSP或版本的不同,这些布局和命名也可能会有显著的差异。在SX-580 SDK中,rootfs被称为"target",模板被称为"skeleton",但在silex的其他产品中,这些可能被称为"rootfs"和"default"。

-编辑snapshot/staging/skeleton/etc/hostapd.conf
  (将bridge=br0注释掉)
-在snapshot/staging/skeleton/etc/下添加udhcpd.conf
-编辑snapshot/staging/skeleton/etc/init.d/ipconfig
   (IPV4METHOD=static, IPV4ADDR=192.168.99.1, WIFIMODE=AP)
-编辑snapshot/staging/skeleton/etc/init.d/rcW
  (注释掉网桥初始化,添加启动udhcpd)

完成上述修改后,在snapshot目录下执行make rootfs-build命令,这样staging/images/rootfs.jffs2就会被更新。按照通常的步骤执行update_rootfs。重启后,hostapd和udhcpd应该会自动启动,设备应该处于可以被iPhone连接的状态。

下一篇文章将讨论 HTTP 服务器和 CGI。
 

 



嵌入式无线LAN模块产品介绍页面