OpenHarmony3.1适配移远EC20模组4G上网功能

OpenHarmony3.1适配移远EC20模组4G上网功能

一、概述

通过阅读本篇文档,您将学习到如何适配移远EC20模组到OpenHarmony3.1(以下简称OHOS),并添加4G上网功能。

本篇文档,使用硬件为大禹RK3568开发板。

开发板资料:https://gitee.com/openharmony/device_board_hihope/blob/master/rk3568/README_zh.md

软件方案分为PPP和QMI两种,请读者自行选择。

二、PPP方案

2.1.内核添加对应配置

CONFIG_PPP=y
CONFIG_PPP_ASYNC=y
CONFIG_PPP_SYNC_TTY=y
CONFIG_PPP_DEFLATE=y

2.2.修改内核驱动源码

2.2.1修改drivers/usb/serial/option.c

diff --git a/v5.10.11/drivers/usb/serial/option.c b/v5.10.11/drivers/usb/serial/option.c
index 3fe9591..2a3e20e 100644
--- a/v5.10.11/drivers/usb/serial/option.c
+++ b/v5.10.11/drivers/usb/serial/option.c
@@ -580,6 +580,32 @@ static void option_instat_callback(struct urb *urb);
 
 
 static const struct usb_device_id option_ids[] = {
+#if 1 //Added by Quectel
+	{ USB_DEVICE(0x05C6, 0x9090) }, /* Quectel UC15 */
+	{ USB_DEVICE(0x05C6, 0x9003) }, /* Quectel UC20 */
+	{ USB_DEVICE(0x05C6, 0x9215) }, /* Quectel EC20(MDM9215) */
+	{ USB_DEVICE(0x2C7C, 0x0125) }, /* Quectel EC20(MDM9x07)/EC25/EG25 */
+	{ USB_DEVICE(0x2C7C, 0x0121) }, /* Quectel EC21 */
+	{ USB_DEVICE(0x2C7C, 0x0191) }, /* Quectel EG91 */
+	{ USB_DEVICE(0x2C7C, 0x0195) }, /* Quectel EG95 */
+	{ USB_DEVICE(0x2C7C, 0x0306) }, /* Quectel EG06/EP06/EM06 */
+	{ USB_DEVICE(0x2C7C, 0x030B) }, /* Quectel EG065K/EG060K */
+	{ USB_DEVICE(0x2C7C, 0x0514) }, /* Quectel BL EG060K RNDIS Only */
+	{ USB_DEVICE(0x2C7C, 0x0512) }, /* Quectel EG12/EP12/EM12/EG16/EG18 */
+	{ USB_DEVICE(0x2C7C, 0x0296) }, /* Quectel BG96 */
+	{ USB_DEVICE(0x2C7C, 0x0700) }, /* Quectel BG95/BG77/BG600L-M3/BC69 */
+	{ USB_DEVICE(0x2C7C, 0x0435) }, /* Quectel AG35 */
+	{ USB_DEVICE(0x2C7C, 0x0415) }, /* Quectel AG15 */
+	{ USB_DEVICE(0x2C7C, 0x0452) }, /* Quectel AG520 */
+	{ USB_DEVICE(0x2C7C, 0x0455) }, /* Quectel AG550 */
+	{ USB_DEVICE(0x2C7C, 0x0620) }, /* Quectel EG20 */
+	{ USB_DEVICE(0x2C7C, 0x0800) }, /* Quectel RG500/RM500/RG510/RM510 */
+	{ USB_DEVICE(0x2C7C, 0x0801) }, /* Quectel RG520/RM520/SG520 */
+	{ USB_DEVICE(0x2C7C, 0x6026) }, /* Quectel EC200 */
+	{ USB_DEVICE(0x2C7C, 0x6120) }, /* Quectel UC200 */
+	{ USB_DEVICE(0x2C7C, 0x6000) }, /* Quectel EC200/UC200 */
+	{ .match_flags = USB_DEVICE_ID_MATCH_VENDOR, .idVendor = 0x2C7C }, /* Match All Quectel Modules */
+#endif
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_LIGHT) },
@@ -2071,7 +2097,26 @@ MODULE_DEVICE_TABLE(usb, option_ids);
  * recognizes separately, thus num_port=1.
  */
 
