2014年3月20日 星期四

Android Intel CedarTrail整合MTK MT7610U USB WiFi Dongle

1. 首先拿到WiFi driver,看一下driver的Makefile
  • 看來這driver並非Kernel driver,可以直接丟到driver下並透由menuconfig選擇。
  • 這driver是可以直接在Linux PC環境下編譯的。
P.S. 因為改成Kernel driver很麻煩,所以改了一下Android.mk的描述,儘量不改driver。

2. 將driver放到Kernel底下
  • 如果直接編譯driver,會出現沒有.config的設定。
  • 也非Kernel driver所用的makefile,無法跟著Kernel一起編譯。

3. 修改Kernel底下的Android.mk,增加WiFi driver路徑描述
    $(mk_kernel) oldnoconfig
    $(mk_kernel) $(KERNEL_TARGET) $(if $(MOD_ENABLED),modules)
    $(hide) $(ACP) -fp $(BUILT_KERNEL_TARGET) $@
    $(if $(FIRMWARE_ENABLED),$(mk_kernel) ... ... ...
    $(mk_kernel) -C XXXu
    cp $(CURDIR)/kernel/XXXu/MODULE/os/linux/XXXu_sta.ko     
    $(KBUILD_OUTPUT)/drivers/net/
    cp $(CURDIR)/kernel/XXXu/NETIF/os/linux/XXXu_sta_net.ko
    $(KBUILD_OUTPUT)/drivers/net/
    cp $(CURDIR)/kernel/XXXu/UTIL/os/linux/XXXu_sta_util.ko
    $(KBUILD_OUTPUT)/drivers/net/

  • 改完後,在Kernel編譯完後,會自動編譯WiFi driver。
  • 編譯完後會將WiFi driver拷貝到output driver路徑下。

4. 將所有的drivers拷貝到Platform目錄下

5. 在Platform/Platform.mk修改mk檔,將driver及wpa_supplicant.conf包進image
    PRODUCT_COPY_FILES += \
    $(LOCAL_PATH)/XXXu_sta.ko:system/XXXu_sta.ko \
    $(LOCAL_PATH)/XXXu_sta_util.ko:system/XXXu_sta_util.ko \
    $(LOCAL_PATH)/XXXu_sta_net.ko:system/XXXu_sta_net.ko \
    $(LOCAL_PATH)/XXXSTA.dat:system/XXXSTA.dat \
    $(LOCAL_PATH)/wpa_supplicant.conf:data/wpa_supplicant.conf \


6. wpa_supplicant.conf寫法如下
    update_config=1
    ctrl_interface=DIR=/data/system/wpa_supplicant GROUP=wifi
    eapol_version=1
    ap_scan=1
    fast_reauth=1


7. 在BoardConfig.mk修改WiFi設定如下
    # This enables the wpa wireless driver
    #BOARD_WPA_SUPPLICANT_DRIVER := NL80211
    BOARD_WPA_SUPPLICANT_DRIVER := WEXT
    #BOARD_WPA_SUPPLICANT_PRIVATE_LIB ?= private_lib_driver_cmd
    WPA_SUPPLICANT_VERSION := VER_0_5_X

P.S. Driver是搭配WPA_SUPPLICANT VER_0_5_X版本

8. 在platform_defconfig設定相關所需要用到的config,如wext

9. 在init.rc載入driver module
    insmod system/XXXu_sta_util.ko
    insmod system/XXXu_sta.ko
    insmod system/XXXu_sta_net.ko


    mkdir /data/misc 01771 system misc
    # give system access to wpa_supplicant.conf for backup and restore
    mkdir /data/misc/wifi 0770 wifi wifi
    mkdir /data/misc/wifi/sockets 0770 wifi wifi
    mkdir /data/system 0771 system system
    mkdir /data/system/wpa_supplicant 0771 wifi wifi
    chmod 0771 /data/system/wpa_supplicant
    chown wifi wifi /data/misc/wifi/wpa_supplicant.conf   
    chmod 0660 /data/misc/wifi/wpa_supplicant.conf
    chown wifi wifi /data/wpa_supplicant.conf   
    chmod 0660 /data/wpa_supplicant.conf

10. 因為WiFi driver是走libhardware_legacy架構,wifi.c需要做對應修改
  • 修正相關檔案路徑
static const char SUPP_CONFIG_FILE[]    = "/data/wpa_supplicant.conf";
  • 因為已在init.rc載入driver,所以直接return 1
int is_wifi_driver_loaded() {
... ... ...
... ... ...
... ... ...
#ifdef WIFI_DRIVER_MODULE_PATH
... ... ...
... ... ...
... ... ...
#else
    return 1;
#endif

}
  • 已經定義了ctrl_interface=,所以code裡拿掉
int update_ctrl_interface(const char *config_file) {
... ... ...
... ... ...
... ... ...

    if (!strcmp(config_file, SUPP_CONFIG_FILE)) {
        property_get("wifi.interface", ifc, WIFI_TEST_INTERFACE);
    } else {
        strcpy(ifc, CONTROL_IFACE_PATH);
    }
#if 0
    if ((sptr = strstr(pbuf, "ctrl_interface="))) {
        char *iptr = sptr + strlen("ctrl_interface=");
        int ilen = 0;
        int mlen = strlen(ifc);
        int nwrite;
        if (strncmp(ifc, iptr, mlen) != 0) {
            LOGE("ctrl_interface != %s", ifc);
            while (((ilen + (iptr - pbuf)) < nread) && (iptr[ilen] != '\n'))
                ilen++;
            mlen = ((ilen >= mlen) ? ilen : mlen) + 1;
            memmove(iptr + mlen, iptr + ilen + 1, nread - (iptr + ilen + 1 - pbuf));
            memset(iptr, '\n', mlen);
            memcpy(iptr, ifc, strlen(ifc));
            destfd = open(config_file, O_RDWR, 0660);
            if (destfd < 0) {
                LOGE("Cannot update \"%s\": %s", config_file, strerror(errno));
                free(pbuf);
                return -1;
            }
            write(destfd, pbuf, nread + mlen - ilen -1);
            close(destfd);
        }
    }
#endif

    free(pbuf);
    return 0;
}

11. 利用dmesg、logcat、netcfg、wpa_supplicant及wpa_cli觀看並除錯

12. WiFi正常運作了

P.S. 如果在Android看不到WiFi選項,請做下面的步驟
  • 在裝置的/system/etc/permissions中會列出裝置支援的設備
  • 相關設備支援檔案放在本機的frameworks/base/data/etc
  • 要支援WiFi,
將本機frameworks/base/data/etc下的android.hardware.wifi.xml
放置到裝置/system/etc/permissions

沒有留言:

張貼留言