7.Ad hoc的支持

添加ad hoc的支持有两种方式,改wpa_supplicant和改Android Frameworkwpa_supplicant的原理和方法请参考http://www.xda-developers.com/android/android-ad-hoc-wireless-network-support/这种方法不推荐,不是解决问题的根本。下面是改Android Framework的方法。

Android Framework中添加adhoc支持很简单,可能只需要改一行代码(当然还没经过测试)如下:

List<ScanResult> results =mWifiManager.getScanResults();

if(results !=null) {

for(ScanResult result : results) {

// Ignore hidden and ad-hocnetworks.

if(result.SSID==null|| result.SSID.length() == 0 ||

result.capabilities.contains("[IBSS]")) {

continue;

}

booleanfound =false;

for(AccessPoint accessPoint : accessPoints) {

if(accessPoint.update(result)) {

found =true;

}

}

if(!found) {

accessPoints.add(newAccessPoint(this, result));

}

}

}

上面一段代码在Settings应用的WifiSettings类里发生在wpa_supplicant扫描ap结束时||result.capabilities.contains("[IBSS]")去掉即可支持adhoc

可见google是故意禁了ad hoc的功能。那么总有原因下面摘自某论坛

What you say is true - it is relatively easy to support ad-hoc networks. I also appreciate that it sucks if you have to rely on ad-hoc wifi and you own an Android device.
However, there are good reasons as to why Android, or any OS for that matter, doesn't support it.

Ad-hoc networks are inherently insecure as they require no authentication for people joining the network. Ad-hoc networks were only ever intended to be used for very short term spontaneous and informal networks. "Short term", in this context, means the time it takes you to purchase a proper wireless access point.

Ad-hoc networks are highly discouraged, as not only are they insecure, but they interfere with people using the proper, secure, and recommended, infrastructure WiFi networks.

These facts probably demotivated Google from implementing support for it.

As most broadband (Cable or ADSL) routers come with WiFi these days, and as a lot of the rest of us (like me) use stand-alone wireless access points, the requirement for Ad-Hoc support is low. Also, as the phones that run Android have3G, Edge, and GPRS support the need is even lower for Android users. As such, you can probably see why Google didn't bother - there are other features that more people "require", and so Google probably concentrated on adding those.

TODO:怎样创建ad hoc网络让其它设备连进来?

8.wifi direct

Wifi direct又叫wifi p2p,是一种新型的技术,用来取代蓝牙,具有速度快连接方便的特点。不过目前Android2.3还并不支持,但应该会很快有支持。下面是一些资料。

http://wireless.kernel.org/en/developers/p2p

Android4.0已经支持wifi direct api已经导出。

9.Soft ap支持

Ap可以为游戏应用提供联机对战的功能,也可以基于软ap实现网络共享,即连接到软Ap上的设备可以共享软Ap设备的网络,比如手机可以作为软Ap笔记本连进来就可以通过手机的3g上网。

支持soft ap当然首先要驱动支持,初步调研结论是ar6k驱动可以支持soft ap后续还需确认。

Android 2.2(froyo)开始支持soft ap可以在Settings程序里设置soft ap功能,如下图:

android 2.3 wifi (二)_第1张图片

但是我们在模拟器上并无上面的界面,是在运行时会调用ConnectivityManager.isTetheringSupported()函数来判断系统是否支持Tethering如果不支持Tethering就隐藏上面界面。

开启Soft ap功能在Settings程序的WifiApEnabler. onPreferenceChange里,设置soft apWifiApDialog.onClick里。它们依赖WifiManager的如下接口:

publicbooleansetWifiApEnabled(WifiConfiguration wifiConfig,booleanenabled)

publicintgetWifiApState()

publicWifiConfiguration getWifiApConfiguration()

publicbooleansetWifiApConfiguration(WifiConfiguration wifiConfig)

WifiManager调用WifiService实现的功能,WifiService最终调用NetworkManagementService.startAccessPoint函数,如下:

publicvoidstartAccessPoint(WifiConfigurationwifiConfig, StringwlanIface, String softapIface)

