摘要:
  本文主要针对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的,模组支持热插拔。

Android6.0 EC20 R2.1 4G模块移植相关推荐

  1. [Android6.0][RK3399] PCIe 接口 4G模块 EC20 调试记录

    原址 Platform: RK3399  OS: Android 6.0  Kernel: 4.4  Version: v2017.04  4G Module: EC20-CE 一基本概念 USB 部 ...

  2. 迅为干货 | Linux系统移远EC20 4G模块移植方法

    硬件平台:迅为i.MX6Q开发板 1. 4G网络连接 对于嵌入式Linux而言,4G网络连接是一个比较容易实现的功能,大多数的4G模块接口都是MiniPCIE接口,但是深入了解一下就会发现,4G模块的 ...

  3. linux系统华为4G模块移植及pppd拨号上网开发总结

    一.开发环境简介 开发系统: Ubuntu 14.04 内核版本:linux 3.10 4G模块:ME909-821和ME909-120 模块接口:pcle SIM卡:联通 二.内核驱动配置 需向li ...

  4. DM368开发 -- 华为3G/4G模块移植

    一.模块介绍 用的是华为 ME909s-821 Mini PCIe. 模块介绍,参看: ME909s-821 Mini PCIe 规格参数 其他模块,参看:华为全系列模块 产品介绍 ME909s-82 ...

  5. 驱动程序开发:基于EC20 4G模块自动拨号联网的两种方式(GobiNet工具拨号和PPP工具拨号)

    目录 一.EC20 4G模块简介 二.根据移远官方文档修改EC20 4G模组驱动   1.因为EC20 4G模组min-pice接口其实就是usb接口,因此需要修改Linux内核源码drivers/u ...

  6. Banana Pi R2 Pro使用EC25 4G模块实现路由功能,萤石云摄像头配置。

    器材:Banana Pi R2 Pro(Ubuntu 22.04 mate server),移远EC25 4G模块, CS-C6CN(4MP JD) EC25/EC20配置 将4G模块连接到开发板后, ...

  7. 嵌入式linux驱动开发之移远4G模块EC800驱动移植指南

    回顾下移远4G模块移植过程, 还是蛮简单的.一通百通,无论是其他4G模块都是一样的.这里记录下过程,分享给有需要的人.环境使用正点原子的imax6ul开发板,板子默认支持中兴和移远EC20的驱动,这里 ...

  8. NRF52832学习笔记(35)——4G模块EC200S使用

    一.简介 EC200S-CN 是移远通信最近推出的 LTE Cat 1 无线通信模块,支持最大下行速率 10Mbps 和最大上行速率 5Mbps,具有超高的性价比:同时在封装上兼容移远通信多网络制式 ...

  9. [RK3288][Android5.1] 调试笔记 --- 根据VIDPID读取不同的rilLib以实现4G模块的适配

    Platform: RK3288 OS: Android 5.1.1 Kernel: v3.10.0 需求: 适配4G模块,本文以YUGA-CLM920-AC3为例 1.添加USB转虚拟串口设备 把4 ...

最新文章

  1. java上传图片报404_ssm框架上传图片成功后跳转jsp页面显示却404访问不到图片
  2. 常见算子使用_spark快速入门(二)spark粗略流程简述及常见名词解释
  3. Linux系统下MySQL的导出数据语句SELECT … INTO OUTFILE的用法
  4. 进击的数据中台,企业数字化转型的新引擎
  5. MySQL基础——数据库和SQL概述\MySQL基本使用\DQL语言学习\条件查询\排序查询\常见函数\分组查询\连接查询\子查询\分页查询\联合查询
  6. CMD执行命令出现NOMALY: meaningless REX prefix used以及IDEA提示Cannot run git问题解决
  7. JS 打印 iframe
  8. php session位置,关于PHP中Session文件过多的问题及session文件保存位置
  9. 版本控制工具的必要性、作用、分类和发展历程
  10. 高性能的MySQL(8)优化服务器配置一安全与稳定
  11. 我在项目中运用 IOC(依赖注入)--入门篇
  12. wchar_t转为char*
  13. Java内存监控程序_java内存监控工具及命令
  14. 简单融合双系统 苹果虚拟Win8实用技巧
  15. 智能型电话远程遥控器
  16. java不能覆盖父类的_java中子类覆盖父类方法所必须满足的条件
  17. 响应式网页设计与应用
  18. 基于近端策略优化算法的车载边缘计算网络频谱资源分配
  19. return 0、return 1、return-1
  20. apt-get update出现无法连接上 archive.ubuntukylin.com:10006

热门文章

  1. 数据安全治理白皮书4.0(附下载link)
  2. 关于GUI图形界面化交互模式
  3. EF t4模板将实体与DBContext分离
  4. 创业开公司不知道怎么选办公室?办公室租赁需要知道的26条常识
  5. 免费图标和 UI 素材大荟萃
  6. telnet登陆路由器。。。
  7. <qsort实现一个通用的冒泡排序,排序各种类型的数据详解>
  8. 揭开进程的概念、状态、通信的迷雾。看完瞬间豁然开朗
  9. [POWERSHELL] [.net 3.5] [Windows Server] 在Windows Server上安装.NET3.5
  10. ArcGIS的工作空间