Android KitKat 4.4 Wifi移植之AP模式与网络共享功能调试记录

Tethering技术在移动平台上已经运用的越来越广泛了,它可以把移动设备当做一个接入点,其它的设备可以通过Wi-Fi,USB或是Bluetooth等方式连接到此移动设备。在Android中可以将Wifi设为AP模式作为WLAN接入点,从而与其他设备共享Android的互联网连接。Android成为接入点后,就无法通过WLAN连接使用Android的应用程序访问互联网,但可以通过其他方式如以太网或移动网络访问互联网。此时以太网或移动网络在网络共享(Tethering)中是作为upstream的角色。

最近在Atmel的SAMA5D3-EK开发板上调试Wifi模块,需要在Android下实现Tethering,通过Wi-Fi的AP模式,将网络连接共享给其它设备。

开发板上一个有线网卡(eth0),一个无线网卡(wlan0),eth0连接到外网,wlan0作为AP共享给其他设备比如Android手机,使得Android手机可以通过开发板连接到外网。

硬件平台:Atmel SAMA5

软件平台:Linux 3.10 +Android 4.4

Wifi模组:RTL8723AU(USB接口)

因为使用的内核是厂商基于主线内核开发的,虽然主线内核中加入了Android的基本支持,但并不完全。在做Android移植时,如果发现Android上层的某些功能缺乏内核的支持,可以根据Google维护的AndroidLinux内核将相应的更改应用到厂商Linux内核中,在前文《Android KitKat 4.4平台开发-添加USBADB和MTP功能支持》中就是使用的这种方法。

整个Wifi移植过程,Wifi模组厂商Realtek给出了详细的过程,但内容只涉及Wifi驱动及Android部分,使用哪个Linux内核以及内核如何配置需要我们自己决定。

按照Realtek提供的移植文档进行AndroidWifi的移植,在测试Wifi
网络共享功能时出现如下问题:

在“设置”程序“网络共享与便携式热点”中,打开“便携式Wi-Fi热点”,并没有真正开启Wifi热点,而是相应单选框不断关开,如此反复。

对于在测试Android功能时出现的异常情况,一般在log中会存在相应的错误信息,虽然并不是绝对准确,但调试时应该考虑先分析log信息,尝试从中定位导致异常发生的代码位置。

经过一番分析推测,如下高亮显示的log信息很有可能是诱发异常发生的关键代码点。

V/NatController(972): enableNat(intIface=<wlan0>, extIface=<eth0>)

V/NatController(972): runCmd(/system/bin/iptables -t nat -A natctrl_nat_POSTROUTING -o eth0 -jMASQUERADE) res=0

V/NatController(972): runCmd(/system/bin/iptables -A natctrl_FORWARD -i eth0 -o wlan0 -m state--state ESTABLISHED,RELATED -g natctrl_tether_counters) res=0

D/dalvikvm(1339): GC_CONCURRENT freed 373K, 54% free 6723K/14460K, paused 44ms+14ms, total219ms

V/NatController(972): runCmd(/system/bin/iptables -A natctrl_FORWARD -i wlan0 -o eth0 -m state--state INVALID -j DROP) res=0

V/NatController(972): runCmd(/system/bin/iptables -A natctrl_FORWARD -i wlan0 -o eth0 -gnatctrl_tether_counters) res=0

V/NatController( 972): runCmd(/system/bin/iptables-A natctrl_tether_counters -i wlan0 -o eth0 -m quota2 --name wlan0_eth0 --grow-j RETURN) res=1

V/NatController(972): runCmd(/system/bin/iptables -D natctrl_FORWARD -i wlan0 -o eth0 -m state--state INVALID -j DROP) res=0

V/NatController(972): runCmd(/system/bin/iptables -D natctrl_FORWARD -i eth0 -o wlan0 -m state--state ESTABLISHED,RELATED -g natctrl_tether_counters) res=0

E/NatController( 972): Error setting forward rules

V/NatController(972): runCmd(/system/bin/iptables -F natctrl_FORWARD) res=0

V/NatController(972): runCmd(/system/bin/iptables -A natctrl_FORWARD -j DROP) res=0

http://androidxref.com/4.4.2_r1/xref/system/netd/NatController.cpp#294