+#if 1 //Added by Quectel
+static void cfmakeraw(struct ktermios *t)
+{
+	t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
+	t->c_oflag &= ~OPOST;
+	t->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+	t->c_cflag &= ~(CSIZE|PARENB);
+	t->c_cflag |= CS8;
+	t->c_cc[VMIN] = 1;
+	t->c_cc[VTIME] = 0;
+}
+
+static void option_init_termios(struct tty_struct *tty)
+{
+	cfmakeraw(&tty->termios);
+}
+#endif
+
 static struct usb_serial_driver option_1port_device = {
+	.init_termios  = option_init_termios,
 	.driver = {
 		.owner =	THIS_MODULE,
 		.name =		"option1",
@@ -2098,6 +2143,9 @@ static struct usb_serial_driver option_1port_device = {
 #ifdef CONFIG_PM
 	.suspend           = usb_wwan_suspend,
 	.resume            = usb_wwan_resume,
+#if 1 //Added by Quectel
+	.reset_resume = usb_wwan_resume,
+#endif
 #endif
 };
 
@@ -2122,6 +2170,35 @@ static int option_probe(struct usb_serial *serial,
 				&serial->interface->cur_altsetting->desc;
 	unsigned long device_flags = id->driver_info;
 
+#if 1 //Added by Quectel
+	//Quectel UC20's interface 4 can be used as USB Network device
+	if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9003)
+		&& serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
+		return -ENODEV;
+
+	//Quectel EC20(MDM9215)'s interface 4 can be used as USB Network device
+	if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9215)
+		&& serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
+		return -ENODEV;
+
+	if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {
+		__u16 idProduct = le16_to_cpu(serial->dev->descriptor.idProduct);
+		struct usb_interface_descriptor *intf = &serial->interface->cur_altsetting->desc;
+
+		if (intf->bInterfaceClass != 0xFF || intf->bInterfaceSubClass == 0x42) {
+			//ECM, RNDIS, NCM, MBIM, ACM, UAC, ADB
+			return -ENODEV;
+		}
+
+		if ((idProduct&0xF000) == 0x0000) {
+			//MDM interface 4 is QMI
+			if (intf->bInterfaceNumber == 4 && intf->bNumEndpoints == 3
+				&& intf->bInterfaceSubClass == 0xFF && intf->bInterfaceProtocol == 0xFF)
+				return -ENODEV;
+		}
+	}
+#endif
+
 	/* Never bind to the CD-Rom emulation interface	*/
 	if (iface_desc->bInterfaceClass == USB_CLASS_MASS_STORAGE)
 		return -ENODEV;
@@ -2235,7 +2312,7 @@ static void option_instat_callback(struct urb *urb)
 		dev_dbg(dev, "%s: error %d\n", __func__, status);
 
 	/* Resubmit urb so we continue receiving IRQ data */
-	if (status != -ESHUTDOWN && status != -ENOENT) {
+	if (status != -ESHUTDOWN && status != -ENOENT && status != -EPROTO) {
 		usb_mark_last_busy(port->serial->dev);
 		err = usb_submit_urb(urb, GFP_ATOMIC);
 		if (err)

2.2.2修改drivers/usb/serial/qcserial.c

diff --git a/v5.10.11/drivers/usb/serial/qcserial.c b/v5.10.11/drivers/usb/serial/qcserial.c
index 83da823..469b202 100644
--- a/v5.10.11/drivers/usb/serial/qcserial.c
+++ b/v5.10.11/drivers/usb/serial/qcserial.c
@@ -63,7 +63,7 @@ static const struct usb_device_id id_table[] = {
 	{DEVICE_G1K(0x05c6, 0x9202)},	/* Generic Gobi Modem device */
 	{DEVICE_G1K(0x05c6, 0x9203)},	/* Generic Gobi Modem device */
 	{DEVICE_G1K(0x05c6, 0x9222)},	/* Generic Gobi Modem device */
-	{DEVICE_G1K(0x05c6, 0x9008)},	/* Generic Gobi QDL device */
+//	{DEVICE_G1K(0x05c6, 0x9008)},	/* Generic Gobi QDL device */
 	{DEVICE_G1K(0x05c6, 0x9009)},	/* Generic Gobi Modem device */
 	{DEVICE_G1K(0x05c6, 0x9201)},	/* Generic Gobi QDL device */
 	{DEVICE_G1K(0x05c6, 0x9221)},	/* Generic Gobi QDL device */

2.2.3修改drivers/usb/serial/usb_wwan.c

diff --git a/v5.10.11/drivers/usb/serial/usb_wwan.c b/v5.10.11/drivers/usb/serial/usb_wwan.c
index 4b98458..236102b 100644
--- a/v5.10.11/drivers/usb/serial/usb_wwan.c
+++ b/v5.10.11/drivers/usb/serial/usb_wwan.c
@@ -272,7 +272,7 @@ static void usb_wwan_indat_callback(struct urb *urb)
 			__func__, status, endpoint);
 
 		/* don't resubmit on fatal errors */
-		if (status == -ESHUTDOWN || status == -ENOENT)
+		if (status == -ESHUTDOWN || status == -ENOENT || status == -EPROTO)
 			return;
 	} else {
 		if (urb->actual_length) {
@@ -476,6 +476,19 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port,
 			  usb_sndbulkpipe(serial->dev, endpoint) | dir,
 			  buf, len, callback, ctx);
 
+#if 1 //Added by Quectel for Zero Packet
+	if (dir == USB_DIR_OUT) {
+		if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9090))
+			urb->transfer_flags |= URB_ZERO_PACKET;
+		if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9003))
+			urb->transfer_flags |= URB_ZERO_PACKET;
+		if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9215))
+			urb->transfer_flags |= URB_ZERO_PACKET;
+		if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C))
+			urb->transfer_flags |= URB_ZERO_PACKET;
+	}
+#endif
+
 	if (intfdata->use_zlp && dir == USB_DIR_OUT)
 		urb->transfer_flags |= URB_ZERO_PACKET;

