2. SoftapCmd命令


2014-05-23 16:16:41      我来说两句 
收藏     我要投稿   
本书是经典畅销书深入理解Android系列的新作,由资深Android系统专家邓凡平先生撰写。从通信专业知识和Android系统代码实现的角度,对Netd、Wi-Fi、NFC和GPS等模块的代码进行深入的剖析,旨在深刻揭示其实现原理   立即去当当网订购

Softap命令和Wi-Fi有紧密关系。本节先简单介绍Soft AP相关的背景知识,后续章节将对Wi-Fi开展深入讨论。

(1)背景知识介绍

Soft AP代表通过软件实现Access Point的功能。那么AP是什么?AP和Soft AP有什么不同?
在Wi-Fi无线技术规范中,AP和Station是其中的两个基本概念。

从功能角度来看,AP作为基站设备,起着连接其他无线设备到有线网的作用,相当于有线网络中的HUB与交换机。在日常工作和家庭中经常使用的无线路由器就是一个AP。一般情况下,它一端接着有线网络,另一端连接其他无线设备。

Station代表配备无线网络接口的设备,如手机、笔记本等。

虽然AP和Station是两个不同的设备,但实际上在Station中用软件也能实现AP拥有的功能,如桥接、路由等。在基本功能上,Soft AP与AP并没有太大的差别,只是Soft AP设备的接入能力和覆盖范围不如AP。

以前面提到的高铁列车上的应用场景为例,除了用USB绑定外,还可以打开笔记本和手机的Wi-Fi,并启动手机的Soft AP功能。这样,手机一方面用3G接入互联网,另一方面又利用Soft AP向笔记本提供Wi-Fi接入功能。

在Android系统中使用Soft AP功能还得借助另一个开源软件“hostapd”,这是一个运行在用户空间的用于AP和认证服务器的守护进程。它实现了IEEE 802.11相关的接入管理、IEEE 802.1X/WPA/WPA2/EAP 认证、RADIUS客户端、EAP服务器和RADIUS认证服务器。

(2)SoftapCmd命令使用

和TetherCmd类似,开启Android中手机的Soft AP功能将涉及大量Framework层中的操作,本节仅关注和Netd相关的三个步骤。

1)首先为Wi-Fi加载不同的固件(Firmware),这是通过SoftapController的fwReloadSoftap函数完成的,代码如下所示。
[-->SoftapController.cpp::fwReloadSoftap]
int SoftapController::fwReloadSoftap(int argc, char *argv[])
{
    int ret, i = 0;
    char *iface;
    char *fwpath;

   ......// 参数检测
    iface = argv[2];
    if (strcmp(argv[3], "AP") == 0) {
        fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_AP);
    } else if (strcmp(argv[3], "P2P") == 0) {
        fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_P2P);
    } else {
        fwpath = (char *)wifi_get_fw_path(WIFI_GET_FW_PATH_STA);
    }
    // 通过往/sys/module/wlan/parameters/fwpath文件中写入固件名
    // 触发驱动去加载对应的固件
    ret = wifi_change_fw_path((const char *)fwpath);
    ......
    return ret;
}

上面这段代码表示在Android中,如果要让Wi-Fi无线设备扮演不同的角色,得为它们加载不同的固件(Firmware),具体说明如下。

WIFI_GET_FW_PATH_AP:代表Soft AP功能的固件,其对应的文件位置由WIFI_DRIVER_FW_PATH_AP宏表达。三星Tuna平台中,该文件位置为/vendor/firmware/fw_bcmdhd_apsta.bin。

WIFI_GET_FW_PATH_P2P:代表P2P功能的固件,其对应的文件位置由WIFI_DRIVER_FW_PATH_P2P宏表达。三星Tuna平台中,该文件位置为/vendor/firmware/ fw_bcmdp2p.bin。

WIFI_GET_FW_PATH_STA:代表Station功能的固件,其对应的文件位置由WIFI_DRIVER_FW_PATH_STA宏表达。三星Tuna平台中,该文件位置为/vendor/firmware/fw_bcmdhd.bin。

