Android6.0 EC20 R2.1 4G模块移植

摘要:
  本文主要针对MTK MT8317 Android6.0 代码进行4G模块移植,使用pppd拨号的方式实现上网,并没有按照移远提供的文档GobiNet方式上网。


1、内核部分的移植
1.1 内核驱动修改
   添加USB串口驱动,如下:
kernel\kernel-3.18\drivers\usb\serial\option.c
static const struct usb_device_id option_ids[] = {
.....................................................................
    { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9003), /* Quectel UC20 */
      .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
    #if  1//Added by Quectel
    //{ USB_DEVICE(0x05C6, 0x9090) }, //For Quectel UC15
    //{ USB_DEVICE(0x05C6, 0x9003) }, //For Quectel UC20
    //{ USB_DEVICE(0x05C6, 0x9215) }, //For Quectel EC20
    { USB_DEVICE(0x2C7C, 0x0125) }, /* Quectel EC25 */
    #endif

    { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
........................................
}
因系统使用pppd拨号,不用GobiNet,所以其它部分就不需要在进行配置
1.2 内核配置
修改kernel\kernel-3.18\arch\arm\configs\ac83xx_androidm_defconfig 添加如下配置:
CONFIG_USB_SERIAL=y
CONFIG_USB_SERIAL_GENERIC=y
CONFIG_USB_SERIAL_WWAN=y
CONFIG_USB_SERIAL_OPTION=y
2、hardware层的修改
  这个部分主要针对MTK平台dongle的选择以及相应的PID和VID配置,同时在针对Dongle模块的libpath的配置等。
 因为EC20模组不需要进行USB模式切换,需要修改USB模式选择,对EC20模式不进行USB模式切换。具体修改如下:
2.1 模块配置
修改:vendor\atc\proprietary\hardware\dongle-ril\configs\dongleselect.conf 添加
VID=1e89,PID=2916,ATPort=/dev/ttyUSB3,ModemPort=/dev/ttyUSB4,LIBPATH=libmtk-ril.so
VID=2c7c,PID=0125,ATPort=/dev/ttyUSB2,ModemPort=/dev/ttyUSB0,LIBPATH=libmtk-ril-ec20.so   
修改:device\atc\ac83xx\device.mk
ifeq ($(strip $(MTK_EXTERNAL_DONGLE_SUPPORT)), yes)
  PRODUCT_PACKAGES += dongled
  PRODUCT_PACKAGES += usb_modeswitch
  PRODUCT_PACKAGES += chat
  PRODUCT_PACKAGES += rild_dongle
  PRODUCT_PACKAGES += libril_dongle
  PRODUCT_PACKAGES += libmtk-ril
  PRODUCT_PACKAGES += libmtk-ril-e1750
  PRODUCT_PACKAGES += libmtk-ril-mf626
  PRODUCT_PACKAGES += libmtk-ril-e3131
  PRODUCT_PACKAGES += libmtk-ril-ec20
.....................................................................
$(call inherit-product-if-exists, vendor/atc/proprietary/hardware/dongle-ril/configs/dongled.mk)
Endif
2.2 USB Dongle不进行USB模式切换
  具体修改如下:
vendor\atc\proprietary\hardware\dongle-ril\dongled\UsbSelect.cpp
int UsbSelect::handleUsbAutoSelect(NetlinkEvent *evt)
{
 .........................................................................
 if (strtoul(lastDevice.VID, NULL, 16) == strtoul(vid, NULL, 16) &&
        strtoul(lastDevice.PID, NULL, 16) == strtoul(pid, NULL, 16)) {
        SLOGD("handleUsbAutoSelect: NetlinkEvent is the same of last one");
    } else {
        //if(doUsbModeSwitch(vid ,pid))
        //{
        //     SLOGD("doUsbModeSwitch:device vid:%s,pid:%s, success!", vid, pid);
        //     return 0;
        // }
/*Quectel's EC20 do not need to modeswitch*/
        if (tmpvid == 0x2c7c && tmppid == 0x0125) {
            SLOGD("Quectel EC20 is no need to do modeswitch");
        } else {
            bool modeSwitch = false;
            modeSwitch = doUsbModeSwitch(vid ,pid);
            if (modeSwitch){
            SLOGD("doUsbModeSwitch:device vid:%s,pid:%s, success!", vid, pid)    
                return 0;
            }
        }

 found = findDevice(vid, pid, &device);
  ..........................................................
}
2.3 EC20  R2.1 4G模块的reference-ril模块的移植
将移远提供reference-ril代码目录拷贝到
vendor\atc\proprietary\hardware\dongle-ril\mtk-ril\目录下,重命名为mtk-ril-ec20,如下:
vendor\atc\proprietary\hardware\dongle-ril\mtk-ril\mtk-ril-ec20\
修改
vendor\atc\proprietary\hardware\dongle-ril\mtk-ril\Android.mk文件,添加对针对mtk-ril-ec20模块的编译,如下:
ifeq ($(MTK_EXTERNAL_DONGLE_SUPPORT),yes)
.................................................................................
LOCAL_MODULE:= libmtk-ril-e3131
include $(BUILD_SHARED_LIBRARY)

#for Quectel EC20
include $(CLEAR_VARS)
USE_MUXD=1

LOCAL_SRC_FILES:= \
    mtk-ril-ec20/mtk-ril-ec20.c \
    mtk-ril-ec20/atchannel.c \
    mtk-ril-ec20/misc.c \
    mtk-ril-ec20/at_tok.c \
    mtk-ril-ec20/ql-pppd.c \
    mtk-ril-ec20/ql-gps.c \
    mtk-ril-ec20/ql-datafwd.c \
    mtk-ril-ec20/ql-dtmf.c \
    mtk-ril-ec20/ql-tty2tcp.c

ifeq ($(USE_NDK),1)
LOCAL_CFLAGS += -DUSE_NDK
LOCAL_LDLIBS += -llog
LOCAL_SRC_FILES += mtk-ril-ec20/ql-ndk.c
else
LOCAL_SHARED_LIBRARIES := \
    libcutils libutils libril libnetutils
endif

# for asprinf
LOCAL_CFLAGS += -D_GNU_SOURCE

LOCAL_C_INCLUDES := $(KERNEL_HEADERS)

ifeq ($(USE_MUXD),1)
LOCAL_CFLAGS += -DMUX_ANDROID -DUSE_MUXD
$(shell touch $(LOCAL_PATH)/mtk-ril-ec20/CMUX/*)
LOCAL_SRC_FILES += mtk-ril-ec20/CMUX/gsm0710muxd_bp.c
endif

#build shared library
LOCAL_SHARED_LIBRARIES += \
    libcutils libutils
LOCAL_CFLAGS += -DRIL_SHLIB
LOCAL_MODULE:= libmtk-ril-ec20
include $(BUILD_SHARED_LIBRARY)

endif #(($(MTK_EXTERNAL_DONGLE_SUPPORT),yes)
2.3.1 去掉不必要的文件
  因MTK平台已经自带chat、ip-up、ip-down,所以去掉移远提供的ril代码中的chat.c、ip-up.c、ip-down.c文件,将reference-ril.c重命名为mtk-ril-ec20.c
2.3.2 修改Android.mk去掉Gobinet相关的文件编译、以及chat.c、ip-up.c、ip-down.c三个文件编译,如下:
USE_MUXD=1  ------->使用改选项
USE_NDIS=0   -------->使用pppd上网,不使用NDIS
LOCAL_PATH:= $(call my-dir)
$(shell touch $(LOCAL_PATH)/*)
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \
    mtk-ril-ec20.c \
    atchannel.c \
    misc.c \
    at_tok.c \
    ql-pppd.c \
    ql-gps.c \
    ql-datafwd.c \
    ql-dtmf.c \
    ql-tty2tcp.c

ifeq ($(USE_NDK),1)
LOCAL_CFLAGS += -DUSE_NDK
LOCAL_LDLIBS += -llog
LOCAL_SRC_FILES += ql-ndk.c
else
LOCAL_SHARED_LIBRARIES := \
    libcutils libutils libril libnetutils
endif

# for asprinf
LOCAL_CFLAGS += -D_GNU_SOURCE

LOCAL_C_INCLUDES := $(KERNEL_HEADERS)

ifeq ($(USE_MUXD),1)
LOCAL_CFLAGS += -DMUX_ANDROID -DUSE_MUXD
$(shell touch $(LOCAL_PATH)/CMUX/*)
LOCAL_SRC_FILES += CMUX/gsm0710muxd_bp.c
endif

#build shared library
LOCAL_SHARED_LIBRARIES += \
    libcutils libutils
LOCAL_CFLAGS += -DRIL_SHLIB
LOCAL_MODULE:= libmtk-ril-ec20   ------>EC20 lib库模块编译

include $(BUILD_SHARED_LIBRARY)
2.3.3 不使用quectel-CM的时候,将影响的相关代码移除
修改:vendor\atc\proprietary\hardware\dongle-ril\mtk-ril\mtk-ril-ec20\atchannel.c
#define LOG_NDEBUG 0
#define LOG_TAG "ATC"
#include <utils/Log.h>
#include "ql-log.h"
....................................................
#ifdef USE_NP
static void setTimespecRelative(struct timespec *p_ts, long long msec)
{
    struct timeval tv;

    gettimeofday(&tv, (struct timezone *) NULL);

    /* what's really funny about this is that I know
       pthread_cond_timedwait just turns around and makes this
       a relative time again */
    p_ts->tv_sec = tv.tv_sec + (msec / 1000);
    p_ts->tv_nsec = (tv.tv_usec + (msec % 1000) * 1000L ) * 1000L;
}
#endif /*USE_NP*/
.......................................
2.3.4 mtk-ril-ec20.c文件的修改
2.3.4.1 打开ril层库的pppd模式开关,如下:
#define USB_HOST_USE_Autochips_ac83xx
#ifdef USB_HOST_USE_Autochips_ac83xx
/*only use pppd,not NDIS*/
#define USE_MUXD

static int s_ppp_fd = -1;
#endif
2.3.4.2 针对上层请求SIM卡时,移动远ril层返回空的问题,需要将其修改成自定义,如下:
#ifdef USE_NDIS
................................................
#else
static int ql_get_ndisname(char **pp_usbnet_adapter) { return -ENODEV; }
static int ql_ndis_start(const char *apn, const char *user, const char *password, const char *auth_type) { return 0; }
static int ql_ndis_stop(int signo) { return 0; }

#endif
修改成:
#ifdef USE_NDIS
.................................................
#else
static int ql_get_ndisname(char **pp_usbnet_adapter) { return -ENODEV; }
static int ql_ndis_start(const char *apn, const char *user, const char *password, const char *auth_type,int default_pdp) { return 0; }
static int ql_ndis_stop(int signo) { return 0; }
#endif
static void  requestSIM_IO(void *data, size_t datalen, RIL_Token t)
{
...........................................................
#ifdef QUECTEL_REPORT_SIGNAL_STRENGTH
    if ((p_args->fileid == EF_ICCID) && (p_args->command == COMMAND_READ_BINARY)) {
        requestSignalStrength(NULL, 0, NULL);
    }
#endif
//if (p_args->fileid == EF_ICCID && sr.simResponse == NULL)
    //    goto error;
    if (p_args->fileid == EF_ICCID && *(sr.simResponse) == NULL ){
        LOGD("[%s]EF_ICCID=%d,p_args->fileid is %d,sr.simResponse=%p",__func__,EF_ICCID,p_args->fileid,sr.simResponse);
        LOGD("deal with SIMIO error");
        goto error;
    }
    LOGD("[%s]EF_ICCID=%d,p_args->fileid is %d,sr.simResponse=%p",__func__,EF_ICCID,p_args->fileid,sr.simResponse);
    LOGD("[%s]SIMIO REQUEST COMPLETE------NO ERROR",__func__);

    RIL_onRequestComplete(t, RIL_E_SUCCESS, &sr, sizeof(sr));
    at_response_free(p_response);
    free(cmd);

    return;
error:
.............................................
.......................................................
}
2.3.4.3 去掉ril调试开关
static void *
mainLoop(void *param)
{
    int fd;
    int ret;
//#if 1
#if 0

    //pay attention:
    //these codes means will result catch log every time your device boot up.
    //so make sure these codes are commented in your release software
    if (access(QL_DEBUG_LOG_PATH, W_OK) && errno == ENOENT) {
        system("/system/bin/mkdir "QL_DEBUG_LOG_PATH);
    }
#endif
..........................................................................
}
2.3.4.4 RIL版本号跟Android6.0版本不一致导致上层获取不到网络数据包的问题
将RIL的版本号修改成Android6.0的版本号为9,修改如下:
const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **argv)
{
    int ret;
    int fd = -1;
    int opt;
    pthread_attr_t attr;
struct passwd *pwd;
.........................................
if (anroid_version <= 40) QL_RIL_VERSION = 6;
    else if (anroid_version == 41) QL_RIL_VERSION = 6;
    else if (anroid_version == 42) QL_RIL_VERSION = 7;
    else if (anroid_version == 43) QL_RIL_VERSION = 8; //maybe should be 7
    else if (anroid_version == 44) QL_RIL_VERSION = 9;
    //else if (anroid_version == 50) QL_RIL_VERSION = 10;
    //else if (anroid_version == 51) QL_RIL_VERSION = 11;
    //else if (anroid_version == 60) QL_RIL_VERSION = 11;
else if (anroid_version == 50) QL_RIL_VERSION = 9;
else if (anroid_version == 51) QL_RIL_VERSION = 9;
else if (anroid_version == 60) QL_RIL_VERSION = 9;

    else LOGE("Unsupport Android Version %d by Quectel Now!!!!", anroid_version);
    LOGD("Android Version: %d, RIL_VERSION: %d / %d", anroid_version, QL_RIL_VERSION, RIL_VERSION);
#ifndef USE_NDK
   if (QL_RIL_VERSION != RIL_VERSION) //maybe get error when dynamic detect ril version
        QL_RIL_VERSION = RIL_VERSION;
#endif
......................................................
}
修改ril.h,将版本号修改成9,并添加对应版本的结构体参数,如下:
//#define RIL_VERSION 11     /* Current version */
#define RIL_VERSION 9     /* Current version */

.....................................................................................
} RIL_Data_Call_Response_v9; // FIXME: Change to v10