2.3添加ppp拨号软件

2.3.1pcap移植

主页:https://www.tcpdump.org/index.html

https://www.tcpdump.org/release/libpcap-1.10.1.tar.gz

解压到目录third_party/libpcap

原生编译:

./configure --host=arm-linux-gnueabi
#修改Makefile
#CC = arm-linux-gnueabi-gcc
#AR = arm-linux-gnueabi-ar
make

创建gn文件BUILD.gn,内容如下:

import("//build/ohos.gni")

ohos_static_library("libpcap") {
  sources = [
    "pcap-linux.c",
    "fad-getad.c",
    "pcap-usb-linux.c",
    "pcap-netfilter-linux.c",
    "pcap.c",
    "gencode.c",
    "optimize.c",
    "nametoaddr.c",
    "etherent.c",
    "fmtutils.c",
    "savefile.c",
    "sf-pcap.c",
    "sf-pcapng.c",
    "pcap-common.c",
    "bpf_image.c",
    "bpf_filter.c",
    "bpf_dump.c",
    "scanner.c",
    "grammar.c",
    "missing/strlcat.c",
    "missing/strlcpy.c"
  ]

  include_dirs = [
    "//third_party/libpcap"
  ]

  cflags = [
    "-O2",
    "-g",
    "-fvisibility=hidden",
    "-fpic",
    "-DBUILDING_PCAP",
    "-Dpcap_EXPORTS",
    "-DHAVE_CONFIG_H",
    "-Wno-int-conversion",
  ]

  part_name = "libpcap"
  subsystem_name = "ppp"
}

