分享

wifi热点项目总结

 昵称14797374 2013-12-20

本文档基于Android2.3.4,描述wifi热点相关工作事宜

1.将Android2.3.4设置里的便携式热点及相关配置显示出来。
.配置android2.3.4frameworksbasecoreresresvaluesConfig.xml

增加相关tether interface:



"wlan0"

增加相关upstream interface: [增加的就是以太网的接口eth0]


"eth0"

. 配置android2.3.4devicesoftwinnercrane-commonProductCommon.mk
增加:
PRODUCT_PROPERTY_OVERRIDES += ro.tether.denied=false

.修改android2.3.4frameworksbaseservicesjavacomandroidserver
ConnectivityService.java,接口函数ConnectivityService()

增加红色部分:
mTetheringConfigValid = (((mNetTrackers[ConnectivityManager.TYPE_MOBILE_DUN] != null) ||(mNetTrackers[ConnectivityManager.TYPE_ETHERNET] != null)
||!mTethering.isDunRequired()) &&(mTethering.getTetherableUsbRegexs().length != 0 ||
mTethering.getTetherableWifiRegexs().length != 0) &&
mTethering.getUpstreamIfaceRegexs().length != 0);

上面三项修改后,重新编译后,在 android设置里就会找到便携式热点选项了!

2.编译带ap功能的nano wifi driver(版本为7.0.8),从nanoradio原厂获得。
.将nano_7.0.8拷贝到linux wifi driver module目录:
licheelinux-2.6.36moduleswifinano_7.0.8
.配置build script,编译新的wifi driver.
修改licheelinux-2.6.36scriptsbuild_sun4i_crane.sh
build_modules() :
#build swl-n20 sdio wifi module
#make -C modules/wifi/nano-c047.12 LICHEE_MOD_DIR=${LICHEE_MOD_DIR} KERNEL_DIR=${LICHEE_KDIR}
#CONFIG_CHIP_ID=${CONFIG_CHIP_ID} HOST=${CROSS_COMPILE} INSTALL_DIR=${LICHEE_MOD_DIR} all install
make -C modules/wifi/nano_7.0.8 LICHEE_MOD_DIR=${LICHEE_MOD_DIR} KERNEL_DIR=${LICHEE_KDIR}
CONFIG_CHIP_ID=${CONFIG_CHIP_ID} HOST=${CROSS_COMPILE} INSTALL_DIR=${LICHEE_MOD_DIR} all install

clean_modules() :
#clean swl-n20 sdio wifi module
#make -C modules/wifi/nano-c047.12 LICHEE_MOD_DIR=${LICHEE_MOD_DIR} KERNEL_DIR=${LICHEE_KDIR}
#CONFIG_CHIP_ID=${CONFIG_CHIP_ID} HOST=${CROSS_COMPILE} INSTALL_DIR=${LICHEE_MOD_DIR} clean
make -C modules/wifi/nano_7.0.8 LICHEE_MOD_DIR=${LICHEE_MOD_DIR} KERNEL_DIR=${LICHEE_KDIR}
CONFIG_CHIP_ID=${CONFIG_CHIP_ID} HOST=${CROSS_COMPILE} INSTALL_DIR=${LICHEE_MOD_DIR} clean

1
这样的话,就可以编译新的wifi dirver了!

3.修改wifi.c
//caihua.zhao modify here
//nano-c047.12

//#define WIFI_FIRMWARE_MODULE_ARG "nrx_config=/drv"
//nano_7.0.8

define WIFI_FIRMWARE_MODULE_ARG "nrx_fw_path=/drv/x_mac.axf"

其中x_mac.axf为softap的固件fireware.

4.编译,刷包后起机,在android设置里欲启动wifi热点,不行,竟然出错,为什么呢?

查看debug知道: Exception in startAccessPoint() SIOCGIPRIV failed:
,同时知道wifi driver的ko及固件是成功加载的,而且也注册了wifi interface:wlan0

跟踪源码后知道引起这个问题有两个原因:
.android2.3.4frameworksbaseservicesjavacomandroidserverWifiService.java
private static final String SOFTAP_IFACE = "wl0.1";

需要修改为:
private static final String SOFTAP_IFACE = "wlan0";// "wl0.1";

. android2.3.4systemnetd SoftapController.cpp
int SoftapController::getPrivFuncNum(char *iface, const char *fname) {
……
if ((ret = ioctl(mSock, SIOCGIWPRIV, &wrq)) < 0) {
LOGE("SIOCGIPRIV failed: %d", ret);
return ret;
}
……
}

根据ioctl的流程,可以知道最终调用都wifi driver的nanoiw.c中:

static struct iw_handler_def nrx_iw_handler_def = {
.standard = nrx_iw_handlers,
.num_standard = ARRAY_SIZE(nrx_iw_handlers),

if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)

