編輯:關於Android編程
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=
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("a_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("a_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
Date:Mon Feb 24 09:39:46 2014 -0800
netfilter: xt_qtaguid: 64-bit warning fixes
Change-Id:I2adc517c0c51050ed601992fa0ea4de8f1449414
Signed-off-by: Greg Hackmann
net/netfilter/xt_quota2.c
commit73570fe76d3b47e669558f06f1a18e0f02dff606
Author:Arve Hj?nnev?g
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
net/netfilter/xt_quota2.c
commitea34f99edb73b67ef0a99d304887c64febd4c878
Author:JP Abgrall
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
net/netfilter/Kconfig
net/netfilter/Makefile
net/netfilter/xt_quota2.c
commit3db08b39ea752748744e9c7733ce9ef54bed9f3b
Author:JP Abgrall
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
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
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
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編程實現的重力感應效果。分享給大家供大家參考,具體如下:android中的很多游戲的游戲都使用了重力感應的技術,就研究了一下重力感應以屏幕的左
搜索框上下滑動變透明度是現在APP中很常見的效果,先看看效果:首先來看下布局骨架:<RelativeLayout xmlns:android=http://sche
ES文件浏覽器連接電腦顯示登錄失敗。之前在連著電腦看著電視,不知道手機怎麼了,現在連接不上,還顯示登錄失敗。現在不知道怎麼辦。小編來給大家演示一下,當ES浏
board_init_r 函數中,兩個重要的過程就是 norflash 的識別和 nandflash 的識別,norflash 的識別過程以及如何移植前邊已經分析過,本文