修改ftmacros.h,宏_GNU_SOURCE重复定义:

  #ifndef _GNU_SOURCE
    #define _GNU_SOURCE
  #endif

修改config.h文件,屏蔽以下两行:

/* define if we have the Linux getnetbyname_r() */
// #define HAVE_LINUX_GETNETBYNAME_R 1

/* define if we have the Linux getprotobyname_r() */
// #define HAVE_LINUX_GETPROTOBYNAME_R 1

2.3.2.ppp移植

主页:https://download.samba.org/pub/ppp/

下载地址:https://download.samba.org/pub/ppp/ppp-2.4.9.tar.gz

代码解压到目录third_party/ppp

原生编译:

./configure --cross_compile=arm-linux-gnueabi-g
make

新建文件bundle.json,内容如下:

{
    "name": "@ohos/ppp",
    "description": "the Point-to-Point Protocol (PPP) to provide Internet connections over serial lines",
    "version": "3.1",
    "license": "Public Domain",
    "publishAs": "code-segment",
    "segment": {
        "destPath": "third_party/ppp"
    },
    "dirs": {},
    "scripts": {},
    "licensePath": "",
    "readmePath": {
        "en": ""
    },
    "component": {
        "name": "ppp",
        "subsystem": "ppp",
        "syscap": [],
        "features": [],
        "adapted_system_type": [],
        "rom": "",
        "ram": "",
        "deps": {
            "components": [],
            "third_party": []
        },
        "build": {
            "sub_component": [
                "//third_party/ppp:ppp_group"
            ],
            "inner_kits": [],
            "test": []
        }
    }
}

新建文件ohos.build,内容如下:

{
  "subsystem": "ppp",
  "parts": {
    "ppp": {
      "module_list": [
        "//third_party/ppp:ppp_group"
      ]
    }
  }
}

新建文件BUILD.gn,内容如下:

import("//build/ohos.gni")
group("ppp_group") {
  deps =[
    "pppd:pppd_group",
    "chat:chat",
    "etc:ppp_copy"
  ]
}
2.3.2.1pppd移植

原生交叉编译:

./configure --host=arm-linux-gnueabi
make CC=arm-linux-gnueabi-gcc AR=arm-linux-gnueabi-ar

新建gn,并编译:

import("//build/ohos.gni")

group("pppd_group") {
  deps =[
    ":pppd",
    # "plugins:pppd_plugins",
  ]
}

ohos_executable("pppd") {
  sources = [
    "main.c",
    "magic.c",
    "fsm.c",
    "lcp.c",
    "ipcp.c",
    "upap.c",
    "chap-new.c",
    # "md5.c",
    "ccp.c",
    "ecp.c",
    "ipxcp.c",
    "auth.c",
    "options.c",
    "sys-linux.c",
    "md4.c",
    "chap_ms.c",
    "demand.c",
    "utils.c",
    "tty.c",
    "eap.c",
    "chap-md5.c",
    "session.c",
    # "sha1.c",
    "multilink.c",
    "tdb.c",
    "spinlock.c",
    "ipv6cp.c",
    "eui64.c",

    "pppcrypt.c",
    "eap-tls.c"
  ]

  include_dirs = [
    "//third_party/ppp/include",
    "//third_party/ppp/pppd",
    "//third_party/openssl/include",
    "//third_party/libpcap",
  ]

  defines = [
    "HAVE_PATHS_H",
    "IPX_CHANGE",
    "HAVE_MMAP",
    "DESTDIR=\"/usr/local\"",
    "CHAPMS=1",
    "MPPE=1",
    "USE_EAPTLS=1",
    "HAS_SHADOW",
    "HAVE_CRYPT_H=1",
    # "HAVE_LOGWTMP=1",
    "HAVE_MULTILINK",
    "USE_TDB=1",
    "PLUGIN",
    "PPP_FILTER",
    "INET6=1",
    "MAXOCTETS",
    "USE_CRYPT=1",
    "_PATH_VARRUN=\"/data/ppp/var/run/\""
  ]

  cflags = [
    "-Wno-implicit-function-declaration",
    "-O2",
    "-g",
    "-pipe",
  ]

  deps = [
      "//third_party/openssl:libcrypto_static",
      "//third_party/openssl:ssl_source",
      "//third_party/libpcap:libpcap",
  ]

  install_enable = true
  part_name = "ppp"
  subsystem_name = "ppp"
  install_images = [
    "system",
    "updater",
  ]
}
2.3.2.2chat移植
import("//build/ohos.gni")