提示 三星Tuna平台对应的配置文件在Android 4.2源码根目录/device/samsung/tuna目录中。从上面的固件文件名来看,它用的Wi-Fi无线芯片是博通(Broadcom)公司生产的。通过加载不同固件的方式来启用无线芯片硬件的不同功能可能和Wi-Fi驱动及芯片的设计有关。

另外,根据审稿专家的反馈,在Android 4.2中,STA和P2P可同时运行(即所谓的共存模式),这样STA和P2P实际对应的固件相同,但可能文件名不同。而SoftAP的固件与STA/P2P就不一样了。

2)加载完指定的Wi-Fi固件后,下一步将对Soft AP功能进行一些配置,配置信息最终将写到一个配置文件。这部分功能由SoftapController的setSoftap函数完成,代码如下所示。
[-->SoftapController.cpp::setSoftap]
int SoftapController::setSoftap(int argc, char *argv[]) {
    char psk_str[2*SHA256_DIGEST_LENGTH+1];
    int ret = 0, i = 0, fd;
    char *ssid, *iface;

    ......// 参数检查

    iface = argv[2];

    char *wbuf = NULL;
    char *fbuf = NULL;

    if (argc > 3) {
        ssid = argv[3];
    } else {
        ssid = (char *)"AndroidAP"; // SSID即接入点的名称
    }

    asprintf(&wbuf, "interface=%s\ndriver=nl80211\nctrl_interface="
            "/data/misc/wifi/hostapd\nssid=%s\nchannel=6\nieee80211n=1\n",
            iface, ssid);

    if (argc > 4) { // 判断AP的加密类型
        if (!strcmp(argv[4], "wpa-psk")) {
            generatePsk(ssid, argv[5], psk_str);
            asprintf(&fbuf, "%swpa=1\nwpa_pairwise=TKIP CCMP\nwpa_psk=%s\n",
                      wbuf, psk_str);
        } else if (!strcmp(argv[4], "wpa2-psk")) {
            generatePsk(ssid, argv[5], psk_str);
            asprintf(&fbuf, "%swpa=2\nrsn_pairwise=CCMP\nwpa_psk=%s\n",
                      wbuf, psk_str);
        } else if (!strcmp(argv[4], "open")) {
            asprintf(&fbuf, "%s", wbuf);
        }
    }  ......
    // HOSTAPD_CONF_FILE指向/data/misc/wifi/hostapd.conf文件
    fd = open(HOSTAPD_CONF_FILE, O_CREAT | O_TRUNC | O_WRONLY, 0660);
    ......
    if (write(fd, fbuf, strlen(fbuf)) < 0) {
        ALOGE("Cannot write to \"%s\": %s", HOSTAPD_CONF_FILE, strerror(errno));
        ret = -1;
    }
    ......// 修改该文件的读写权限等
    return ret;
}

上面代码中涉及Wi-Fi技术的很多概念,将在后续章节统一介绍。从功能上来说,setSoftap函数无非就是把一些配置信息写到一个hostapd.conf文件中。可以通过一个例子文件来了解此文件的内容。

Android4.2/hardware/ti/wlan/mac80211/config目录中有一个hostapd.conf文件,其内容如下所示。
[-->hostapd.conf]
driver=nl80211   #指定Wi-Fi驱动的名称
......#略去部分内容
ssid=AndroidAP   #设置接入点名称为AndroidAP
country_code=US
wep_rekey_period=0
eap_server=0
own_ip_addr=127.0.0.1
wpa_group_rekey=0
wpa_gmk_rekey=0   #加密方式等设置
wpa_ptk_rekey=0
interface=wlan1   #网络设备接口
......#略去部分内容

由上边示例的hostapd.conf可知,当使用该配置文件后,其他Station搜索到由这台手机设置的Soft AP的名称将会是“AndroidAP”。

