为什么要拿手机做路由器?因为我现在每天要带着一个火柴盒大小的路由器(703n)。它提供了一个f了q的无线网络,电脑,手机,平板等设备连接上这个无线网络之后之后就可以自由上twitter,看youtube。但是它还不够理想。,我不希望在拥挤的包里再塞一个设备,我还希望在路上只有3G网络没有USB电源的地方也可以刷刷twitter。最好的设备莫过于手机了。

手机拿来做fq路由器最大的缺陷在于,它不是一个路由器。最开始手机都是处于网络的终端,要么接收3G信号,要么接收wifi信号。后来技术发展之后,手机开始有了无线发射的功能,这个在iphone上叫personal hotspot,在android上叫softap。虽然手机能够发射无线了,但是其还不能承担路由器的功能。手机只要开始发射无线,本来连着的无线网络(上行无线)就会被断开。这样,手机要么只能做客户端,要么只能做无线热点。只有同时做客户端,又做无线热点才能满足手机做fq路由器的要求。有什么办法呢?最直接的办法是,手机用3G上网,然后提供无线热点出来。这个能力基本上现在所有的智能手机都可以做到了。但是3G上网多贵啊。

手机能不能既连着上行无线,又开启无线热点把***环境共享给其他的设备呢?这是我一直以来的一个梦想。如今梦想成真了。今天不谈fq这一块,单独来讲怎么把Android手机变成无线中继路由器。

何为无线中继?前面的描述并不是非常的精确。最精确的关于无线组网的文章是OpenWRT的 一文。我所说的无线中继是文章中的Routed Client Mode - Masqueraded。就是一个设备同时加入两个子网,用iptables的masquerade功能代理一个子网的设备去访问另外一个子网。masquerade一个更常用的名称是NAT。基本上所有的家用无线路由器都是这个模式的网络。

无线中继路由器与普通的家用无线路由器的组网有一个本质不同。普通的无线路由器上行走的一般是ADSL的pppoe,也就是有线网络。下行通过无线热点把有线网络的internet共享给其他设备用。无线中继不同,无线中继的上行是一个无线网络,一般就是家里那个连着猫的无线路由器共享出来的无线热点,而下行是另外一个无线网络。所以,无线中继路由器的配置要比普通的路由器更加麻烦。刷了OpenWRT操作系统的家用无线路由器(比如tplink 703n)可以比较容易的实现无线中继功能,因为OpenWRT自身设计就支持这样一种组网方式,而且其硬件也设计得非常通用(ar71xx)对于使用方式限制很少。一般无线硬件厂商把芯片分为三个等级,比如broadcom就分为手机bcm4334(Galaxy S3), 平板 bcm43241(Nexus 10),以及 固定基础设施(Infrastructure)bcm4360(Asus RT-AC66U)。OpenWRT适用的设备就是属于Infrastructure系列的无线芯片。这些路由器的芯片本来就是专业做无线热点的,所以支持无线中继就不奇怪了。但是手机与平板的无线芯片与这些路由器的无线芯片虽然是同一个厂家的,但是因为使用场合完全不同,支持无线中继就变得非常困难。

所以,虽然Android手机是一个非常理想的***路由器平台,但是仅仅把Android手机变成一个路由器就非常不容易。其间要跨过这么几道坎:

  • 手机无线芯片硬件本身是否支持无线中继
  • 手机的无线芯片使用的固件(运行在无线芯片上的小操作系统)是否支持无线中继
  • 芯片对应的驱动是否支持无线中继
  • Android上相关的启动命令是否在手机上存在
  • 与对应无线芯片相适应的配置无线中继的脚本

=== 用户态 ===脚本VV命令(iw, p2p-cli等) V[Via Netlink Socket]=== 内核态 ===V驱动 (比如bcmdhd)V[Via SDIO]=== 另外一个小机器 ==V固件 (比如fw_bcm4330.bin)VV硬件 (比如bcm4330)