256int
NatController::setTetherCountingRules(bool
add, const char *intIface, const char *extIface) {

257

258   
/* We only ever add tethering quota rules so thatthey stick. */

259    if (!add) {

260        return 0;

261    }

262    char *quota_name,
*proc_path;

263    int
quota_fd;

264   
asprintf(&quota_name,
"%s_%s", intIface, extIface);

265

266   
asprintf(&proc_path,
"/proc/net/xt_quota/%s",
quota_name);

267   
quota_fd = open(proc_path,
O_RDONLY);

268    if (quota_fd
>= 0) {

269       
/* quota for iface pair already exists*/

270       
free(proc_path);

271       
free(quota_name);

272        return 0;

273    }

274   
close(quota_fd);

275   
free(proc_path);

276

277    const char *cmd2b[]
= {

278           
IPTABLES_PATH,

279           
"-A",

280           
LOCAL_TETHER_COUNTERS_CHAIN,

281           
"-i",

282           
intIface,

283           
"-o",

284           
extIface,

285           
"-m",

286           
"quota2",

287           
"--name",

288           
quota_name,

289           
"--grow",

290           
"-j",

291         
"RETURN"

292    };

293

294    if (runCmd(ARRAY_SIZE(cmd2b),
cmd2b) && add) {

295       
free(quota_name);

296        return -1;

297    }

298   
free(quota_name);

299

300   
asprintf(&quota_name,
"%s_%s", extIface, intIface);

301   
asprintf(&proc_path,
"/proc/net/xt_quota/%s",
quota_name);

302   
quota_fd = open(proc_path,
O_RDONLY);

303    if (quota_fd
>= 0) {

304       
/* quota for iface pair already exists*/

305       
free(proc_path);

306       
free(quota_name);

307        return 0;

308    }

309   
close(quota_fd);

310   
free(proc_path);

311

分析这个函数NatController::setTetherCountingRules及log信息,推断出异常发生的原因是执行命令

/system/bin/iptables -A natctrl_tether_counters -i wlan0 -o eth0 -mquota2 --name wlan0_eth0 --grow -j
失败。

而且还涉及到路径/proc/net/xt_quota/,但当前系统下并不存在这个路径。由此推断应该是内核缺乏与quota2或xt_quota相关的支持。

找到问题的可能原因,接下来就是验证了。比较Android Linux内核、厂商Linux内核以及主线Linux内核网络部分的差异,发现Android
Linux内核在主线Linux内核基础上增加了quota2的支持。涉及四次提交

$git log --name-only net/netfilter/xt_quota2.cinclude/linux/netfilter/xt_quota2.h net/netfilter/Kconfignet/netfilter/Makefile

commit7d89969ad270d4c535e33830188806233bf35442

Author:Greg Hackmann <[email protected]>

Date:Mon Feb 24 09:39:46 2014 -0800

netfilter: xt_qtaguid: 64-bit warning fixes

Change-Id:I2adc517c0c51050ed601992fa0ea4de8f1449414

Signed-off-by: Greg Hackmann<[email protected]>

net/netfilter/xt_quota2.c

commit73570fe76d3b47e669558f06f1a18e0f02dff606

Author:Arve Hj?nnev?g
<[email protected]>

Date:Mon May 13 20:42:46 2013 -0700

netfilter: xt_quota2: 3.10 fixes.

- Stop using obsolete create_proc_entry api.

- Use proc_set_user instead of directlyaccessing the private structure.

Signed-off-by: Arve Hj?nnev?g<[email protected]>

net/netfilter/xt_quota2.c

commitea34f99edb73b67ef0a99d304887c64febd4c878

Author:JP Abgrall <[email protected]>

Date:Tue Jul 12 12:02:59 2011 -0700

netfilter: fixup the quota2, and enable.

The xt_quota2 came from

http://sourceforge.net/projects/xtables-addons/develop

It needed tweaking for it to compile withinthe kernel tree.

Fixed kmalloc() and create_proc_entry()invocations within

a non-interruptible context.

Removed useless copying of current quotaback to the iptable‘s

struct matchinfo:

- those are per CPU: they will changerandomly based on which

cpu gets to update the value.

- they prevent matching a rule: e.g.

-A chain -m quota2 --name q1 --quota 123

can‘t be followed by

-D chain -m quota2 --name q1 --quota 123

as the 123 will be compared to the structmatchinfo‘s quota member.

Use the NETLINK NETLINK_NFLOG family to loga single message

when the quota limit is reached.

It uses the same packet type as ipt_ULOG,but

- never copies skb data,

- uses 112 as the event number (ULOG‘s +1)

It doesn‘t log if the module param"event_num" is 0.

Change-Id:I021d3b743db3b22158cc49acb5c94d905b501492

Signed-off-by: JP Abgrall<[email protected]>

net/netfilter/Kconfig

net/netfilter/Makefile

net/netfilter/xt_quota2.c

commit3db08b39ea752748744e9c7733ce9ef54bed9f3b

Author:JP Abgrall <[email protected]>

Date:Tue Jun 21 11:14:49 2011 -0700

netfilter: adding the original quota2 fromxtables-addons

The original xt_quota in the kernel is plainbroken:

- counts quota at a per CPU level

(was written back when ubiquitous SMP wasjust a dream)

- provides no way to count across IPV4/IPV6.

This patch is the original unaltered codefrom:

http://sourceforge.net/projects/xtables-addons

at commite84391ce665cef046967f796dd91026851d6bbf3

Change-Id:I19d49858840effee9ecf6cff03c23b45a97efdeb

Signed-off-by: JP Abgrall<[email protected]>

include/linux/netfilter/xt_quota2.h

net/netfilter/xt_quota2.c

提取quota2相关的commit,制作补丁

$ git format-patch -n4 net/netfilter/xt_quota2.c include/linux/netfilter/xt_quota2.hnet/netfilter/Kconfig net/netfilter/Makefile

0001-netfilter-adding-the-original-quota2-from-xtables-ad.patch

0002-netfilter-fixup-the-quota2-and-enable.patch

0003-netfilter-xt_quota2-3.10-fixes.patch

0004-netfilter-xt_qtaguid-64-bit-warning-fixes.patch

将这些补丁应用到厂商Linux内核
(git am命令)

在内核配置中增加quota2支持

commit4e6bf851ffd340f83062d053a6a20d358def121e

Author:Max Liao <[email protected]>

Date:Mon Jun 16 06:08:25 2014 -0400

ARM: at91/SAMA5: android_ubifs_defconfig:add netfilter quota2 support for sama5d3 and sama5d4

Signed-off-by: Max Liao<[email protected]>

diff--git a/arch/arm/configs/sama5_android_ubifs_defconfigb/arch/arm/configs/sama5_android_ubifs_defconfig

index9881f7d..48c68a1 100644

---a/arch/arm/configs/sama5_android_ubifs_defconfig

+++b/arch/arm/configs/sama5_android_ubifs_defconfig

@@-623,6 +623,7 @@ CONFIG_NETFILTER_XT_MATCH_OSF=y

CONFIG_NETFILTER_XT_MATCH_OWNER=y

CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y

CONFIG_NETFILTER_XT_MATCH_QUOTA=y

+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y

CONFIG_NETFILTER_XT_MATCH_RATEEST=y

CONFIG_NETFILTER_XT_MATCH_REALM=y

CONFIG_NETFILTER_XT_MATCH_RECENT=y

编译内核。

测试Wifi
网络共享功能,之前的异常现象消失,功能测试正常,这说明之前的推导猜测是正确的,异常的原因的确是内核缺乏netfilter quota2支持。

Android KitKat 4.4 Wifi移植之AP模式与网络共享功能调试记录,布布扣,bubuko.com

时间: 2024-12-25 03:34:24

Android KitKat 4.4 Wifi移植之AP模式与网络共享功能调试记录的相关文章

Android KitKat 4.4 Wifi移植之Wifi driver

本文讲述在Linux 3.10下Realek RTL8723A Linux Wifi 驱动的移植. Prerequisites 硬件平台:Atmel SAMA5 软件平台:Linux 3.10 + Android 4.4 Wifi模组:RTL8723AU (USB接口) Realtek RTL8723A Wi-Fi Software& Driver for Linux and Android RTL8723A_WiFi_linux_v4.1.6_7336.20130426_CCC02.zip 文

第1章 Android系统的编译和移植实例:

第一章 本章Android系统的编译和移植实例,其中移植涉及的主要内容有下载Android Linux内核,安装交叉工具链,移植Android Linux内核支持EZ6410平台,安装Android SDK,获得Android根文件系统,设置系统环境,完成Android正常启动.安装交叉工具链在ldd6410-read-only目录下修改vim.cross_compile内容为:/usr/local/arm/arm-none-Linux-gnueabi/bin/arm-none-linux-gu

Android开发实践:WIFI连接功能的封装

在上一篇文章<Android开发实践:WIFI扫描功能的封装>介绍了如何利用Andriod的API实现WIFI的扫描,本文则重点讲述一下如何连接WIFI吧,在此,也给出一个封装WIFI连接过程的类,提供简单的接口以供在各个代码工程中复用. 与WIFI扫描类似,WIFI的连接同样是一个耗时的过程,所以需要放到线程中执行,通过回调来通知调用者连接结果.该回调接口的定义如下: public interface WifiConnectListener { public void OnWifiConne

第一章 Android系统的编译和移植实例

第一章 Android系统的编译和移植实例 这一章节主要介绍了Android系统的编译和移植技术,作为建立在Linux内核的基础上的Android操作系统,它的编译和移植不论在过程还是技术方面都和嵌入式Linux非常相似. 首先要准备一套可以正常运行Linux系统的一套开发版,需要在其移植Android系统,并能够正常运行. 移植的主要过程为: 1.下载Android Linux 内核 2.安装交叉工具链 3.移植Android Linux 内核支持的平台 4.安装Android SDK 5.获

学习第一章 Android系统的编译和移植实例后的心得体会

说起来,去年在岳老师的带领下就接触了嵌入式系统的编译和移植.而现在我们又开始接触Android系统的编译和移植.第一章主要介绍安卓系统的编译和移植技术.其实安卓和嵌入式非常相似. 安卓 移植涉及的主要过程大致分为六步:1.下载安卓linux内核. 2.安装交叉工具链.3.移植安卓linux内核支持EZ6410平台.4.安装安卓SDK.4.获得安卓根文件系统.5.设置系统环境,完成安卓正常启动.虽然步骤不多,但是涉及了很多东西.在开始内核移植之前,先完成工具链的搭建.在移植过程中会发现硬件差异.差

Android KitKat 4.4平台开发-添加USB ADB和MTP功能支持

ADB和MTP是Android基于USB实现的两个重要功能,极大地方便了用户在PC与Android设备之间的互操作,比如传输文件.安装应用.开发调试应用. 本文讲述如何在特定软硬件平台下支持Android ADB和MTP功能. Android版本: KitKat 4.4.2 Linux内核版本: 3.10 (Vendor Kernel) 硬件平台: Atmel SAMA5D3 SoC 针对Linux内核的更改 Merge Android Linux内核USB Gadget驱动到处理器厂商Linu

Android 广播监听wifi

第一步:配置AndroidManifest.xml,在application结点下面添加如下代码 <receiver android:name=".NetworkConnectChangedReceiver" > <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> <action android:name="a

解决Android 6.0获取wifi Mac地址为02:00:00:00:00:00问题【转】

本文转载自:http://www.jb51.net/article/128398.htm 这篇文章主要介绍了Android 6.0获取wifi Mac地址为02:00:00:00:00:00的解决方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下 前言: 之前项目比较旧,手机版本还比较低,还使用eclipse开发.用到了需要获取手机wifi Mac地址.使用了如下代码: // Android 6.0之前的版本可以用的方法(模拟器可以使用) private String getMacAddrO

WIFI模块开发教程之W600网络篇1:AP模式下TCP Client通信

前言 本文研究如何在AP模式下进行TCP Client通信,所谓AP模式是说模块起来一个softAP热点,可以供其他WIFI设备连接,当其他设备连接成功后,另WIFI模块作为客户端,局域网中其他设备作为服务端进行TCP数据通信. 一.理论基础 本节要处理的有两个问题,其一是如何利用RT_Thread起来一个softAP,其二是如何使用Socket套接字编程搞定TCP Client程序编写. 1.模块开启SoftAP 模块需要起来一个名字为sand,密码为12345678的热点,RT_Thread