typedef struct {
int      status;     /* A RIL_DataCallFailCause, 0 which is PDP_FAIL_NONE if no error */
    int      suggestedRetryTime; /* If status != 0, this fields indicates the suggested retry
                                back-off timer value RIL wants to override the one
                                pre-configured in FW.
                                The unit is miliseconds.
                                The value < 0 means no value is suggested.
                                The value 0 means retry should be done ASAP.
                                he value of INT_MAX(0x7fffffff) means no retry. */
    int       cid;        /* Context ID, uniquely identifies this call */
    int     active;     /* 0=inactive, 1=active/physical link down, 2=active/physical link up */
    char *   type;       /* One of the PDP_type values in TS 27.007 section 10.1.1.
                       For example, "IP", "IPV6", "IPV4V6", or "PPP". If status is
                    PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED this is the type supported
                     such as "IP" or "IPV6" */
    char *  ifname;     /* The network interface name */
    char *  addresses;  /* A space-delimited list of addresses with optional "/" prefix length,
                        e.g., "192.0.1.3" or "192.0.1.11/16 2001:db8::1/64".
                       May not be empty, typically 1 IPv4 or 1 IPv6 or
                      one of each. If the prefix length is absent the addresses
                      are assumed to be point to point with IPv4 having a prefix
                      length of 32 and IPv6 128. */
    char *  dnses;      /* A space-delimited list of DNS server addresses,
                                   e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1".
                                   May be empty. */
    char *          gateways;   /* A space-delimited list of default gateway addresses,
                               e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1".
                              May be empty in which case the addresses represent point
                              to point connections. */
    char *          pcscf;    /* the Proxy Call State Control Function address
                                 via PCO(Protocol Configuration Option) for IMS client. */
    int             mtu;        /* MTU received from network
                               Value <= 0 means network has either not sent a value or
                              sent an invalid value */
} RIL_Data_Call_Response_v11;