第1、2、3点是你我无法搞定的。如果硬件本身不支持,哪怕是驱动的一个编译参数,普通用户,甚至是开发者都很难搞定。因为Linux的内核与驱动之间没有稳定的ABI,在一个linux上编译好的驱动没有办法拿到另外一个linux上去用。只要原厂的无线驱动不直接支持无线中继,那么哪怕我可以找出修改驱动的方式,要给千千万万种手机,不同的Linux内核配置编译合适的无线驱动简直是一个不可想象的事情。何况很多手机的内核都没有办法自己编译,如果要逼到去无线驱动的份上基本上就属于无解了。

无线芯片的固件是一个平时不会注意的东西。它比无线驱动还要底层。无线驱动只是一个操作木偶的提线人而已,真正干活的其实是无线芯片的固件。这个固件其实一个完整的操作系统,是一个独立的小机器。一个手机里起码有三个完整的机器,每个都有自己的CPU和内存与代码。第一个是显而易见的Android与CPU。第二个是基带(baseband)提供语音通话的。第三个是wifi芯片与其固件。所以,如果手机无线芯片的固件不支持无线中继,基本上也就无解了。因为所有的无线芯片的固件都不是开源的(哪怕对应的驱动是开源的)。而且芯片种类非常多,即便是同一个型号同一个批次的无线芯片,对应的固件都可能有好多种不同的版本(比如有的固件支持wapi,中国的无线标准)。硬件这一块我不是很懂。也许无线芯片真正到了硬件这个层次都差不多,没有什么支持不支持无线中继的问题。

好在我们解决不了的问题,Google可以帮我们解决。Google在Android 4.0中引入了对Wifi Direct的支持。而Wifi Direct就是这帮提供无线硬件设备的厂商搞的标准。于是乎第1、2、3就不成为问题了。手机原厂支持Android 4.0的,基本上都满足了Wifi Direct的标准了,也就很有可能支持无线中继。这个支持意味着:驱动支持,固件支持,硬件支持。我们需要做的,只是把启动的命令与脚本拷贝过来,执行一下就可以了。可以理解为挖掘了一个Android手机本来就支持,只是Android没有提供界面配置的一个“隐藏功能”。

Wifi Direct为什么可以解决无线中继的问题?Wifi Direct其实就是wifi技术的一个用户友好版本的一个封装。其实质就是在你离开无线网络环境的时候,可以用手机临时启动一个无线网络,然后你周围的朋友可以用手机加入你这个临时组建的无线网络,然后双方就可以干传大文件之类的事情了。其相对于蓝牙来说,带宽更大。相对于无线的ad-hoc组网方式更安全。除此之外,wifi direct还允许一个设备同时提供无线热点与做无线客户端。也就是可以在手机自身的无线网不断掉的情况下,通过wifi direct与其他设备传文件。但是这个特性有一个很严重的硬件限制,手机连接着的无线,与启动的无线热点必须是在同一个channel的(无线电频率相同)。这导致在实际使用过程中,两个设备都连接着各自的无线网(channel不同)的时候无法通过wifi direct传文件。这也就导致了很多wifi direct的实现干脆在启动wifi direct模式的时候先把无线网断了。不过Google与这些硬件厂商在设计的时候并不是这么想的。理想的情况是将来的硬件发展到可以支持multi-channel concurrency。就现状而言,原厂支持wifi direct的手机,都可以拿来做无线中继。