ohos_executable("chat") {
  sources = [
    "chat.c",
  ]

  cflags = [
    "-O2",
    "-g",
    "-pipe",
    "-fPIC",
    "-UNO_SLEEP"
  ]

  defines = [
    "TERMIOS",
    "SIGTYPE=void",
    "FNDELAY=O_NDELAY"
  ]

  include_dirs = [
    "//third_party/ppp/include",
    "//third_party/ppp/chat",
    "//third_party/ppp",
  ]

  deps = [
      "//third_party/openssl:libcrypto_static",
      "//third_party/openssl:ssl_source",
      "//third_party/libpcap:libpcap",
  ]

  part_name = "ppp"
  subsystem_name = "ppp"
  install_enable = true
  install_images = [
    "system",
    "updater",
  ]
}
2.3.2.3etc配置

新建etc目录,用于拷贝ppp配置到/data目录。

注:因为OHOS的/system分区为只读,所以需要修改部分源码将ppp配置文件路径修改到/data下,这部分请读者自行修改。

新建文件BUILD.gn,内容如下:

import("//build/ohos.gni")

group("ppp_copy") {
  deps =[
    ":ip-up",
    ":ip-down",
    ":ipv6-up",
    ":ipv6-down",
    ":options",
    ":options.pptp",
    ":chap-secrets",
    ":pap-secrets",
    ":resolv.conf",
    ":peers_provider",
    ":peers_quectel-ppp",
    ":peers_quectel-chat-connect",
    ":peers_quectel-chat-disconnect",
    ":ip-up.d_0000usepeerdns",
    ":ip-down.d_0000usepeerdns"
  ]
}

ohos_prebuilt_etc("ip-up") {
  source = "ppp/ip-up"
  relative_install_dir = "ppp"
  part_name = "ppp"
}

ohos_prebuilt_etc("ipv6-up") {
  relative_install_dir = "ppp"
  source = "ppp/ipv6-up"
  part_name = "ppp"
}

ohos_prebuilt_etc("ip-down") {
  relative_install_dir = "ppp"
  source = "ppp/ip-down"
  part_name = "ppp"
}

ohos_prebuilt_etc("ipv6-down") {
  relative_install_dir = "ppp"
  source = "ppp/ipv6-down"
  part_name = "ppp"
}

ohos_prebuilt_etc("options") {
  relative_install_dir = "ppp"
  source = "ppp/options"
  part_name = "ppp"
}

ohos_prebuilt_etc("options.pptp") {
  relative_install_dir = "ppp"
  source = "ppp/options.pptp"
  part_name = "ppp"
}

ohos_prebuilt_etc("chap-secrets") {
  relative_install_dir = "ppp"
  source = "ppp/chap-secrets"
  part_name = "ppp"
}

ohos_prebuilt_etc("pap-secrets") {
  relative_install_dir = "ppp"
  source = "ppp/pap-secrets"
  part_name = "ppp"
}

ohos_prebuilt_etc("resolv.conf") {
  relative_install_dir = "ppp"
  source = "ppp/resolv.conf"
  part_name = "ppp"
}

ohos_prebuilt_etc("peers_provider") {
  relative_install_dir = "ppp/peers"
  source = "ppp/peers/provider"
  part_name = "ppp"
}

ohos_prebuilt_etc("peers_quectel-ppp") {
  relative_install_dir = "ppp/peers"
  source = "ppp/peers/quectel-ppp"
  part_name = "ppp"
}