typedef enum {
    RADIO_TECH_3GPP = 1, /* 3GPP Technologies - GSM, WCDMA */
    RADIO_TECH_3GPP2 = 2 /* 3GPP2 Technologies - CDMA */
} RIL_RadioTechnologyFamily;
添加ril.h头文件的路径:
//#include "../include/telephony/ril.h"
#include "../../include/telephony/ril.h"

2.3.4.5 修改ril主循环调用libril库的路径
const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **argv)
{
    int ret;
    int fd = -1;
    int opt;
    pthread_attr_t attr;
struct passwd *pwd;
....................................................
s_callbacks.version = QL_RIL_VERSION;
    //if (property_get("rild.libpath", prop_value, NULL) > 0) {
    if (property_get("ro.build.description", prop_value, NULL) > 0) {

        LOGD("[ro.build.description]: [%s]", prop_value);
    }
    //if (property_get("rild.libargs", prop_value, NULL) > 0) {
    if (property_get("tedongle.rild.libpath", prop_value, NULL) > 0) {

        LOGD("[rild.libpath]: [%s]", prop_value);
    }
    if (property_get("tedongle.rild.libargs", prop_value, NULL) > 0) {
        LOGD("[rild.libargs]: [%s]", prop_value);
    }

    if ((QL_RIL_VERSION > 9) && access("/sys/fs/selinux", F_OK) == 0) {

3测试
合并好代码之后,全部编译系统,用SD卡烧录系统到机器,在4G模块插入之前只用
Adb root
Adb shell
#logcat >/sdcard/4G_logacta.log
如果log信息中有:
 D Dongled : handleUsbAutoSelect: The PRODUCT is: 2c7c/125/318 
01-01 08:08:57.337   843   848 D Dongled : Quectel EC20 is no need to do modeswitch
01-01 08:08:57.337   843   848 E Dongled :  not found the value of ModemPort
01-01 08:08:57.337   843   848 E Dongled : It's not ModemPort
01-01 08:08:57.337   843   848 E Dongled : The 3Gdongle(vid = 2c7c,pid = 0125) is not found
说明vendor\atc\proprietary\hardware\dongle-ril\configs\dongleselect.conf文件中模组的PID、VID、AT口相关没配置正确,如果全部OK,一般情况状态栏就会显示4G信号图标了。
注意模组的SIM卡,要保证能够上4G网络,首先在手机上使用,确认OK之后在到机器上使用。
其它请看代码上传部分,ATC_AndroidM-8317代码库的Development分支commit ID:
f6b819c78d9708b73a2f889f9c70c82969d1b251
或者ATC_AndroidM-8317代码库的GS1_AndroidM分支commit ID:
cc1e31c4d401fb0f6d4107b91235582dd9656799
经过GS1_AndroidM分支上是OK的,模组支持热插拔。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值