虽然wifi direct可以用来支持无线中继。但并不代表无线中继的唯一实现方式就是通过wifi direct的命令。家用无线路由器刷了OpenWRT之后也可以做无线中继。我们也没有看见这些路由器支持wifi direct啊。那是因为这些路由器的无线芯片支持linux 的 mac80211,简单来说就是用软件来管理无线芯片,无线芯片不用管太多,软件说发什么frame就发什么frame。那么手机上的无线芯片有支持mac80211的吗?还真有,那就是wl12xx系列(德州仪器TI出品)。比如wl1271, 这个芯片可比Android 4早很多了。当年红极一时的摩托罗拉里程碑用的就是这个芯片。但是遗憾的是,芯片与固件支持是不够的,还需要给力的驱动。wl12xx的mac80211驱动是比较晚的事情了,早期使用的驱动tiwlan_drv并不支持mac80211。所以除非有人愿意把新的wl12xx驱动backport给早期的手机,比如摩托罗拉里程碑,否则这些老手机是没法做无线中继的。不过新出的使用wl12xx系列芯片的设备都使用的是新的wl12xx驱动,比如说kindle fire。这些新设备不但支持无线中继无压力,甚至还可能可以用来做无线破解等更有意思的事情。

OK,我们现在已经了解到了大概的一个前提条件。要么手机原厂支持wifi direct,要么手机使用的无线网卡驱动是mac80211的。那么究竟这个配置过程是怎样的呢?这个就要分不同平台来说了。主流的手机无线芯片有四个系列(这个列表通过人工爬虫爬CM的github源代码库

  • 博通系(bcm):bcm4325, bcm4329, 【bcm4330, bcm4334, bcm43214】。
  • 德仪系(wl):【wl1271 等,统称wl12xx】
  • 山寨系(mtk):【mt6620,mt6628】
  • 高通系: wcn1312, wcn1314, ar6002, ar6003, 【wcn3660,未测试】

这四个系列中,前三个我都亲测可用的,高通系只有最新的平台(比如nexus 4用的那个)才有可能支持无线中继,因为设备还比较贵所以我没有买来测。在【】中的芯片是测试可用的,【】之外是希望比较渺茫的。

bcm与mtk的无线中继启动方式都是用wifi direct的命令。而wl的无线中继用的是mac80211的方法。高通系的启动方式我猜可能会与bcm4330的非常类似。无论是用哪种方式,过程原理都是类似的:

  • 无论用什么手段,搞出两个wifi interface,比如说默认都有一个wlan0的网卡,再弄一个ap0之类的出来
  • 保持wlan0的无线连接不动,想办法在新添加的wifi interface上启动一个无线热点
  • 给ap0配置本机的IP地址
  • 启动DHCP服务器,监听ap0,给连进来客户端分配IP地址
  • 设置本机的iptables规则(masquerade),让通过ap0连进来的客户端可以从wlan0走出去上网

目前的现状是,MTK的手机在我心目中已经把703n这样的迷你路由器pk下去了。比如说我现在用的联想P770手机,不过一千出头的售价,4.5的屏幕,有3500毫安时的电池,双卡双待,这本来已经够性价比的了。现在再加上一个无线中继当路由器,将来软件支持上来了,还可以做***路由器。拿着这样的一个手机怎么有点美军单兵武器的感觉。

Android手机做无线中继路由器的更多相关文章

  1. Android手机间无线互传功能探索及实现

    年前研究了一下Android如何实现无线互传的功能,写了个小demo,最近无事,遂整理一下,与各位共享.前期调研发现,Android想要实现无线互传有以下几种技术:1,Bluetooth通行已久,简单 ...

  2. 提升网速的路由器优化方法(UPnP、QoS、MTU、交换机模式、无线中继)

    在上一篇<为什么房间的 Wi-Fi 信号这么差>中,猫哥从微波炉.相对论.人存原理出发,介绍了影响 Wi-Fi 信号强弱的几大因素,接下来猫哥再给大家介绍几种不用升级带宽套餐也能提升网速的 ...

  3. Android 手机 无线 ADB

    要用网络调试Android需要设备已经获取root权限 如果手机没有命令行工具,请先在手机端安装终端模拟器,然后在终端输入: $su #stop adbd #setprop service.adb.t ...

  4. 路由器桥接(WIFI无线中继)设置及摆放位置图解

    路由器桥接(WIFI无线中继)设置及摆放位置图解 WIFI实在好用,但它的波覆盖面小.穿透力很差.我们安装时要考虑波的衍射特点,装在衍射效果最佳的位置(居中,室外可绕,避开密封墙).确实无法兼顾的地方 ...

  5. 将Android手机无线连接到Ubuntu实现唱跳Rap

    您想要将Android设备连接到Ubuntu以传输文件.查看Android通知.以及从Ubuntu桌面发送短信 – 你会怎么做?将文件从手机传输到PC时不要打电话给自己:使用GSConnect就可以. ...

  6. Android手机便携式wifi的使用及无线数据传输(主要针对XP系统)

    适用条件: 1.可以上网的安卓系统2.2以上的智能手机,或有便携式wifi功能的安卓智能手机 2.有无线网卡的笔记本电脑或台式机(特别是XP系统) 测试手机:中兴U930 电脑:华硕K50系列笔记本 ...

  7. 强烈鄙视那些:自己完全不用android手机,却在做android开发的人

    前言: 最近参加android技术交流会,看到几个同时用mac和iphone的人,以为他们是全栈工程师(android和ios都会) , 谁知道交流下来,居然只是做android开发的,ios根本不会 ...

  8. adb无线连接android手机进行调式,无需获得root权限

    利用adb无线连接android手机进行调式 无需获得root权限 转载来自CSDN  https://blog.csdn.net/lnking1992/article/details/5346518 ...

  9. Android手机用KSWEB搭建Web服务器成功安装WordPress

    之前部落分享的几个免费Web服务器软件都是用来安装在本地电脑上,搭建Apache.PhpMyAdmin.MySQL等网站运行环境,然后我们就可以在电脑上测试运行Wordpress.Discuz! 论坛 ...

随机推荐

  1. XML 命名空间

    XML 命名空间 一.XML命名冲突 在 XML 中,元素名称是由开发者定义的,当两个不同的文档使用相同的元素名时,就会发生命名冲突. 这个 XML 文档携带着某个表格中的信息: <table& ...

  2. Linux Centos 7 使用yum安装 mysql5.7 (实验成功)

    第一部分:安装Mysql5.7 1.下载YUM库 shell > wget http://dev.mysql.com/get/mysql57-community-release-el7-7.no ...

  3. Linux与Windows文件传输实现

    Linux与Windows文件传输实现 一.概述 在学习Linux服务器的时候,我们有时需要与Windows下的文件进行交互传输,这个时候我们需要如何实现呢?今天是我第一次在博客园上写文章,此时正值学 ...

  4. ASP-----分页功能的实现

    WEB 分页功能的实现后端C#代码部分: // 建立Linq 数据库的连接 private MYDateDataContext context = new MYDateDataContext(); / ...

  5. 关于ios项目沙盒中的文件和Xcode项目创建的文件

    //1.1获取在Xcode项目打开的情况下创建的Plist文件 NSString *path = [[NSBundle mainBundle]pathForResource:@"Profes ...

  6. TortoiseSVN 更新时忽略指定文件夹

    命令行可以这么来svn update –set-depth=exclude 文件夹 那么TortoiseSVN客户端呢?在文件夹右键中的”更新至版本(U)”更新深度选”排除”,确定,搞定下次更新就不会 ...

  7. EasyPusher推流服务接口的.NET导出

    本文是在使用由 EasyDarwin 团队开发的EasyPusher时导出的C++接口的.NET实现 public class EasyPushSDK { public EasyPushSDK() { ...

  8. PHP和CS的引用传值

    PHP的引用传值 function change_value($num){ $num+=2; } $age = 3; change_value(&$age); echo $age; CS的引用 ...

  9. ASP.NET缓存全解析4:应用程序数据缓存 转自网络原文作者李天平

    System.Web.Caching 命名空间提供用于缓存服务器上常用数据的类.此命名空间包括 Cache 类,该类是一个字典,您可以在其中存储任意数据对象,如哈希表和数据集.它还为这些对象提供了失效 ...

  10. dispatch_async 子线程,主线程的简单用法

    子线程的使用方法: dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{ //子线程的处理逻辑 ...