|| defined(CONFIG_WEXT_PRIV)
.private = NULL,
.num_private = 0,
.private_args = NULL,
.num_private_args = 0,

endif

if WIRELESS_EXT >= 17

.get_wireless_stats = nrx_get_wireless_stats

endif

};

endif /* < 2.6.22 || WEXT */

由于没有定义相应的private接口函数,所以上述ioctl会出错。因为这个ioctl就是为了得到wifi driver定义的private函数接口地址。

问题点:
要想解决这个问题,必须在驱动里增加相应的接口函数。
但nanoradio 技术支持说他也没有加过这样的接口,却没有提及其有开发的Android2.3.4SDK(坑爹哟!),后才知道这才是正道,我根据这个SDK大概花了不到两天时间,在android2.3.4的softap及client都弄好了,或许是之前的折腾,让我熟悉很多工具和并对驱动也熟悉很多。另,也没有说,softap和client需要不同的固件,后来我们测试时,发现启动client功能时宕机,我查看流程在知道需要不同固件。

当时,我们商量先用命令行模式将softap调试好。

涉及到android系统中没有的命令有iwconfig 、hostapd 。
而已有命令如下:
iptables、dnsmasq.
命令简介:
iwconfig是Linux Wireless Extensions(LWE)的用户层配置工具之一。LWE是Linux下对无线网络配置的工具,包括内核的支持、用户层配置工具和驱动接口的支持三部分。目前很多无线网卡都支持LWE,而且主流的Linux发布版本,比如Redhat Linux、Ubuntu Linux都已经带了这个配置工具。
hostapd 是一个用户态用于AP和认证服务器的守护进程。它实现了IEEE 802.11相关的接入管理,IEEE 802.1X/WPA/WPA2/EAP 认证, RADIUS客户端,EAP服务器和RADIUS 认证服务器。Linux下支持的驱动有:Host AP,madwifi,基于mac80211的驱动。
iptables IP 信息包过滤系统是一种功能强大的工具,可用于添加、编辑和除去规则,这些规则是在做信息包过滤决定时,防火墙所遵循和组成的规则。这些规则存储在专用的信息包过滤表中,而这些表集成在 Linux 内核中。在信息包过滤表中,规则被分组放在我们所谓的链(chain)中。
DNSmasq是一个小巧且方便地用于配置DNS和DHCP的工具,适用于小型网络,它提供了DNS功能和可选择的DHCP功能。它服务那些只在本地适用的域名,这些域名是不会在全球的DNS服务器中出现的。DHCP服务器和DNS服务器结合,并且允许DHCP分配的地址能在DNS中正常解析,而这些DHCP分配的地址和相关命令可以配置到每台主机中,也可以配置到一台核心设备中(比如路由器),DNSmasq支持静态和动态两种DHCP配置方式。

下面我们就开始编译相关可执行的命令行文件!

5.编译iwconfig命令行文件
总的来说,编译这个命令行文件很是顺利.
.下载wireless_tools.29.tar.gz
. 在ubantu10.04下解压,交叉编译
#tar zxvf wireless_tools.29.tar.gz
#cd wireless_tools.29
#gedit Makefile

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
   修改如下地方:
   ## Compiler to use (modify this for cross compile).
   CC = arm-none-linux-gnueabi-gcc
   #CC = gcc
   ## Other tools you need to modify for cross compile (static lib only).
   AR = arm-none-linux-gnueabi-ar
   RANLIB = arm-none-linux-gnueabi-ranlib
   #AR = ar
   #RANLIB = ranlib

  然后编译
  #make
  编译完成后,会生成6个可执行文件:
  iwconfig  iwevent  iwgetid  iwlist  iwpriv  iwspy

  用adb将iwconfig上传到/system/bin目录下
  #adb push iwconfig /system/bin
  adb shell里执行
  #iwconfig --help
  提示:iwconfig不是一个可执行文件,解决方法就是加上可执行权限(x)
  #chmod 0777 /system/bin/iwconfig
  而后在执行:iwconfig --help
  提示iwconfig not found

  后才发现Makefile还有一个选项,选择是否编译成static
  我将BUILD_STATIC = y打开后,重新编译,
  重复上传步骤,发现iwconfig可以正常用了,just so happy!

6.现在就可以开始用iwconfig来命令配置softap了。
具体命令行流程如下:
.load dirver
insmod /drv/nano_if.ko nrx_fw_path=/drv/x_mac.axf;insmod /drv/nano_ksdio.ko

. config softAP
iwconfig wlan0 mode master
iwconfig wlan0 channel 1
iwconfig wlan0 essid HuaziNanoAP

.config ip address
ifconfig wlan0 192.168.43.1;ifconfig wlan0 up

.config iptables
echo 1 > /proc/sys/net/ipv4/ip_forward
cat /proc/sys/net/ipv4/ip_forward

