TetherCmd和SoftapCmd命令都和手机中一项名为绑定(Tether)的功能相关。简单来说,绑定功能即把手机当成Modem用。智能手机一般都有多种连接网络的方式,例如使用Wi-Fi或3G。在某些环境下如高铁列车上,差旅人士只要把手机接到笔记本上,然后开启3G和Tether,笔记本就可以利用手机上网了(在智能机普及前,类似的场景中就需要使用3G上网卡)。
另外,如果手机中的无线网络设备支持Soft AP(Soft Access Point,软件实现的接入点)功能,还可以通过Softap命令将手机变成一个AP(可以把它看成是一个无线路由器)。
目前Android 4.2系统支持以下三种方式的绑定。
* Soft AP:利用Wi-Fi无线网络的特性,开启手机Soft AP功能。主机和手机间通过Wi-Fi通信。
* Bluetooth:主机(PC或笔记本电脑)和手机通过蓝牙协议通信。
* USB:主机和手机通过USB协议通信。手机相当于一个USB上网卡。
本节主要介绍TetherCmd中的USB绑定和Softap命令。其余内容我们将留给读者自行研究。
* * * * *
**提示** TetherCmd还支持所谓的逆绑定(reverse tethering),即手机借助主机上网。这部分内容请读者自行研究。
* * * * *
**1.TetherCmd命令**
本节仅介绍利用USB实现Tether的功能,其中涉及RNDIS以及DHCP相关的背景知识,我们先来介绍它们。
(1)背景知识介绍[26][27][28][29][30]
RNDIS(Remote Network Driver Interface Specification)是微软公司的,主要用于Windows平台中USB网络设备的驱动开发。RNDIS的协议栈如图2-24所示。
:-: ![](https://box.kancloud.cn/fa420f6e5219def4b7d9d69e43c60d79_777x636.jpg)
图2-24 RNDIS协议栈
RNDIS的作用是简化Windows平台上USB网络设备驱动开发的流程。此处不讨论相关内容,感兴趣的读者可阅读本章最后列出的参考资料。
RNDIS和Android有什么关系呢?当手机通过USB连接到主机(主机一般运行Windows系统)后,如果要启用USB绑定,必须要把手机的USB设置成RNDIS(绝大部分厂商的手机都是这么实现的)。这样,主机上的OS就能识别到一个新的网卡。然后用户就可以选择使用它来开展网络操作了。
* * * * *
**提示** 本书后续章节将讨论Android平台上USB的相关功能。
* * * * *
假设用户选择使用这个通过USB绑定的网卡,下一步要做的就是给主机分配IP地址了。此处涉及DHCP协议。
DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)的前身是BOOTP。BOOTP原本是用于无磁盘主机连接的网络上的,网络主机使用BOOT ROM而不是磁盘启动并连接上网络,BOOTP则可以自动地为那些主机设定TCP/IP环境DHCP是BOOTP的增强版本,它分为两个部分。
* 服务器端:所有的IP网络设定数据都由DHCP服务器集中管理,并负责处理客户端的DHCP要求。
* 客户端:客户端会使用从服务器分配下来的IP地址等配置信息。
根据上述介绍,相信读者很容易想到,在USB绑定中,主机将是DHCP的客户端,而手机是DHCP的服务器端。那么在Android系统中,DHCP服务器端是谁呢?同Pppd类似,Android也使用了另外一个开源软件DNSmasq来充当DHCP服务器。
DNSmasq是一个用于配置DNS和DHCP的工具,小巧且方便,适用于小型网络,它提供了DNS功能和可选择的DHCP功能。它服务只在本地适用的域名,这些域名是不会在全球的DNS服务器中出现的。DHCP服务器和DNS服务器结合,并且允许DHCP分配的地址能在DNS中正常解析,而这些DHCP分配的地址和相关命令可以配置到每台主机中,也可以配置到一台核心设备中(如路由器)。
DNSmasq适用于拥有NAT的家庭网络、用Modem、ADSL设备连接到互联网等环境。对于需求低资源消耗且配置方便简单的小型网络(最多可支持1000台主机)是一个很好的选择。
(2)TetherCmd命令使用
Android中启动USB Tether功能将涉及Framework层多个模块,其详细过程留待后续章节介绍。此处读者仅需从TetherCmd角度考虑其中的两个主要步骤。
- 1、**添加需要Tether的接口**。对USB绑定来说,接口名为rndis0。对应的处理函数是TetherController的tetherInterface,代码如下所示。
**TetherController.cpp::tetherInterface**
~~~
int TetherController::tetherInterface(const char *interface) {
mInterfaces->push_back(strdup(interface));
// 把需要interface名字保存到一个链表即可
return 0;
}
~~~
tetherInterface的功能很简单,就是保存需要Tether的设备名。这一步其实没有太多实质性的内容。
- 2、**通过"start"选项启动Tether**。这个步骤将触发TetherController的startTethering函数被调用。该函数的主要功能就是配置dnsmasq的启动参数并启动它。这部分代码比较简单,dnsmasq的启动参数如下所示。
~~~
dnsmasq\
--keep-in-foreground\#前台运行
--no-resolv\#不解析/etc/resolv.conf,该文件记录域名和dns服务器的一些信息
--no-poll\#不关注/etc/resolv.conf文件的变化
--dhcp-option-force=43,ANDROID_METERED\#强制的dhcp选项。客户端和dnsmasq交互时,首先
#会获取dhcp服务器的一些配置信息。43是DHCP协议中定义的option的一种,代表vendor specific
#infomation该选项说明vendor specifi information就是ANDROID_METERED
--pid-file\#指定dnsmasq记录自己进程id(pid)到某个文件。默认是/var/run/dnsmasq.pid
--dhcp-range=192.168.1.2 192.168.1.100 1h\#该选项开启dnsmasq的dhcp服务功能。分配的IP地址
#位于192.168.1.2和192.168.1.100之间。1h代表租约时间为1小时。租约时间即某IP地址可以被DHCP
#客户端使用的时间。如果超过租约时间,dnsmasq必须为该客户端重新分配IP
~~~
这两步完成后,USB绑定功能中和TetherCmd相关的任务就完成了。从整个绑定过程来看,涉及应用(例如Settings提供的设置功能)、网络模块、USB模块、驱动等,是一个非常复杂的过程。
* * * * *
**提示** 这个过程对软件开发者来说也是一个挑战,只有对USB Tether涉及的各个模块都有相应了解,碰到问题时候才能快速定位和解决它。
* * * * *
**2.SoftapCmd命令**
Softap命令和Wi-Fi有紧密关系。本节先简单介绍Soft AP相关的背景知识,后续章节将对Wi-Fi开展深入讨论。
(1)背景知识介绍[31][32][33]
Soft AP代表通过软件实现Access Point的功能。那么AP是什么?AP和Soft AP有什么不同?
在Wi-Fi无线技术规范中,AP和Station是其中的两个基本概念。
- 从功能角度来看,AP作为基站设备,起着连接其他无线设备到有线网的作用,相当于有线网络中的HUB与交换机。在日常工作和家庭中经常使用的无线路由器就是一个AP。一般情况下,它一端接着有线网络,另一端连接其他无线设备。
- Station代表配备无线网络接口的设备,如手机、笔记本等。
虽然AP和Station是两个不同的设备,但实际上在Station中用软件也能实现AP拥有的功能,如桥接、路由等。在基本功能上,Soft AP与AP并没有太大的差别,只是Soft AP设备的接入能力和覆盖范围不如AP。
以前面提到的高铁列车上的应用场景为例,除了用USB绑定外,还可以打开笔记本和手机的Wi-Fi,并启动手机的Soft AP功能。这样,手机一方面用3G接入互联网,另一方面又利用SoftAP向笔记本提供Wi-Fi接入功能。
在Android系统中使用Soft AP功能还得借助另一个开源软件"hostapd",这是一个运行在用户空间的用于AP和认证服务器的守护进程。它实现了IEEE 802.11相关的接入管理、IEEE802.1X/WPA/WPA2/EAP认证、RADIUS客户端、EAP服务器和RADIUS认证服务器。
(2)SoftapCmd命令使用
和TetherCmd类似,开启Android中手机的Soft AP功能将涉及大量Framework层中的操作,本节仅关注和Netd相关的三个步骤。
1)首先为Wi-Fi加载不同的固件(Firmware),这是通过SoftapController的fwReloadSoftap函数完成的,代码如下所示。
**SoftapController.cpp::fwReloadSoftap**
~~~
int SoftapController::fwReloadSoftap(int argc, char *argv[])
{
int ret, i = 0;
char *iface;
char *fwpath;
......// 参数检测
iface = argv[2];
if (strcmp(argv[3], "AP") == 0) {
fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_AP);
} else if (strcmp(argv[3], "P2P") == 0) {
fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_P2P);
} else {
fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_STA);
}
// 通过往/sys/module/wlan/parameters/fwpath文件中写入固件名
// 触发驱动去加载对应的固件
ret = wifi_change_fw_path((const char *)fwpath);
......
return ret;
}
~~~
上面这段代码表示在Android中,如果要让Wi-Fi无线设备扮演不同的角色,得为它们加载不同的固件(Firmware),具体说明如下。
* **WIFI_GET_FW_PATH_AP**:代表Soft AP功能的固件,其对应的文件位置由WIFI_DRIVER_FW_PATH_AP宏表达。三星Tuna平台中,该文件位置为/vendor/firmware/fw_bcmdhd_apsta.bin。
* **WIFI_GET_FW_PATH_P2P**:代表P2P功能的固件,其对应的文件位置由WIFI_DRIVER_FW_PATH_P2P宏表达。三星Tuna平台中,该文件位置为/vendor/firmware/fw_bcmdp2p.bin。
* **WIFI_GET_FW_PATH_STA**:代表Station功能的固件,其对应的文件位置由WIFI_DRIVER_FW_PATH_STA宏表达。三星Tuna平台中,该文件位置为/vendor/firmware/fw_bcmdhd.bin。
* * * * *
**提示** 三星Tuna平台对应的配置文件在Android 4.2源码根目录/device/samsung/tuna目录中。从上面的固件文件名来看,它用的Wi-Fi无线芯片是博通(Broadcom)公司生产的。通过加载不同固件的方式来启用无线芯片硬件的不同功能可能和Wi-Fi驱动及芯片的设计有关。
另外,根据审稿专家的反馈,在Android 4.2中,STA和P2P可同时运行(即所谓的共存模式),这样STA和P2P实际对应的固件相同,但可能文件名不同。而SoftAP的固件与STA/P2P就不一样了。
* * * * *
2)加载完指定的Wi-Fi固件后,下一步将对Soft AP功能进行一些配置,配置信息最终将写到一个配置文件。这部分功能由SoftapController的setSoftap函数完成,代码如下所示。
**SoftapController.cpp::setSoftap**
~~~
int SoftapController::setSoftap(int argc, char *argv[]) {
char psk_str[2*SHA256_DIGEST_LENGTH+1];
int ret = 0, i = 0, fd;
char *ssid, *iface;
......// 参数检查
iface = argv[2];
char *wbuf = NULL;
char *fbuf = NULL;
if (argc > 3) {
ssid = argv[3];
} else {
ssid = (char *)"AndroidAP"; // SSID即接入点的名称
}
asprintf(&wbuf, "interface=%s\ndriver=nl80211\nctrl_interface="
"/data/misc/wifi/hostapd\nssid=%s\nchannel=6\nieee80211n=1\n",
iface, ssid);
if (argc > 4) { // 判断AP的加密类型
if (!strcmp(argv[4], "wpa-psk")) {
generatePsk(ssid, argv[5], psk_str);
asprintf(&fbuf, "%swpa=1\nwpa_pairwise=TKIP CCMP\nwpa_psk=%s\n",
wbuf, psk_str);
} else if (!strcmp(argv[4], "wpa2-psk")) {
generatePsk(ssid, argv[5], psk_str);
asprintf(&fbuf, "%swpa=2\nrsn_pairwise=CCMP\nwpa_psk=%s\n",
wbuf, psk_str);
} else if (!strcmp(argv[4], "open")) {
asprintf(&fbuf, "%s", wbuf);
}
} ......
// HOSTAPD_CONF_FILE指向/data/misc/wifi/hostapd.conf文件
fd = open(HOSTAPD_CONF_FILE, O_CREAT | O_TRUNC | O_WRONLY, 0660);
......
if (write(fd, fbuf, strlen(fbuf)) < 0) {
ALOGE("Cannot write to \"%s\": %s", HOSTAPD_CONF_FILE, strerror(errno));
ret = -1;
}
......// 修改该文件的读写权限等
return ret;
}
~~~
上面代码中涉及Wi-Fi技术的很多概念,将在后续章节统一介绍。从功能上来说,setSoftap函数无非就是把一些配置信息写到一个hostapd.conf文件中。可以通过一个例子文件来了解此文件的内容。
Android4.2/hardware/ti/wlan/mac80211/config目录中有一个hostapd.conf文件,其内容如下所示。
**hostapd.conf**
~~~
driver=nl80211 #指定Wi-Fi驱动的名称
......#略去部分内容
ssid=AndroidAP #设置接入点名称为AndroidAP
country_code=US
wep_rekey_period=0
eap_server=0
own_ip_addr=127.0.0.1
wpa_group_rekey=0
wpa_gmk_rekey=0 #加密方式等设置
wpa_ptk_rekey=0
interface=wlan1 #网络设备接口
......#略去部分内容
~~~
由上边示例的hostapd.conf可知,当使用该配置文件后,其他Station搜索到由这台手机设置的Soft AP的名称将会是"AndroidAP"。
3)最后,SoftapController的startap函数被调用,它将启动hostapd进程。重点关注hostapd启动的参数信息,如下所示。
~~~
hostapd\
-e/data/misc/wifi/entropy.bin \和Wi-Fi协议中的信息加密有关
/data/misc/wifi/hostapd.conf \hostapd的配置文件
~~~
- 前言
- 第1章 准备工作
- 1.1 Android系统架构
- 1.2 工具使用
- 1.2.1 Source Insight的使用
- 1.2.2 Eclipse的使用
- 1.2.3 BusyBox的使用
- 1.3 本书资源下载说明
- 第2章 深入理解Netd
- 2.1 概述
- 2.2 Netd工作流程
- 2.2.1 main函数分析
- 2.2.2 NetlinkManager分析
- 2.2.3 CommandListener分析
- 2.2.4 DnsProxyListener分析
- 2.2.5 MDnsSdListener分析
- 2.3 CommandListener中的命令
- 2.3.1 iptables、tc和ip命令
- 2.3.2 CommandListener构造函数和测试工具ndc
- 2.3.3 InterfaceCmd命令
- 2.3.4 IpFwd和FirewallCmd命令
- 2.3.5 ListTtysCmd和PppdCmd命令
- 2.3.6 BandwidthControlCmd和IdletimerControlCmd命令
- 2.3.7 NatCmd命令
- 2.3.8 TetherCmd和SoftapCmd命令
- 2.3.9 ResolverCmd命令
- 2.4 NetworkManagementService介绍
- 2.4.1 create函数详解
- 2.4.2 systemReady函数详解
- 2.5 本章总结和参考资料说明
- 2.5.1 本章总结
- 2.5.2 参考资料说明
- 第3章 Wi-Fi基础知识
- 3.1 概述
- 3.2 无线电频谱和802.11协议的发展历程
- 3.2.1 无线电频谱知识
- 3.2.2 IEEE 802.11发展历程
- 3.3 802.11无线网络技术
- 3.3.1 OSI基本参考模型及相关基本概念
- 3.3.2 802.11知识点导读
- 3.3.3 802.11组件
- 3.3.4 802.11 Service介绍
- 3.3.5 802.11 MAC服务和帧
- 3.3.6 802.11 MAC管理实体
- 3.3.7 无线网络安全技术知识点
- 3.4 Linux Wi-Fi编程API介绍
- 3.4.1 Linux Wireless Extensions介绍
- 3.4.2 nl80211介绍
- 3.5 本章总结和参考资料说明
- 3.5.1 本章总结
- 3.5.2 参考资料说明
- 第4章 深入理解wpa_supplicant
- 4.1 概述
- 4.2 初识wpa_supplicant
- 4.2.1 wpa_supplicant架构
- 4.2.2 wpa_supplicant编译配置
- 4.2.3 wpa_supplicant命令和控制API
- 4.2.4 git的使用
- 4.3 wpa_supplicant初始化流程
- 4.3.1 main函数分析
- 4.3.2 wpa_supplicant_init函数分析
- 4.3.3 wpa_supplicant_add_iface函数分析
- 4.3.4 wpa_supplicant_init_iface函数分析
- 4.4 EAP和EAPOL模块
- 4.4.1 EAP模块分析
- 4.4.2 EAPOL模块分析
- 4.5 wpa_supplicant连接无线网络分析
- 4.5.1 ADD_NETWORK命令处理
- 4.5.2 SET_NETWORK命令处理
- 4.5.3 ENABLE_NETWORK命令处理
- 4.6 本章总结和参考资料说明
- 4.6.1 本章总结
- 4.6.2 参考资料说明
- 第5章 深入理解WifiService
- 5.1 概述
- 5.2 WifiService的创建及初始化
- 5.2.1 HSM和AsyncChannel介绍
- 5.2.2 WifiService构造函数分析
- 5.2.3 WifiStateMachine介绍
- 5.3 加入无线网络分析
- 5.3.1 Settings操作Wi-Fi分析
- 5.3.2 WifiService操作Wi-Fi分析
- 5.4 WifiWatchdogStateMachine介绍
- 5.5 Captive Portal Check介绍
- 5.6 本章总结和参考资料说明
- 5.6.1 本章总结
- 5.6.2 参考资料说明
- 第6章 深入理解Wi-Fi Simple Configuration
- 6.1 概述
- 6.2 WSC基础知识
- 6.2.1 WSC应用场景
- 6.2.2 WSC核心组件及接口
- 6.3 Registration Protocol详解
- 6.3.1 WSC IE和Attribute介绍
- 6.3.2 802.11管理帧WSC IE设置
- 6.3.3 EAP-WSC介绍
- 6.4 WSC代码分析
- 6.4.1 Settings中的WSC处理
- 6.4.2 WifiStateMachine的处理
- 6.4.3 wpa_supplicant中的WSC处理
- 6.4.4 EAP-WSC处理流程分析
- 6.5 本章总结和参考资料说明
- 6.5.1 本章总结
- 6.5.2 参考资料说明
- 第7章 深入理解Wi-Fi P2P
- 7.1 概述
- 7.2 P2P基础知识
- 7.2.1 P2P架构
- 7.2.2 P2P Discovery技术
- 7.2.3 P2P工作流程
- 7.3 WifiP2pSettings和WifiP2pService介绍
- 7.3.1 WifiP2pSettings工作流程
- 7.3.2 WifiP2pService工作流程
- 7.4 wpa_supplicant中的P2P
- 7.4.1 P2P模块初始化
- 7.4.2 P2P Device Discovery流程分析
- 7.4.3 Provision Discovery流程分析
- 7.4.4 GO Negotiation流程分析
- 7.5 本章总结和参考资料说明
- 7.5.1 本章总结
- 7.5.2 参考资料说明
- 第8章 深入理解NFC
- 8.1 概述
- 8.2 NFC基础知识
- 8.2.1 NFC概述
- 8.2.2 NFC R/W运行模式
- 8.2.3 NFC P2P运行模式
- 8.2.4 NFC CE运行模式
- 8.2.5 NCI原理
- 8.2.6 NFC相关规范
- 8.3 Android中的NFC
- 8.3.1 NFC应用示例
- 8.3.2 NFC系统模块
- 8.4 NFC HAL层讨论
- 8.5 本章总结和参考资料说明
- 8.5.1 本章总结
- 8.5.2 参考资料说明
- 第9章 深入理解GPS
- 9.1 概述
- 9.2 GPS基础知识
- 9.2.1 卫星导航基本原理
- 9.2.2 GPS系统组成及原理
- 9.2.3 OMA-SUPL协议
- 9.3 Android中的位置管理
- 9.3.1 LocationManager架构
- 9.3.2 LocationManager应用示例
- 9.3.3 LocationManager系统模块
- 9.4 本章总结和参考资料说明
- 9.4.1 本章总结
- 9.4.2 参考资料说明
- 附录