ohos_prebuilt_etc("peers_quectel-chat-connect") {
  relative_install_dir = "ppp/peers"
  source = "ppp/peers/quectel-chat-connect"
  part_name = "ppp"
}

ohos_prebuilt_etc("peers_quectel-chat-disconnect") {
  relative_install_dir = "ppp/peers"
  source = "ppp/peers/quectel-chat-disconnect"
  part_name = "ppp"

}

ohos_prebuilt_etc("ip-up.d_0000usepeerdns") {
  relative_install_dir = "ppp/ip-up.d"
  source = "ppp/ip-up.d/0000usepeerdns"
  part_name = "ppp"
}

ohos_prebuilt_etc("ip-down.d_0000usepeerdns") {
  relative_install_dir = "ppp/ip-down.d"
  source = "ppp/ip-down.d/0000usepeerdns"
  part_name = "ppp"
}

2.4添加route

原始OHOS3.1中没有route程序,造成ppp拨号成功后无法设置路由。

需要添加route软件到toybox中,修改文件third_party/toybox/generated/config.h,内容如下:

#ifdef WITH_SELINUX
# define CFG_ROUTE 1
# define USE_ROUTE(...) __VA_ARGS__
#else
# define CFG_ROUTE 1
# define USE_ROUTE(...) __VA_ARGS__

2.5编译配置

修改productdefine/common/products/rk3568.json,新增ppp:

"ppp:ppp":{}

修改build/subsystem_config.json,新增ppp:

  "ppp":{
    "path": "third_party/ppp",
    "name": "ppp"
  },

修改文件build/config/compiler/BUILD.gn

treat_warnings_as_errors = false

注:这里因为无需遵守编码规范,故取消该设置。

2.6启动配置

修改文件base/startup/init_lite/services/etc/init.cfg。

新增jobs:

{
            "name" : "services:pppd_service",
            "cmds" : [
                "mkdir /data/ppp",
                "mkdir /data/ppp/var",
                "mkdir /data/ppp/var/lock",
                "mkdir /data/ppp/var/run",
                "mkdir /data/ppp/var/log",

                "mkdir /data/ppp/etc",
                "mkdir /data/ppp/etc/ppp",
                "copy /etc/ppp/ip-up /data/ppp/etc/ppp/ip-up",
                "copy /etc/ppp/ip-down /data/ppp/etc/ppp/ip-down",
                "chmod 0775 /data/ppp/etc/ppp/ip-up",
                "chmod 0775 /data/ppp/etc/ppp/ip-down",

                "copy /etc/ppp/ipv6-up /data/ppp/etc/ppp/ipv6-up",
                "copy /etc/ppp/ipv6-down /data/ppp/etc/ppp/ipv6-down",
                "chmod 0775 /data/ppp/etc/ppp/ipv6-up",
                "chmod 0775 /data/ppp/etc/ppp/ipv6-down",
                "copy /etc/ppp/options /data/ppp/etc/ppp/options",
                "copy /etc/ppp/options.pptp /data/ppp/etc/ppp/options.pptp",
                "copy /etc/ppp/chap-secrets /data/ppp/etc/ppp/chap-secrets",
                "copy /etc/ppp/pap-secrets /data/ppp/etc/ppp/pap-secrets",
                "copy /etc/ppp/resolv.conf /data/ppp/etc/ppp/resolv.conf",

                "mkdir /data/ppp/etc/ppp/ip-up.d",
                "copy /etc/ppp/ip-up.d/0000usepeerdns /data/ppp/etc/ppp/ip-up.d/0000usepeerdns",
                "mkdir /data/ppp/etc/ppp/ip-down.d",
                "copy /etc/ppp/ip-down.d/0000usepeerdns /data/ppp/etc/ppp/ip-down.d/0000usepeerdns",

                "mkdir /data/ppp/etc/ppp/peers",
                "copy /etc/ppp/peers/provider /data/ppp/etc/ppp/peers/provider",
                "copy /etc/ppp/peers/quectel-ppp /data/ppp/etc/ppp/peers/quectel-ppp",
                "copy /etc/ppp/peers/quectel-chat-connect /data/ppp/etc/ppp/peers/quectel-chat-connect",
                "copy /etc/ppp/peers/quectel-chat-disconnect /data/ppp/etc/ppp/peers/quectel-chat-disconnect"
            ]
        }