throwsIllegalStateException {

mContext.enforceCallingOrSelfPermission(

android.Manifest.permission.CHANGE_NETWORK_STATE,"NetworkManagementService");

mContext.enforceCallingOrSelfPermission(

android.Manifest.permission.CHANGE_WIFI_STATE,"NetworkManagementService");

try{

mConnector.doCommand(String.format("softap stop "+wlanIface));

mConnector.doCommand(String.format("softap fwreload "+wlanIface+" AP"));

mConnector.doCommand(String.format("softap start "+wlanIface));

if(wifiConfig ==null) {

mConnector.doCommand(String.format("softap set "+wlanIface+" "+ softapIface));

}else{

String str = String.format("softap set "+wlanIface+" "+ softapIface +

" %s %s %s", convertQuotedString(wifiConfig.SSID),

wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK) ?

"wpa2-psk":"open",

convertQuotedString(wifiConfig.preSharedKey));

mConnector.doCommand(str);

}

mConnector.doCommand(String.format("softap startap"));

}catch(NativeDaemonConnectorException e) {

thrownewIllegalStateException("Error communicating to native daemon to start softap", e);

}

}

NetworkManagementService顾名思义是Android系统的网络管理服务,负责比较特殊的网络的设置(比如网络共享(Tether)和网络地址转换(Nat)ip转发(ip forwording))和向上层通知网络相关的事件。mConnector是一个NativeDaemonConnector这里用来和系统的netd守护进程通信。NetworkManagementService的好多功能都是通过Netd实现的。Netd的代码在“android sources/system/netd里。Netdsoftap控制的功能在“android sources/system/netd/SoftapController.{h,cpp}里,是通过wireless extention定义的SIOCGIWPRIV来调用网卡驱动的ap功能。如果具体网卡驱动提供的soft ap接口不同,SoftapController的代码就需要改。比如ar6k的驱动厂家提供了hostapd来控制ap就需要改SoftapController来适配hostapd提供的接口。

10.Wifi Tethering支持

Settings程序里看不到关于Wifi Tethering的任何代码,着实让我迷惑了一下。原来开启soft ap功能后就会自动启动wifi tetheringcom.android.server.connectivity.Tethering类向NetworkManagementService(NetworkManagementService通过netd来监听,netdnetlink socket监听内核热插拔事件)类注册了一个Observer来监听Interfaceaddremovechange的信息。当使能soft ap时,会以soft ap模式加载驱动,此时驱动会发出热插拔事件。Tethering类里面跑了两种状态机,一个TetherMasterSMnTetherInterfaceSM(每个tetherable interface对应一个)添加Interface时就会启动一个TetherInterfaceSM状态机,并进入Initial状态,发出ConnectivityManager.ACTION_TETHER_STATE_CHANGED广播。WifiService收到广播后调用ConnectivityService.tethering(inf)函数,TetherInterfaceSM发送CMD_TETHER_REQUESTED命令,进入tethered状态。

UpstreamIface(比如现在不共享以太网而变为共享3g网络)发生变化时,TetherMasterSM会通知所有TetherInterfaceSM改变nat

TetherMasterSM初始阶段UpstreamIface的选择是根据从NetworkManagementServicem获得所有Ingerface,能匹配上com.android.internal.R.array.config_tether_upstream_regexs(base.core.res.res.values.configs中定义,原始为空需要根据实际情况来改)的第一个状态为upinterface即被选为UpstreamIface

运行时UpstreamIface也可能变化,Tethering类监听ConnectivityManager.CONNECTIVITY_ACTION事件(当网络连接变化时由ConnectivityService发出)当收到时给TetherMasterSMTetherMasterSM.CMD_UPSTREAM_CHANGED消息。TetherMasterSM收到后重新选择UpstreamIface,并向所有TetherInterfaceSM发送TetherInterfaceSM.CMD_TETHER_CONNECTION_CHANGED事件来用新的UpstreamIface重启Nat

Tethering原理如下:

NetworkManagementService.setIpForwardingEnabled(true)

NetworkManagementService.startTethering(mDhcpRange)//启动dnsmasq(负责dhcpdns forwarding)

NetworkManagementService. setDnsForwarders(mDnsServers)//通过给dnsmasq发命令来设置dns服务器

NetworkManagementService.enableNat(String internalInterface, String externalInterface)//启动nat(网络地址转换)

11.Usb Tethering支持

何谓usb tethering这里举个例子,我们的设备连上了wifi此时将设备通过usb连接到pcpc即可以共享我们设备的wifi网络,可以将我们的设备看做是一块usb接口的无线网卡。

Wifi Tethering从用户的角度来看是手动启动(通过Settings使能soft ap)但从原理上看是自动启动,使能soft apNetworkManagementService收到interfaceAdded信号后便自动启动wifi tethering

usb tethering则不同,无论从用户的角度还是从原理的角度都是手动启动。当设备通过usb连上pc时,NetworkManagementService会收到interfaceAdded信号。不过并不能立刻开启tethering因为连上pc的目的并不只有一个,用户想要的可能是读写设备的sd卡。所以Usb Tethering会很关心Usb.ACTION_USB_STATEIntent.ACTION_MEDIA_SHAREDIntent.ACTION_MEDIA_UNSHARED事件。只有当usb连上并且media unshared的情况下才可以usb tetheringtethering过程中收到Intent.ACTION_MEDIA_SHAREDTethering类和WifiSettings类都会有相应的动作。