3)最后,SoftapController的startap函数被调用,它将启动hostapd进程。重点关注hostapd启动的参数信息,如下所示。
hostapd \
-e /data/misc/wifi/entropy.bin \和Wi-Fi协议中的信息加密有关
/data/misc/wifi/hostapd.conf \hostapd的配置文件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
a20_hummingbird_v4.5_v1.0_csi01_2ov7670_rtl8188eus 20150918 1830 JNI.7z 无法打开USB Wifi rtl8188eus.txt 配置前后ov7670双摄像头 JNI调用读写一次之后就会出现内核出错,系统死机。 有可能与系统为android4.4有关。 无法打开USB Wifi rtl8188eus shell@wing-k70:/ $ shell@wing-k70:/ $ shell@wing-k70:/ $ shell@wing-k70:/ $ logcat -c shell@wing-k70:/ $ logcat --------- beginning of /dev/log/system I/ActivityManager( 1670): Waited long enough for: ServiceRecord{41e90e08 u0 com.android.calendar/.alerts.InitAlarmsService} --------- beginning of /dev/log/main D/dalvikvm( 1849): GC_FOR_ALLOC freed 673K, 22% free 5143K/6512K, paused 41ms, total 47ms I/ActivityManager( 1670): START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.settings/.Settings} from pid 1849 D/PermissionCache( 1252): checking android.permission.READ_FRAME_BUFFER for uid=1000 => granted (3161 us) D/BluetoothAdapter( 1931): 1103979928: getState() : mService = null. Returning STATE_OFF D/libEGL ( 1931): loaded /system/lib/egl/libEGL_mali.so D/libEGL ( 1931): loaded /system/lib/egl/libGLESv1_CM_mali.so D/libEGL ( 1931): loaded /system/lib/egl/libGLESv2_mali.so D/OpenGLRenderer( 1931): Enabling debug mode 0 D/BluetoothAdapter( 1931): 1103979928: getState() : mService = null. Returning STATE_OFF I/ActivityManager( 1670): Displayed com.android.settings/.Settings: +1s78ms D/WifiService( 1670): setWifiEnabled: true pid=1931, uid=1000 D/WifiHW ( 1670): Start to insmod 8188eu.ko [ 54.805792] ****wyb arch/arm/mach-sun7i/rf/wifi_pm.c:69/wifi_pm_power()! on=1 [ 54.813855] ****wyb arch/arm/mach-sun7i/rf/wifi_pm.c:73/wifi_pm_power()! [ 54.821376] ****wyb arch/arm/mach-sun7i/rf/wifi_pm_rtl8188eu.c:197/rtl8188eu_power()! mode=1 *updown=1 [ 54.831805] ****wyb arch/arm/mach-sun7i/rf/wifi_pm_rtl8188eu.c:95/rtl8188eu_gpio_ctrl()! name=rtk_rtl8188eu_wl_dis, level=1 [ 54.844290] ****wyb arch/arm/mach-sun7i/rf/wifi_pm_rtl8188eu.c:209/rtl8188eu_power()! usb wifi power state: on [ 54.855621] ----wyb arch/arm/mach-sun7i/rf/wifi_pm_rtl8188eu.c:222/rtl8188eu_power()! D/WifiHW ( 1670): faied to read proc/net/wireless D/WifiHW ( 1670): loading wifi driver... D/WifiHW ( 1670): faied to read proc/net/wireless D/WifiHW ( 1670): loading wifi driver... I/USB3G ( 1258): event { 'add', '/devices/platform/sw-ehci.2/usb4/4-1', 'usb', '', 189, 385 } I/USB3G ( 1258): path : '/sys/devices/platform/sw-ehci.2/usb4/4-1' I/USB3G ( 1258): VID :size 5,vid_path '/sys/devices/platform/sw-ehci.2/usb4/4-1/idVendor',VID '0bda I/USB3G ( 1258): '. I/USB3G ( 1258): PID :size 5,Pid_path '/sys/devices/platform/sw-ehci.2/usb4/4-1/idProduct',PID '8179 I/USB3G ( 1258): '. I/USB3G ( 1258): cmd=source /system/xbin/usb_modeswitch.sh /system/etc/usb_modeswitch.d/0bda_8179 &, D/WifiHW ( 1670): faied to read proc/net/wireless D/WifiHW ( 1670): loading wifi driver... I/USB3G ( 1258): excute ret:0,err:No such file or directory I/USB3G ( 1258): free cmd W/ContextImpl( 1670): Calling a method in the system process without a qualified user: android.app.ContextImpl.sendBroadcast:1123 com.android.server.usb.UsbSettingsManager.deviceAttached:621 com.android.server.usb.UsbHostManager.usbDeviceAdded:156 com.android.server.usb.UsbHostManager.monitorUsbHostBus:-2 com.android.server.usb.UsbHostManager.access$000:38 D/Tethering( 1670): sendTetherStateChangedBroadcast 1, 0, 0 W/SocketClient( 1249): write error (Broken pipe) D/Tethering( 1670): InitialState.processMessage what=4 D/Tethering( 1670): sendTetherStateChangedBroadcast 0, 0, 0 D/WifiHW ( 1670): faied to read proc/net/wireless D/WifiHW ( 1670): loading wifi driver... D/WifiHW ( 1249): Enter: wifi_get_fw_path function, fw_type=0, D/WifiHW ( 1249): Eneter: wifi_change_fw_path, fwpath = STA. D/SoftapController( 1249): Softap fwReload - Ok D/CommandListener( 1249): Setting iface cfg D/CommandListener( 1249): Trying to bring down wlan0 D/WifiMonitor( 1670): startMonitoring(wlan0) with mConnected = false I/wpa_supplicant( 2247): Successfully initialized wpa_supplicant I/wpa_supplicant( 2247): rfkill: Cannot open RFKILL control device D/BluetoothAdapter( 1931): 1103979928: getState() : mService = null. Returning STATE_OFF I/wpa_supplicant( 2247): rfkill: Cannot open RFKILL control device D/WifiConfigStore( 1670): Loading config and enabling all networks E/WifiConfigStore( 1670): Error parsing configurationjava.io.FileNotFoundException: /data/misc/wifi/ipconfig.txt: open failed: ENOENT (No such file or directory) D/BluetoothAdapter( 1931): 1103979928: getState() : mService = null. Returning STATE_OFF E/WifiStateMachine( 1670): Failed to set device name wing_k70 E/WifiStateMachine( 1670): Failed to set manufacturer Allwinner E/WifiStateMachine( 1670): Failed to set model name AOSP on wing E/WifiStateMachine( 1670): Failed to set model number AOSP on wing E/WifiStateMachine( 1670): Failed to set serial number 582034060190a829459 E/WifiStateMachine( 1670): Failed to set WPS config methods E/WifiStateMachine( 1670): Failed to set primary device type 10-0050F204-5 D/CommandListener( 1249): Setting iface cfg D/CommandListener( 1249): Trying to bring up p2p0 D/WifiMonitor( 1670): startMonitoring(p2p0) with mConnected = true E/WifiStateMachine( 1670): Failed to set frequency band 0 [ 57.384990] init: untracked pid 2221 exited D/InitAlarmsService( 2053): Clearing and rescheduling alarms. W/SocketClient( 1249): write error (Broken pipe) D/ConnectivityService( 1670): Sampling interval elapsed, updating statistics .. D/ConnectivityService( 1670): Done. D/ConnectivityService( 1670): Setting timer for 720seconds I/MediaFocusControl( 1670): AudioFocus abandonAudioFocus() from android.media.AudioManager@41cc7828com.android.music.MediaPlaybackService$3@41cc66a8 I/ActivityManager( 1670): Start proc com.android.musicfx for broadcast com.android.musicfx/.ControlPanelReceiver: pid=2265 uid=10008 gids={50008, 3003, 3002} V/MusicFXControlPanelReceiver( 2265): onReceive V/MusicFXControlPanelReceiver( 2265): Action: android.media.action.CLOSE_AUDIO_EFFECT_CONTROL_SESSION V/MusicFXControlPanelReceiver( 2265): Package name: com.android.music V/MusicFXControlPanelReceiver( 2265): Audio session: 8 V/MusicFXControlPanelEffect( 2265): closeSession(android.app.ReceiverRestrictedContext@41ccc508, com.android.music, 8) ^C 130|shell@wing-k70:/ $
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值