.create share net chain
iptables -A FORWARD -i eth0 -o wlan0 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

.config dnsmasq
dnsmasq --no-daemon --no-resolv --no-poll --dhcp-range=192.168.43.100,192.168.43.200,
100h

如此配置后,能后手机搜索到softap : HuaziNanoAP,没有加密的,并且也能正常获得ip地址,但是手机并不能正常的上网。

查找原因后知道:dnamasq没有配置dns服务器的地址。
解决方法:
新建一个文件resolv.conf,内容如下:
nameserver 202.96.134.133
nameserver 202.96.128.86
nameserver 8.8.8.8
nameserver 4.2.2.2

其中202.96.134.133、202.96.128.86是我们办公室网线上网时获得到的dns服务器地址.
而8.8.8.8、4.2.2.2是两个免费的dns服务器.

将resolv.conf通过adb上传到/etc目录
修改上面的第六步命令如下:
dnsmasq --no-daemon --no-poll --dhcp-range=192.168.43.100,192.168.43.200,100h
这样的话,启动dnsmasq时,会自动加载/etc/resolv.conf配置dns.

后用手机再次测试,这次能正常上网了!(可喜可贺)

7.根据SoftapController.cpp中需要的private interface,依照iwconfig命令流程,在wifi driver的nanoiw.c中封装出相应的接口

封装接口的对应关系如下:
getPrivFuncNum(iface, "START"); ?
nano_iwpriv_control_on()

getPrivFuncNum(iface, "STOP"); ?
nano_iwpriv_control_off()

getPrivFuncNum(mIface, "AP_BSS_START"); ?
nano_iwpriv_softap_start ()

fnum = getPrivFuncNum(mIface, "AP_BSS_STOP"); ?
nano_iwpriv_softap_stop ()

getPrivFuncNum(argv[2], "AP_SET_CFG"); ?
nano_iwpriv_set_ap_config()

getPrivFuncNum(iface, "FW_RELOAD"); ?
nano_iwpriv_fw_reload ()

在nano_iwpriv_softap_start调用driver的相关api实现如下命令行的流程:
iwconfig wlan0 mode master
iwconfig wlan0 channel 1
iwconfig wlan0 essid HuaziNanoAP

nano_iwpriv_softap_start依次调用了:
//SET Mode
nrx_iw_set_mode()
//Set Channel
nrx_iw_set_freq()
//SET ESSID
nrx_iw_set_essid()

而后,编译后,我们发现在Android设置里,能正常启动不加密的softap了,
并且后边的iptables/dnsmasq流程在android code是正常的。
用手机测试能DHCP连接到softap,且能正常上网!

至此,softap在android2.3.4上,不加密时就OK了!

8.在这个“蹭网”现象很普遍的时代,wifi ap不加密是万万不行的!
加密势在必行。

1
 下面开始调试softap的加密功能:

其实要实现WEP(有线等效加密)加密还是很容易的,但是WEP加密体制缺陷,通过收集足够的数据包,使用分析加密算法还原出密码,形象地称为 “塑料锁”,也即有锁好似无锁,但“有胜于无”。

实现wep加密,用iwconfig就能实现。
在第6步的. config softAP增加一句命令即可:
iwconfig wlan0 key s:1234efghijklm

后按照第6步启动softap,这时用手机搜到的softap显示wep加密保护,输入密码“1234efghijklm”后,能自动获取到IP,同时也能正常上网。

需要注意的是:
WEP密码长度必须是5BYTE和13BYTE两种,不过一般设13byte,这样破解起来也需时久些!

根据命令流程,在、在nano_iwpriv_softap_start调用driver的相关api实现wep,
nano_iwpriv_softap_start调用了:
if (strcmp(my_ap.sec, "wpa2-psk") == 0)
{
……
res = nrx_iw_set_encodeext(dev, info, &wrqu->encoding, my_ap.key);
……
}

修改android2.3.4systemnetd SoftapController.cpp
int SoftapController::setSoftap(int argc, char *argv[]) 函数接口里:
修改之前:
if (argc > 6) {
int j;
// Use the PKCS#5 PBKDF2 with 4096 iterations
PKCS5_PBKDF2_HMAC_SHA1(argv[6], strlen(argv[6]),
reinterpret_cast(ssid), strlen(ssid),
4096, SHA256_DIGEST_LENGTH, psk);

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
 LOGE("setSoftap psk: n");   
 for (j = 0; j< SHA256_DIGEST_LENGTH; j++)
    LOGE("[%d] = %02x n", j, psk[j]);

    for (j=0; j < SHA256_DIGEST_LENGTH; j++) {
        sprintf(&psk_str[j<<1], "%02x", psk[j]);
    }
    psk_str[j<<1] = '

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多