手动在Settings里启动UsbTethering时,会调用ConnectivityService.Tethering(inf)函数开启usb tethering

原理如下:

NetworkManagementService.setIpForwardingEn cpRange)//启动dnsmasq(负责dhcpdns forwarding)

NetworkManagementService.setDnsForwarders(mDnsServers)//通过给dnsmasq发命令来设置dns服务器

Tethering.configureUsbIface(true)//配置usb interfaceipnetmaskup

Tethering.enableUsbRndis(true)//开启Usb Rndis(Remote Network Driver Interface Specification),使设备变成usb无线网卡

NetworkManagementService.enableNat(String internalInterface, String externalInterface)//启动nat(网络地址转换)abled(true)

NetworkManagementService.startTethering(mDh

另外补充一点,如果是Windows还需要安装usb tethering驱动才可以:http://www.android.com/tether

12.Reverse usb Tethering

何谓Reverse usb Tetheringusb Tetheringpc可以通过我们的设备上网,Reverse usb Tethering是设备可以通过Pc上网,只要usb线连上pc

目前Android不支持,Framework只改Settings程序应该就可以添加支持,在驱动层也需要支持,可能只是编译内核时打开某些选项而已,待确定。

未完待续……

13.Ethernet Tethering

所谓Ethernet TetheringPc机通过网线连接到设备时即可共享设备的wifi3g网络。

目前Android不支持,有线网卡connected3gwifi都会禁掉。

14.需要改动的地方

针对5201平台(ar6k驱动)我们需要对framework做如下修改。

基本:

android sources\hardware\libhardware_legacy\wifi\wifi.c:驱动名称

lAdhoc支持:

Settings应用的WifiSettings类:将隐藏adhoc网络的代码去掉

lSoftap支持:

android sources/system/netd/SoftapController.{h,cpp}:适配到hostapd

android sources\hardware\libhardware_legacy\wifi\wifi.c:驱动的参数决定模式(ap or station)

com.android.server.connectivity: ipdefault dns

lWifi Tethering支持:

base.core.res.res.values.configs根据平台实际情况修改config_tether_upstream_regexsarray.config_tether_wifi_regexs,array.config_tether_usb_regexs

lUsb Tethering支持:

base.core.res.res.values.configs:根据平台实际情况修改array.config_tether_usb_regexs

15.测试

驱动的测试可以借助工具比如wpa_cli当我们改好framework代码后,怎样确保它能工作呢?Android framework针对ConnectivityManagerWifiManager的单元测试,位于core.test.ConnectivityManagerTest中,都是依赖于真实硬件的,模拟器做不了。当我们改了代码后,可以运行这些单元测试来确保我们的改动。

运行WifiConnectionTest命令:

adbshell am instrument-e class\

com.android.connectivitymanagertest.functional.WifiConnectionTest\

-w com.android.connectivitymanagertest/.ConnectivityManagerTestRunner

运行WifiSoftAPTest命令:

adbshell am instrument \

-w com.android.connectivitymanagertest/.ConnectivityManagerUnitTestRunner

详情看代码。

16.调试中遇到的问题

系统中多个Dhcpcd进程存在,经查是setproperty(“ctl.stop”, “dhcpcd_eth0”)不能停掉Dhcpcd进程,以至于下次启动时又会创建新的Dhcpcd进程。最后发现是启动dhcp参数问题导致,应用-B参数不让dpcp以daemon形式运行即可。

更多相关文章

  1. 获取Android设备的方向
  2. Android使用代码实现关机/重启
  3. android的设备永不休眠(增加 Settings-->Dispaly-->-->screenout-
  4. 【知识点】android代码中设置margin
  5. Android蓝牙通信代码
  6. 简单的通过request判断客户端设备类型
  7. Android代码规范

随机推荐

  1. navicat 8 for mysql建库的方法
  2. 将MySQL去重操作优化到极致的操作方法
  3. 监听mysql表内容变化 mysql开启binlog
  4. CentOS7离线安装MySQL的教程详解
  5. Mysql数据库监听binlog的开启步骤
  6. centos7.2下安装mysql5.7数据库的命令详
  7. 如何将Excel文件导入MySQL数据库
  8. MySQL不停地自动重启的解决方法
  9. mysql索引最左原则实例代码
  10. 关于MySQL的sql_mode合理设置详解