Brillo: 使用iw命令设置无线网卡工作模式

在Brillo系统中,提供了iw这个命令,可以对无线网卡进行配置,设置WiFi的工作模式AP(接入点模式,相当于一个无线路由器,SoftAP)或者是STA模式。apmanager需要一个WiFi HAL层模块,对WiFi的工作模式进行切换。(device/generic/brillo/wifi_driver_hal/README)。

从相关的代码来看,各家实现的方式都不太一样:

  • Intel – Edision的实现方式

相关的代码在hardware/bsp/intel/peripheral/wifi/bcm43340/bcm43340_hal.cpp

从代码上看,实现方式是先往kernel结点中写入对应的firmware, 再重启一下WiFi对应的网口(wlan0)。

 

  • Qualcomm – Dragonboard的实现方式

相关的代码在:hardware/bsp/qcom/peripheral/wifi/wcn3620/wifi_driver_hal_qcwcn.cpp

从代码上看,只需要往/sys/module/wlan/parameters/con_mode写入工作模式就可以了。相对来说简单了一点。

 

  • RPi 2B – rtl8188cu的实现方式 (目前SoftAP模式还不能正常工作)

相关的代码在:device/hzak/rpi/bsp/rtl8192cu/rtl8192cu_hal.cpp

参考相关的文档,使用命令进行切换(SoftAP模式):

$ ifconfig wlan0 down
$ iw dev wlan0 del
$ iw phy phy0 interface add wlan0 type __ap
$ ifconfig wlan0 up

切换成STA模式:

$ ifconfig wlan0 down
$ iw dev wlan0 del
$ iw phy phy0 interface add wlan0 type station
$ ifconfig wlan0 up

设置完后再通过iw查看:

$ iw dev wlan0 info

本来想用最简单的方法来实现HAL层:

static wifi_driver_error wifi_driver_set_mode_rtl8192cu(
        wifi_driver_mode mode, char* wifi_device_name, size_t wifi_device_name_size) {
    system("/system/bin/ifconfig wlan0 down");
    switch (mode) {
    case WIFI_MODE_AP:
        system("/system/bin/iw phy phy0 interface add wlan0 type __ap");
        break;

    case WIFI_MODE_STATION:
        system("/system/bin/iw phy phy0 interface add wlan0 type station");
        break;
    }
     system("/system/bin/ifconfig wlan0 up");
    // ...
}

由于SELinux的存在,程序运行的时候给了很多的警告。由于有iw(external/iw)的源代码,分析了一下,当iw编译成静态库最终编译进HAL模块问题也不大,于是改写的相关的代码。需要注意的是,连接成动态库的时候,要将iw所有的section编译进去(LOCAL_WHOLE_STATIC_LIBRARIES := libiw):

include $(CLEAR_VARS)

LOCAL_CFLAGS += -Wno-unused-parameter
LOCAL_LDFLAGS := -Wl,--no-gc-sections
LOCAL_C_INCLUDES += device/generic/brillo/wifi_driver_hal/include
LOCAL_WHOLE_STATIC_LIBRARIES := libiw
LOCAL_STATIC_LIBRARIES := libnl
LOCAL_SHARED_LIBRARIES := libcutils
LOCAL_SRC_FILES := rtl8192cu_hal.cpp
LOCAL_MODULE := $(WIFI_DRIVER_HAL_MODULE)
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_MODULE_TAGS := optional

include $(BUILD_SHARED_LIBRARY)

原因是iw对所有的命令的定义都放在了特定的section里了,从external/iw/iw.h中可以看到:

#define __COMMAND(_section, _symname, _name, _args, _nlcmd, _flags, _hidden, _idby, _handler, _help, _sel)\
    static struct cmd                       \
    __cmd ## _ ## _symname ## _ ## _handler ## _ ## _nlcmd ## _ ## _idby ## _ ## _hidden\
    __attribute__((used)) __attribute__((section("__cmd"))) = { \
        .name = (_name),                    \
        .args = (_args),                    \
        .cmd = (_nlcmd),                    \
        .nl_msg_flags = (_flags),               \
        .hidden = (_hidden),                    \
        .idby = (_idby),                    \
        .handler = (_handler),                  \
        .help = (_help),                    \
        .parent = _section,                 \
        .selector = (_sel),                 \
    }

编译后可以用arm-linux-androideabi-objdump查看(可以看到__cmd有0x1040字节):