新增services:

{
            "name" : "pppd_service",
            "start-mode" : "condition",
            "path" : ["/system/bin/pppd", "call", "quectel-ppp"],
            "once" : 1,
            "disabled" : 1,
            "console" : 1,
            "uid" : "root",
            "gid" : ["shell", "log", "readproc"],
            "jobs" : {
                "on-start" : "services:pppd_service"
            }
        }

在init的最后新增:

            "name" : "init",
            "cmds" : [
#            ......
                "start pppd_service"
            ]

2.7最终效果

系统启动后,自动启动pppd进行拨号,成功效果如下:

OpenHarmony3.1适配移远EC20模组4G上网功能_第1张图片

三、QMI方案

3.1内核添加对应配置

CONFIG_USB_NET_QMI_WWAN=y
CONFIG_USB_WDM=y

3.2修改内核代码

拷贝移远提供的qmi_wwan_q.c源码到drivers/net/usb/目录。

修改drivers/net/usb/Makefile,内容如下:

obj-${CONFIG_USB_NET_QMI_WWAN} += qmi_wwan_q.o
obj-${CONFIG_USB_NET_QMI_WWAN} += qmi_wwan.o

3.3添加quectel-cm软件

该软件源码由移远提供。

新建BUILD.gn,内容如下:

import("//build/ohos.gni")

group("quectel-cm-group") {
  deps = [
    ":quectel-CM",
#    ":quectel-qmi-proxy",
#    ":quectel-mbim-proxy",
#    ":quectel-atc-proxy",
    ":quectel-script"
  ]
}

ohos_prebuilt_etc("quectel-script") {
  # relative_install_dir = "quectel"
  source = "default.script"
  part_name = "quectel"
  module_install_dir = "quectel"
  subsystem_name = "quectel"
}

ohos_executable("quectel-CM") {
  sources = [
    "QmiWwanCM.c",
    "GobiNetCM.c",
    "main.c",
    "MPQMUX.c",
    "QMIThread.c",
    "util.c",
    "qmap_bridge_mode.c",
    "mbim-cm.c",
    "device.c",
    "atc.c",
    "atchannel.c",
    "at_tok.c",
    "udhcpc.c"
  ]

  defines = [
    "USE_OHOS"
  ]

  include_dirs = [
    "//third_party/quectel/quectel-cm",
  ]

  install_enable = true
  part_name = "quectel"
  subsystem_name = "quectel"
  install_images = [
    "system",
    "updater",
  ]
}

3.4启动配置

修改文件base/startup/init_lite/services/etc/init.cfg。

添加trigger,用以启动软件:

----------------- base/startup/init_lite/services/etc/init.cfg -----------------
index 3a1e0b1f3d..b093e0fb6c 100755
@@ -166,7 +166,8 @@
                 "trigger post-fs-data",
                 "trigger firmware_mounts_complete",
                 "trigger early-boot",
-                "trigger boot"
+                "trigger boot",
+                "trigger quectel-cm"
             ]
         }, {
             "name" : "early-fs",
@@ -431,6 +432,11 @@
                 "chmod 0773 /data/misc/trace",
                 "chmod 0775 /data/misc/wmtrace"
             ]
+        }, {
+            "name" : "quectel-cm",
+            "cmds" : [
+                "exec /system/bin/quectel-CM &"
+            ]
         }
     ],
     "services" : [{

3.5最终效果

OpenHarmony3.1适配移远EC20模组4G上网功能_第2张图片

你可能感兴趣的:(OHOS,c++,c语言,linux,驱动开发)