$ arm-linux-androideabi-objdump -h out/target/product/rpi/symbols/system/bin/iw 

out/target/product/rpi/symbols/system/bin/iw:     file format elf32-littlearm

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .interp       00000013  00000154  00000154  00000154  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .note.android.ident 00000018  00000168  00000168  00000168  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .note.gnu.build-id 00000020  00000180  00000180  00000180  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .dynsym       00000790  000001a0  000001a0  000001a0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .dynstr       0000050a  00000930  00000930  00000930  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .gnu.hash     000000e8  00000e3c  00000e3c  00000e3c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .gnu.version  000000f2  00000f24  00000f24  00000f24  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .gnu.version_r 00000070  00001018  00001018  00001018  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  8 .rel.dyn      00002508  00001088  00001088  00001088  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  9 .rel.plt      000002b8  00003590  00003590  00003590  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 10 .plt          00000428  00003848  00003848  00003848  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 .text         00015e6c  00003c70  00003c70  00003c70  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 12 .ARM.exidx    00000e58  00019adc  00019adc  00019adc  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 13 .rodata       0000af6c  0001a940  0001a940  0001a940  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 14 .ARM.extab    000000f8  000258ac  000258ac  000258ac  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 15 .data.rel.ro.local 000013ec  00027910  00027910  00026910  2**4
                  CONTENTS, ALLOC, LOAD, DATA
 16 .preinit_array 00000008  00028cfc  00028cfc  00027cfc  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 17 .init_array   0000001c  00028d04  00028d04  00027d04  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 18 .fini_array   0000000c  00028d20  00028d20  00027d20  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 19 .dynamic      00000118  00028d2c  00028d2c  00027d2c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 20 .got          000001b8  00028e48  00028e48  00027e48  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 21 .data         00000c0c  00029000  00029000  00028000  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 22 __cmd         00001040  00029c0c  00029c0c  00028c0c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 23 .bss          00000210  0002ac50  0002ac50  00029c50  2**3
                  ALLOC
 24 .comment      00000049  00000000  00000000  00029c4c  2**0
                  CONTENTS, READONLY
 25 .debug_str    0000f5b4  00000000  00000000  00029c95  2**0
                  CONTENTS, READONLY, DEBUGGING
 26 .debug_loc    0001a514  00000000  00000000  00039249  2**0
                  CONTENTS, READONLY, DEBUGGING
 27 .debug_abbrev 000061ef  00000000  00000000  0005375d  2**0
                  CONTENTS, READONLY, DEBUGGING
 28 .debug_info   00031efa  00000000  00000000  0005994c  2**0
                  CONTENTS, READONLY, DEBUGGING
 29 .debug_ranges 00003b80  00000000  00000000  0008b846  2**0
                  CONTENTS, READONLY, DEBUGGING
 30 .debug_pubnames 0000671e  00000000  00000000  0008f3c6  2**0
                  CONTENTS, READONLY, DEBUGGING
 31 .debug_pubtypes 00005613  00000000  00000000  00095ae4  2**0
                  CONTENTS, READONLY, DEBUGGING
 32 .debug_frame  0000417c  00000000  00000000  0009b0f8  2**2
                  CONTENTS, READONLY, DEBUGGING
 33 .debug_line   00011ff3  00000000  00000000  0009f274  2**0
                  CONTENTS, READONLY, DEBUGGING
 34 .debug_aranges 00000160  00000000  00000000  000b1268  2**3
                  CONTENTS, READONLY, DEBUGGING
 35 .note.gnu.gold-version 0000001c  00000000  00000000  000b13c8  2**2
                  CONTENTS, READONLY
 36 .ARM.attributes 00000038  00000000  00000000  000b13e4  2**0
                  CONTENTS, READONLY

虽然做了这么多的努力,但还是只能使STA模式正常工作,SoftAP还是不能正常工作。

参考文档:

  1. https://wireless.wiki.kernel.org/en/users/documentation/iw
  2. https://wiki.archlinux.org/index.php/Software_access_point
  3. https://wiki.archlinux.org/index.php/Wireless_network_configuration

《Brillo: 使用iw命令设置无线网卡工作模式》有5个想法

    1. 请看这篇文档(命令行的做法):http://www.brobwind.com/archives/179
      后续会在Android客户端加上这个功能。

发表评论

电子邮件地址不会被公开。 必填项已用*标注