mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-11 05:57:51 +08:00
🎨 Sync 2026-06-07 18:17:40
This commit is contained in:
1 parent
31e511aff8
commit
71aabc1bca
276 files changed
+1284
-96850
No files matched your search
+11
-7
@@ -1,22 +1,26 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=fibocom-dial
|
PKG_NAME:=fibocom-dial
|
||||||
PKG_RELEASE:=3
|
PKG_RELEASE:=4
|
||||||
|
|
||||||
include $(INCLUDE_DIR)/package.mk
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
define Package/fibocom-dial
|
define Package/fibocom-dial
|
||||||
SECTION:=net
|
SECTION:=utils
|
||||||
CATEGORY:=Network
|
CATEGORY:=Utilities
|
||||||
SUBMENU:=WWAN
|
TITLE:=Fibocom Dial
|
||||||
TITLE:=Dialing tool for Fibocom WWAN modules
|
endef
|
||||||
|
|
||||||
|
define Build/Prepare
|
||||||
|
mkdir -p $(PKG_BUILD_DIR)
|
||||||
|
$(CP) ./src/* $(PKG_BUILD_DIR)/
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/fibocom-dial/install
|
define Package/fibocom-dial/install
|
||||||
$(INSTALL_DIR) $(1)/usr/bin
|
$(INSTALL_DIR) $(1)/usr/bin
|
||||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/fibocom-dial $(1)/usr/bin
|
$(INSTALL_BIN) $(PKG_BUILD_DIR)/fibocom-dial $(1)/usr/bin
|
||||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/fibo_qmimsg_server $(1)/usr/bin/fibocom-qmimsg-server
|
$(INSTALL_BIN) $(PKG_BUILD_DIR)/fibo_qmimsg_server $(1)/usr/bin
|
||||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/multi-pdn-manager $(1)/usr/bin/fibocom-multi-pdn-manager
|
$(INSTALL_BIN) $(PKG_BUILD_DIR)/multi-pdn-manager $(1)/usr/bin
|
||||||
endef
|
endef
|
||||||
|
|
||||||
$(eval $(call BuildPackage,fibocom-dial))
|
$(eval $(call BuildPackage,fibocom-dial))
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
--- a/QmiWwanCM.c
|
|
||||||
+++ b/QmiWwanCM.c
|
|
||||||
@@ -8,7 +8,7 @@ typedef unsigned short sa_family_t;
|
|
||||||
#include "QMIThread.h"
|
|
||||||
|
|
||||||
#ifdef CONFIG_QMIWWAN
|
|
||||||
-#define FIBO_QMI_PROXY "fibo_qmimsg_server"
|
|
||||||
+#define FIBO_QMI_PROXY "fibocom-qmimsg-server"
|
|
||||||
static int cdc_wdm_fd = -1;
|
|
||||||
|
|
||||||
static UCHAR GetQCTLTransactionId(void)
|
|
||||||
--- a/fibo_qmimsg_server.c
|
|
||||||
+++ b/fibo_qmimsg_server.c
|
|
||||||
@@ -984,7 +984,7 @@ qmi_proxy_init_fail:
|
|
||||||
}
|
|
||||||
//2021-06-03 willa.liu@fibocom.com changed begin
|
|
||||||
static void qmi_start_server(void) {
|
|
||||||
- qmi_proxy_server_fd = create_local_server("fibo_qmimsg_server");
|
|
||||||
+ qmi_proxy_server_fd = create_local_server("fibocom-qmimsg-server");
|
|
||||||
printf("%s: qmi_proxy_server_fd = %d\n", __func__, qmi_proxy_server_fd);
|
|
||||||
if (qmi_proxy_server_fd == -1) {
|
|
||||||
dprintf("%s Failed to create %s, errno: %d (%s)\n", __func__, "fibocom-qmi-proxy", errno, strerror(errno));
|
|
||||||
--- a/multi-pdn-manager.c
|
|
||||||
+++ b/multi-pdn-manager.c
|
|
||||||
@@ -812,7 +812,7 @@ int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
dbg_time("The Fibocom multi-pdn-manager is already running! So killall multi-pdn-manager!");
|
|
||||||
system("killall -9 fibocom-dial");
|
|
||||||
- system("killall -9 multi-pdn-manager");
|
|
||||||
+ system("killall -9 fibocom-multi-pdn-manager");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
@@ -846,7 +846,7 @@ int main(int argc, char *argv[])
|
|
||||||
if (is_pcie_dial())
|
|
||||||
{
|
|
||||||
dbg_time("start qmi proxy server");
|
|
||||||
- //system("./fibo_qmimsg_server -d /dev/mhi_QMI0 &");
|
|
||||||
+ //system("./fibocom-qmimsg-server -d /dev/mhi_QMI0 &");
|
|
||||||
}
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
|
||||||
|
|
||||||
PKG_NAME:=fibocom-qmi-wwan
|
|
||||||
PKG_VERSION:=1.0.5
|
|
||||||
PKG_RELEASE:=1
|
|
||||||
|
|
||||||
include $(INCLUDE_DIR)/kernel.mk
|
|
||||||
include $(INCLUDE_DIR)/package.mk
|
|
||||||
|
|
||||||
define KernelPackage/usb-net-qmi-wwan-fibocom
|
|
||||||
SUBMENU:=USB Support
|
|
||||||
TITLE:=QMI WWAN driver for Fibocom modules
|
|
||||||
DEPENDS:=+kmod-usb-net +kmod-usb-wdm
|
|
||||||
FILES:=$(PKG_BUILD_DIR)/qmi_wwan_f.ko
|
|
||||||
AUTOLOAD:=$(call AutoLoad,82,qmi_wwan_f)
|
|
||||||
endef
|
|
||||||
|
|
||||||
define Build/Compile
|
|
||||||
+$(KERNEL_MAKE) M="$(PKG_BUILD_DIR)" modules
|
|
||||||
endef
|
|
||||||
|
|
||||||
$(eval $(call KernelPackage,usb-net-qmi-wwan-fibocom))
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
--- a/qmi_wwan_f.c
|
|
||||||
+++ b/qmi_wwan_f.c
|
|
||||||
@@ -712,7 +712,11 @@ static struct rtnl_link_stats64 *_rmnet_
|
|
||||||
stats64 = per_cpu_ptr(dev->stats64, cpu);
|
|
||||||
|
|
||||||
do {
|
|
||||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6,6,0)
|
|
||||||
start = u64_stats_fetch_begin_irq(&stats64->syncp);
|
|
||||||
+#else
|
|
||||||
+ start = u64_stats_fetch_begin(&stats64->syncp);
|
|
||||||
+#endif
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0)
|
|
||||||
rx_packets = stats64->rx_packets;
|
|
||||||
rx_bytes = stats64->rx_bytes;
|
|
||||||
@@ -724,7 +728,11 @@ static struct rtnl_link_stats64 *_rmnet_
|
|
||||||
tx_packets = u64_stats_read(&stats64->tx_packets);
|
|
||||||
tx_bytes = u64_stats_read(&stats64->tx_bytes);
|
|
||||||
#endif
|
|
||||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6,6,0)
|
|
||||||
} while (u64_stats_fetch_retry_irq(&stats64->syncp, start));
|
|
||||||
+#else
|
|
||||||
+ } while (u64_stats_fetch_retry(&stats64->syncp, start));
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
stats->rx_packets += rx_packets;
|
|
||||||
stats->rx_bytes += rx_bytes;
|
|
||||||
@@ -1187,7 +1195,11 @@ static int qmap_register_device(sQmiWwan
|
|
||||||
priv->mux_id = FIBOCOM_QMAP_MUX_ID + offset_id;
|
|
||||||
sprintf(qmap_net->name, "%s.%d", real_dev->name, offset_id + 1);
|
|
||||||
qmap_net->netdev_ops = &qmap_netdev_ops;
|
|
||||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5,17,0)
|
|
||||||
memcpy (qmap_net->dev_addr, real_dev->dev_addr, ETH_ALEN);
|
|
||||||
+#else
|
|
||||||
+ __dev_addr_set(qmap_net, real_dev->dev_addr, ETH_ALEN);
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
#ifdef FIBOCOM_BRIDGE_MODE
|
|
||||||
priv->bridge_mode = !!(pDev->bridge_mode & BIT(offset_id));
|
|
||||||
@@ -1196,8 +1208,12 @@ static int qmap_register_device(sQmiWwan
|
|
||||||
|
|
||||||
priv->agg_skb = NULL;
|
|
||||||
priv->agg_count = 0;
|
|
||||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6,18,0)
|
|
||||||
hrtimer_init(&priv->agg_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
|
||||||
priv->agg_hrtimer.function = rmnet_usb_tx_agg_timer_cb;
|
|
||||||
+#else
|
|
||||||
+ hrtimer_setup(&priv->agg_hrtimer, rmnet_usb_tx_agg_timer_cb, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
|
||||||
+#endif
|
|
||||||
INIT_WORK(&priv->agg_wq, rmnet_usb_tx_agg_work);
|
|
||||||
ktime_get_ts64(&priv->agg_time);
|
|
||||||
spin_lock_init(&priv->agg_lock);
|
|
||||||
@@ -1319,7 +1335,7 @@ typedef struct {
|
|
||||||
unsigned int dl_minimum_padding; //0x1A
|
|
||||||
} QMAP_SETTING;
|
|
||||||
|
|
||||||
-int qma_setting_store(struct device *dev, QMAP_SETTING *qmap_settings, size_t size) {
|
|
||||||
+static int qma_setting_store(struct device *dev, QMAP_SETTING *qmap_settings, size_t size) {
|
|
||||||
struct net_device *netdev = to_net_dev(dev);
|
|
||||||
struct usbnet * usbnetdev = netdev_priv( netdev );
|
|
||||||
struct qmi_wwan_state *info = (void *)&usbnetdev->data;
|
|
||||||
@@ -1760,8 +1776,14 @@ static void ql_net_get_drvinfo(struct ne
|
|
||||||
{
|
|
||||||
/* Inherit standard device info */
|
|
||||||
usbnet_get_drvinfo(net, info);
|
|
||||||
+ /* strlcpy() is deprecated in kernel 6.8.0+, using strscpy instead */
|
|
||||||
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0))
|
|
||||||
strlcpy(info->driver, driver_name, sizeof(info->driver));
|
|
||||||
strlcpy(info->version, VERSION_NUMBER, sizeof(info->version));
|
|
||||||
+#else
|
|
||||||
+ strscpy(info->driver, driver_name, sizeof(info->driver));
|
|
||||||
+ strscpy(info->version, VERSION_NUMBER, sizeof(info->version));
|
|
||||||
+#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ethtool_ops ql_net_ethtool_ops;
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
From 85990e155cb684ec6380bcf70f588255ec41dc69 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?=E7=80=AC=E5=90=8D=E7=94=B1=E5=B8=8C?=
|
|
||||||
<wanglei199909210927@gmail.com>
|
|
||||||
Date: Wed, 5 Nov 2025 14:16:56 +0800
|
|
||||||
Subject: [PATCH] qmi_wwan: return correct tx/rx stats in kernel 6.10+ (#130)
|
|
||||||
|
|
||||||
---
|
|
||||||
driver/fibocom_QMI_WWAN/src/qmi_wwan_f.c | 9 ++++++++-
|
|
||||||
driver/quectel_QMI_WWAN/src/qmi_wwan_q.c | 7 +++++++
|
|
||||||
2 files changed, 15 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
--- a/qmi_wwan_f.c
|
|
||||||
+++ b/qmi_wwan_f.c
|
|
||||||
@@ -1910,8 +1910,15 @@ static int qmi_wwan_bind(struct usbnet *
|
|
||||||
dev_addr_mod(dev->net, 0, &addr, 1);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
- if (!_usbnet_get_stats64)
|
|
||||||
+ if (!_usbnet_get_stats64)
|
|
||||||
+#if (LINUX_VERSION_CODE < KERNEL_VERSION( 6,10,0 ))
|
|
||||||
_usbnet_get_stats64 = dev->net->netdev_ops->ndo_get_stats64;
|
|
||||||
+#else
|
|
||||||
+ /* From kernel 6.10+, usbnet sets pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS (352f5b3282), but removed ndo_get_stats64 (9cb3d523c1) */
|
|
||||||
+ /* Use dev_get_tstats64 to read per-CPU stats when NETDEV_PCPU_STAT_TSTATS was set */
|
|
||||||
+ if (dev->net->pcpu_stat_type == NETDEV_PCPU_STAT_TSTATS)
|
|
||||||
+ _usbnet_get_stats64 = dev_get_tstats64;
|
|
||||||
+#endif
|
|
||||||
dev->net->netdev_ops = &qmi_wwan_netdev_ops;
|
|
||||||
|
|
||||||
ql_net_ethtool_ops = *dev->net->ethtool_ops;
|
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
|||||||
|
|
||||||
PKG_NAME:=qmi_wwan_f
|
PKG_NAME:=qmi_wwan_f
|
||||||
PKG_VERSION:=1.0
|
PKG_VERSION:=1.0
|
||||||
PKG_RELEASE:=4
|
PKG_RELEASE:=5
|
||||||
|
|
||||||
include $(INCLUDE_DIR)/kernel.mk
|
include $(INCLUDE_DIR)/kernel.mk
|
||||||
include $(INCLUDE_DIR)/package.mk
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|||||||
@@ -712,19 +712,27 @@ static struct rtnl_link_stats64 *_rmnet_vnd_get_stats64(struct net_device *net,
|
|||||||
stats64 = per_cpu_ptr(dev->stats64, cpu);
|
stats64 = per_cpu_ptr(dev->stats64, cpu);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(6,6,0)
|
||||||
start = u64_stats_fetch_begin_irq(&stats64->syncp);
|
start = u64_stats_fetch_begin_irq(&stats64->syncp);
|
||||||
|
#else
|
||||||
|
start = u64_stats_fetch_begin(&stats64->syncp);
|
||||||
|
#endif
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0)
|
||||||
rx_packets = stats64->rx_packets;
|
rx_packets = stats64->rx_packets;
|
||||||
rx_bytes = stats64->rx_bytes;
|
rx_bytes = stats64->rx_bytes;
|
||||||
tx_packets = stats64->tx_packets;
|
tx_packets = stats64->tx_packets;
|
||||||
tx_bytes = stats64->tx_bytes;
|
tx_bytes = stats64->tx_bytes;
|
||||||
#else
|
#else
|
||||||
rx_packets = u64_stats_read(&stats64->rx_packets);
|
rx_packets = u64_stats_read(&stats64->rx_packets);
|
||||||
rx_bytes = u64_stats_read(&stats64->rx_bytes);
|
rx_bytes = u64_stats_read(&stats64->rx_bytes);
|
||||||
tx_packets = u64_stats_read(&stats64->tx_packets);
|
tx_packets = u64_stats_read(&stats64->tx_packets);
|
||||||
tx_bytes = u64_stats_read(&stats64->tx_bytes);
|
tx_bytes = u64_stats_read(&stats64->tx_bytes);
|
||||||
#endif
|
#endif
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(6,6,0)
|
||||||
} while (u64_stats_fetch_retry_irq(&stats64->syncp, start));
|
} while (u64_stats_fetch_retry_irq(&stats64->syncp, start));
|
||||||
|
#else
|
||||||
|
} while (u64_stats_fetch_retry(&stats64->syncp, start));
|
||||||
|
#endif
|
||||||
|
|
||||||
stats->rx_packets += rx_packets;
|
stats->rx_packets += rx_packets;
|
||||||
stats->rx_bytes += rx_bytes;
|
stats->rx_bytes += rx_bytes;
|
||||||
@@ -1187,7 +1195,11 @@ static int qmap_register_device(sQmiWwanQmap * pDev, u8 offset_id)
|
|||||||
priv->mux_id = FIBOCOM_QMAP_MUX_ID + offset_id;
|
priv->mux_id = FIBOCOM_QMAP_MUX_ID + offset_id;
|
||||||
sprintf(qmap_net->name, "%s.%d", real_dev->name, offset_id + 1);
|
sprintf(qmap_net->name, "%s.%d", real_dev->name, offset_id + 1);
|
||||||
qmap_net->netdev_ops = &qmap_netdev_ops;
|
qmap_net->netdev_ops = &qmap_netdev_ops;
|
||||||
memcpy (qmap_net->dev_addr, real_dev->dev_addr, ETH_ALEN);
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,17,0)
|
||||||
|
memcpy(qmap_net->dev_addr, real_dev->dev_addr, ETH_ALEN);
|
||||||
|
#else
|
||||||
|
__dev_addr_set(qmap_net, real_dev->dev_addr, ETH_ALEN);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef FIBOCOM_BRIDGE_MODE
|
#ifdef FIBOCOM_BRIDGE_MODE
|
||||||
priv->bridge_mode = !!(pDev->bridge_mode & BIT(offset_id));
|
priv->bridge_mode = !!(pDev->bridge_mode & BIT(offset_id));
|
||||||
@@ -1760,8 +1772,14 @@ static void ql_net_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *i
|
|||||||
{
|
{
|
||||||
/* Inherit standard device info */
|
/* Inherit standard device info */
|
||||||
usbnet_get_drvinfo(net, info);
|
usbnet_get_drvinfo(net, info);
|
||||||
|
/* strlcpy() is deprecated in kernel 6.8.0+, using strscpy instead */
|
||||||
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0))
|
||||||
strlcpy(info->driver, driver_name, sizeof(info->driver));
|
strlcpy(info->driver, driver_name, sizeof(info->driver));
|
||||||
strlcpy(info->version, VERSION_NUMBER, sizeof(info->version));
|
strlcpy(info->version, VERSION_NUMBER, sizeof(info->version));
|
||||||
|
#else
|
||||||
|
strscpy(info->driver, driver_name, sizeof(info->driver));
|
||||||
|
strscpy(info->version, VERSION_NUMBER, sizeof(info->version));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ethtool_ops ql_net_ethtool_ops;
|
static struct ethtool_ops ql_net_ethtool_ops;
|
||||||
|
|||||||
+13
-1
@@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
|
|||||||
|
|
||||||
PKG_NAME:=gecoosac
|
PKG_NAME:=gecoosac
|
||||||
PKG_VERSION:=2.2.20251015
|
PKG_VERSION:=2.2.20251015
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=2
|
||||||
|
|
||||||
ifeq ($(ARCH),aarch64)
|
ifeq ($(ARCH),aarch64)
|
||||||
PKG_ARCH:=ac_linux_arm64
|
PKG_ARCH:=ac_linux_arm64
|
||||||
@@ -44,12 +44,24 @@ define Package/$(PKG_NAME)
|
|||||||
DEPENDS:=@(aarch64||arm||i386||mips||mipsel||x86_64)
|
DEPENDS:=@(aarch64||arm||i386||mips||mipsel||x86_64)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
define Package/$(PKG_NAME)/conffiles
|
||||||
|
/etc/config/gecoosac
|
||||||
|
/etc/gecoosac/
|
||||||
|
endef
|
||||||
|
|
||||||
define Build/Compile
|
define Build/Compile
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/$(PKG_NAME)/install
|
define Package/$(PKG_NAME)/install
|
||||||
$(INSTALL_DIR) $(1)/usr/bin
|
$(INSTALL_DIR) $(1)/usr/bin
|
||||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/usr/bin
|
$(INSTALL_BIN) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/usr/bin
|
||||||
|
$(INSTALL_DIR) $(1)/etc/init.d
|
||||||
|
$(INSTALL_BIN) ./files/etc/init.d/gecoosac $(1)/etc/init.d/gecoosac
|
||||||
|
$(INSTALL_DIR) $(1)/etc/config
|
||||||
|
$(INSTALL_CONF) ./files/etc/config/gecoosac $(1)/etc/config/gecoosac
|
||||||
|
$(INSTALL_DIR) $(1)/etc/uci-defaults
|
||||||
|
$(INSTALL_BIN) ./files/etc/uci-defaults/gecoosac $(1)/etc/uci-defaults/gecoosac
|
||||||
|
$(INSTALL_DIR) $(1)/etc/gecoosac/tls
|
||||||
endef
|
endef
|
||||||
|
|
||||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
$(eval $(call BuildPackage,$(PKG_NAME)))
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
config gecoosac 'config'
|
||||||
|
option enabled '0'
|
||||||
|
option port '60650'
|
||||||
|
option isonlyoneprot '0'
|
||||||
|
option m_port '8080'
|
||||||
|
option https '0'
|
||||||
|
option crt_file '/etc/gecoosac/tls/gecoosac.crt'
|
||||||
|
option key_file '/etc/gecoosac/tls/gecoosac.key'
|
||||||
|
option upload_dir '/tmp/gecoosac/upload/'
|
||||||
|
option db_dir '/etc/gecoosac/'
|
||||||
|
option piddir '/var/run/'
|
||||||
|
option lang 'zh'
|
||||||
|
option debug '0'
|
||||||
|
option showtip '1'
|
||||||
|
option log '0'
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
#!/bin/sh /etc/rc.common
|
||||||
|
# Copyright (C) 2024 ImmortalWrt
|
||||||
|
|
||||||
|
. /lib/functions.sh
|
||||||
|
. /lib/functions/procd.sh
|
||||||
|
|
||||||
|
USE_PROCD=1
|
||||||
|
|
||||||
|
START=90
|
||||||
|
STOP=10
|
||||||
|
|
||||||
|
PROG=/usr/bin/gecoosac
|
||||||
|
DEFAULT_DB_DIR=/etc/gecoosac/
|
||||||
|
DEFAULT_UPLOAD_DIR=/tmp/gecoosac/upload/
|
||||||
|
DEFAULT_CRT_FILE=/etc/gecoosac/tls/gecoosac.crt
|
||||||
|
DEFAULT_KEY_FILE=/etc/gecoosac/tls/gecoosac.key
|
||||||
|
DEFAULT_PID_DIR=/var/run/
|
||||||
|
DEFAULT_LANG=zh
|
||||||
|
|
||||||
|
init_conf() {
|
||||||
|
config_load "gecoosac"
|
||||||
|
config_get "db_dir" "config" "db_dir" "$DEFAULT_DB_DIR"
|
||||||
|
config_get "upload_dir" "config" "upload_dir" "$DEFAULT_UPLOAD_DIR"
|
||||||
|
config_get "enabled" "config" "enabled" "0"
|
||||||
|
config_get "port" "config" "port" "60650"
|
||||||
|
config_get "isonlyoneprot" "config" "isonlyoneprot" "0"
|
||||||
|
config_get "m_port" "config" "m_port" "8080"
|
||||||
|
config_get "https" "config" "https" "0"
|
||||||
|
config_get "crt_file" "config" "crt_file" "$DEFAULT_CRT_FILE"
|
||||||
|
config_get "key_file" "config" "key_file" "$DEFAULT_KEY_FILE"
|
||||||
|
config_get "piddir" "config" "piddir" "$DEFAULT_PID_DIR"
|
||||||
|
config_get "lang" "config" "lang" "$DEFAULT_LANG"
|
||||||
|
config_get "debug" "config" "debug" "0"
|
||||||
|
config_get "showtip" "config" "showtip" "1"
|
||||||
|
config_get "log" "config" "log" "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
is_abs_path() {
|
||||||
|
case "$1" in
|
||||||
|
/*) return 0 ;;
|
||||||
|
*) return 1 ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
is_port() {
|
||||||
|
case "$1" in
|
||||||
|
""|*[!0-9]*) return 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
[ "$1" -ge 1 ] 2>/dev/null && [ "$1" -le 65535 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
normalize_conf() {
|
||||||
|
is_abs_path "$upload_dir" || upload_dir="$DEFAULT_UPLOAD_DIR"
|
||||||
|
is_abs_path "$db_dir" || db_dir="$DEFAULT_DB_DIR"
|
||||||
|
is_abs_path "$crt_file" || crt_file="$DEFAULT_CRT_FILE"
|
||||||
|
is_abs_path "$key_file" || key_file="$DEFAULT_KEY_FILE"
|
||||||
|
is_abs_path "$piddir" && [ "$piddir" != "/" ] || piddir="$DEFAULT_PID_DIR"
|
||||||
|
is_port "$port" || port="60650"
|
||||||
|
is_port "$m_port" || m_port="8080"
|
||||||
|
|
||||||
|
[ "$enabled" = "1" ] || enabled="0"
|
||||||
|
[ "$isonlyoneprot" = "1" ] || isonlyoneprot="0"
|
||||||
|
[ "$https" = "1" ] || https="0"
|
||||||
|
case "$lang" in
|
||||||
|
zh|en) ;;
|
||||||
|
*) lang="$DEFAULT_LANG" ;;
|
||||||
|
esac
|
||||||
|
[ "$debug" = "1" ] || debug="0"
|
||||||
|
[ "$showtip" = "0" ] || showtip="1"
|
||||||
|
[ "$log" = "1" ] || log="0"
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_dirs() {
|
||||||
|
mkdir -p "$upload_dir" "$db_dir" "$piddir" /etc/gecoosac/tls
|
||||||
|
}
|
||||||
|
|
||||||
|
start_service() {
|
||||||
|
init_conf
|
||||||
|
normalize_conf
|
||||||
|
|
||||||
|
[ "$enabled" = "1" ] || return 0
|
||||||
|
if [ ! -x "$PROG" ]; then
|
||||||
|
logger -t gecoosac "program not found: $PROG"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ensure_dirs
|
||||||
|
|
||||||
|
if [ "$isonlyoneprot" = "0" ] && [ "$https" = "1" ]; then
|
||||||
|
if [ ! -r "$crt_file" ] || [ ! -r "$key_file" ]; then
|
||||||
|
logger -t gecoosac "HTTPS is enabled but certificate or key file is missing"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
procd_open_instance gecoosac
|
||||||
|
procd_set_param command "$PROG"
|
||||||
|
procd_append_param command -f "$upload_dir"
|
||||||
|
procd_append_param command -p "$port"
|
||||||
|
procd_append_param command -debug "$debug"
|
||||||
|
procd_append_param command -dbpath "$db_dir"
|
||||||
|
procd_append_param command -token "1"
|
||||||
|
procd_append_param command -lang "$lang"
|
||||||
|
procd_append_param command -piddir "$piddir"
|
||||||
|
if [ "$isonlyoneprot" = "0" ]; then
|
||||||
|
procd_append_param command -isonlyoneprot "0"
|
||||||
|
procd_append_param command -mp "$m_port"
|
||||||
|
if [ "$https" = "1" ]; then
|
||||||
|
procd_append_param command -https "1"
|
||||||
|
procd_append_param command -crt "$crt_file"
|
||||||
|
procd_append_param command -key "$key_file"
|
||||||
|
else
|
||||||
|
procd_append_param command -https "0"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
procd_append_param command -isonlyoneprot "1"
|
||||||
|
fi
|
||||||
|
procd_append_param command -showtip "$showtip"
|
||||||
|
procd_set_param env GIN_MODE=release
|
||||||
|
procd_set_param file /etc/config/gecoosac
|
||||||
|
procd_set_param pidfile "${piddir%/}/gecoosac.pid"
|
||||||
|
procd_set_param stdout "$log"
|
||||||
|
procd_set_param stderr "$log"
|
||||||
|
procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
|
||||||
|
procd_close_instance
|
||||||
|
}
|
||||||
|
|
||||||
|
reload_service() {
|
||||||
|
stop
|
||||||
|
start
|
||||||
|
}
|
||||||
|
|
||||||
|
service_triggers() {
|
||||||
|
procd_add_reload_trigger "gecoosac"
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
changed=0
|
||||||
|
|
||||||
|
ensure_section() {
|
||||||
|
uci -q get gecoosac.config >/dev/null && return 0
|
||||||
|
uci -q set gecoosac.config=gecoosac
|
||||||
|
changed=1
|
||||||
|
}
|
||||||
|
|
||||||
|
set_default() {
|
||||||
|
local option="$1"
|
||||||
|
local value="$2"
|
||||||
|
|
||||||
|
uci -q get "gecoosac.config.${option}" >/dev/null && return 0
|
||||||
|
uci -q set "gecoosac.config.${option}=${value}"
|
||||||
|
changed=1
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_section
|
||||||
|
set_default enabled 0
|
||||||
|
set_default port 60650
|
||||||
|
set_default isonlyoneprot 0
|
||||||
|
set_default m_port 8080
|
||||||
|
set_default https 0
|
||||||
|
set_default crt_file /etc/gecoosac/tls/gecoosac.crt
|
||||||
|
set_default key_file /etc/gecoosac/tls/gecoosac.key
|
||||||
|
set_default upload_dir /tmp/gecoosac/upload/
|
||||||
|
set_default db_dir /etc/gecoosac/
|
||||||
|
set_default piddir /var/run/
|
||||||
|
set_default lang zh
|
||||||
|
set_default debug 0
|
||||||
|
# Preserve the previous package behavior for upgraded configs that never had showtip.
|
||||||
|
set_default showtip 0
|
||||||
|
set_default log 0
|
||||||
|
|
||||||
|
[ "$changed" = "1" ] && uci -q commit gecoosac
|
||||||
|
|
||||||
|
exit 0
|
||||||
@@ -7,16 +7,12 @@ include $(TOPDIR)/rules.mk
|
|||||||
|
|
||||||
PKG_NAME:=luci-app-gecoosac
|
PKG_NAME:=luci-app-gecoosac
|
||||||
PKG_VERSION:=2.2
|
PKG_VERSION:=2.2
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=2
|
||||||
|
|
||||||
LUCI_TITLE:=LuCI Support for gecoosac
|
LUCI_TITLE:=LuCI Support for gecoosac
|
||||||
LUCI_DEPENDS:=+luci-compat +gecoosac
|
LUCI_DEPENDS:=+luci-compat +gecoosac
|
||||||
LUCI_PKGARCH:=all
|
LUCI_PKGARCH:=all
|
||||||
|
|
||||||
define Package/$(PKG_NAME)/conffiles
|
|
||||||
/etc/gecoosac
|
|
||||||
endef
|
|
||||||
|
|
||||||
include $(TOPDIR)/feeds/luci/luci.mk
|
include $(TOPDIR)/feeds/luci/luci.mk
|
||||||
|
|
||||||
# call BuildPackage - OpenWrt buildroot signature
|
# call BuildPackage - OpenWrt buildroot signature
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
|
|
||||||
module("luci.controller.gecoosac", package.seeall)
|
module("luci.controller.gecoosac", package.seeall)
|
||||||
|
|
||||||
|
local fs = require "nixio.fs"
|
||||||
|
local sys = require "luci.sys"
|
||||||
|
|
||||||
function index()
|
function index()
|
||||||
if not nixio.fs.access("/etc/config/gecoosac") then
|
if not fs.access("/etc/config/gecoosac") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local page
|
local page
|
||||||
@@ -13,17 +16,9 @@ function index()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function act_status()
|
function act_status()
|
||||||
local e = {}
|
local e = {
|
||||||
local binpath = "/usr/bin/gecoosac"
|
running = sys.call("/etc/init.d/gecoosac status >/dev/null 2>&1") == 0
|
||||||
e = {
|
|
||||||
running = luci.sys.call("pgrep " .. binpath .. " >/dev/null") == 0
|
|
||||||
}
|
}
|
||||||
luci.http.prepare_content("application/json")
|
luci.http.prepare_content("application/json")
|
||||||
luci.http.write_json(e)
|
luci.http.write_json(e)
|
||||||
end
|
end
|
||||||
|
|
||||||
function clear_upload()
|
|
||||||
local path = "/tmp/gecoosac/upload/"
|
|
||||||
luci.sys.call("rm -rf " .. path .. "/*")
|
|
||||||
luci.http.status(200, "OK")
|
|
||||||
end
|
|
||||||
@@ -1,11 +1,88 @@
|
|||||||
function program_exists(program)
|
local fs = require "nixio.fs"
|
||||||
local handle = io.popen('which ' .. program)
|
|
||||||
local result = handle:read('*a')
|
local DEFAULT_UPLOAD_DIR = "/tmp/gecoosac/upload/"
|
||||||
handle:close()
|
local DEFAULT_DB_DIR = "/etc/gecoosac/"
|
||||||
return result ~= ''
|
local DEFAULT_CRT_FILE = "/etc/gecoosac/tls/gecoosac.crt"
|
||||||
|
local DEFAULT_KEY_FILE = "/etc/gecoosac/tls/gecoosac.key"
|
||||||
|
local DEFAULT_PID_DIR = "/var/run/"
|
||||||
|
|
||||||
|
local function trim(value)
|
||||||
|
return (value or ""):gsub("^%s+", ""):gsub("%s+$", "")
|
||||||
end
|
end
|
||||||
|
|
||||||
if program_exists("/usr/bin/gecoosac") then
|
local function is_abs_path(value)
|
||||||
|
return type(value) == "string" and value:match("^/") and not value:find("[%z\r\n]")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function validate_abs_path(self, value)
|
||||||
|
value = trim(value)
|
||||||
|
if is_abs_path(value) then
|
||||||
|
return value
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil, translate("Expecting an absolute path")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function is_upload_path(path)
|
||||||
|
path = trim(path):gsub("/+$", "")
|
||||||
|
return path == "/tmp/gecoosac/upload" or path:match("/gecoosac/upload$") ~= nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local function remove_tree(path)
|
||||||
|
local stat = fs.lstat and fs.lstat(path) or fs.stat(path)
|
||||||
|
if not stat then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if stat.type == "dir" then
|
||||||
|
local iter = fs.dir(path)
|
||||||
|
if iter then
|
||||||
|
for entry in iter do
|
||||||
|
if entry ~= "." and entry ~= ".." then
|
||||||
|
remove_tree(path .. "/" .. entry)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
fs.rmdir(path)
|
||||||
|
else
|
||||||
|
fs.unlink(path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function clear_upload_dir(path)
|
||||||
|
path = trim(path)
|
||||||
|
if path == "" then
|
||||||
|
path = DEFAULT_UPLOAD_DIR
|
||||||
|
end
|
||||||
|
|
||||||
|
path = path:gsub("/+$", "")
|
||||||
|
if not is_abs_path(path) then
|
||||||
|
return nil, translate("Expecting an absolute path")
|
||||||
|
end
|
||||||
|
|
||||||
|
local real = fs.realpath(path) or path
|
||||||
|
real = real:gsub("/+$", "")
|
||||||
|
if not is_upload_path(real) then
|
||||||
|
return nil, translate("Only Gecoos upload directories can be cleared")
|
||||||
|
end
|
||||||
|
|
||||||
|
if fs.stat(real, "type") ~= "dir" then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local iter = fs.dir(real)
|
||||||
|
if iter then
|
||||||
|
for entry in iter do
|
||||||
|
if entry ~= "." and entry ~= ".." then
|
||||||
|
remove_tree(real .. "/" .. entry)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
if fs.access("/usr/bin/gecoosac") then
|
||||||
m = Map("gecoosac", translate("Gecoos AC"), translate("Batch management Gecoos AP, Default password: admin") .. "<br>" .. translatef("The current AC version %s, only supports AP 7.6 and above.","2.2"))
|
m = Map("gecoosac", translate("Gecoos AC"), translate("Batch management Gecoos AP, Default password: admin") .. "<br>" .. translatef("The current AC version %s, only supports AP 7.6 and above.","2.2"))
|
||||||
else
|
else
|
||||||
m = Map("gecoosac", translate("Gecoos AC"), translate("Batch management Gecoos AP, Default password: admin") .. "<br>" .. translate("The AC program does not exist, please check."))
|
m = Map("gecoosac", translate("Gecoos AC"), translate("Batch management Gecoos AP, Default password: admin") .. "<br>" .. translate("The AC program does not exist, please check."))
|
||||||
@@ -27,48 +104,75 @@ o.datatype = "port"
|
|||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
|
|
||||||
o = s:option(Flag, "isonlyoneprot", translate("Single Port Mode"), translate("Do not enable the independent management port, only use one port for management."))
|
o = s:option(Flag, "isonlyoneprot", translate("Single Port Mode"), translate("Do not enable the independent management port, only use one port for management."))
|
||||||
o.default = 1
|
o.default = 0
|
||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
|
|
||||||
o = s:option(Value, "m_port", translate("Set management port"))
|
o = s:option(Value, "m_port", translate("Set management port"))
|
||||||
o.placeholder = 8080
|
o.placeholder = 8080
|
||||||
o.default = 8080
|
o.default = 8080
|
||||||
o.datatype = "port"
|
o.datatype = "port"
|
||||||
o:depends("isonlyoneprot", false)
|
o:depends("isonlyoneprot", "0")
|
||||||
|
|
||||||
o = s:option(Flag, "https", translate("Enable HTTPS service"), translate("A certificate file must be specified, otherwise it will fail to start."))
|
o = s:option(Flag, "https", translate("Enable HTTPS service"), translate("A certificate file must be specified, otherwise it will fail to start."))
|
||||||
o.default = 0
|
o.default = 0
|
||||||
o:depends("isonlyoneprot", false)
|
o:depends("isonlyoneprot", "0")
|
||||||
|
|
||||||
o = s:option(Value, "crt_file", translate("Specify crt certificate file"))
|
o = s:option(Value, "crt_file", translate("Specify crt certificate file"))
|
||||||
o.placeholder = "/etc/gecoosac/tls/1.crt"
|
o.placeholder = DEFAULT_CRT_FILE
|
||||||
o.default = "/etc/gecoosac/tls/1.crt"
|
o.default = DEFAULT_CRT_FILE
|
||||||
o:depends("https", true)
|
o.validate = validate_abs_path
|
||||||
|
o:depends({isonlyoneprot = "0", https = "1"})
|
||||||
|
|
||||||
o = s:option(Value, "key_file", translate("Specify key certificate file"))
|
o = s:option(Value, "key_file", translate("Specify key certificate file"))
|
||||||
o.placeholder = "/etc/gecoosac/tls/1.key"
|
o.placeholder = DEFAULT_KEY_FILE
|
||||||
o.default = "/etc/gecoosac/tls/1.key"
|
o.default = DEFAULT_KEY_FILE
|
||||||
o:depends("https", true)
|
o.validate = validate_abs_path
|
||||||
|
o:depends({isonlyoneprot = "0", https = "1"})
|
||||||
|
|
||||||
upload_dir = s:option(Value, "upload_dir", translate("Upload dir path"), translate("The path to upload AP upgrade firmware"))
|
upload_dir = s:option(Value, "upload_dir", translate("Upload dir path"), translate("The path to upload AP upgrade firmware"))
|
||||||
upload_dir.placeholder = "/tmp/gecoosac/upload/"
|
upload_dir.placeholder = DEFAULT_UPLOAD_DIR
|
||||||
upload_dir.default = "/tmp/gecoosac/upload/"
|
upload_dir.default = DEFAULT_UPLOAD_DIR
|
||||||
upload_dir.rmempty = false
|
upload_dir.rmempty = false
|
||||||
|
upload_dir.validate = validate_abs_path
|
||||||
|
|
||||||
db_dir = s:option(Value, "db_dir", translate("Database dir path"), translate("The path to store the config database"))
|
db_dir = s:option(Value, "db_dir", translate("Database dir path"), translate("The path to store the config database"))
|
||||||
db_dir.placeholder = "/etc/gecoosac/"
|
db_dir.placeholder = DEFAULT_DB_DIR
|
||||||
db_dir.default = "/etc/gecoosac/"
|
db_dir.default = DEFAULT_DB_DIR
|
||||||
db_dir.rmempty = false
|
db_dir.rmempty = false
|
||||||
|
db_dir.validate = validate_abs_path
|
||||||
|
|
||||||
|
o = s:option(Value, "piddir", translate("PID dir path"), translate("The path to store the AC program pid file"))
|
||||||
|
o.placeholder = DEFAULT_PID_DIR
|
||||||
|
o.default = DEFAULT_PID_DIR
|
||||||
|
o.rmempty = false
|
||||||
|
o.validate = validate_abs_path
|
||||||
|
|
||||||
|
o = s:option(ListValue, "lang", translate("Language"))
|
||||||
|
o:value("zh", translate("Chinese"))
|
||||||
|
o:value("en", translate("English"))
|
||||||
|
o.default = "zh"
|
||||||
|
o.rmempty = false
|
||||||
|
|
||||||
|
debug = s:option(Flag, "debug", translate("Debug Mode"))
|
||||||
|
debug.default = 0
|
||||||
|
debug.rmempty = false
|
||||||
|
|
||||||
|
showtip = s:option(Flag, "showtip", translate("Show IP Tip"), translate("Show the IP 6.7.8.9 setup tip when it is not configured."))
|
||||||
|
showtip.default = 1
|
||||||
|
showtip.rmempty = false
|
||||||
|
|
||||||
log = s:option(Flag, "log", translate("Enable Log"))
|
log = s:option(Flag, "log", translate("Enable Log"))
|
||||||
log.default = 1
|
log.default = 0
|
||||||
log.rmempty = false
|
log.rmempty = false
|
||||||
|
|
||||||
clear_upload = s:option(Button, "clear_upload", translate("Clear Upload Directory"))
|
clear_upload = s:option(Button, "clear_upload", translate("Clear Upload Directory"))
|
||||||
clear_upload.inputstyle = "remove"
|
clear_upload.inputstyle = "remove"
|
||||||
clear_upload.write = function(self, section)
|
clear_upload.write = function(self, section)
|
||||||
local path = upload_dir:formvalue(section) or "/tmp/gecoosac/upload/"
|
local path = upload_dir:formvalue(section) or upload_dir:cfgvalue(section) or DEFAULT_UPLOAD_DIR
|
||||||
luci.sys.call("rm -rf " .. path .. "/*")
|
local ok, err = clear_upload_dir(path)
|
||||||
|
if not ok then
|
||||||
|
self.map.message = err or translate("Upload directory was not cleared")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return m
|
return m
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
<%
|
<%
|
||||||
local uci=require"luci.model.uci".cursor()
|
local uci=require"luci.model.uci".cursor()
|
||||||
|
local json=require"luci.jsonc"
|
||||||
|
|
||||||
local isonlyoneprot = uci:get("gecoosac", "config", "isonlyoneprot") or "1"
|
local isonlyoneprot = uci:get("gecoosac", "config", "isonlyoneprot") or "0"
|
||||||
local https = uci:get("gecoosac", "config", "https") or "0"
|
local https = uci:get("gecoosac", "config", "https") or "0"
|
||||||
local port = uci:get("gecoosac", "config", "port") or "60650"
|
local port = uci:get("gecoosac", "config", "port") or "60650"
|
||||||
local m_port = uci:get("gecoosac", "config", "m_port") or "8080"
|
local m_port = uci:get("gecoosac", "config", "m_port") or "8080"
|
||||||
@@ -14,8 +15,8 @@ if isonlyoneprot == "0" then
|
|||||||
end
|
end
|
||||||
-%>
|
-%>
|
||||||
<script type="text/javascript">//<![CDATA[
|
<script type="text/javascript">//<![CDATA[
|
||||||
var Port = "<%=port%>"
|
var Port = <%=json.stringify(port)%>;
|
||||||
var Http = "<%=http%>"
|
var Http = <%=json.stringify(http)%>;
|
||||||
XHR.poll(3, '<%=url([[admin]], [[services]], [[gecoosac]], [[status]])%>', null,
|
XHR.poll(3, '<%=url([[admin]], [[services]], [[gecoosac]], [[status]])%>', null,
|
||||||
function(x, data) {
|
function(x, data) {
|
||||||
var tb = document.getElementById('gecoosac_status');
|
var tb = document.getElementById('gecoosac_status');
|
||||||
@@ -30,8 +31,16 @@ XHR.poll(3, '<%=url([[admin]], [[services]], [[gecoosac]], [[status]])%>', null,
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function clientHost() {
|
||||||
|
var host = window.location.hostname;
|
||||||
|
if (host.indexOf(':') !== -1 && host.charAt(0) !== '[') {
|
||||||
|
host = '[' + host + ']';
|
||||||
|
}
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
function openClient() {
|
function openClient() {
|
||||||
var url = Http + window.location.hostname + ":" + Port;
|
var url = Http + clientHost() + ":" + Port;
|
||||||
window.open(url);
|
window.open(url);
|
||||||
}
|
}
|
||||||
//]]>
|
//]]>
|
||||||
|
|||||||
@@ -55,6 +55,30 @@ msgstr "数据库目录"
|
|||||||
msgid "The path to store the config database"
|
msgid "The path to store the config database"
|
||||||
msgstr "存放配置数据库的路径"
|
msgstr "存放配置数据库的路径"
|
||||||
|
|
||||||
|
msgid "PID dir path"
|
||||||
|
msgstr "PID 目录"
|
||||||
|
|
||||||
|
msgid "The path to store the AC program pid file"
|
||||||
|
msgstr "存放 AC 程序 PID 文件的路径"
|
||||||
|
|
||||||
|
msgid "Language"
|
||||||
|
msgstr "语言"
|
||||||
|
|
||||||
|
msgid "Chinese"
|
||||||
|
msgstr "中文"
|
||||||
|
|
||||||
|
msgid "English"
|
||||||
|
msgstr "英文"
|
||||||
|
|
||||||
|
msgid "Debug Mode"
|
||||||
|
msgstr "调试模式"
|
||||||
|
|
||||||
|
msgid "Show IP Tip"
|
||||||
|
msgstr "显示 IP 提示"
|
||||||
|
|
||||||
|
msgid "Show the IP 6.7.8.9 setup tip when it is not configured."
|
||||||
|
msgstr "未配置 6.7.8.9 时显示相关提示信息。"
|
||||||
|
|
||||||
msgid "Enable Log"
|
msgid "Enable Log"
|
||||||
msgstr "启用日志"
|
msgstr "启用日志"
|
||||||
|
|
||||||
@@ -72,3 +96,12 @@ msgstr "收集数据..."
|
|||||||
|
|
||||||
msgid "Clear Upload Directory"
|
msgid "Clear Upload Directory"
|
||||||
msgstr "清理上传目录"
|
msgstr "清理上传目录"
|
||||||
|
|
||||||
|
msgid "Expecting an absolute path"
|
||||||
|
msgstr "请输入绝对路径"
|
||||||
|
|
||||||
|
msgid "Only Gecoos upload directories can be cleared"
|
||||||
|
msgstr "只能清理集客 AC 上传目录"
|
||||||
|
|
||||||
|
msgid "Upload directory was not cleared"
|
||||||
|
msgstr "上传目录未清理"
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
config gecoosac 'config'
|
|
||||||
option enabled '0'
|
|
||||||
option port '60650'
|
|
||||||
option isonlyoneprot '1'
|
|
||||||
option upload_dir '/tmp/gecoosac/upload/'
|
|
||||||
option db_dir '/etc/gecoosac/'
|
|
||||||
option log '0'
|
|
||||||
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDljCCAn6gAwIBAgIIeEgcfPZbDC0wDQYJKoZIhvcNAQELBQAwejELMAkGA1UE
|
|
||||||
BhMCQ04xFzAVBgNVBAoTDktleU1hbmFnZXIub3JnMTEwLwYDVQQLEyhLZXlNYW5h
|
|
||||||
Z2VyIFRlc3QgUm9vdCAtIEZvciBUZXN0IFVzZSBPbmx5MR8wHQYDVQQDExZLZXlN
|
|
||||||
YW5hZ2VyIFRlc3QgUlNBIENBMCAXDTI0MTIxMTA0MDUyNloYDzIxMjQxMjExMDQw
|
|
||||||
NTI2WjAZMQswCQYDVQQGEwJDTjEKMAgGA1UEAwwBKjCCASIwDQYJKoZIhvcNAQEB
|
|
||||||
BQADggEPADCCAQoCggEBALM3K/5+yX6H9Dvq8TrKuk0KtFBqmDDP3lKXMpMkWjDn
|
|
||||||
4OtKGq4QtaPPJfGBjitYecyHLWbqGZlWU2H8ug/kL/PtAFgtTgiFvObePbP4VUVO
|
|
||||||
lICitAWCSMo7xsvt/XSGLOF3dV1tCoEcjK9GtJEMOyoqHMOgbuZ986wIR4LkgULz
|
|
||||||
3A2uC5abXP5Exa6phMCv3MojjaVgOFEIuC4371ZeLU/YXja9ssQ0Bs8PzOIjCP7i
|
|
||||||
pce94hYYSgAH3Ua1ZcWVZVEbCytoaOGWXkrhNTVZ+nAarlFY4fgN3yCi+YgFipKU
|
|
||||||
1H9oNr4PgLsxhtM3f19wwu9XNY1RF72cfRPS/mPy86sCAwEAAaN/MH0wDgYDVR0P
|
|
||||||
AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4E
|
|
||||||
FgQUOW6TXeYQEZs1tMI05Vx2aSb9dk0wHwYDVR0jBBgwFoAUfzXMx0QcDHIhuynW
|
|
||||||
4rB+75TRqw8wDAYDVR0RBAUwA4IBKjANBgkqhkiG9w0BAQsFAAOCAQEAl63ixtfN
|
|
||||||
azLCIvIKGhjhqk2aU9NZtnsjYO729bNSk8SGtqVvCyXO8FJwdhoybtBlSkxjyvrb
|
|
||||||
nsR+QbeYGu0ZPsSsJJKuwlsM+ZoTOEGRQrhT7AkkXsNQHSalDCWczPW45xWHkg/s
|
|
||||||
P9xIGeySWMu4CJ1/eZYczT6bzS0eLd05camVCeU2E5N/M7hAO4SnK0agFZnaUEjp
|
|
||||||
13KZA3MfFNXZ2Q7na9CRjTbpqDCOpsLteP22fwUq7zutwvkQsQQYnQuVlpiUjSsV
|
|
||||||
MvY7oxkTi9M5BtowdEtVpWkVO2WOMs5dy2kxfgcIJ5KRZLmU+cPsWgsE76fErIYs
|
|
||||||
FU2leWlNpSvuMw==
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIID2jCCAsKgAwIBAgIILz9r/y+4/ZgwDQYJKoZIhvcNAQELBQAwezELMAkGA1UE
|
|
||||||
BhMCQ04xFzAVBgNVBAoTDktleU1hbmFnZXIub3JnMTEwLwYDVQQLEyhLZXlNYW5h
|
|
||||||
Z2VyIFRlc3QgUm9vdCAtIEZvciBUZXN0IFVzZSBPbmx5MSAwHgYDVQQDExdLZXlN
|
|
||||||
YW5hZ2VyIFRlc3QgUm9vdCBDQTAeFw0yNDEyMTEwMzI3MzJaFw0zNDEyMTEwMzI3
|
|
||||||
MzJaMHoxCzAJBgNVBAYTAkNOMRcwFQYDVQQKEw5LZXlNYW5hZ2VyLm9yZzExMC8G
|
|
||||||
A1UECxMoS2V5TWFuYWdlciBUZXN0IFJvb3QgLSBGb3IgVGVzdCBVc2UgT25seTEf
|
|
||||||
MB0GA1UEAxMWS2V5TWFuYWdlciBUZXN0IFJTQSBDQTCCASIwDQYJKoZIhvcNAQEB
|
|
||||||
BQADggEPADCCAQoCggEBAMa7Tdag8tcvEwqRMD+gVEd4G3XeQyYzSYGLAa9DGji4
|
|
||||||
qUDUcBi0Ml2AndHtNNPcAk4vBUsZ10jjpNtOWtsy+r8VivBIlM5PE38JLhlZWao9
|
|
||||||
JvT1duxfxss+Q7xdT1oO++CDN/6avPXmDD1dmbTD09/cxcPW8M/3aaHfbI5GWxlr
|
|
||||||
ZLu8N50yQQxiXLEJad3n7fPjAosGroqa5FcsJ2vDQHuK13mpZG1eBoNZe6/OAzAz
|
|
||||||
yYkUKyixpS4xc8Agb9BCl7M9Tvkr8VkELGoFPWBMwBsa4BD0OYE7Vc+ZFEqhyzva
|
|
||||||
mOpicU1xl8mMkNIhiIaSU52fzRgYryZKmxPfYo8JaRUCAwEAAaNjMGEwDgYDVR0P
|
|
||||||
AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH81zMdEHAxyIbsp
|
|
||||||
1uKwfu+U0asPMB8GA1UdIwQYMBaAFElv+F66JtNinfmGM1cttCjILv/hMA0GCSqG
|
|
||||||
SIb3DQEBCwUAA4IBAQDOrqBCHRfVrTC/mfIIXcFn3lB+3kGmAmBVxH5UILljPdl9
|
|
||||||
ADjW9iiJtaEYxCOjrnFzpcOvuQnWPC7dbb+cy+DntLy/g6x95kBlAPdp02nYoS42
|
|
||||||
mDHmYUx+rIvnAceSTr72R+Vu9LNVzdbvnULT1o/4kW6uwRnrskisoFkAzeMd/4DT
|
|
||||||
tY71Dkz9faJt4VIE0wF3/jYXbqVhffyu6xXl+mS9mmCw/u9pFXMys2i/5tF90qIx
|
|
||||||
hpcVLhqFq4+dTnXaohC2DRpd+sCH4wRHMIRpi7gWI+6nXwLg95VSSwRNd+C+tyyh
|
|
||||||
GXlSB7/9WOGRGv74M5W9im3VFn5Ot3zMruEtl/WA
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
-----BEGIN RSA PRIVATE KEY-----
|
|
||||||
MIIEogIBAAKCAQEAszcr/n7Jfof0O+rxOsq6TQq0UGqYMM/eUpcykyRaMOfg60oa
|
|
||||||
rhC1o88l8YGOK1h5zIctZuoZmVZTYfy6D+Qv8+0AWC1OCIW85t49s/hVRU6UgKK0
|
|
||||||
BYJIyjvGy+39dIYs4Xd1XW0KgRyMr0a0kQw7Kiocw6Bu5n3zrAhHguSBQvPcDa4L
|
|
||||||
lptc/kTFrqmEwK/cyiONpWA4UQi4LjfvVl4tT9heNr2yxDQGzw/M4iMI/uKlx73i
|
|
||||||
FhhKAAfdRrVlxZVlURsLK2ho4ZZeSuE1NVn6cBquUVjh+A3fIKL5iAWKkpTUf2g2
|
|
||||||
vg+AuzGG0zd/X3DC71c1jVEXvZx9E9L+Y/LzqwIDAQABAoIBAELDuAkMdMZFodA8
|
|
||||||
m3e6lKMk7L3UqDPvDLUaDMZSUaNMjzc4mS3lnbWT81/AUxWE1YNDjL99UOIWDeRA
|
|
||||||
QZSv/slRrsIqxppYMGKVwsjsJ+A1AQ/XDVfMDJACqvHIDJc/cTLhzQBsIfCtkR+v
|
|
||||||
KI+szdHMdIDQoOAPZhrdzr5NoHYvQM7B8HYe5G9dyw5GinRnTNqNUIhFM1HW5Gki
|
|
||||||
dhLAiqUGj2drSsbRoIWIOIzBbM3+hWZK1mO3q+QhdBEPcwzrOgMaj2722Dea57Hb
|
|
||||||
duCpdpKH43JfSmQ+f0V8OS/zYNUcyQikQg+Euak6dOuMhFN1ma7bNEug3slJMQ0M
|
|
||||||
JVG55IECgYEAxNgUXU+ORxCVZjMLxq2Uk2qJxbZspRIQ0ElsvsUpVpw0q0KV7V8K
|
|
||||||
qnxL4c6khOqWZQ9M7PWG4nJgjNXhYW9PpYdTXkmOZzAq+XU8nUYGHR0ZAlDj0oAd
|
|
||||||
lC9m9hBZPovxRozjMcRpnJinkZRLB0KEuTBECB6ZKZscLqbMIH81kWsCgYEA6RLd
|
|
||||||
b1Kk6xUjmUcGnq6bZN4a0spEGLayzgFOA2o/Ma1d94c3NsWsz97KGpCISExBOoPd
|
|
||||||
e/vryCrgvY50U4989z3mOVlcW9IJxaX5jyLmyG1POMkzwpWSST5u1DqnHpZ1xhzo
|
|
||||||
qjdd+F9E05PG8YM/2JYUDoCgL+BWvSYUsW/bdsECgYA2LZr9S8ZHPQNBy87z8haw
|
|
||||||
tGQTLPCeRmimS29I2o9ULU45zOvjF4OiBPAFyJBznPWj/yAXIETt0rlMShnsbWyo
|
|
||||||
jKSfkPNG53UMj/4M85b/MGEPyB/MckKx5JIcK8fEdVQFLQXjTsIavdFxOjWkW+SX
|
|
||||||
6/btnS5eyzhohrQsRZcC3QKBgEuzauSLbTFFjmhsX0QO5j3evcuVEoUMYgry9Ym6
|
|
||||||
aogSDSEmc9KAZd6mN/Jk2z7QNadxyPBKJIzBEHnA2RuC0U3kdvBNi+fu0mm1vNa2
|
|
||||||
uUqD5mVFRGCBACB1/L1Fx53xtJMCNLeEgCr5lns51jX/MS+Bn0YOlPi33rRUuAfh
|
|
||||||
kuCBAoGAPvxUmDXFnYyt8/3t5dpKt1GEpqDdQfhUDqE6zOPulsv0IkMKCvbyHdKI
|
|
||||||
iR1EbSvCMP9aVO7BeVRnr9FSrdL10TWNLP4JveSI4Ee1bzy0vvTj5l8CC4MwSdhN
|
|
||||||
04I8F7UqPhSbdVjsTxw16XrHSkvB5JRZsIAz/K0jVMwZs7fS8Lk=
|
|
||||||
-----END RSA PRIVATE KEY-----
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
#!/bin/sh /etc/rc.common
|
|
||||||
# Copyright (C) 2024 ImmortalWrt
|
|
||||||
|
|
||||||
. /lib/functions.sh
|
|
||||||
. /lib/functions/procd.sh
|
|
||||||
|
|
||||||
USE_PROCD=1
|
|
||||||
|
|
||||||
START=90
|
|
||||||
STOP=10
|
|
||||||
|
|
||||||
init_conf() {
|
|
||||||
config_load "gecoosac"
|
|
||||||
config_get "db_dir" "config" "db_dir" "/etc/gecoosac/"
|
|
||||||
config_get "upload_dir" "config" "upload_dir" "/tmp/gecoosac/upload/"
|
|
||||||
config_get "enabled" "config" "enabled" "0"
|
|
||||||
config_get "port" "config" "port" "60650"
|
|
||||||
config_get "isonlyoneprot" "config" "isonlyoneprot" "1"
|
|
||||||
config_get "m_port" "config" "m_port" "8080"
|
|
||||||
config_get "https" "config" "https" "0"
|
|
||||||
config_get "crt_file" "config" "crt_file" "/etc/gecoosac/tls/1.crt"
|
|
||||||
config_get "key_file" "config" "key_file" "/etc/gecoosac/tls/1.key"
|
|
||||||
config_get "log" "config" "log" "0"
|
|
||||||
}
|
|
||||||
|
|
||||||
start_service() {
|
|
||||||
init_conf
|
|
||||||
[ "${enabled}" = "1" ] || return 0
|
|
||||||
procd_open_instance gecoosac
|
|
||||||
procd_set_param command "/usr/bin/gecoosac"
|
|
||||||
procd_append_param command -f "${upload_dir}"
|
|
||||||
procd_append_param command -p "${port}"
|
|
||||||
procd_append_param command -debug "0"
|
|
||||||
procd_append_param command -dbpath "${db_dir}"
|
|
||||||
procd_append_param command -token "1"
|
|
||||||
if [ "${isonlyoneprot}" = "0" ]; then
|
|
||||||
procd_append_param command -isonlyoneprot "0"
|
|
||||||
procd_append_param command -mp "${m_port}"
|
|
||||||
if [ "${https}" = "1" ]; then
|
|
||||||
procd_append_param command -https "1"
|
|
||||||
procd_append_param command -crt "${crt_file}"
|
|
||||||
procd_append_param command -key "${key_file}"
|
|
||||||
else
|
|
||||||
procd_append_param command -https "0"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
procd_append_param command -isonlyoneprot "1"
|
|
||||||
fi
|
|
||||||
procd_append_param command -showtip "0"
|
|
||||||
procd_set_param env GIN_MODE=release
|
|
||||||
procd_set_param pidfile /var/run/gecoosac.pid
|
|
||||||
procd_set_param stdout $log
|
|
||||||
procd_set_param stderr $log
|
|
||||||
procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
|
|
||||||
procd_close_instance
|
|
||||||
}
|
|
||||||
|
|
||||||
stop_service(){
|
|
||||||
init_conf
|
|
||||||
}
|
|
||||||
|
|
||||||
reload_service()
|
|
||||||
{
|
|
||||||
stop
|
|
||||||
start
|
|
||||||
}
|
|
||||||
|
|
||||||
service_triggers() {
|
|
||||||
procd_add_reload_trigger "gecoosac"
|
|
||||||
}
|
|
||||||
@@ -15,5 +15,6 @@ uci -q batch <<-EOF >/dev/null
|
|||||||
commit ucitrack
|
commit ucitrack
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
rm -rf /tmp/luci-*
|
rm -f /tmp/luci-indexcache
|
||||||
|
rm -rf /tmp/luci-modulecache
|
||||||
exit 0
|
exit 0
|
||||||
@@ -11,8 +11,8 @@ LUCI_DESCRIPTION:=LuCI JS interface for the modemband. The package allows set LT
|
|||||||
LUCI_DEPENDS:=+modemband
|
LUCI_DEPENDS:=+modemband
|
||||||
|
|
||||||
PKG_NAME:=luci-app-modemband
|
PKG_NAME:=luci-app-modemband
|
||||||
PKG_VERSION:=1.0.24
|
PKG_VERSION:=1.0.25.20240519
|
||||||
PKG_RELEASE:=2
|
PKG_RELEASE:=3
|
||||||
PKG_MAINTAINER:=Rafał Wabik <4Rafal@gmail.com>
|
PKG_MAINTAINER:=Rafał Wabik <4Rafal@gmail.com>
|
||||||
|
|
||||||
include $(TOPDIR)/feeds/luci/luci.mk
|
include $(TOPDIR)/feeds/luci/luci.mk
|
||||||
|
|||||||
@@ -3,14 +3,14 @@
|
|||||||
'require form';
|
'require form';
|
||||||
'require network';
|
'require network';
|
||||||
|
|
||||||
var callFileList = rpc.declare({
|
const callFileList = rpc.declare({
|
||||||
object: 'file',
|
object: 'file',
|
||||||
method: 'list',
|
method: 'list',
|
||||||
params: [ 'path' ],
|
params: [ 'path' ],
|
||||||
expect: { entries: [] },
|
expect: { entries: [] },
|
||||||
filter: function(list, params) {
|
filter: function(list, params) {
|
||||||
var rv = [];
|
let rv = [];
|
||||||
for (var i = 0; i < list.length; i++)
|
for (let i = 0; i < list.length; i++)
|
||||||
if (list[i].name.match(/^cdc-wdm/))
|
if (list[i].name.match(/^cdc-wdm/))
|
||||||
rv.push(params.path + list[i].name);
|
rv.push(params.path + list[i].name);
|
||||||
return rv.sort();
|
return rv.sort();
|
||||||
@@ -31,7 +31,7 @@ return network.registerProtocol('quectel', {
|
|||||||
return this._ubus('l3_device') || 'quectel-%s'.format(this.sid);
|
return this._ubus('l3_device') || 'quectel-%s'.format(this.sid);
|
||||||
},
|
},
|
||||||
|
|
||||||
getOpkgPackage: function() {
|
getPackageName: function() {
|
||||||
return 'quectel-cm';
|
return 'quectel-cm';
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -52,14 +52,14 @@ return network.registerProtocol('quectel', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
renderFormOptions: function(s) {
|
renderFormOptions: function(s) {
|
||||||
var dev = this.getL3Device() || this.getDevice(), o;
|
let dev = this.getL3Device() || this.getDevice(), o;
|
||||||
|
|
||||||
o = s.taboption('general', form.Value, '_modem_device', _('Modem device'));
|
o = s.taboption('general', form.Value, '_modem_device', _('Modem device'));
|
||||||
o.ucioption = 'device';
|
o.ucioption = 'device';
|
||||||
o.rmempty = false;
|
o.rmempty = false;
|
||||||
o.load = function(section_id) {
|
o.load = function(section_id) {
|
||||||
return callFileList('/dev/').then(L.bind(function(devices) {
|
return callFileList('/dev/').then(L.bind(function(devices) {
|
||||||
for (var i = 0; i < devices.length; i++)
|
for (let i = 0; i < devices.length; i++)
|
||||||
this.value(devices[i]);
|
this.value(devices[i]);
|
||||||
return form.Value.prototype.load.apply(this, [section_id]);
|
return form.Value.prototype.load.apply(this, [section_id]);
|
||||||
}, this));
|
}, this));
|
||||||
@@ -99,7 +99,7 @@ return network.registerProtocol('quectel', {
|
|||||||
|
|
||||||
o = s.taboption('advanced', form.Value, 'delay', _('Modem init timeout'),
|
o = s.taboption('advanced', form.Value, 'delay', _('Modem init timeout'),
|
||||||
_('Maximum amount of seconds to wait for the modem to become ready'));
|
_('Maximum amount of seconds to wait for the modem to become ready'));
|
||||||
o.placeholder = '20';
|
o.placeholder = '10';
|
||||||
o.datatype = 'min(1)';
|
o.datatype = 'min(1)';
|
||||||
|
|
||||||
o = s.taboption('advanced', form.Value, 'mtu', _('Override MTU'));
|
o = s.taboption('advanced', form.Value, 'mtu', _('Override MTU'));
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
|
||||||
|
|
||||||
PKG_NAME:=modemband
|
|
||||||
PKG_VERSION:=20240616
|
|
||||||
PKG_RELEASE:=1
|
|
||||||
|
|
||||||
PKG_LICENSE:=MIT
|
|
||||||
PKG_MAINTAINER:=Cezary Jackiewicz <cezary@eko.one.pl>
|
|
||||||
|
|
||||||
include $(INCLUDE_DIR)/package.mk
|
|
||||||
|
|
||||||
define Package/modemband
|
|
||||||
SECTION:=net
|
|
||||||
CATEGORY:=Network
|
|
||||||
SUBMENU:=WWAN
|
|
||||||
TITLE:=Setting LTE/5G bands for selected modems
|
|
||||||
DEPENDS:=+sms-tool
|
|
||||||
PKGARCH:=all
|
|
||||||
endef
|
|
||||||
|
|
||||||
define Build/Compile
|
|
||||||
endef
|
|
||||||
|
|
||||||
define Package/modemband/install
|
|
||||||
$(CP) ./files/* $(1)
|
|
||||||
endef
|
|
||||||
|
|
||||||
$(eval $(call BuildPackage,modemband))
|
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
Setting LTE/5G NSA/5G SA bands for selected modems.
|
|
||||||
|
|
||||||
Supported devices:
|
|
||||||
- BroadMobi BM806U
|
|
||||||
- Dell DW5821e Snapdragon X20 LTE (Foxconn T77W968)
|
|
||||||
- Fibocom FM350-GL
|
|
||||||
- Fibocom L850-GL
|
|
||||||
- Fibocom L850-GL in mbim mode
|
|
||||||
- Fibocom L860-GL
|
|
||||||
- Fibocom L860-GL-16
|
|
||||||
- HP lt4112 (Huawei ME906E)
|
|
||||||
- HP lt4132 LTE/HSPA+ 4G Module (Huawei ME906s-158)
|
|
||||||
- HP lt4220 (Foxconn T77W676)
|
|
||||||
- HP lt4220 (Foxconn T77W676) in mbim mode
|
|
||||||
- Huawei (various models) in serial mode
|
|
||||||
- Quectel EC20
|
|
||||||
- Quectel EC25
|
|
||||||
- Quectel EG06-E
|
|
||||||
- Quectel EG18-EA
|
|
||||||
- Quectel EM12-G
|
|
||||||
- Quectel EM160R-GL
|
|
||||||
- Quectel EP06-E
|
|
||||||
- Quectel RG500Q-EA
|
|
||||||
- Quectel RG502Q-EA
|
|
||||||
- Quectel RM500Q-GL
|
|
||||||
- Quectel RM500U-CNV
|
|
||||||
- Quectel RM502Q-AE
|
|
||||||
- Quectel RM502Q-GL
|
|
||||||
- Quectel RM505Q-AE
|
|
||||||
- Quectel RM520N-GL
|
|
||||||
- Sierra Wireless EM7455/MC7455/DW5811e
|
|
||||||
- SIMCOM SIM8200EA-M2
|
|
||||||
- Telit LM940
|
|
||||||
- Telit LN940 (Foxconn T77W676)
|
|
||||||
- Telit LN940 (Foxconn T77W676) in mbim mode
|
|
||||||
- Telit LN960 (Foxconn T77W968)
|
|
||||||
- Telit LN960
|
|
||||||
- Yuge CLM920 NC_5
|
|
||||||
- ZTE MF286 (router)
|
|
||||||
- ZTE MF286A (router)
|
|
||||||
- ZTE MF286D (router)
|
|
||||||
- ZTE MF286R (router)
|
|
||||||
- ZTE MF289R (router)
|
|
||||||
|
|
||||||
```
|
|
||||||
root@MiFi:~# modemband.sh help
|
|
||||||
Available commands:
|
|
||||||
/usr/bin/modemband.sh getinfo
|
|
||||||
/usr/bin/modemband.sh json
|
|
||||||
/usr/bin/modemband.sh help
|
|
||||||
|
|
||||||
for LTE modem
|
|
||||||
/usr/bin/modemband.sh getsupportedbands
|
|
||||||
/usr/bin/modemband.sh getsupportedbandsext
|
|
||||||
/usr/bin/modemband.sh getbands
|
|
||||||
/usr/bin/modemband.sh getbandsext
|
|
||||||
/usr/bin/modemband.sh setbands "<band list>"
|
|
||||||
|
|
||||||
for 5G NSA modem
|
|
||||||
/usr/bin/modemband.sh getsupportedbands5gnsa
|
|
||||||
/usr/bin/modemband.sh getsupportedbandsext5gnsa
|
|
||||||
/usr/bin/modemband.sh getbands5gnsa
|
|
||||||
/usr/bin/modemband.sh getbandsext5gnsa
|
|
||||||
/usr/bin/modemband.sh setbands5gnsa "<band list>"
|
|
||||||
|
|
||||||
for 5G SA modem
|
|
||||||
/usr/bin/modemband.sh getsupportedbands5gsa
|
|
||||||
/usr/bin/modemband.sh getsupportedbandsext5gsa
|
|
||||||
/usr/bin/modemband.sh getbands5gsa
|
|
||||||
/usr/bin/modemband.sh getbandsext5gsa
|
|
||||||
/usr/bin/modemband.sh setbands5gsa "<band list>"
|
|
||||||
|
|
||||||
root@MiFi:~# # modemband.sh
|
|
||||||
Modem: Quectel EC25
|
|
||||||
Supported LTE bands: 1 3 5 7 8 20 38 40 41
|
|
||||||
LTE bands: 1 3 5 7 8 20 38 40 41
|
|
||||||
|
|
||||||
1: FDD 2100 MHz
|
|
||||||
3: FDD 1800 MHz
|
|
||||||
5: FDD 850 MHz
|
|
||||||
7: FDD 2600 MHz
|
|
||||||
8: FDD 900 MHz
|
|
||||||
20: FDD 800 MHz
|
|
||||||
38: TDD 2600 MHz
|
|
||||||
40: TDD 2300 MHz
|
|
||||||
41: TDD 2500 MHz
|
|
||||||
|
|
||||||
root@MiFi:~# modemband.sh json
|
|
||||||
{ "modem": "Quectel EC25", "supported": [ { "band": 1, "txt": "FDD 2100 MHz" }, { "band": 3, "txt": "FDD 1800 MHz" }, { "band": 5, "txt": "FDD 850 MHz" }, { "band": 7, "txt": "FDD 2600 MHz" }, { "band": 8, "txt": "FDD 900 MHz" }, { "band": 20, "txt": "FDD 800 MHz" }, { "band": 38, "txt": "TDD 2600 MHz" }, { "band": 40, "txt": "TDD 2300 MHz" }, { "band": 41, "txt": "TDD 2500 MHz" } ], "enabled": [ 1, 3, 5, 7, 8, 20, 38, 40, 41 ] }
|
|
||||||
|
|
||||||
root@MiFi:~# modemband.sh getinfo
|
|
||||||
Quectel EC25
|
|
||||||
|
|
||||||
root@MiFi:~# modemband.sh getsupportedbands
|
|
||||||
1 3 5 7 8 20 38 40 41
|
|
||||||
|
|
||||||
root@MiFi:~# modemband.sh getsupportedbandsext
|
|
||||||
1: FDD 2100 MHz
|
|
||||||
3: FDD 1800 MHz
|
|
||||||
5: FDD 850 MHz
|
|
||||||
7: FDD 2600 MHz
|
|
||||||
8: FDD 900 MHz
|
|
||||||
20: FDD 800 MHz
|
|
||||||
38: TDD 2600 MHz
|
|
||||||
40: TDD 2300 MHz
|
|
||||||
41: TDD 2500 MHz
|
|
||||||
|
|
||||||
root@MiFi:~# modemband.sh getbands
|
|
||||||
1 3 5 7 8 20 38 40 41
|
|
||||||
|
|
||||||
root@MiFi:~# modemband.sh getbandsext
|
|
||||||
1: FDD 2100 MHz
|
|
||||||
3: FDD 1800 MHz
|
|
||||||
5: FDD 850 MHz
|
|
||||||
7: FDD 2600 MHz
|
|
||||||
8: FDD 900 MHz
|
|
||||||
20: FDD 800 MHz
|
|
||||||
38: TDD 2600 MHz
|
|
||||||
40: TDD 2300 MHz
|
|
||||||
41: TDD 2500 MHz
|
|
||||||
|
|
||||||
root@MiFi:~# modemband.sh setbands "1 3 5 40"
|
|
||||||
at+qcfg="band",0,8000000015,0,1
|
|
||||||
|
|
||||||
root@MiFi:~# modemband.sh getbands
|
|
||||||
1 3 5 40
|
|
||||||
|
|
||||||
root@MiFi:~# modemband.sh setbands default
|
|
||||||
at+qcfg="band",0,1a0000800d5,0,1
|
|
||||||
|
|
||||||
root@MiFi:~# modemband.sh getbands
|
|
||||||
1 3 5 7 8 20 38 40 41
|
|
||||||
```
|
|
||||||
|
|
||||||
See also [description in Polish](https://eko.one.pl/?p=openwrt-modemband).
|
|
||||||
@@ -1,518 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
#
|
|
||||||
# (c) 2022-2024 Cezary Jackiewicz <cezary@eko.one.pl>
|
|
||||||
#
|
|
||||||
# (c) 2022-2024 modified by Rafał Wabik - IceG - From eko.one.pl forum
|
|
||||||
#
|
|
||||||
|
|
||||||
hextobands() {
|
|
||||||
BANDS=""
|
|
||||||
HEX="$1"
|
|
||||||
LEN=${#HEX}
|
|
||||||
if [ $LEN -gt 18 ]; then
|
|
||||||
CNT=$((LEN - 16))
|
|
||||||
HHEX=${HEX:0:CNT}
|
|
||||||
HEX="0x"${HEX:CNT}
|
|
||||||
fi
|
|
||||||
|
|
||||||
for B in $(seq 0 63); do
|
|
||||||
POW=$((2 ** $B))
|
|
||||||
T=$((HEX&$POW))
|
|
||||||
[ "x$T" = "x$POW" ] && BANDS="${BANDS}$((B + 1)) "
|
|
||||||
done
|
|
||||||
if [ -n "$HHEX" ]; then
|
|
||||||
for B in $(seq 0 63); do
|
|
||||||
POW=$((2 ** $B))
|
|
||||||
T=$((HHEX&$POW))
|
|
||||||
[ "x$T" = "x$POW" ] && BANDS="${BANDS}$((B + 1 + 64)) "
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
echo "$BANDS"
|
|
||||||
}
|
|
||||||
|
|
||||||
bandstohex() {
|
|
||||||
BANDS="$1"
|
|
||||||
SUM=0
|
|
||||||
HSUM=0
|
|
||||||
for BAND in $BANDS; do
|
|
||||||
case $BAND in
|
|
||||||
''|*[!0-9]*) continue ;;
|
|
||||||
esac
|
|
||||||
if [ $BAND -gt 64 ]; then
|
|
||||||
B=$((BAND - 1 - 64))
|
|
||||||
POW=$((2 ** $B))
|
|
||||||
HSUM=$((HSUM + POW))
|
|
||||||
else
|
|
||||||
B=$((BAND - 1))
|
|
||||||
POW=$((2 ** $B))
|
|
||||||
SUM=$((SUM + POW))
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [ $HSUM -eq 0 ]; then
|
|
||||||
HEX=$(printf '%x' $SUM)
|
|
||||||
else
|
|
||||||
HEX=$(printf '%x%016x' $HSUM $SUM)
|
|
||||||
fi
|
|
||||||
echo "$HEX"
|
|
||||||
}
|
|
||||||
|
|
||||||
bandtxt() {
|
|
||||||
BAND=$1
|
|
||||||
|
|
||||||
# see https://en.wikipedia.org/wiki/LTE_frequency_bands
|
|
||||||
|
|
||||||
case "$BAND" in
|
|
||||||
"1") echo " $BAND: FDD 2100 MHz";;
|
|
||||||
"2") echo " $BAND: FDD 1900 MHz";;
|
|
||||||
"3") echo " $BAND: FDD 1800 MHz";;
|
|
||||||
"4") echo " $BAND: FDD 1700 MHz";;
|
|
||||||
"5") echo " $BAND: FDD 850 MHz";;
|
|
||||||
"7") echo " $BAND: FDD 2600 MHz";;
|
|
||||||
"8") echo " $BAND: FDD 900 MHz";;
|
|
||||||
"11") echo "$BAND: FDD 1500 MHz";;
|
|
||||||
"12") echo "$BAND: FDD 700 MHz";;
|
|
||||||
"13") echo "$BAND: FDD 700 MHz";;
|
|
||||||
"14") echo "$BAND: FDD 700 MHz";;
|
|
||||||
"17") echo "$BAND: FDD 700 MHz";;
|
|
||||||
"18") echo "$BAND: FDD 850 MHz";;
|
|
||||||
"19") echo "$BAND: FDD 850 MHz";;
|
|
||||||
"20") echo "$BAND: FDD 800 MHz";;
|
|
||||||
"21") echo "$BAND: FDD 1500 MHz";;
|
|
||||||
"24") echo "$BAND: FDD 1600 MHz";;
|
|
||||||
"25") echo "$BAND: FDD 1900 MHz";;
|
|
||||||
"26") echo "$BAND: FDD 850 MHz";;
|
|
||||||
"28") echo "$BAND: FDD 700 MHz";;
|
|
||||||
"29") echo "$BAND: SDL 700 MHz";;
|
|
||||||
"30") echo "$BAND: FDD 2300 MHz";;
|
|
||||||
"31") echo "$BAND: FDD 450 MHz";;
|
|
||||||
"32") echo "$BAND: SDL 1500 MHz";;
|
|
||||||
"34") echo "$BAND: TDD 2000 MHz";;
|
|
||||||
"37") echo "$BAND: TDD 1900 MHz";;
|
|
||||||
"38") echo "$BAND: TDD 2600 MHz";;
|
|
||||||
"39") echo "$BAND: TDD 1900 MHz";;
|
|
||||||
"40") echo "$BAND: TDD 2300 MHz";;
|
|
||||||
"41") echo "$BAND: TDD 2500 MHz";;
|
|
||||||
"42") echo "$BAND: TDD 3500 MHz";;
|
|
||||||
"43") echo "$BAND: TDD 3700 MHz";;
|
|
||||||
"46") echo "$BAND: TDD 5200 MHz";;
|
|
||||||
"47") echo "$BAND: TDD 5900 MHz";;
|
|
||||||
"48") echo "$BAND: TDD 3500 MHz";;
|
|
||||||
"50") echo "$BAND: TDD 1500 MHz";;
|
|
||||||
"51") echo "$BAND: TDD 1500 MHz";;
|
|
||||||
"53") echo "$BAND: TDD 2400 MHz";;
|
|
||||||
"54") echo "$BAND: TDD 1600 MHz";;
|
|
||||||
"65") echo "$BAND: FDD 2100 MHz";;
|
|
||||||
"66") echo "$BAND: FDD 1700 MHz";;
|
|
||||||
"67") echo "$BAND: SDL 700 MHz";;
|
|
||||||
"69") echo "$BAND: SDL 2600 MHz";;
|
|
||||||
"70") echo "$BAND: FDD 1700 MHz";;
|
|
||||||
"71") echo "$BAND: FDD 600 MHz";;
|
|
||||||
"72") echo "$BAND: FDD 450 MHz";;
|
|
||||||
"73") echo "$BAND: FDD 450 MHz";;
|
|
||||||
"74") echo "$BAND: FDD 1500 MHz";;
|
|
||||||
"75") echo "$BAND: SDL 1500 MHz";;
|
|
||||||
"76") echo "$BAND: SDL 1500 MHz";;
|
|
||||||
"85") echo "$BAND: FDD 700 MHz";;
|
|
||||||
"87") echo "$BAND: FDD 410 MHz";;
|
|
||||||
"88") echo "$BAND: FDD 410 MHz";;
|
|
||||||
"103") echo "$BAND: FDD 700 MHz";;
|
|
||||||
"106") echo "$BAND: FDD 900 MHz";;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
bandtxt5g() {
|
|
||||||
BAND=$1
|
|
||||||
|
|
||||||
# see https://en.wikipedia.org/wiki/5G_NR_frequency_bands
|
|
||||||
|
|
||||||
case "$BAND" in
|
|
||||||
"1") echo " $BAND: FDD 2100 MHz";;
|
|
||||||
"2") echo " $BAND: FDD 1900 MHz";;
|
|
||||||
"3") echo " $BAND: FDD 1800 MHz";;
|
|
||||||
"5") echo " $BAND: FDD 850 MHz";;
|
|
||||||
"7") echo " $BAND: FDD 2600 MHz";;
|
|
||||||
"8") echo " $BAND: FDD 900 MHz";;
|
|
||||||
"12") echo "$BAND: FDD 700 MHz";;
|
|
||||||
"13") echo "$BAND: FDD 700 MHz";;
|
|
||||||
"14") echo "$BAND: FDD 700 MHz";;
|
|
||||||
"18") echo "$BAND: FDD 850 MHz";;
|
|
||||||
"20") echo "$BAND: FDD 800 MHz";;
|
|
||||||
"24") echo "$BAND: FDD 1600 MHz";;
|
|
||||||
"25") echo "$BAND: FDD 1900 MHz";;
|
|
||||||
"26") echo "$BAND: FDD 850 MHz";;
|
|
||||||
"28") echo "$BAND: FDD 700 MHz";;
|
|
||||||
"29") echo "$BAND: SDL 700 MHz";;
|
|
||||||
"30") echo "$BAND: TDD 2300 MHz";;
|
|
||||||
"34") echo "$BAND: TDD 2100 MHz";;
|
|
||||||
"38") echo "$BAND: TDD 2600 MHz";;
|
|
||||||
"39") echo "$BAND: TDD 1900 MHz";;
|
|
||||||
"40") echo "$BAND: TDD 2300 MHz";;
|
|
||||||
"41") echo "$BAND: TDD 2500 MHz";;
|
|
||||||
"46") echo "$BAND: TDD 5200 MHz";;
|
|
||||||
"47") echo "$BAND: TDD 5900 MHz";;
|
|
||||||
"48") echo "$BAND: TDD 3500 MHz";;
|
|
||||||
"50") echo "$BAND: TDD 1500 MHz";;
|
|
||||||
"51") echo "$BAND: TDD 1500 MHz";;
|
|
||||||
"53") echo "$BAND: TDD 2400 MHz";;
|
|
||||||
"54") echo "$BAND: TDD 1600 MHz";;
|
|
||||||
"65") echo "$BAND: FDD 2100 MHz";;
|
|
||||||
"66") echo "$BAND: FDD 1700/2100 MHz";;
|
|
||||||
"67") echo "$BAND: SDL 700 MHz";;
|
|
||||||
"70") echo "$BAND: FDD 2000 MHz";;
|
|
||||||
"71") echo "$BAND: FDD 600 MHz";;
|
|
||||||
"74") echo "$BAND: FDD 1500 MHz";;
|
|
||||||
"75") echo "$BAND: SDL 1500 MHz";;
|
|
||||||
"76") echo "$BAND: SDL 1500 MHz";;
|
|
||||||
"77") echo "$BAND: TDD 3700 MHz";;
|
|
||||||
"78") echo "$BAND: TDD 3500 MHz";;
|
|
||||||
"79") echo "$BAND: TDD 4700 MHz";;
|
|
||||||
"80") echo "$BAND: SUL 1800 MHz";;
|
|
||||||
"81") echo "$BAND: SUL 900 MHz";;
|
|
||||||
"82") echo "$BAND: SUL 800 MHz";;
|
|
||||||
"83") echo "$BAND: SUL 700 MHz";;
|
|
||||||
"84") echo "$BAND: SUL 2100 MHz";;
|
|
||||||
"85") echo "$BAND: FDD 700 MHz";;
|
|
||||||
"86") echo "$BAND: SUL 1700 MHz";;
|
|
||||||
"89") echo "$BAND: SUL 850 MHz";;
|
|
||||||
"90") echo "$BAND: TDD 2500 MHz";;
|
|
||||||
"91") echo "$BAND: FDD 800/1500 MHz";;
|
|
||||||
"92") echo "$BAND: FDD 800/1500 MHz";;
|
|
||||||
"93") echo "$BAND: FDD 900/1500 MHz";;
|
|
||||||
"94") echo "$BAND: FDD 900/1500 MHz";;
|
|
||||||
"95") echo "$BAND: SUL 2100 MHz";;
|
|
||||||
"96") echo "$BAND: TDD 6000 MHz";;
|
|
||||||
"97") echo "$BAND: SUL 2300 MHz";;
|
|
||||||
"98") echo "$BAND: SUL 1900 MHz";;
|
|
||||||
"99") echo "$BAND: SUL 1600 MHz)";;
|
|
||||||
"100") echo "$BAND: FDD 900 MHz";;
|
|
||||||
"101") echo "$BAND: TDD 1900 MHz";;
|
|
||||||
"102") echo "$BAND: TDD 6200 MHz";;
|
|
||||||
"104") echo "$BAND: TDD 6700 MHz";;
|
|
||||||
"105") echo "$BAND: FDD 600 MHz";;
|
|
||||||
"257") echo "$BAND: 28 GHz";;
|
|
||||||
"258") echo "$BAND: 26 GHz";;
|
|
||||||
"259") echo "$BAND: 41 GHz";;
|
|
||||||
"260") echo "$BAND: 39 GHz";;
|
|
||||||
"261") echo "$BAND: 28 GHz";;
|
|
||||||
"262") echo "$BAND: 47 GHz";;
|
|
||||||
"263") echo "$BAND: 60 GHz";;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
_DEVICE=""
|
|
||||||
_DEFAULT_LTE_BANDS=""
|
|
||||||
_DEFAULT_5GNSA_BANDS=""
|
|
||||||
_DEFAULT_5GSA_BANDS=""
|
|
||||||
|
|
||||||
# default templates
|
|
||||||
|
|
||||||
# modem name/type
|
|
||||||
getinfo() {
|
|
||||||
echo "Unsupported"
|
|
||||||
}
|
|
||||||
|
|
||||||
# get supported band - 4G
|
|
||||||
getsupportedbands() {
|
|
||||||
echo "Unsupported"
|
|
||||||
}
|
|
||||||
|
|
||||||
getsupportedbandsext() {
|
|
||||||
T=$(getsupportedbands)
|
|
||||||
[ "x$T" = "xUnsupported" ] && return
|
|
||||||
for BAND in $T; do
|
|
||||||
bandtxt "$BAND"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# get current configured bands - 4G
|
|
||||||
getbands() {
|
|
||||||
echo "Unsupported"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbandsext() {
|
|
||||||
T=$(getbands)
|
|
||||||
[ "x$T" = "xUnsupported" ] && return
|
|
||||||
for BAND in $T; do
|
|
||||||
bandtxt "$BAND"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# set bands - 4G
|
|
||||||
setbands() {
|
|
||||||
echo "Unsupported"
|
|
||||||
}
|
|
||||||
|
|
||||||
# get supported band - 5G NSA
|
|
||||||
getsupportedbands5gnsa() {
|
|
||||||
echo "Unsupported"
|
|
||||||
}
|
|
||||||
|
|
||||||
getsupportedbandsext5gnsa() {
|
|
||||||
T=$(getsupportedbands5gnsa)
|
|
||||||
[ "x$T" = "xUnsupported" ] && return
|
|
||||||
for BAND in $T; do
|
|
||||||
bandtxt5g "$BAND"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# get current configured bands - 5G NSA
|
|
||||||
getbands5gnsa() {
|
|
||||||
echo "Unsupported"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbandsext5gnsa() {
|
|
||||||
T=$(getbands5gnsa)
|
|
||||||
[ "x$T" = "xUnsupported" ] && return
|
|
||||||
for BAND in $T; do
|
|
||||||
bandtxt5g "$BAND"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# set bands - 5G NSA
|
|
||||||
setbands5gnsa() {
|
|
||||||
echo "Unsupported"
|
|
||||||
}
|
|
||||||
|
|
||||||
# get supported band - 5G SA
|
|
||||||
getsupportedbands5gsa() {
|
|
||||||
echo "Unsupported"
|
|
||||||
}
|
|
||||||
|
|
||||||
getsupportedbandsext5gsa() {
|
|
||||||
T=$(getsupportedbands5gsa)
|
|
||||||
[ "x$T" = "xUnsupported" ] && return
|
|
||||||
for BAND in $T; do
|
|
||||||
bandtxt5g "$BAND"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# get current configured bands - 5G SA
|
|
||||||
getbands5gsa() {
|
|
||||||
echo "Unsupported"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbandsext5gsa() {
|
|
||||||
T=$(getbands5gsa)
|
|
||||||
[ "x$T" = "xUnsupported" ] && return
|
|
||||||
for BAND in $T; do
|
|
||||||
bandtxt5g "$BAND"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# set bands - 5G SA
|
|
||||||
setbands5gsa() {
|
|
||||||
echo "Unsupported"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RES="/usr/share/modemband"
|
|
||||||
|
|
||||||
_DEVS=$(awk '{gsub("="," ");
|
|
||||||
if ($0 ~ /Bus.*Lev.*Prnt.*Port.*/) {T=$0}
|
|
||||||
if ($0 ~ /Vendor.*ProdID/) {idvendor[T]=$3; idproduct[T]=$5}
|
|
||||||
if ($0 ~ /Product/) {product[T]=$3}}
|
|
||||||
END {for (idx in idvendor) {printf "%s%s\n%s%s%s\n", idvendor[idx], idproduct[idx], idvendor[idx], idproduct[idx], product[idx]}}' /sys/kernel/debug/usb/devices)
|
|
||||||
for _DEV in $_DEVS; do
|
|
||||||
if [ -e "$RES/$_DEV" ]; then
|
|
||||||
. "$RES/$_DEV"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ -z "$_DEVICE" ]; then
|
|
||||||
if [ "x$1" = "xjson" ]; then
|
|
||||||
echo '{"error":"No supported modem was found, quitting..."}'
|
|
||||||
else
|
|
||||||
echo "No supported modem was found, quitting..."
|
|
||||||
fi
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
_DEVICE1=$(uci -q get modemband.@modemband[0].set_port)
|
|
||||||
if [ -n "$_DEVICE1" ]; then
|
|
||||||
_DEVICE=$_DEVICE1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if [ ! -e "$_DEVICE" ]; then
|
|
||||||
if [ "x$1" = "xjson" ]; then
|
|
||||||
echo '{"error":"Port not found, quitting..."}'
|
|
||||||
else
|
|
||||||
echo "Port not found, quitting..."
|
|
||||||
fi
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
case $1 in
|
|
||||||
"getinfo")
|
|
||||||
getinfo
|
|
||||||
;;
|
|
||||||
"getsupportedbands")
|
|
||||||
getsupportedbands
|
|
||||||
;;
|
|
||||||
"getsupportedbandsext")
|
|
||||||
getsupportedbandsext
|
|
||||||
;;
|
|
||||||
"getbands")
|
|
||||||
getbands
|
|
||||||
;;
|
|
||||||
"getbandsext")
|
|
||||||
getbandsext
|
|
||||||
;;
|
|
||||||
"setbands")
|
|
||||||
[ -n "$2" ] && setbands "$2"
|
|
||||||
;;
|
|
||||||
"getsupportedbands5gnsa")
|
|
||||||
getsupportedbands5gnsa
|
|
||||||
;;
|
|
||||||
"getsupportedbandsext5gnsa")
|
|
||||||
getsupportedbandsext5gnsa
|
|
||||||
;;
|
|
||||||
"getbands5gnsa")
|
|
||||||
getbands5gnsa
|
|
||||||
;;
|
|
||||||
"getbandsext5gnsa")
|
|
||||||
getbandsext5gnsa
|
|
||||||
;;
|
|
||||||
"setbands5gnsa")
|
|
||||||
[ -n "$2" ] && setbands5gnsa "$2"
|
|
||||||
;;
|
|
||||||
"getsupportedbands5gsa")
|
|
||||||
getsupportedbands5gsa
|
|
||||||
;;
|
|
||||||
"getsupportedbandsext5gsa")
|
|
||||||
getsupportedbandsext5gsa
|
|
||||||
;;
|
|
||||||
"getbands5gsa")
|
|
||||||
getbands5gsa
|
|
||||||
;;
|
|
||||||
"getbandsext5gsa")
|
|
||||||
getbandsext5gsa
|
|
||||||
;;
|
|
||||||
"setbands5gsa")
|
|
||||||
[ -n "$2" ] && setbands5gsa "$2"
|
|
||||||
;;
|
|
||||||
"json")
|
|
||||||
. /usr/share/libubox/jshn.sh
|
|
||||||
json_init
|
|
||||||
json_add_string modem "$(getinfo)"
|
|
||||||
json_add_array supported
|
|
||||||
T=$(getsupportedbands)
|
|
||||||
if [ "x$T" != "xUnsupported" ]; then
|
|
||||||
for BAND in $T; do
|
|
||||||
json_add_object ""
|
|
||||||
json_add_int band $BAND
|
|
||||||
TXT="$(bandtxt $BAND)"
|
|
||||||
json_add_string txt "${TXT##*: }"
|
|
||||||
json_close_object
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
json_close_array
|
|
||||||
json_add_array enabled
|
|
||||||
T=$(getbands)
|
|
||||||
if [ "x$T" != "xUnsupported" ]; then
|
|
||||||
for BAND in $T; do
|
|
||||||
json_add_int "" $BAND
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
json_close_array
|
|
||||||
|
|
||||||
T=$(getsupportedbands5gnsa)
|
|
||||||
if [ "x$T" != "xUnsupported" ]; then
|
|
||||||
json_add_array supported5gnsa
|
|
||||||
for BAND in $T; do
|
|
||||||
json_add_object ""
|
|
||||||
json_add_int band $BAND
|
|
||||||
TXT="$(bandtxt5g $BAND)"
|
|
||||||
json_add_string txt "${TXT##*: }"
|
|
||||||
json_close_object
|
|
||||||
done
|
|
||||||
json_close_array
|
|
||||||
json_add_array enabled5gnsa
|
|
||||||
T=$(getbands5gnsa)
|
|
||||||
if [ "x$T" != "xUnsupported" ]; then
|
|
||||||
for BAND in $T; do
|
|
||||||
json_add_int "" $BAND
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
json_close_array
|
|
||||||
fi
|
|
||||||
T=$(getsupportedbands5gsa)
|
|
||||||
if [ "x$T" != "xUnsupported" ]; then
|
|
||||||
json_add_array supported5gsa
|
|
||||||
for BAND in $T; do
|
|
||||||
json_add_object ""
|
|
||||||
json_add_int band $BAND
|
|
||||||
TXT="$(bandtxt5g $BAND)"
|
|
||||||
json_add_string txt "${TXT##*: }"
|
|
||||||
json_close_object
|
|
||||||
done
|
|
||||||
json_close_array
|
|
||||||
json_add_array enabled5gsa
|
|
||||||
T=$(getbands5gsa)
|
|
||||||
if [ "x$T" != "xUnsupported" ]; then
|
|
||||||
for BAND in $T; do
|
|
||||||
json_add_int "" $BAND
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
json_close_array
|
|
||||||
fi
|
|
||||||
json_dump
|
|
||||||
;;
|
|
||||||
"help")
|
|
||||||
echo "Available commands:"
|
|
||||||
echo " $0 getinfo"
|
|
||||||
echo " $0 json"
|
|
||||||
echo " $0 help"
|
|
||||||
echo ""
|
|
||||||
echo "for LTE modem"
|
|
||||||
echo " $0 getsupportedbands"
|
|
||||||
echo " $0 getsupportedbandsext"
|
|
||||||
echo " $0 getbands"
|
|
||||||
echo " $0 getbandsext"
|
|
||||||
echo " $0 setbands \"<band list>\""
|
|
||||||
echo ""
|
|
||||||
echo "for 5G NSA modem"
|
|
||||||
echo " $0 getsupportedbands5gnsa"
|
|
||||||
echo " $0 getsupportedbandsext5gnsa"
|
|
||||||
echo " $0 getbands5gnsa"
|
|
||||||
echo " $0 getbandsext5gnsa"
|
|
||||||
echo " $0 setbands5gnsa \"<band list>\""
|
|
||||||
echo ""
|
|
||||||
echo "for 5G SA modem"
|
|
||||||
echo " $0 getsupportedbands5gsa"
|
|
||||||
echo " $0 getsupportedbandsext5gsa"
|
|
||||||
echo " $0 getbands5gsa"
|
|
||||||
echo " $0 getbandsext5gsa"
|
|
||||||
echo " $0 setbands5gsa \"<band list>\""
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo -n "Modem: "
|
|
||||||
getinfo
|
|
||||||
echo -n "Supported LTE bands: "
|
|
||||||
getsupportedbands
|
|
||||||
echo -n "Enabled LTE bands: "
|
|
||||||
getbands
|
|
||||||
echo ""
|
|
||||||
getsupportedbandsext
|
|
||||||
T=$(getsupportedbands5gnsa)
|
|
||||||
if [ "x$T" != "xUnsupported" ]; then
|
|
||||||
echo -n "Supported 5G NSA bands: "
|
|
||||||
getsupportedbands5gnsa
|
|
||||||
echo -n "Enabled 5G NSA bands: "
|
|
||||||
getbands5gnsa
|
|
||||||
echo ""
|
|
||||||
getsupportedbandsext5gnsa
|
|
||||||
fi
|
|
||||||
T=$(getsupportedbands5gsa)
|
|
||||||
if [ "x$T" != "xUnsupported" ]; then
|
|
||||||
echo -n "Supported 5G SA bands: "
|
|
||||||
getsupportedbands5gsa
|
|
||||||
echo -n "Enabled 5G SA bands: "
|
|
||||||
getbands5gsa
|
|
||||||
echo ""
|
|
||||||
getsupportedbandsext5gsa
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB1
|
|
||||||
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 17 18 19 20 21 25 26 28 29 30 38 39 40 41 66"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Qualcomm Snapdragon(TM) X12 LTE-A"
|
|
||||||
}
|
|
||||||
|
|
||||||
. $RES/_foxconn_common2
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB2
|
|
||||||
_DEFAULT_LTE_BANDS="1 3 5 7 8 20"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Quectel EC20"
|
|
||||||
}
|
|
||||||
|
|
||||||
# +QCFG: "band",0xdf,0x800d5,0x3f
|
|
||||||
|
|
||||||
. $RES/_quectel_common
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB2
|
|
||||||
_DEFAULT_LTE_BANDS="1 3 5 8 38 39 40 41"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Yuge CLM920 NC_5"
|
|
||||||
}
|
|
||||||
|
|
||||||
getsupportedbands() {
|
|
||||||
echo "$_DEFAULT_LTE_BANDS"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands() {
|
|
||||||
O=$(sms_tool -d $_DEVICE at "as+bandcfg?")
|
|
||||||
HEXHI=$(echo "$O" | awk -F[,] '/^\+BANDCFG:3,/{print $2}' | xargs)
|
|
||||||
HEXLO=$(echo "$O" | awk -F[,] '/^\+BANDCFG:3,/{print $3}' | xargs)
|
|
||||||
hextobands $(printf "0x%x%08x" 0x${HEXHI:-0} 0x${HEXLO:-0})
|
|
||||||
}
|
|
||||||
|
|
||||||
setbands() {
|
|
||||||
BANDS="$1"
|
|
||||||
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_LTE_BANDS"
|
|
||||||
|
|
||||||
HEX=$(bandstohex "$BANDS")
|
|
||||||
LEN=${#HEX}
|
|
||||||
if [ $LEN -gt 8 ]; then
|
|
||||||
CNT=$((LEN - 8))
|
|
||||||
HEXHI=${HEX:0:CNT}
|
|
||||||
HEXLO=${HEX:CNT}
|
|
||||||
else
|
|
||||||
HEXLO=$HEX
|
|
||||||
HEXHI=0
|
|
||||||
fi
|
|
||||||
HEXHI=$(printf "%X" 0x$HEXHI)
|
|
||||||
HEXLO=$(printf "%X" 0x$HEXLO)
|
|
||||||
[ "$HEX" != "0" ] && sms_tool -d $_DEVICE at "at+bandcfg=$HEXHI,$HEXLO,3"
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
# +GTUSBMODE: 40
|
|
||||||
_DEVICE=/dev/ttyUSB2
|
|
||||||
|
|
||||||
. $RES/_fibocom_fm350_common
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
# +GTUSBMODE: 41
|
|
||||||
_DEVICE=/dev/ttyUSB4
|
|
||||||
|
|
||||||
. $RES/_fibocom_fm350_common
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB2
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Sierra Wireless EM7455/MC7455/DW5811e"
|
|
||||||
}
|
|
||||||
|
|
||||||
getsupportedbands() {
|
|
||||||
sms_tool -d $_DEVICE at 'AT!ENTERCND="A710"' >/dev/null 2>&1
|
|
||||||
O=$(sms_tool -d $_DEVICE at 'AT!BAND=?')
|
|
||||||
HEX=$(echo "$O" | awk '/^00, All bands/{printf "0x%s\n", $5}')
|
|
||||||
[ "$HEX" = "0x" ] || hextobands "$HEX"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands() {
|
|
||||||
sms_tool -d $_DEVICE at 'AT!ENTERCND="A710"' >/dev/null 2>&1
|
|
||||||
O=$(sms_tool -d $_DEVICE at 'AT!BAND?')
|
|
||||||
HEX=$(echo "$O" | awk -F, '/^[0-9a-fA-F][0-9a-fA-F],/{print $3}' | awk '{printf "0x%s\n", $2}')
|
|
||||||
[ "$HEX" = "0x" ] || hextobands "$HEX"
|
|
||||||
}
|
|
||||||
|
|
||||||
setbands() {
|
|
||||||
BANDS="$1"
|
|
||||||
|
|
||||||
if [ "$BANDS" = "default" ]; then
|
|
||||||
sms_tool -d $_DEVICE at 'AT!ENTERCND="A710"' >/dev/null 2>&1
|
|
||||||
sms_tool -d $_DEVICE at 'AT!BAND=00' >/dev/null 2>&1
|
|
||||||
else
|
|
||||||
HEXL=$(bandstohex "$BANDS")
|
|
||||||
if [ "$HEXL" != "0" ]; then
|
|
||||||
sms_tool -d $_DEVICE at 'AT!ENTERCND="A710"' >/dev/null 2>&1
|
|
||||||
O=$(sms_tool -d $_DEVICE at 'AT!BAND?')
|
|
||||||
HEXGW=$(echo "$O" | awk -F, '/^[0-9a-fA-F][0-9a-fA-F],/{print $3}' | awk '{print $1}')
|
|
||||||
sms_tool -d $_DEVICE at 'AT!BAND=10,"Custom bands",'$HEXGW','$HEXL
|
|
||||||
sms_tool -d $_DEVICE at 'AT!BAND=10'
|
|
||||||
sms_tool -d $_DEVICE at 'AT!RESET'
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB2
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Sierra Wireless EM7465"
|
|
||||||
}
|
|
||||||
|
|
||||||
getsupportedbands() {
|
|
||||||
sms_tool -d $_DEVICE at 'AT!ENTERCND="A710"' >/dev/null 2>&1
|
|
||||||
O=$(sms_tool -d $_DEVICE at 'AT!BAND=?')
|
|
||||||
HEX=$(echo "$O" | awk '/^00, All bands/{printf "0x%s%s\n", $6, $5}')
|
|
||||||
[ "$HEX" = "0x" ] || hextobands "$HEX"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands() {
|
|
||||||
sms_tool -d $_DEVICE at 'AT!ENTERCND="A710"' >/dev/null 2>&1
|
|
||||||
O=$(sms_tool -d $_DEVICE at 'AT!BAND?')
|
|
||||||
HEX=$(echo "$O" | awk -F, '/^[0-9a-fA-F][0-9a-fA-F],/{print $3}' | awk '{printf "0x%s%s\n", $3, $2}')
|
|
||||||
[ "$HEX" = "0x" ] || hextobands "$HEX"
|
|
||||||
}
|
|
||||||
|
|
||||||
setbands() {
|
|
||||||
BANDS="$1"
|
|
||||||
|
|
||||||
if [ "$BANDS" = "default" ]; then
|
|
||||||
sms_tool -d $_DEVICE at 'AT!ENTERCND="A710"' >/dev/null 2>&1
|
|
||||||
sms_tool -d $_DEVICE at 'AT!BAND=00' >/dev/null 2>&1
|
|
||||||
else
|
|
||||||
HEX=$(bandstohex "$BANDS")
|
|
||||||
if [ "$HEX" != "0" ]; then
|
|
||||||
sms_tool -d $_DEVICE at 'AT!ENTERCND="A710"' >/dev/null 2>&1
|
|
||||||
O=$(sms_tool -d $_DEVICE at 'AT!BAND?')
|
|
||||||
HEXGW=$(echo "$O" | awk -F, '/^[0-9a-fA-F][0-9a-fA-F],/{print $3}' | awk '{print $1}')
|
|
||||||
LEN=${#HEX}
|
|
||||||
if [ $LEN -gt 16 ]; then
|
|
||||||
CNT=$((LEN - 16))
|
|
||||||
HEXL2=${HEX:0:CNT}
|
|
||||||
HEXL1=${HEX:CNT}
|
|
||||||
else
|
|
||||||
HEXL1=$HEX
|
|
||||||
HEXL2=0
|
|
||||||
fi
|
|
||||||
sms_tool -d $_DEVICE at 'AT!BAND=10,"Custom bands",'$HEXGW','$HEXL1','$HEXL2
|
|
||||||
sms_tool -d $_DEVICE at 'AT!BAND=10'
|
|
||||||
sms_tool -d $_DEVICE at 'AT!RESET'
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB1
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
O=$(sms_tool -d $_DEVICE at "at+cgmi")
|
|
||||||
VENDOR=$(echo "$O" | awk '/^[a-zA-Z0-9]/ && !/at\+cgmi/{print $0}' | xargs)
|
|
||||||
O=$(sms_tool -d $_DEVICE at "at+cgmm")
|
|
||||||
PRODUCT=$(echo "$O" | awk '/^[a-zA-Z0-9]/ && !/at\+cgmm/{print $0}' | xargs)
|
|
||||||
echo "$(echo ${VENDOR:0:1} | tr '[a-z]' '[A-Z]')${VENDOR:1} $PRODUCT"
|
|
||||||
}
|
|
||||||
|
|
||||||
getsupportedbands() {
|
|
||||||
O=$(sms_tool -d $_DEVICE at "at+cgmm")
|
|
||||||
_NAME=$(echo "$O" | awk '/^[a-zA-Z0-9]/ && !/at\+cgmm/{print tolower($0)}' | xargs)
|
|
||||||
case "$_NAME" in
|
|
||||||
"me906e"* | \
|
|
||||||
"me909u-521")
|
|
||||||
echo "1 2 3 5 7 8 20"
|
|
||||||
;;
|
|
||||||
"me906s"*)
|
|
||||||
echo "1 2 3 5 7 8 20 28"
|
|
||||||
;;
|
|
||||||
"me909s-120")
|
|
||||||
echo "1 2 3 4 5 7 8 20"
|
|
||||||
;;
|
|
||||||
"me909s-821")
|
|
||||||
echo "1 3 8 38 39 40 41"
|
|
||||||
;;
|
|
||||||
"me909s-821a")
|
|
||||||
echo "1 3 5 8 38 39 40 41"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "1 3 7 8 20"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands() {
|
|
||||||
O=$(sms_tool -d $_DEVICE at "at^syscfgex?")
|
|
||||||
HEX="0x"$(echo "$O" | awk -F[:,] '/^\^SYSCFGEX:/{print $6}' | xargs)
|
|
||||||
if [ "$HEX" = "0x7FFFFFFFFFFFFFFF" ]; then
|
|
||||||
getsupportedbands
|
|
||||||
else
|
|
||||||
[ "$HEX" = "0x" ] || hextobands "$HEX"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
setbands() {
|
|
||||||
BANDS="$1"
|
|
||||||
|
|
||||||
if [ "$BANDS" = "default" ]; then
|
|
||||||
HEX="7FFFFFFFFFFFFFFF"
|
|
||||||
else
|
|
||||||
HEX=$(bandstohex "$BANDS")
|
|
||||||
fi
|
|
||||||
if [ "$HEX" != "0" ]; then
|
|
||||||
O=$(sms_tool -d $_DEVICE at "at^syscfgex?")
|
|
||||||
MODE=$(echo "$O" | awk -F[:,] '{print $2}' | xargs)
|
|
||||||
sms_tool -d $_DEVICE at "at^syscfgex=\"${MODE:-030201}\",3FFFFFFF,2,4,$HEX,,"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB2
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Huawei E3372h-320"
|
|
||||||
}
|
|
||||||
|
|
||||||
getsupportedbands() {
|
|
||||||
echo "1 3 7 8 20 28"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands() {
|
|
||||||
O=$(sms_tool -d $_DEVICE at "at^syscfgex?")
|
|
||||||
HEX="0x"$(echo "$O" | awk -F[:,] '/^\^SYSCFGEX:/{print $6}' | xargs)
|
|
||||||
if [ "$HEX" = "0x7FFFFFFFFFFFFFFF" ]; then
|
|
||||||
getsupportedbands
|
|
||||||
else
|
|
||||||
[ "$HEX" = "0x" ] || hextobands "$HEX"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
setbands() {
|
|
||||||
BANDS="$1"
|
|
||||||
|
|
||||||
if [ "$BANDS" = "default" ]; then
|
|
||||||
HEX="7FFFFFFFFFFFFFFF"
|
|
||||||
else
|
|
||||||
HEX=$(bandstohex "$BANDS")
|
|
||||||
fi
|
|
||||||
if [ "$HEX" != "0" ]; then
|
|
||||||
O=$(sms_tool -d $_DEVICE at "at^syscfgex?")
|
|
||||||
MODE=$(echo "$O" | awk -F[:,] '{print $2}' | xargs)
|
|
||||||
sms_tool -d $_DEVICE at "at^syscfgex=\"${MODE:-030201}\",3FFFFFFF,2,4,$HEX,,"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB1
|
|
||||||
_DEFAULT_LTE_BANDS="1 3 7 8 20 28"
|
|
||||||
_NAME="ZTE MF286"
|
|
||||||
|
|
||||||
case $(cat /tmp/sysinfo/board_name) in
|
|
||||||
"zte,mf286a")
|
|
||||||
_DEFAULT_LTE_BANDS="1 2 3 5 7 8 20 38"
|
|
||||||
_NAME="ZTE MF286A"
|
|
||||||
;;
|
|
||||||
"zte,mf289f")
|
|
||||||
_DEFAULT_LTE_BANDS="1 3 7 8 20 28 32 38"
|
|
||||||
_NAME="ZTE MF289F"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "$_NAME"
|
|
||||||
}
|
|
||||||
|
|
||||||
. $RES/_zte_common
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB1
|
|
||||||
_DEFAULT_LTE_BANDS="1 3 7 8 20 28 32 38"
|
|
||||||
_NAME="ZTE MF286D"
|
|
||||||
|
|
||||||
case $(cat /tmp/sysinfo/board_name) in
|
|
||||||
"zte,mf289f")
|
|
||||||
_NAME="ZTE MF289F"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "$_NAME"
|
|
||||||
}
|
|
||||||
|
|
||||||
. $RES/_zte_common
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyACM0
|
|
||||||
_DEFAULT_LTE_BANDS="1 3 7 8 20 38"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "ZTE MF286R"
|
|
||||||
}
|
|
||||||
|
|
||||||
. $RES/_zte_common
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB2
|
|
||||||
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 17 20 25 26 28 29 30 38 40 41"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Telit LM940"
|
|
||||||
}
|
|
||||||
|
|
||||||
getsupportedbands() {
|
|
||||||
echo "$_DEFAULT_LTE_BANDS"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands() {
|
|
||||||
# #BND: 0,11,1A03B0918DF
|
|
||||||
|
|
||||||
O=$(sms_tool -d $_DEVICE at "at#bnd?")
|
|
||||||
HEX="0x"$(echo "$O" | awk -F[:,] '{print $4}' | xargs)
|
|
||||||
hextobands "$HEX"
|
|
||||||
}
|
|
||||||
|
|
||||||
setbands() {
|
|
||||||
BANDS="$1"
|
|
||||||
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_LTE_BANDS"
|
|
||||||
|
|
||||||
HEX=$(bandstohex "$BANDS")
|
|
||||||
if [ "$HEX" != "0" ]; then
|
|
||||||
O=$(sms_tool -d $_DEVICE at "at#bnd?")
|
|
||||||
GSM=$(echo "$O" | awk -F[:,] '{print $2}' | xargs)
|
|
||||||
UMTS=$(echo "$O" | awk -F[:,] '{print $3}' | xargs)
|
|
||||||
sms_tool -d $_DEVICE at "at#bnd=${GSM},${UMTS},${HEX}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB1
|
|
||||||
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 17 18 19 20 21 25 26 28 29 30 38 39 40 41 66"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Telit LN940 Mobile Broadband"
|
|
||||||
}
|
|
||||||
|
|
||||||
. $RES/_foxconn_common2
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB1
|
|
||||||
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 17 18 19 20 25 26 28 29 30 32 38 39 40 41 42 43 46 66"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Telit LN960 Mobile Broadband"
|
|
||||||
}
|
|
||||||
|
|
||||||
. $RES/_foxconn_common1
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB2
|
|
||||||
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 17 18 19 20 25 26 28 29 30 32 34 38 39 40 41 42 43 48 66 71"
|
|
||||||
_DEFAULT_5GNSA_BANDS="1 2 3 5 7 8 12 14 20 28 38 40 41 48 66 71 77 78"
|
|
||||||
_DEFAULT_5GSA_BANDS="1 2 3 5 7 8 12 14 20 28 38 40 41 48 66 71 77 78"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "SIMCOM SIM8200EA-M2"
|
|
||||||
}
|
|
||||||
|
|
||||||
getsupportedbands() {
|
|
||||||
echo "$_DEFAULT_LTE_BANDS"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands() {
|
|
||||||
O=$(sms_tool -d $_DEVICE at "AT+CSYSSEL=\"lte_band\"")
|
|
||||||
echo "$O" | awk -F, '/^\+CSYSSEL: "lte_band",/{gsub(":"," ");print $2}' | xargs
|
|
||||||
}
|
|
||||||
|
|
||||||
setbands() {
|
|
||||||
BANDS="$1"
|
|
||||||
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_LTE_BANDS"
|
|
||||||
|
|
||||||
T=""
|
|
||||||
for BAND in $BANDS; do
|
|
||||||
case $BAND in
|
|
||||||
''|*[!0-9]*) continue ;;
|
|
||||||
esac
|
|
||||||
[ -n "$T" ] && T="${T}:"
|
|
||||||
T="${T}${BAND}"
|
|
||||||
done
|
|
||||||
|
|
||||||
[ -n "$T" ] && sms_tool -d $_DEVICE at "AT+CSYSSEL=\"lte_band\",$T"
|
|
||||||
}
|
|
||||||
|
|
||||||
getsupportedbands5gnsa() {
|
|
||||||
echo "$_DEFAULT_5GNSA_BANDS"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands5gnsa() {
|
|
||||||
O=$(sms_tool -d $_DEVICE at "AT+CSYSSEL=\"nsa_nr5g_band\"")
|
|
||||||
echo "$O" | awk -F, '/^\+CSYSSEL: "nsa_nr5g_band",/{gsub(":"," ");print $2}' | xargs
|
|
||||||
}
|
|
||||||
|
|
||||||
setbands5gnsa() {
|
|
||||||
BANDS="$1"
|
|
||||||
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_5GNSA_BANDS"
|
|
||||||
|
|
||||||
T=""
|
|
||||||
for BAND in $BANDS; do
|
|
||||||
case $BAND in
|
|
||||||
''|*[!0-9]*) continue ;;
|
|
||||||
esac
|
|
||||||
[ -n "$T" ] && T="${T}:"
|
|
||||||
T="${T}${BAND}"
|
|
||||||
done
|
|
||||||
|
|
||||||
[ -n "$T" ] && sms_tool -d $_DEVICE at "AT+CSYSSEL=\"nsa_nr5g_band\",$T"
|
|
||||||
}
|
|
||||||
|
|
||||||
getsupportedbands5gsa() {
|
|
||||||
echo "$_DEFAULT_5GSA_BANDS"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands5gsa() {
|
|
||||||
O=$(sms_tool -d $_DEVICE at "AT+CSYSSEL=\"nr5g_band\"")
|
|
||||||
echo "$O" | awk -F, '/^\+CSYSSEL: "nr5g_band",/{gsub(":"," ");print $2}' | xargs
|
|
||||||
}
|
|
||||||
|
|
||||||
setbands5gsa() {
|
|
||||||
BANDS="$1"
|
|
||||||
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_5GSA_BANDS"
|
|
||||||
|
|
||||||
T=""
|
|
||||||
for BAND in $BANDS; do
|
|
||||||
case $BAND in
|
|
||||||
''|*[!0-9]*) continue ;;
|
|
||||||
esac
|
|
||||||
[ -n "$T" ] && T="${T}:"
|
|
||||||
T="${T}${BAND}"
|
|
||||||
done
|
|
||||||
|
|
||||||
[ -n "$T" ] && sms_tool -d $_DEVICE at "AT+CSYSSEL=\"nr5g_band\",$T"
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB2
|
|
||||||
_DEFAULT_LTE_BANDS="1 2 3 5 7 8 12 17 20 38 40"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "BroadMobi BM806U"
|
|
||||||
}
|
|
||||||
|
|
||||||
getsupportedbands() {
|
|
||||||
echo "$_DEFAULT_LTE_BANDS"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands() {
|
|
||||||
O=$(sms_tool -d $_DEVICE at "at+bmbandpref?")
|
|
||||||
HEX=$(echo "$O" | awk -F[:,] '{print $3}' | xargs)
|
|
||||||
hextobands "$HEX"
|
|
||||||
}
|
|
||||||
|
|
||||||
setbands() {
|
|
||||||
BANDS="$1"
|
|
||||||
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_LTE_BANDS"
|
|
||||||
|
|
||||||
HEX=$(bandstohex "$BANDS")
|
|
||||||
[ "$HEX" != "0" ] && sms_tool -d $_DEVICE at "at+bmbandpref=,$HEX,"
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB2
|
|
||||||
_DEFAULT_LTE_BANDS="1 3 5 7 8 20 38 40 41"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Quectel EC25"
|
|
||||||
}
|
|
||||||
|
|
||||||
. $RES/_quectel_common
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB2
|
|
||||||
_DEFAULT_LTE_BANDS="1 3 5 7 8 20 28 32 38 40 41"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Quectel EG06-E"
|
|
||||||
}
|
|
||||||
|
|
||||||
# +QCFG: "band",0x8df,0x1a0880800d5,0x0
|
|
||||||
|
|
||||||
. $RES/_quectel_common
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB2
|
|
||||||
_DEFAULT_LTE_BANDS="1 3 5 7 8 20 28 38 40 41"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Quectel EP06-E"
|
|
||||||
}
|
|
||||||
|
|
||||||
# +QCFG: "band",0x8d0,0x1a0080800d5,0x1
|
|
||||||
|
|
||||||
. $RES/_quectel_common
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB2
|
|
||||||
_DEFAULT_LTE_BANDS="1 3 5 7 8 20 28 38 40 41"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Quectel EG18-EA"
|
|
||||||
}
|
|
||||||
|
|
||||||
. $RES/_quectel_common
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB2
|
|
||||||
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 9 12 13 14 17 18 19 20 21 25 26 28 29 30 32 38 39 40 41 66"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Quectel EM12-G"
|
|
||||||
}
|
|
||||||
|
|
||||||
getsupportedbands() {
|
|
||||||
echo "$_DEFAULT_LTE_BANDS"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands() {
|
|
||||||
# +QCFG: "band",0x5af0,0x42000000003300185a,0x1
|
|
||||||
|
|
||||||
O=$(sms_tool -d $_DEVICE at "AT+QCFG=\"band\"")
|
|
||||||
HEX=$(echo "$O" | awk -F[:,] '{print $4}' | xargs)
|
|
||||||
hextobands "$HEX"
|
|
||||||
}
|
|
||||||
|
|
||||||
setbands() {
|
|
||||||
BANDS="$1"
|
|
||||||
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_LTE_BANDS"
|
|
||||||
|
|
||||||
HEX=$(bandstohex "$BANDS")
|
|
||||||
[ "$HEX" != "0" ] && sms_tool -d $_DEVICE at "AT+QCFG=\"band\",0,$HEX,1"
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB2
|
|
||||||
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 18 19 20 25 26 28 29 30 32 38 39 40 41 42 46 48 66"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Quectel EM160R-GL"
|
|
||||||
}
|
|
||||||
|
|
||||||
getsupportedbands() {
|
|
||||||
echo "$_DEFAULT_LTE_BANDS"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands() {
|
|
||||||
# +QNWPREFCFG: "lte_band",1:3:7:8:20:28:38
|
|
||||||
|
|
||||||
O=$(sms_tool -d $_DEVICE at "at+qnwprefcfg=\"lte_band\"?")
|
|
||||||
echo "$O" | awk -F, '/^\+QNWPREFCFG:/{gsub(":"," ");print $2}'
|
|
||||||
}
|
|
||||||
|
|
||||||
setbands() {
|
|
||||||
BANDS="$1"
|
|
||||||
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_LTE_BANDS"
|
|
||||||
|
|
||||||
T=""
|
|
||||||
for BAND in $BANDS; do
|
|
||||||
case $BAND in
|
|
||||||
''|*[!0-9]*) continue ;;
|
|
||||||
esac
|
|
||||||
[ -n "$T" ] && T="${T}:"
|
|
||||||
T="${T}${BAND}"
|
|
||||||
done
|
|
||||||
|
|
||||||
[ -n "$T" ] && sms_tool -d $_DEVICE at "at+qnwprefcfg=\"lte_band\",$T"
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB2
|
|
||||||
_DEFAULT_LTE_BANDS="1 3 5 7 8 18 19 20 26 28 32 34 38 39 40 41 42 43"
|
|
||||||
_DEFAULT_5GNSA_BANDS="1 3 5 7 8 20 28 38 40 41 77 78 79"
|
|
||||||
_DEFAULT_5GSA_BANDS="1 3 5 7 8 20 28 38 40 41 77 78 79"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Quectel RG500Q-EA"
|
|
||||||
}
|
|
||||||
|
|
||||||
# +QNWPREFCFG: "lte_band",1:3:7:8:20:28:38
|
|
||||||
|
|
||||||
. $RES/_quectel_common2
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB2
|
|
||||||
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 17 18 19 20 25 26 28 29 30 32 34 38 39 40 41 42 43 46 48 66 71"
|
|
||||||
_DEFAULT_5GNSA_BANDS="1 3 5 7 8 20 28 38 40 41 77 78 79"
|
|
||||||
_DEFAULT_5GSA_BANDS="1 3 5 7 8 20 28 38 40 41 77 78 79"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Quectel RG502Q-EA"
|
|
||||||
}
|
|
||||||
|
|
||||||
# +QNWPREFCFG: "lte_band",1:3:7:8:20:28:38
|
|
||||||
|
|
||||||
. $RES/_quectel_common2
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB2
|
|
||||||
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 17 18 19 20 25 26 28 29 30 32 34 38 39 40 41 42 43 46 48 66 71"
|
|
||||||
_DEFAULT_5GNSA_BANDS="1 2 3 5 7 8 12 20 25 28 38 40 41 48 66 71 77 78 79"
|
|
||||||
_DEFAULT_5GSA_BANDS="1 2 3 5 7 8 12 20 25 28 38 40 41 48 66 71 77 78 79"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Quectel RM500Q-GL"
|
|
||||||
}
|
|
||||||
|
|
||||||
# +QNWPREFCFG: "lte_band",1:3:7:8:20:28:38
|
|
||||||
|
|
||||||
. $RES/_quectel_common2
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB2
|
|
||||||
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 18 19 20 25 26 28 29 30 32 34 38 39 40 41 42 43 46 48 66 71"
|
|
||||||
_DEFAULT_5GNSA_BANDS="1 2 3 5 7 8 12 20 25 28 38 40 41 48 66 71 77 78 79"
|
|
||||||
_DEFAULT_5GSA_BANDS="1 2 3 5 7 8 12 20 25 28 38 40 41 48 66 71 77 78 79"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Quectel RM502Q-AE"
|
|
||||||
}
|
|
||||||
|
|
||||||
# +QNWPREFCFG: "lte_band",1:3:7:8:20:28:38
|
|
||||||
|
|
||||||
. $RES/_quectel_common2
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB2
|
|
||||||
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 17 18 19 20 25 26 28 29 30 32 34 38/39 40 41 42 43 48 66 71"
|
|
||||||
_DEFAULT_5GNSA_BANDS="38 41 77 78"
|
|
||||||
_DEFAULT_5GSA_BANDS="1 2 3 5 7 8 12 20 25 28 38 40 41 48 66 71 77 78"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Quectel RM502Q-GL"
|
|
||||||
}
|
|
||||||
|
|
||||||
# +QNWPREFCFG: "lte_band",1:3:7:8:20:28:38
|
|
||||||
|
|
||||||
. $RES/_quectel_common2
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB2
|
|
||||||
_DEFAULT_LTE_BANDS="1 2 3 4 5 8 12 13 14 17 18 19 20 25 26 28 29 30 32 34 39 40 41 42 43 46 48 66 71"
|
|
||||||
_DEFAULT_5GNSA_BANDS="1 2 3 5 7 8 12 14 20 25 28 38 40 41 48 66 71 77 78 79"
|
|
||||||
_DEFAULT_5GSA_BANDS="1 2 3 5 7 8 12 14 20 25 28 38 40 41 48 66 71 77 78 79"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Quectel RM505Q-AE"
|
|
||||||
}
|
|
||||||
|
|
||||||
# +QNWPREFCFG: "lte_band",1:3:7:8:20:28:38
|
|
||||||
|
|
||||||
. $RES/_quectel_common2
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB3
|
|
||||||
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 17 18 19 20 25 26 28 29 30 32 34 38 39 40 41 42 43 46 48 66 71"
|
|
||||||
_DEFAULT_5GNSA_BANDS="1 2 3 5 7 8 12 13 14 18 20 25 26 28 29 30 38 40 41 48 66 70 71 75 76 77 78 79"
|
|
||||||
_DEFAULT_5GSA_BANDS="1 2 3 5 7 8 12 13 14 18 20 25 26 28 29 30 38 40 41 48 66 70 71 75 76 77 78 79"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
VENDOR=$(sms_tool -d /dev/ttyUSB3 at AT+CGMI | tr -s '\n' | xargs)
|
|
||||||
DEVICE=$(sms_tool -d /dev/ttyUSB3 at AT+CGMM | tr -s '\n' | xargs)
|
|
||||||
echo "$VENDOR $DEVICE"
|
|
||||||
}
|
|
||||||
|
|
||||||
# +QNWPREFCFG: "lte_band",1:2:3:4:5:7:8:12:13:14:17:18:19:20:25:26:28:29:30:32:34:38:39:40:41:42:43:46:48:66:71
|
|
||||||
# +QNWPREFCFG: "nsa_nr5g_band",1:2:3:5:7:8:12:13:14:18:20:25:26:28:29:30:38:40:41:48:66:70:71:75:76:77:78:79
|
|
||||||
|
|
||||||
. $RES/_quectel_common2
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB2
|
|
||||||
_DEFAULT_LTE_BANDS="1 2 3 5 8 34 38 39 40 41"
|
|
||||||
_DEFAULT_5GNSA_BANDS="41 78 79"
|
|
||||||
_DEFAULT_5GSA_BANDS="1 2 3 5 8 28 41 77 78 79"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Quectel RM500U-CNV"
|
|
||||||
}
|
|
||||||
|
|
||||||
# +QNWPREFCFG: "lte_band",1:3:7:8:20:28:38
|
|
||||||
|
|
||||||
. $RES/_quectel_common2
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyUSB1
|
|
||||||
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 17 18 19 20 25 26 28 29 30 32 38 39 40 41 42 43 46 66"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
echo "Dell DW5821e Snapdragon X20 LTE"
|
|
||||||
}
|
|
||||||
|
|
||||||
. $RES/_foxconn_common1
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
_DEVICE=/dev/ttyACM2
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
O=$(sms_tool -d $_DEVICE at "at+gmm")
|
|
||||||
_NAME="Fibocom $(echo "$O" | awk -F, '{print $2}')"
|
|
||||||
echo "$_NAME"
|
|
||||||
}
|
|
||||||
|
|
||||||
getsupportedbands() {
|
|
||||||
O=$(sms_tool -d $_DEVICE at "at+gmm")
|
|
||||||
if echo "$O" | grep -q "L850"; then
|
|
||||||
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 11 12 13 17 18 19 20 21 26 28 29 30 38 39 40 41 66"
|
|
||||||
fi
|
|
||||||
if echo "$O" | grep -q "L860"; then
|
|
||||||
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 17 18 19 20 25 26 28 29 30 32 38 39 40 41 42 46 66"
|
|
||||||
fi
|
|
||||||
if echo "$O" | grep -q "L860-GL-16"; then
|
|
||||||
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 17 18 19 20 25 26 28 29 30 32 34 38 39 40 41 42 43 46 48 66 71"
|
|
||||||
fi
|
|
||||||
echo "$_DEFAULT_LTE_BANDS"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands() {
|
|
||||||
# +XACT: 4,2,1,1,2,4,5,8,101,102,103,104,105,107,108,112,113,114,117,118,119,120,125,126,128,129,130,132,138,139,140,141,142,146,166
|
|
||||||
|
|
||||||
O=$(sms_tool -d $_DEVICE at "at+xact?")
|
|
||||||
BANDS=$(echo "$O" | awk -F: '/^\+XACT:/{gsub(","," ");print $2}')
|
|
||||||
for BAND in $BANDS; do
|
|
||||||
if [ $BAND -gt 100 ] && [ $BAND -lt 200 ]; then
|
|
||||||
echo -n "$((BAND - 100)) "
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo ""
|
|
||||||
}
|
|
||||||
|
|
||||||
setbands() {
|
|
||||||
BANDS="$1"
|
|
||||||
|
|
||||||
T=""
|
|
||||||
if [ "$BANDS" = "default" ]; then
|
|
||||||
T="0"
|
|
||||||
else
|
|
||||||
for BAND in $BANDS; do
|
|
||||||
case $BAND in
|
|
||||||
''|*[!0-9]*) continue ;;
|
|
||||||
esac
|
|
||||||
[ -n "$T" ] && T="${T},"
|
|
||||||
T="${T}$((BAND + 100))"
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$T" ]; then
|
|
||||||
O=$(sms_tool -d $_DEVICE at "at+xact?")
|
|
||||||
MODE=$(echo "$O" | awk -F[:,] '{print $2}' | xargs)
|
|
||||||
sms_tool -d $_DEVICE at "at+xact=$MODE,,,$T"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
# Unified for NSA/SA
|
|
||||||
_DEFAULT_5G_BANDS="1 2 3 5 7 8 20 25 28 30 38 40 41 48 66 71 77 78 79"
|
|
||||||
|
|
||||||
getinfo() {
|
|
||||||
O=$(sms_tool -d $_DEVICE at "AT+CGMM?")
|
|
||||||
_NAME="Fibocom $(echo "$O" | awk -F[:,] '/^\+CGMM:/{gsub("\"","");print $2}' | xargs)"
|
|
||||||
echo "$_NAME"
|
|
||||||
}
|
|
||||||
|
|
||||||
getsupportedbands() {
|
|
||||||
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 17 18 19 20 25 26 28 29 30 32 34 38 39 40 41 42 43 46 48 66 71"
|
|
||||||
echo "$_DEFAULT_LTE_BANDS"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands() {
|
|
||||||
# +GTACT: 20,6,3,101,102,103,104,105,107,108,112,113,114,117,118,119,120,125,126,128,129,130,132,134,138,139,140,141,142,143,146,148,166,171
|
|
||||||
|
|
||||||
O=$(sms_tool -d $_DEVICE at "AT+GTACT?")
|
|
||||||
BANDS=$(echo "$O" | awk -F: '/^\+GTACT:/{gsub(","," ");print $2}')
|
|
||||||
for BAND in $BANDS; do
|
|
||||||
if [ $BAND -gt 100 ] && [ $BAND -lt 200 ]; then
|
|
||||||
echo -n "$((BAND - 100)) "
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo ""
|
|
||||||
}
|
|
||||||
|
|
||||||
setbands() {
|
|
||||||
BANDS="$1"
|
|
||||||
|
|
||||||
T=""
|
|
||||||
if [ "$BANDS" = "default" ]; then
|
|
||||||
T="0"
|
|
||||||
else
|
|
||||||
for BAND in $BANDS; do
|
|
||||||
case $BAND in
|
|
||||||
''|*[!0-9]*) continue ;;
|
|
||||||
esac
|
|
||||||
[ -n "$T" ] && T="${T},"
|
|
||||||
T="${T}$((BAND + 100))"
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$T" ]; then
|
|
||||||
O=$(sms_tool -d $_DEVICE at "AT+GTACT?")
|
|
||||||
MODE=$(echo "$O" | awk -F[:,] '/\+GTACT:/{print $2","$3","$4}'| xargs)
|
|
||||||
sms_tool -d $_DEVICE at "AT+GTACT=$MODE,$T"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
getsupportedbands5gsa() {
|
|
||||||
echo "$_DEFAULT_5G_BANDS"
|
|
||||||
}
|
|
||||||
|
|
||||||
getsupportedbands5gnsa() {
|
|
||||||
echo "$_DEFAULT_5G_BANDS"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands5gsa() {
|
|
||||||
# +GTACT: 20,6,3,501,502,503,505,507,508,5020,5025,5028,5030,5038,5040,5041,5048,5066,5071,5077,5078,5079
|
|
||||||
|
|
||||||
O=$(sms_tool -d $_DEVICE at "AT+GTACT?")
|
|
||||||
BANDS=$(echo "$O" | awk -F: '/^\+GTACT:/{gsub(","," ");print $2}')
|
|
||||||
for BAND in $BANDS; do
|
|
||||||
if [ $BAND -gt 500 ] && [ $BAND -lt 5100 ]; then
|
|
||||||
echo -n "$(echo "$BAND" | sed 's/^50//g') "
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo ""
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands5gnsa() {
|
|
||||||
# +GTACT: 20,6,3,501,502,503,505,507,508,5020,5025,5028,5030,5038,5040,5041,5048,5066,5071,5077,5078,5079
|
|
||||||
|
|
||||||
O=$(sms_tool -d $_DEVICE at "AT+GTACT?")
|
|
||||||
BANDS=$(echo "$O" | awk -F: '/^\+GTACT:/{gsub(","," ");print $2}')
|
|
||||||
for BAND in $BANDS; do
|
|
||||||
if [ $BAND -gt 500 ] && [ $BAND -lt 5100 ]; then
|
|
||||||
echo -n "$(echo "$BAND" | sed 's/^50//g') "
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo ""
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
setbands5gsa() {
|
|
||||||
BANDS="$1"
|
|
||||||
|
|
||||||
T=""
|
|
||||||
if [ "$BANDS" = "default" ]; then
|
|
||||||
T="0"
|
|
||||||
else
|
|
||||||
for BAND in $BANDS; do
|
|
||||||
case $BAND in
|
|
||||||
''|*[!0-9]*) continue ;;
|
|
||||||
esac
|
|
||||||
[ -n "$T" ] && T="${T},"
|
|
||||||
T="${T}50${BAND}"
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$T" ]; then
|
|
||||||
O=$(sms_tool -d $_DEVICE at "AT+GTACT?")
|
|
||||||
MODE=$(echo "$O" | awk -F[:,] '/\+GTACT:/{print $2","$3","$4}'| xargs)
|
|
||||||
sms_tool -d $_DEVICE at "AT+GTACT=$MODE,$T"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
setbands5gnsa() {
|
|
||||||
BANDS="$1"
|
|
||||||
|
|
||||||
T=""
|
|
||||||
if [ "$BANDS" = "default" ]; then
|
|
||||||
T="0"
|
|
||||||
else
|
|
||||||
for BAND in $BANDS; do
|
|
||||||
case $BAND in
|
|
||||||
''|*[!0-9]*) continue ;;
|
|
||||||
esac
|
|
||||||
[ -n "$T" ] && T="${T},"
|
|
||||||
T="${T}50${BAND}"
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$T" ]; then
|
|
||||||
O=$(sms_tool -d $_DEVICE at "AT+GTACT?")
|
|
||||||
MODE=$(echo "$O" | awk -F[:,] '/\+GTACT:/{print $2","$3","$4}'| xargs)
|
|
||||||
sms_tool -d $_DEVICE at "AT+GTACT=$MODE,$T"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
getsupportedbands() {
|
|
||||||
echo "$_DEFAULT_LTE_BANDS"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands() {
|
|
||||||
# ^SLBAND: WCDMA,Enabled,1,2,4,5,6,8,9,19
|
|
||||||
# ^SLBAND: LTE,Enabled,1,2,3,4,5,7,8,12,13,14,17,18,19,20,25,26,28,29,30,32,38,39,40,41,42,43,46,66
|
|
||||||
|
|
||||||
O=$(sms_tool -d $_DEVICE at "at^slband?")
|
|
||||||
echo "$O" | awk -F: '/LTE/{gsub("LTE,Enabled,","");gsub(","," ");print $2}' | xargs
|
|
||||||
}
|
|
||||||
|
|
||||||
setbands() {
|
|
||||||
BANDS="$1"
|
|
||||||
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_LTE_BANDS"
|
|
||||||
|
|
||||||
T=""
|
|
||||||
for BAND in $BANDS; do
|
|
||||||
case $BAND in
|
|
||||||
''|*[!0-9]*) continue ;;
|
|
||||||
esac
|
|
||||||
[ -n "$T" ] && T="${T},"
|
|
||||||
T="${T}${BAND}"
|
|
||||||
done
|
|
||||||
|
|
||||||
[ -n "$T" ] && sms_tool -d $_DEVICE at "at^slband=lte,2,$T"
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
getsupportedbands() {
|
|
||||||
echo "$_DEFAULT_LTE_BANDS"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands() {
|
|
||||||
# ^SLBAND: WCDMA,1,2,4,5,6,8,9,19
|
|
||||||
# ^SLBAND: LTE,1,2,3,4,5,7,8,12,13,17,18,19,20,21,25,26,28,29,30,38,39,40,41,66
|
|
||||||
|
|
||||||
O=$(sms_tool -d $_DEVICE at "at^slband?")
|
|
||||||
echo "$O" | awk -F: '/^\^SLBAND:.*LTE,/{gsub("LTE,","");gsub(","," ");print $2}' | xargs
|
|
||||||
}
|
|
||||||
|
|
||||||
setbands() {
|
|
||||||
BANDS="$1"
|
|
||||||
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_LTE_BANDS"
|
|
||||||
|
|
||||||
T=""
|
|
||||||
for BAND in $BANDS; do
|
|
||||||
case $BAND in
|
|
||||||
''|*[!0-9]*) continue ;;
|
|
||||||
esac
|
|
||||||
[ -n "$T" ] && T="${T},"
|
|
||||||
T="${T}${BAND}"
|
|
||||||
done
|
|
||||||
|
|
||||||
[ -n "$T" ] && sms_tool -d $_DEVICE at "at^slband=lte,$T"
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
getsupportedbands() {
|
|
||||||
echo "${_DEFAULT_LTE_BANDS:-Unsupported}"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands() {
|
|
||||||
O=$(sms_tool -d $_DEVICE at "at+qcfg=\"band\"")
|
|
||||||
HEX=$(echo "$O" | awk -F[:,] '{print $4}' | xargs)
|
|
||||||
hextobands "$HEX"
|
|
||||||
}
|
|
||||||
|
|
||||||
setbands() {
|
|
||||||
BANDS="$1"
|
|
||||||
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_LTE_BANDS"
|
|
||||||
|
|
||||||
HEX=$(bandstohex "$BANDS")
|
|
||||||
[ "$HEX" != "0" ] && sms_tool -d $_DEVICE at "at+qcfg=\"band\",0,$HEX,0,1"
|
|
||||||
}
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
getsupportedbands() {
|
|
||||||
echo "$_DEFAULT_LTE_BANDS"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands() {
|
|
||||||
# +QNWPREFCFG: "lte_band",1:3:7:8:20:28:38
|
|
||||||
|
|
||||||
O=$(sms_tool -d $_DEVICE at "at+qnwprefcfg=\"lte_band\"")
|
|
||||||
echo "$O" | awk -F, '/^\+QNWPREFCFG:/{gsub(":"," ");print $2}'
|
|
||||||
}
|
|
||||||
|
|
||||||
setbands() {
|
|
||||||
BANDS="$1"
|
|
||||||
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_LTE_BANDS"
|
|
||||||
|
|
||||||
T=""
|
|
||||||
for BAND in $BANDS; do
|
|
||||||
case $BAND in
|
|
||||||
''|*[!0-9]*) continue ;;
|
|
||||||
esac
|
|
||||||
[ -n "$T" ] && T="${T}:"
|
|
||||||
T="${T}${BAND}"
|
|
||||||
done
|
|
||||||
|
|
||||||
[ -n "$T" ] && sms_tool -d $_DEVICE at "at+qnwprefcfg=\"lte_band\",$T"
|
|
||||||
}
|
|
||||||
|
|
||||||
getsupportedbands5gnsa() {
|
|
||||||
echo "$_DEFAULT_5GNSA_BANDS"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands5gnsa() {
|
|
||||||
# +QNWPREFCFG: "nsa_nr5g_band",1:2:3:5:7:8:12:20:25:28:38:40:41:48:66:71:77:78:79
|
|
||||||
|
|
||||||
O=$(sms_tool -d $_DEVICE at "at+qnwprefcfg=\"nsa_nr5g_band\"")
|
|
||||||
echo "$O" | awk -F, '/^\+QNWPREFCFG:/{gsub(":"," ");print $2}' | xargs
|
|
||||||
}
|
|
||||||
|
|
||||||
setbands5gnsa() {
|
|
||||||
BANDS="$1"
|
|
||||||
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_5GNSA_BANDS"
|
|
||||||
|
|
||||||
T=""
|
|
||||||
for BAND in $BANDS; do
|
|
||||||
case $BAND in
|
|
||||||
''|*[!0-9]*) continue ;;
|
|
||||||
esac
|
|
||||||
[ -n "$T" ] && T="${T}:"
|
|
||||||
T="${T}${BAND}"
|
|
||||||
done
|
|
||||||
|
|
||||||
[ -n "$T" ] && sms_tool -d $_DEVICE at "at+qnwprefcfg=\"nsa_nr5g_band\",$T"
|
|
||||||
}
|
|
||||||
|
|
||||||
getsupportedbands5gsa() {
|
|
||||||
echo "$_DEFAULT_5GSA_BANDS"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands5gsa() {
|
|
||||||
# +QNWPREFCFG: "nr5g_band",1:2:3:5:7:8:12:20:25:28:38:40:41:48:66:71:77:78:79
|
|
||||||
|
|
||||||
O=$(sms_tool -d $_DEVICE at "at+qnwprefcfg=\"nr5g_band\"")
|
|
||||||
echo "$O" | awk -F, '/^\+QNWPREFCFG:/{gsub(":"," ");print $2}' | xargs
|
|
||||||
}
|
|
||||||
|
|
||||||
setbands5gsa() {
|
|
||||||
BANDS="$1"
|
|
||||||
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_5GSA_BANDS"
|
|
||||||
|
|
||||||
T=""
|
|
||||||
for BAND in $BANDS; do
|
|
||||||
case $BAND in
|
|
||||||
''|*[!0-9]*) continue ;;
|
|
||||||
esac
|
|
||||||
[ -n "$T" ] && T="${T}:"
|
|
||||||
T="${T}${BAND}"
|
|
||||||
done
|
|
||||||
|
|
||||||
[ -n "$T" ] && sms_tool -d $_DEVICE at "at+qnwprefcfg=\"nr5g_band\",$T"
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
getsupportedbands() {
|
|
||||||
echo "$_DEFAULT_LTE_BANDS"
|
|
||||||
}
|
|
||||||
|
|
||||||
getbands() {
|
|
||||||
# +ZNLOCKBAND: 80800c5,2000000680380
|
|
||||||
|
|
||||||
O=$(sms_tool -d $_DEVICE at "at+znlockband?")
|
|
||||||
HEX="0x"$(echo "$O" | awk -F[:,] '{print $2}' | xargs)
|
|
||||||
hextobands "$HEX"
|
|
||||||
}
|
|
||||||
|
|
||||||
setbands() {
|
|
||||||
BANDS="$1"
|
|
||||||
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_LTE_BANDS"
|
|
||||||
|
|
||||||
HEX=$(bandstohex "$BANDS")
|
|
||||||
[ "$HEX" != "0" ] && sms_tool -d $_DEVICE at "at+znlockband=1,0,$HEX,0"
|
|
||||||
}
|
|
||||||
+10
-20
@@ -1,36 +1,26 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=quectel-cm
|
PKG_NAME:=quectel-cm
|
||||||
PKG_VERSION:=1.6.8
|
PKG_VERSION:=1.6.7
|
||||||
PKG_RELEASE:=3
|
PKG_RELEASE:=4
|
||||||
|
|
||||||
|
PKG_SOURCE_PROTO:=git
|
||||||
|
PKG_SOURCE_URL:=https://github.com/quectel-open-source/Quectel_QConnectManager_Linux
|
||||||
|
PKG_SOURCE_VERSION:=170ed7177cc3beb831bc85571aad956492ff7e7e
|
||||||
|
PKG_MIRROR_HASH:=skip
|
||||||
|
|
||||||
include $(INCLUDE_DIR)/package.mk
|
include $(INCLUDE_DIR)/package.mk
|
||||||
include $(INCLUDE_DIR)/cmake.mk
|
|
||||||
|
|
||||||
define Package/quectel-cm
|
define Package/quectel-cm
|
||||||
SECTION:=net
|
SECTION:=net
|
||||||
CATEGORY:=Network
|
CATEGORY:=Network
|
||||||
SUBMENU:=WWAN
|
TITLE:=Quectel dial program
|
||||||
TITLE:=Qconnector Manager for Quectel WWAN modules
|
DEPENDS:=+libpthread
|
||||||
DEPENDS:= \
|
|
||||||
+kmod-usb-net-cdc-mbim \
|
|
||||||
+kmod-usb-net-qmi-wwan \
|
|
||||||
+kmod-usb-net-qmi-wwan-fibocom \
|
|
||||||
+kmod-usb-net-qmi-wwan-quectel \
|
|
||||||
+kmod-usb-serial-option
|
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/quectel-cm/install
|
define Package/quectel-cm/install
|
||||||
$(INSTALL_DIR) $(1)/usr/bin
|
$(INSTALL_DIR) $(1)/usr/bin
|
||||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/quectel-CM $(1)/usr/bin/quectel-cm
|
$(INSTALL_BIN) $(PKG_BUILD_DIR)/quectel-CM $(1)/usr/bin
|
||||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/quectel-{mbim,qmi}-proxy $(1)/usr/bin/
|
|
||||||
|
|
||||||
$(INSTALL_DIR) $(1)/lib/netifd/proto
|
|
||||||
$(INSTALL_BIN) ./files/quectel.sh $(1)/lib/netifd/proto/
|
|
||||||
|
|
||||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/net
|
|
||||||
$(INSTALL_BIN) ./files/smp-affinity-mhi-pcie.sh $(1)/etc/hotplug.d/net/21-smp-affinity-mhi-pcie
|
|
||||||
$(INSTALL_BIN) ./files/smp-affinity-qmi-usb.sh $(1)/etc/hotplug.d/net/22-smp-affinity-qmi-usb
|
|
||||||
endef
|
endef
|
||||||
|
|
||||||
$(eval $(call BuildPackage,quectel-cm))
|
$(eval $(call BuildPackage,quectel-cm))
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
[ -n "$INCLUDE_ONLY" ] || {
|
|
||||||
. /lib/functions.sh
|
|
||||||
. ../netifd-proto.sh
|
|
||||||
init_proto "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
proto_quectel_init_config() {
|
|
||||||
available=1
|
|
||||||
no_device=1
|
|
||||||
proto_config_add_string "device:device"
|
|
||||||
proto_config_add_string "apn"
|
|
||||||
proto_config_add_string "auth"
|
|
||||||
proto_config_add_string "username"
|
|
||||||
proto_config_add_string "password"
|
|
||||||
proto_config_add_string "pincode"
|
|
||||||
proto_config_add_int "delay"
|
|
||||||
proto_config_add_string "pdptype"
|
|
||||||
proto_config_add_boolean "dhcp"
|
|
||||||
proto_config_add_boolean "dhcpv6"
|
|
||||||
proto_config_add_boolean "sourcefilter"
|
|
||||||
proto_config_add_boolean "delegate"
|
|
||||||
proto_config_add_int "mtu"
|
|
||||||
proto_config_add_defaults
|
|
||||||
}
|
|
||||||
|
|
||||||
proto_quectel_setup() {
|
|
||||||
local interface="$1"
|
|
||||||
local device apn auth username password pincode delay pdptype
|
|
||||||
local dhcp dhcpv6 sourcefilter delegate mtu $PROTO_DEFAULT_OPTIONS
|
|
||||||
local ip4table ip6table
|
|
||||||
local pid zone
|
|
||||||
|
|
||||||
json_get_vars device apn auth username password pincode delay
|
|
||||||
json_get_vars pdptype dhcp dhcpv6 sourcefilter delegate ip4table
|
|
||||||
json_get_vars ip6table mtu $PROTO_DEFAULT_OPTIONS
|
|
||||||
|
|
||||||
[ -n "$delay" ] && sleep "$delay"
|
|
||||||
|
|
||||||
[ -n "$metric" ] || metric="0"
|
|
||||||
[ -z "$ctl_device" ] || device="$ctl_device"
|
|
||||||
|
|
||||||
[ -n "$device" ] || {
|
|
||||||
echo "No control device specified"
|
|
||||||
proto_notify_error "$interface" NO_DEVICE
|
|
||||||
proto_set_available "$interface" 0
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
device="$(readlink -f "$device")"
|
|
||||||
[ -c "$device" ] || {
|
|
||||||
echo "The specified control device does not exist"
|
|
||||||
proto_notify_error "$interface" NO_DEVICE
|
|
||||||
proto_set_available "$interface" 0
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
devname="$(basename "$device")"
|
|
||||||
devpath="$(readlink -f "/sys/class/usbmisc/$devname/device/")"
|
|
||||||
ifname="$(ls "$devpath/net" 2>"/dev/null")"
|
|
||||||
[ -n "$ifname" ] || {
|
|
||||||
echo "The interface could not be found."
|
|
||||||
proto_notify_error "$interface" NO_IFACE
|
|
||||||
proto_set_available "$interface" 0
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
[ "$pdptype" = "ipv4" -o "$pdptype" = "ipv4v6" ] && ipv4opt="-4"
|
|
||||||
[ "$pdptype" = "ipv6" -o "$pdptype" = "ipv4v6" ] && ipv6opt="-6"
|
|
||||||
[ -n "$auth" ] || auth="none"
|
|
||||||
|
|
||||||
eval "proto_run_command '$interface' /usr/bin/quectel-cm -i '$ifname' $ipv4opt $ipv6opt ${pincode:+-p $pincode} -s '$apn' '$username' '$password' '$auth'"
|
|
||||||
sleep 5
|
|
||||||
|
|
||||||
ifconfig "$ifname" up
|
|
||||||
ifconfig "${ifname}_1" &>"/dev/null" && ifname="${ifname}_1"
|
|
||||||
|
|
||||||
if [ -n "$mtu" ]; then
|
|
||||||
echo "Setting MTU to $mtu"
|
|
||||||
/sbin/ip link set dev "$ifname" mtu "$mtu"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Setting up $ifname"
|
|
||||||
proto_init_update "$ifname" 1
|
|
||||||
proto_set_keep 1
|
|
||||||
proto_send_update "$interface"
|
|
||||||
|
|
||||||
zone="$(fw3 -q network "$interface" 2>/dev/null)"
|
|
||||||
|
|
||||||
if [ "$pdptype" = "ipv6" ] || [ "$pdptype" = "ipv4v6" ]; then
|
|
||||||
json_init
|
|
||||||
json_add_string name "${interface}_6"
|
|
||||||
json_add_string ifname "@$interface"
|
|
||||||
[ "$pdptype" = "ipv4v6" ] && json_add_string iface_464xlat "0"
|
|
||||||
json_add_string proto "dhcpv6"
|
|
||||||
proto_add_dynamic_defaults
|
|
||||||
[ -z "$ip6table" ] || json_add_string ip6table "$ip6table"
|
|
||||||
# RFC 7278: Extend an IPv6 /64 Prefix to LAN
|
|
||||||
json_add_string extendprefix 1
|
|
||||||
[ "$delegate" = "0" ] && json_add_boolean delegate "0"
|
|
||||||
[ "$sourcefilter" = "0" ] && json_add_boolean sourcefilter "0"
|
|
||||||
[ -z "$zone" ] || json_add_string zone "$zone"
|
|
||||||
json_close_object
|
|
||||||
ubus call network add_dynamic "$(json_dump)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$pdptype" = "ipv4" ] || [ "$pdptype" = "ipv4v6" ]; then
|
|
||||||
json_init
|
|
||||||
json_add_string name "${interface}_4"
|
|
||||||
json_add_string ifname "@$interface"
|
|
||||||
json_add_string proto "dhcp"
|
|
||||||
[ -z "$ip4table" ] || json_add_string ip4table "$ip4table"
|
|
||||||
proto_add_dynamic_defaults
|
|
||||||
[ -z "$zone" ] || json_add_string zone "$zone"
|
|
||||||
json_close_object
|
|
||||||
ubus call network add_dynamic "$(json_dump)"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
proto_quectel_teardown() {
|
|
||||||
local interface="$1"
|
|
||||||
|
|
||||||
local device
|
|
||||||
json_get_vars device
|
|
||||||
[ -z "$ctl_device" ] || device="$ctl_device"
|
|
||||||
|
|
||||||
echo "Stopping network $interface"
|
|
||||||
|
|
||||||
proto_kill_command "$interface"
|
|
||||||
|
|
||||||
proto_init_update "*" 0
|
|
||||||
proto_send_update "$interface"
|
|
||||||
}
|
|
||||||
|
|
||||||
[ -n "$INCLUDE_ONLY" ] || {
|
|
||||||
add_protocol quectel
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
[ "$ACTION" = add ] || exit
|
|
||||||
echo "$INTERFACE" | grep -q "rmnet_mhi" || exit
|
|
||||||
|
|
||||||
core_count="$(grep -c "processor" "/proc/cpuinfo")"
|
|
||||||
irq_path="/sys/class/net/$INTERFACE/queues"
|
|
||||||
|
|
||||||
devnum="$(echo "${INTERFACE%.*}" | grep -Eo "[0-9]+")"
|
|
||||||
core="$(( devnum % (core_count - 1) + 1))"
|
|
||||||
if [ "$INTERFACE" != "${INTERFACE%.*}" ]; then
|
|
||||||
if [ "$core" -lt "$(( core_count - 1 ))" ]; then
|
|
||||||
let core++
|
|
||||||
else
|
|
||||||
core="1"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
irq="$(printf "%x" "$((1 << core))")"
|
|
||||||
|
|
||||||
echo "$irq" > "$irq_path/rx-0/rps_cpus"
|
|
||||||
echo "4096" > "$irq_path/rx-0/rps_flow_cnt"
|
|
||||||
echo "2000" > "/proc/sys/net/core/netdev_max_backlog"
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
[ "$ACTION" = add ] || exit
|
|
||||||
echo "$INTERFACE" | grep -q "wwan" || exit
|
|
||||||
|
|
||||||
core_count="$(grep -c "processor" "/proc/cpuinfo")"
|
|
||||||
irq_path="/sys/class/net/$INTERFACE/queues"
|
|
||||||
|
|
||||||
devnum="$(echo "${INTERFACE%_*}" | grep -Eo "[0-9]+")"
|
|
||||||
core="$(( devnum % (core_count - 1) + 1))"
|
|
||||||
if [ "$INTERFACE" != "${INTERFACE%_*}" ]; then
|
|
||||||
if [ "$core" -lt "$(( core_count - 1 ))" ]; then
|
|
||||||
let core++
|
|
||||||
else
|
|
||||||
core="1"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
irq="$(printf "%x" "$((1 << core))")"
|
|
||||||
|
|
||||||
echo "$irq" > "$irq_path/rx-0/rps_cpus"
|
|
||||||
echo "4096" > "$irq_path/rx-0/rps_flow_cnt"
|
|
||||||
echo "2000" > "/proc/sys/net/core/netdev_max_backlog"
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
--- a/quectel-qrtr-proxy.c
|
|
||||||
+++ b/quectel-qrtr-proxy.c
|
|
||||||
@@ -555,7 +555,7 @@ static int recv_qmi_from_client(PQCQMIMS
|
|
||||||
}
|
|
||||||
else if (le16toh(pQMI->CTLMsg.QMICTLMsgHdr.QMICTLType) == QMICTL_GET_CLIENT_ID_REQ) {
|
|
||||||
uint8_t QMIType = pQMI->CTLMsg.GetClientIdReq.QMIType;
|
|
||||||
- PQCQMIMSG pRsp = (PQCQMIMSG)malloc(256);
|
|
||||||
+ PQCQMIMSG pRsp = (PQCQMIMSG)malloc(sizeof(*pRsp));
|
|
||||||
|
|
||||||
if (pRsp) {
|
|
||||||
uint8_t ClientId = 0;
|
|
||||||
@@ -589,7 +589,7 @@ static int recv_qmi_from_client(PQCQMIMS
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (le16toh(pQMI->CTLMsg.QMICTLMsgHdr.QMICTLType) == QMICTL_RELEASE_CLIENT_ID_REQ) {
|
|
||||||
- PQCQMIMSG pRsp = (PQCQMIMSG)malloc(256);
|
|
||||||
+ PQCQMIMSG pRsp = (PQCQMIMSG)malloc(sizeof(*pRsp));
|
|
||||||
release_qrtr_client_id(qrtr_con, pQMI->CTLMsg.ReleaseClientIdReq.QMIType, pQMI->CTLMsg.ReleaseClientIdReq.ClientId);
|
|
||||||
|
|
||||||
if (pRsp) {
|
|
||||||
@@ -618,7 +618,7 @@ static int recv_qmi_from_client(PQCQMIMS
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (le16toh(pQMI->CTLMsg.QMICTLMsgHdr.QMICTLType) == QMICTL_GET_VERSION_REQ) {
|
|
||||||
- PQCQMIMSG pRsp = (PQCQMIMSG)malloc(256);
|
|
||||||
+ PQCQMIMSG pRsp = (PQCQMIMSG)malloc(sizeof(*pRsp));
|
|
||||||
|
|
||||||
if (pRsp) {
|
|
||||||
pRsp->QMIHdr.IFType = USB_CTL_MSG_TYPE_QMI;
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
--- a/CMakeLists.txt
|
|
||||||
+++ b/CMakeLists.txt
|
|
||||||
@@ -1,4 +1,4 @@
|
|
||||||
-cmake_minimum_required(VERSION 2.4)
|
|
||||||
+cmake_minimum_required(VERSION 3.10)
|
|
||||||
|
|
||||||
project(quectel-CM)
|
|
||||||
add_definitions(-Wall -Wextra -Werror -O1)
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
--- a/device.c
|
|
||||||
+++ b/device.c
|
|
||||||
@@ -342,10 +342,12 @@ BOOL qmidevice_detect(char *qmichannel,
|
|
||||||
switch (profile->usb_dev.idProduct) { //EC200U
|
|
||||||
case 0x0901: //EC200U
|
|
||||||
case 0x0902: //EC200D
|
|
||||||
+ case 0x0904: //EC200G
|
|
||||||
case 0x8101: //RG801H
|
|
||||||
atIntf = 2;
|
|
||||||
break;
|
|
||||||
case 0x0900: //RG500U
|
|
||||||
+ case 0x0903: //EC600
|
|
||||||
atIntf = 4;
|
|
||||||
break;
|
|
||||||
case 0x6026: //EC200T
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 2.4)
|
|
||||||
|
|
||||||
project(quectel-CM)
|
|
||||||
add_definitions(-Wall -Wextra -Werror -O1)
|
|
||||||
option(USE_QRTR "Enable QRTR" OFF)
|
|
||||||
|
|
||||||
set( QL_CM_SRC
|
|
||||||
QmiWwanCM.c GobiNetCM.c main.c QCQMUX.c QMIThread.c util.c qmap_bridge_mode.c mbim-cm.c device.c
|
|
||||||
atc.c atchannel.c at_tok.c
|
|
||||||
udhcpc.c
|
|
||||||
)
|
|
||||||
|
|
||||||
if(USE_QRTR)
|
|
||||||
add_definitions(-DCONFIG_QRTR)
|
|
||||||
set( QRTR_SRC qrtr.c rmnetctl.c)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_executable(quectel-CM ${QL_CM_SRC} ${QRTR_SRC})
|
|
||||||
target_link_libraries(quectel-CM PUBLIC pthread)
|
|
||||||
install (TARGETS quectel-CM DESTINATION bin)
|
|
||||||
|
|
||||||
add_executable(quectel-qmi-proxy quectel-qmi-proxy.c)
|
|
||||||
target_link_libraries(quectel-qmi-proxy PUBLIC pthread)
|
|
||||||
install (TARGETS quectel-qmi-proxy DESTINATION bin)
|
|
||||||
|
|
||||||
add_executable(quectel-mbim-proxy quectel-mbim-proxy.c)
|
|
||||||
target_link_libraries(quectel-mbim-proxy PUBLIC pthread)
|
|
||||||
install (TARGETS quectel-mbim-proxy DESTINATION bin)
|
|
||||||
|
|
||||||
add_executable(quectel-atc-proxy quectel-atc-proxy.c atchannel.c at_tok.c util.c)
|
|
||||||
target_link_libraries(quectel-atc-proxy PUBLIC pthread)
|
|
||||||
install (TARGETS quectel-atc-proxy DESTINATION bin)
|
|
||||||
|
|
||||||
add_executable(quectel-qrtr-proxy quectel-qrtr-proxy.c)
|
|
||||||
target_link_libraries(quectel-qrtr-proxy PUBLIC pthread)
|
|
||||||
install (TARGETS quectel-qrtr-proxy DESTINATION bin)
|
|
||||||
@@ -1,242 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2025 Quectel Wireless Solutions Co.,Ltd
|
|
||||||
|
|
||||||
Quectel hereby grants customers of Quectel a license to use, modify,
|
|
||||||
distribute and publish the Software in binary form provided that
|
|
||||||
customers shall have no right to reverse engineer, reverse assemble,
|
|
||||||
decompile or reduce to source code form any portion of the Software.
|
|
||||||
Under no circumstances may customers modify, demonstrate, use, deliver
|
|
||||||
or disclose any portion of the Software in source code form.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include "QMIThread.h"
|
|
||||||
|
|
||||||
#ifdef CONFIG_GOBINET
|
|
||||||
static int qmiclientId[QMUX_TYPE_ALL];
|
|
||||||
|
|
||||||
// IOCTL to generate a client ID for this service type
|
|
||||||
#define IOCTL_QMI_GET_SERVICE_FILE 0x8BE0 + 1
|
|
||||||
|
|
||||||
// IOCTL to get the VIDPID of the device
|
|
||||||
#define IOCTL_QMI_GET_DEVICE_VIDPID 0x8BE0 + 2
|
|
||||||
|
|
||||||
// IOCTL to get the MEID of the device
|
|
||||||
#define IOCTL_QMI_GET_DEVICE_MEID 0x8BE0 + 3
|
|
||||||
|
|
||||||
static int GobiNetSendQMI(PQCQMIMSG pRequest) {
|
|
||||||
int ret, fd;
|
|
||||||
|
|
||||||
fd = qmiclientId[pRequest->QMIHdr.QMIType];
|
|
||||||
pRequest->QMIHdr.ClientId = (fd&0xFF) ? fd&0xFF : pRequest->QMIHdr.QMIType;
|
|
||||||
|
|
||||||
if (fd <= 0) {
|
|
||||||
dbg_time("%s QMIType: %d has no clientID", __func__, pRequest->QMIHdr.QMIType);
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Always ready to write
|
|
||||||
if (1 == 1) {
|
|
||||||
ssize_t nwrites = le16_to_cpu(pRequest->QMIHdr.Length) + 1 - sizeof(QCQMI_HDR);
|
|
||||||
ret = write(fd, &pRequest->MUXMsg, nwrites);
|
|
||||||
if (ret == nwrites) {
|
|
||||||
ret = 0;
|
|
||||||
} else {
|
|
||||||
dbg_time("%s write=%d, errno: %d (%s)", __func__, ret, errno, strerror(errno));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dbg_time("%s poll=%d, errno: %d (%s)", __func__, ret, errno, strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int GobiNetGetClientID(const char *qcqmi, UCHAR QMIType) {
|
|
||||||
int ClientId;
|
|
||||||
ClientId = cm_open_dev(qcqmi);
|
|
||||||
if (ClientId == -1) {
|
|
||||||
dbg_time("failed to open %s, errno: %d (%s)", qcqmi, errno, strerror(errno));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ioctl(ClientId, IOCTL_QMI_GET_SERVICE_FILE, QMIType) != 0) {
|
|
||||||
dbg_time("failed to get ClientID for 0x%02x errno: %d (%s)", QMIType, errno, strerror(errno));
|
|
||||||
close(ClientId);
|
|
||||||
ClientId = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (QMIType) {
|
|
||||||
case QMUX_TYPE_WDS: dbg_time("Get clientWDS = %d", ClientId); break;
|
|
||||||
case QMUX_TYPE_DMS: dbg_time("Get clientDMS = %d", ClientId); break;
|
|
||||||
case QMUX_TYPE_NAS: dbg_time("Get clientNAS = %d", ClientId); break;
|
|
||||||
case QMUX_TYPE_QOS: dbg_time("Get clientQOS = %d", ClientId); break;
|
|
||||||
case QMUX_TYPE_WMS: dbg_time("Get clientWMS = %d", ClientId); break;
|
|
||||||
case QMUX_TYPE_PDS: dbg_time("Get clientPDS = %d", ClientId); break;
|
|
||||||
case QMUX_TYPE_UIM: dbg_time("Get clientUIM = %d", ClientId); break;
|
|
||||||
case QMUX_TYPE_COEX: dbg_time("Get clientCOEX = %d", ClientId); break;
|
|
||||||
case QMUX_TYPE_WDS_ADMIN: dbg_time("Get clientWDA = %d", ClientId);
|
|
||||||
break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ClientId;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int GobiNetDeInit(void) {
|
|
||||||
unsigned int i;
|
|
||||||
for (i = 0; i < sizeof(qmiclientId)/sizeof(qmiclientId[0]); i++)
|
|
||||||
{
|
|
||||||
if (qmiclientId[i] != 0)
|
|
||||||
{
|
|
||||||
close(qmiclientId[i]);
|
|
||||||
qmiclientId[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void * GobiNetThread(void *pData) {
|
|
||||||
PROFILE_T *profile = (PROFILE_T *)pData;
|
|
||||||
const char *qcqmi = (const char *)profile->qmichannel;
|
|
||||||
int wait_for_request_quit = 0;
|
|
||||||
|
|
||||||
qmiclientId[QMUX_TYPE_WDS] = GobiNetGetClientID(qcqmi, QMUX_TYPE_WDS);
|
|
||||||
if (profile->enable_ipv6)
|
|
||||||
qmiclientId[QMUX_TYPE_WDS_IPV6] = GobiNetGetClientID(qcqmi, QMUX_TYPE_WDS);
|
|
||||||
qmiclientId[QMUX_TYPE_DMS] = GobiNetGetClientID(qcqmi, QMUX_TYPE_DMS);
|
|
||||||
qmiclientId[QMUX_TYPE_NAS] = GobiNetGetClientID(qcqmi, QMUX_TYPE_NAS);
|
|
||||||
qmiclientId[QMUX_TYPE_UIM] = GobiNetGetClientID(qcqmi, QMUX_TYPE_UIM);
|
|
||||||
#ifdef CONFIG_COEX_WWAN_STATE
|
|
||||||
qmiclientId[QMUX_TYPE_COEX] = GobiNetGetClientID(qcqmi, QMUX_TYPE_COEX);
|
|
||||||
#endif
|
|
||||||
if (profile->qmap_mode == 0 || profile->loopback_state) {//when QMAP enabled, set data format in GobiNet Driver
|
|
||||||
qmiclientId[QMUX_TYPE_WDS_ADMIN] = GobiNetGetClientID(qcqmi, QMUX_TYPE_WDS_ADMIN);
|
|
||||||
profile->wda_client = qmiclientId[QMUX_TYPE_WDS_ADMIN];
|
|
||||||
}
|
|
||||||
|
|
||||||
//donot check clientWDA, there is only one client for WDA, if quectel-CM is killed by SIGKILL, i cannot get client ID for WDA again!
|
|
||||||
if (qmiclientId[QMUX_TYPE_WDS] == 0) /*|| (clientWDA == -1)*/ {
|
|
||||||
GobiNetDeInit();
|
|
||||||
dbg_time("%s Failed to open %s, errno: %d (%s)", __func__, qcqmi, errno, strerror(errno));
|
|
||||||
qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_DISCONNECTED);
|
|
||||||
pthread_exit(NULL);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_CONNECTED);
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
struct pollfd pollfds[16] = {{qmidevice_control_fd[1], POLLIN, 0}};
|
|
||||||
int ne, ret, nevents = 1;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; i < sizeof(qmiclientId)/sizeof(qmiclientId[0]); i++)
|
|
||||||
{
|
|
||||||
if (qmiclientId[i] != 0)
|
|
||||||
{
|
|
||||||
pollfds[nevents].fd = qmiclientId[i];
|
|
||||||
pollfds[nevents].events = POLLIN;
|
|
||||||
pollfds[nevents].revents = 0;
|
|
||||||
nevents++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
ret = poll(pollfds, nevents, wait_for_request_quit ? 1000: -1);
|
|
||||||
} while ((ret < 0) && (errno == EINTR));
|
|
||||||
|
|
||||||
if (ret == 0 && wait_for_request_quit) {
|
|
||||||
QmiThreadRecvQMI(NULL); //main thread may pending on QmiThreadSendQMI()
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret <= 0) {
|
|
||||||
dbg_time("%s poll=%d, errno: %d (%s)", __func__, ret, errno, strerror(errno));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ne = 0; ne < nevents; ne++) {
|
|
||||||
int fd = pollfds[ne].fd;
|
|
||||||
short revents = pollfds[ne].revents;
|
|
||||||
|
|
||||||
if (revents & (POLLERR | POLLHUP | POLLNVAL)) {
|
|
||||||
dbg_time("%s poll err/hup/inval", __func__);
|
|
||||||
dbg_time("epoll fd = %d, events = 0x%04x", fd, revents);
|
|
||||||
if (fd == qmidevice_control_fd[1]) {
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
if (revents & (POLLERR | POLLHUP | POLLNVAL))
|
|
||||||
goto __GobiNetThread_quit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((revents & POLLIN) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (fd == qmidevice_control_fd[1]) {
|
|
||||||
int triger_event;
|
|
||||||
if (read(fd, &triger_event, sizeof(triger_event)) == sizeof(triger_event)) {
|
|
||||||
//DBG("triger_event = 0x%x", triger_event);
|
|
||||||
switch (triger_event) {
|
|
||||||
case RIL_REQUEST_QUIT:
|
|
||||||
goto __GobiNetThread_quit;
|
|
||||||
break;
|
|
||||||
case SIG_EVENT_STOP:
|
|
||||||
wait_for_request_quit = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ssize_t nreads;
|
|
||||||
PQCQMIMSG pResponse = (PQCQMIMSG)cm_recv_buf;
|
|
||||||
|
|
||||||
nreads = read(fd, &pResponse->MUXMsg, sizeof(cm_recv_buf) - sizeof(QCQMI_HDR));
|
|
||||||
if (nreads <= 0)
|
|
||||||
{
|
|
||||||
dbg_time("%s read=%d errno: %d (%s)", __func__, (int)nreads, errno, strerror(errno));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < sizeof(qmiclientId)/sizeof(qmiclientId[0]); i++)
|
|
||||||
{
|
|
||||||
if (qmiclientId[i] == fd)
|
|
||||||
{
|
|
||||||
pResponse->QMIHdr.QMIType = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pResponse->QMIHdr.IFType = USB_CTL_MSG_TYPE_QMI;
|
|
||||||
pResponse->QMIHdr.Length = cpu_to_le16(nreads + sizeof(QCQMI_HDR) - 1);
|
|
||||||
pResponse->QMIHdr.CtlFlags = 0x00;
|
|
||||||
pResponse->QMIHdr.ClientId = (fd&0xFF) ? fd&0xFF : pResponse->QMIHdr.QMIType;;
|
|
||||||
|
|
||||||
QmiThreadRecvQMI(pResponse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__GobiNetThread_quit:
|
|
||||||
GobiNetDeInit();
|
|
||||||
qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_DISCONNECTED);
|
|
||||||
QmiThreadRecvQMI(NULL); //main thread may pending on QmiThreadSendQMI()
|
|
||||||
dbg_time("%s exit", __func__);
|
|
||||||
pthread_exit(NULL);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct qmi_device_ops gobi_qmidev_ops = {
|
|
||||||
.deinit = GobiNetDeInit,
|
|
||||||
.send = GobiNetSendQMI,
|
|
||||||
.read = GobiNetThread,
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
ifneq ($(CROSS_COMPILE),)
|
|
||||||
CROSS-COMPILE:=$(CROSS_COMPILE)
|
|
||||||
endif
|
|
||||||
#CROSS-COMPILE:=/workspace/buildroot/buildroot-qemu_mips_malta_defconfig/output/host/usr/bin/mips-buildroot-linux-uclibc-
|
|
||||||
#CROSS-COMPILE:=/workspace/buildroot/buildroot-qemu_arm_vexpress_defconfig/output/host/usr/bin/arm-buildroot-linux-uclibcgnueabi-
|
|
||||||
#CROSS-COMPILE:=/workspace/buildroot-git/qemu_mips64_malta/output/host/usr/bin/mips-gnu-linux-
|
|
||||||
ifeq ($(CC),cc)
|
|
||||||
CC:=$(CROSS-COMPILE)gcc
|
|
||||||
endif
|
|
||||||
LD:=$(CROSS-COMPILE)ld
|
|
||||||
|
|
||||||
QL_CM_SRC=QmiWwanCM.c GobiNetCM.c main.c QCQMUX.c QMIThread.c util.c qmap_bridge_mode.c mbim-cm.c device.c
|
|
||||||
QL_CM_SRC+=atc.c atchannel.c at_tok.c
|
|
||||||
#QL_CM_SRC+=qrtr.c rmnetctl.c
|
|
||||||
ifeq (1,1)
|
|
||||||
QL_CM_DHCP=udhcpc.c
|
|
||||||
else
|
|
||||||
LIBMNL=libmnl/ifutils.c libmnl/attr.c libmnl/callback.c libmnl/nlmsg.c libmnl/socket.c
|
|
||||||
DHCP=libmnl/dhcp/dhcpclient.c libmnl/dhcp/dhcpmsg.c libmnl/dhcp/packet.c
|
|
||||||
QL_CM_DHCP=udhcpc_netlink.c
|
|
||||||
QL_CM_DHCP+=${LIBMNL}
|
|
||||||
endif
|
|
||||||
|
|
||||||
CFLAGS += -Wall -Wextra -Werror -O1 #-s
|
|
||||||
LDFLAGS += -lpthread -ldl -lrt
|
|
||||||
|
|
||||||
release: clean qmi-proxy mbim-proxy atc-proxy #qrtr-proxy
|
|
||||||
$(CC) ${CFLAGS} ${QL_CM_SRC} ${QL_CM_DHCP} -o quectel-CM ${LDFLAGS}
|
|
||||||
|
|
||||||
debug: clean
|
|
||||||
$(CC) ${CFLAGS} -g -DCM_DEBUG ${QL_CM_SRC} ${QL_CM_DHCP} -o quectel-CM -lpthread -ldl -lrt
|
|
||||||
|
|
||||||
qmi-proxy:
|
|
||||||
$(CC) ${CFLAGS} quectel-qmi-proxy.c -o quectel-qmi-proxy ${LDFLAGS}
|
|
||||||
|
|
||||||
mbim-proxy:
|
|
||||||
$(CC) ${CFLAGS} quectel-mbim-proxy.c -o quectel-mbim-proxy ${LDFLAGS}
|
|
||||||
|
|
||||||
qrtr-proxy:
|
|
||||||
$(CC) ${CFLAGS} quectel-qrtr-proxy.c -o quectel-qrtr-proxy ${LDFLAGS}
|
|
||||||
|
|
||||||
atc-proxy:
|
|
||||||
$(CC) ${CFLAGS} quectel-atc-proxy.c atchannel.c at_tok.c util.c -o quectel-atc-proxy ${LDFLAGS}
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf *.o libmnl/*.o quectel-CM quectel-qmi-proxy quectel-mbim-proxy quectel-atc-proxy
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
bin_PROGRAMS = quectel-CM
|
|
||||||
QL_CM_SRC=QmiWwanCM.c GobiNetCM.c main.c QCQMUX.c QMIThread.c util.c qmap_bridge_mode.c mbim-cm.c device.c
|
|
||||||
QL_CM_SRC+=atc.c atchannel.c at_tok.c
|
|
||||||
#QL_CM_SRC+=qrtr.c rmnetctl.c
|
|
||||||
QL_CM_DHCP=udhcpc.c
|
|
||||||
if USE_QRTR
|
|
||||||
quectel_CM_CFLAGS = -DCONFIG_QRTR
|
|
||||||
QL_CM_SRC += qrtr.c rmnetctl.c
|
|
||||||
if USE_MSM_IPC
|
|
||||||
quectel_CM_CFLAGS += -DUSE_LINUX_MSM_IPC
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
quectel_CM_SOURCES = ${QL_CM_SRC} ${QL_CM_DHCP}
|
|
||||||
|
|
||||||
bin_PROGRAMS += quectel-qmi-proxy
|
|
||||||
quectel_qmi_proxy_SOURCES = quectel-qmi-proxy.c
|
|
||||||
|
|
||||||
bin_PROGRAMS += quectel-mbim-proxy
|
|
||||||
quectel_mbim_proxy_SOURCES = quectel-mbim-proxy.c
|
|
||||||
LIBS = -l pthread
|
|
||||||
CFLAGS = -Wall -Wextra -Werror -O1
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
This program is totally open souce code, and public domain software for customers of Quectel company.
|
|
||||||
|
|
||||||
The APIs of QMI WWAMN interfaces are defined by Qualcomm. And this program complies with Qualcomm QMI WWAN interfaces specification.
|
|
||||||
|
|
||||||
Customers are free to modify the source codes and redistribute them.
|
|
||||||
|
|
||||||
For those who is not Quectel's customer, all rights are closed, and any copying and commercial development over this progrma is not allowed.
|
|
||||||
@@ -1,389 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2025 Quectel Wireless Solutions Co.,Ltd
|
|
||||||
|
|
||||||
Quectel hereby grants customers of Quectel a license to use, modify,
|
|
||||||
distribute and publish the Software in binary form provided that
|
|
||||||
customers shall have no right to reverse engineer, reverse assemble,
|
|
||||||
decompile or reduce to source code form any portion of the Software.
|
|
||||||
Under no circumstances may customers modify, demonstrate, use, deliver
|
|
||||||
or disclose any portion of the Software in source code form.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QCQCTL_H
|
|
||||||
#define QCQCTL_H
|
|
||||||
|
|
||||||
#include "QCQMI.h"
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
|
|
||||||
// ================= QMICTL ==================
|
|
||||||
|
|
||||||
// QMICTL Control Flags
|
|
||||||
#define QMICTL_CTL_FLAG_CMD 0x00
|
|
||||||
#define QMICTL_CTL_FLAG_RSP 0x01
|
|
||||||
#define QMICTL_CTL_FLAG_IND 0x02
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
typedef struct _QMICTL_TRANSACTION_ITEM
|
|
||||||
{
|
|
||||||
LIST_ENTRY List;
|
|
||||||
UCHAR TransactionId; // QMICTL transaction id
|
|
||||||
PVOID Context; // Adapter or IocDev
|
|
||||||
PIRP Irp;
|
|
||||||
} QMICTL_TRANSACTION_ITEM, *PQMICTL_TRANSACTION_ITEM;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct _QCQMICTL_MSG_HDR
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // 00-cmd, 01-rsp, 10-ind
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType;
|
|
||||||
USHORT Length;
|
|
||||||
} __attribute__ ((packed)) QCQMICTL_MSG_HDR, *PQCQMICTL_MSG_HDR;
|
|
||||||
|
|
||||||
#define QCQMICTL_MSG_HDR_SIZE sizeof(QCQMICTL_MSG_HDR)
|
|
||||||
|
|
||||||
typedef struct _QCQMICTL_MSG_HDR_RESP
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // 00-cmd, 01-rsp, 10-ind
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType;
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // 0x02 - result code
|
|
||||||
USHORT TLVLength; // 4
|
|
||||||
USHORT QMUXResult; // QMI_RESULT_SUCCESS
|
|
||||||
// QMI_RESULT_FAILURE
|
|
||||||
USHORT QMUXError; // QMI_ERR_INVALID_ARG
|
|
||||||
// QMI_ERR_NO_MEMORY
|
|
||||||
// QMI_ERR_INTERNAL
|
|
||||||
// QMI_ERR_FAULT
|
|
||||||
} __attribute__ ((packed)) QCQMICTL_MSG_HDR_RESP, *PQCQMICTL_MSG_HDR_RESP;
|
|
||||||
|
|
||||||
typedef struct _QCQMICTL_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // 00-cmd, 01-rsp, 10-ind
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType;
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR Payload;
|
|
||||||
} __attribute__ ((packed)) QCQMICTL_MSG, *PQCQMICTL_MSG;
|
|
||||||
|
|
||||||
// TLV Header
|
|
||||||
typedef struct _QCQMICTL_TLV_HDR
|
|
||||||
{
|
|
||||||
UCHAR TLVType;
|
|
||||||
USHORT TLVLength;
|
|
||||||
} __attribute__ ((packed)) QCQMICTL_TLV_HDR, *PQCQMICTL_TLV_HDR;
|
|
||||||
|
|
||||||
#define QCQMICTL_TLV_HDR_SIZE sizeof(QCQMICTL_TLV_HDR)
|
|
||||||
|
|
||||||
// QMICTL Type
|
|
||||||
#define QMICTL_SET_INSTANCE_ID_REQ 0x0020
|
|
||||||
#define QMICTL_SET_INSTANCE_ID_RESP 0x0020
|
|
||||||
#define QMICTL_GET_VERSION_REQ 0x0021
|
|
||||||
#define QMICTL_GET_VERSION_RESP 0x0021
|
|
||||||
#define QMICTL_GET_CLIENT_ID_REQ 0x0022
|
|
||||||
#define QMICTL_GET_CLIENT_ID_RESP 0x0022
|
|
||||||
#define QMICTL_RELEASE_CLIENT_ID_REQ 0x0023
|
|
||||||
#define QMICTL_RELEASE_CLIENT_ID_RESP 0x0023
|
|
||||||
#define QMICTL_REVOKE_CLIENT_ID_IND 0x0024
|
|
||||||
#define QMICTL_INVALID_CLIENT_ID_IND 0x0025
|
|
||||||
#define QMICTL_SET_DATA_FORMAT_REQ 0x0026
|
|
||||||
#define QMICTL_SET_DATA_FORMAT_RESP 0x0026
|
|
||||||
#define QMICTL_SYNC_REQ 0x0027
|
|
||||||
#define QMICTL_SYNC_RESP 0x0027
|
|
||||||
#define QMICTL_SYNC_IND 0x0027
|
|
||||||
#define QMI_MESSAGE_CTL_INTERNAL_PROXY_OPEN 0xFF00
|
|
||||||
|
|
||||||
#define QMICTL_FLAG_REQUEST 0x00
|
|
||||||
#define QMICTL_FLAG_RESPONSE 0x01
|
|
||||||
#define QMICTL_FLAG_INDICATION 0x02
|
|
||||||
|
|
||||||
// QMICTL Message Definitions
|
|
||||||
|
|
||||||
typedef struct _QMICTL_SET_INSTANCE_ID_REQ_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_SET_INSTANCE_ID_REQ
|
|
||||||
USHORT Length; // 4
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
|
|
||||||
USHORT TLVLength; // 1
|
|
||||||
UCHAR Value; // Host-unique QMI instance for this device driver
|
|
||||||
} __attribute__ ((packed)) QMICTL_SET_INSTANCE_ID_REQ_MSG, *PQMICTL_SET_INSTANCE_ID_REQ_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_SET_INSTANCE_ID_RESP_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_SET_INSTANCE_ID_RESP
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
|
|
||||||
USHORT TLVLength; // 0x0004
|
|
||||||
USHORT QMIResult;
|
|
||||||
USHORT QMIError;
|
|
||||||
UCHAR TLV2Type; // QCTLV_TYPE_REQUIRED_PARAMETER
|
|
||||||
USHORT TLV2Length; // 0x0002
|
|
||||||
USHORT QMI_ID; // Upper byte is assigned by MSM,
|
|
||||||
// lower assigned by host
|
|
||||||
} __attribute__ ((packed)) QMICTL_SET_INSTANCE_ID_RESP_MSG, *PQMICTL_SET_INSTANCE_ID_RESP_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_GET_VERSION_REQ_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_GET_VERSION_REQ
|
|
||||||
USHORT Length; // 0
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
|
|
||||||
USHORT TLVLength; // var
|
|
||||||
UCHAR QMUXTypes; // List of one byte QMUX_TYPE values
|
|
||||||
// 0xFF returns a list of versions for all
|
|
||||||
// QMUX_TYPEs implemented on the device
|
|
||||||
} __attribute__ ((packed)) QMICTL_GET_VERSION_REQ_MSG, *PQMICTL_GET_VERSION_REQ_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMUX_TYPE_VERSION_STRUCT
|
|
||||||
{
|
|
||||||
UCHAR QMUXType;
|
|
||||||
USHORT MajorVersion;
|
|
||||||
USHORT MinorVersion;
|
|
||||||
} __attribute__ ((packed)) QMUX_TYPE_VERSION_STRUCT, *PQMUX_TYPE_VERSION_STRUCT;
|
|
||||||
|
|
||||||
typedef struct _ADDENDUM_VERSION_PREAMBLE
|
|
||||||
{
|
|
||||||
UCHAR LabelLength;
|
|
||||||
UCHAR Label;
|
|
||||||
} __attribute__ ((packed)) ADDENDUM_VERSION_PREAMBLE, *PADDENDUM_VERSION_PREAMBLE;
|
|
||||||
|
|
||||||
#define QMICTL_GET_VERSION_RSP_TLV_TYPE_VERSION 0x01
|
|
||||||
#define QMICTL_GET_VERSION_RSP_TLV_TYPE_ADD_VERSION 0x10
|
|
||||||
|
|
||||||
typedef struct _QMICTL_GET_VERSION_RESP_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_GET_VERSION_RESP
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
|
|
||||||
USHORT TLVLength; // 0x0004
|
|
||||||
USHORT QMIResult;
|
|
||||||
USHORT QMIError;
|
|
||||||
UCHAR TLV2Type; // QCTLV_TYPE_REQUIRED_PARAMETER
|
|
||||||
USHORT TLV2Length; // var
|
|
||||||
UCHAR NumElements; // Num of QMUX_TYPE_VERSION_STRUCT
|
|
||||||
QMUX_TYPE_VERSION_STRUCT TypeVersion[0];
|
|
||||||
} __attribute__ ((packed)) QMICTL_GET_VERSION_RESP_MSG, *PQMICTL_GET_VERSION_RESP_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_GET_CLIENT_ID_REQ_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_GET_CLIENT_ID_REQ
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
|
|
||||||
USHORT TLVLength; // 1
|
|
||||||
UCHAR QMIType; // QMUX type
|
|
||||||
} __attribute__ ((packed)) QMICTL_GET_CLIENT_ID_REQ_MSG, *PQMICTL_GET_CLIENT_ID_REQ_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_GET_CLIENT_ID_RESP_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_GET_CLIENT_ID_RESP
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
|
|
||||||
USHORT TLVLength; // 0x0004
|
|
||||||
USHORT QMIResult; // result code
|
|
||||||
USHORT QMIError; // error code
|
|
||||||
UCHAR TLV2Type; // QCTLV_TYPE_REQUIRED_PARAMETER
|
|
||||||
USHORT TLV2Length; // 2
|
|
||||||
UCHAR QMIType;
|
|
||||||
UCHAR ClientId;
|
|
||||||
} __attribute__ ((packed)) QMICTL_GET_CLIENT_ID_RESP_MSG, *PQMICTL_GET_CLIENT_ID_RESP_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_RELEASE_CLIENT_ID_REQ_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_RELEASE_CLIENT_ID_REQ
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
|
|
||||||
USHORT TLVLength; // 0x0002
|
|
||||||
UCHAR QMIType;
|
|
||||||
UCHAR ClientId;
|
|
||||||
} __attribute__ ((packed)) QMICTL_RELEASE_CLIENT_ID_REQ_MSG, *PQMICTL_RELEASE_CLIENT_ID_REQ_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_RELEASE_CLIENT_ID_RESP_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_RELEASE_CLIENT_ID_RESP
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
|
|
||||||
USHORT TLVLength; // 0x0004
|
|
||||||
USHORT QMIResult; // result code
|
|
||||||
USHORT QMIError; // error code
|
|
||||||
UCHAR TLV2Type; // QCTLV_TYPE_REQUIRED_PARAMETER
|
|
||||||
USHORT TLV2Length; // 2
|
|
||||||
UCHAR QMIType;
|
|
||||||
UCHAR ClientId;
|
|
||||||
} __attribute__ ((packed)) QMICTL_RELEASE_CLIENT_ID_RESP_MSG, *PQMICTL_RELEASE_CLIENT_ID_RESP_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_REVOKE_CLIENT_ID_IND_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_INDICATION
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_REVOKE_CLIENT_ID_IND
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
|
|
||||||
USHORT TLVLength; // 0x0002
|
|
||||||
UCHAR QMIType;
|
|
||||||
UCHAR ClientId;
|
|
||||||
} __attribute__ ((packed)) QMICTL_REVOKE_CLIENT_ID_IND_MSG, *PQMICTL_REVOKE_CLIENT_ID_IND_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_INVALID_CLIENT_ID_IND_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_INDICATION
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_REVOKE_CLIENT_ID_IND
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
|
|
||||||
USHORT TLVLength; // 0x0002
|
|
||||||
UCHAR QMIType;
|
|
||||||
UCHAR ClientId;
|
|
||||||
} __attribute__ ((packed)) QMICTL_INVALID_CLIENT_ID_IND_MSG, *PQMICTL_INVALID_CLIENT_ID_IND_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_SET_DATA_FORMAT_REQ_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_SET_DATA_FORMAT_REQ
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
|
|
||||||
USHORT TLVLength; // 1
|
|
||||||
UCHAR DataFormat; // 0-default; 1-QoS hdr present
|
|
||||||
} __attribute__ ((packed)) QMICTL_SET_DATA_FORMAT_REQ_MSG, *PQMICTL_SET_DATA_FORMAT_REQ_MSG;
|
|
||||||
|
|
||||||
#ifdef QC_IP_MODE
|
|
||||||
#define SET_DATA_FORMAT_TLV_TYPE_LINK_PROTO 0x10
|
|
||||||
#define SET_DATA_FORMAT_LINK_PROTO_ETH 0x0001
|
|
||||||
#define SET_DATA_FORMAT_LINK_PROTO_IP 0x0002
|
|
||||||
typedef struct _QMICTL_SET_DATA_FORMAT_TLV_LINK_PROT
|
|
||||||
{
|
|
||||||
UCHAR TLVType; // Link-Layer Protocol
|
|
||||||
USHORT TLVLength; // 2
|
|
||||||
USHORT LinkProt; // 0x1: ETH; 0x2: IP
|
|
||||||
} QMICTL_SET_DATA_FORMAT_TLV_LINK_PROT, *PQMICTL_SET_DATA_FORMAT_TLV_LINK_PROT;
|
|
||||||
|
|
||||||
#ifdef QCMP_UL_TLP
|
|
||||||
#define SET_DATA_FORMAT_TLV_TYPE_UL_TLP 0x11
|
|
||||||
typedef struct _QMICTL_SET_DATA_FORMAT_TLV_UL_TLP
|
|
||||||
{
|
|
||||||
UCHAR TLVType; // 0x11, Uplink TLP Setting
|
|
||||||
USHORT TLVLength; // 1
|
|
||||||
UCHAR UlTlpSetting; // 0x0: Disable; 0x01: Enable
|
|
||||||
} QMICTL_SET_DATA_FORMAT_TLV_UL_TLP, *PQMICTL_SET_DATA_FORMAT_TLV_UL_TLP;
|
|
||||||
#endif // QCMP_UL_TLP
|
|
||||||
|
|
||||||
#ifdef QCMP_DL_TLP
|
|
||||||
#define SET_DATA_FORMAT_TLV_TYPE_DL_TLP 0x13
|
|
||||||
typedef struct _QMICTL_SET_DATA_FORMAT_TLV_DL_TLP
|
|
||||||
{
|
|
||||||
UCHAR TLVType; // 0x11, Uplink TLP Setting
|
|
||||||
USHORT TLVLength; // 1
|
|
||||||
UCHAR DlTlpSetting; // 0x0: Disable; 0x01: Enable
|
|
||||||
} QMICTL_SET_DATA_FORMAT_TLV_DL_TLP, *PQMICTL_SET_DATA_FORMAT_TLV_DL_TLP;
|
|
||||||
#endif // QCMP_DL_TLP
|
|
||||||
|
|
||||||
#endif // QC_IP_MODE
|
|
||||||
|
|
||||||
#ifdef MP_QCQOS_ENABLED
|
|
||||||
#define SET_DATA_FORMAT_TLV_TYPE_QOS_SETTING 0x12
|
|
||||||
typedef struct _QMICTL_SET_DATA_FORMAT_TLV_QOS_SETTING
|
|
||||||
{
|
|
||||||
UCHAR TLVType; // 0x12, QoS setting
|
|
||||||
USHORT TLVLength; // 1
|
|
||||||
UCHAR QosSetting; // 0x0: Disable; 0x01: Enable
|
|
||||||
} QMICTL_SET_DATA_FORMAT_TLV_QOS_SETTING, *PQMICTL_SET_DATA_FORMAT_TLV_QOS_SETTING;
|
|
||||||
#endif // MP_QCQOS_ENABLED
|
|
||||||
|
|
||||||
typedef struct _QMICTL_SET_DATA_FORMAT_RESP_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_SET_DATA_FORMAT_RESP
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
|
|
||||||
USHORT TLVLength; // 0x0004
|
|
||||||
USHORT QMIResult; // result code
|
|
||||||
USHORT QMIError; // error code
|
|
||||||
} __attribute__ ((packed)) QMICTL_SET_DATA_FORMAT_RESP_MSG, *PQMICTL_SET_DATA_FORMAT_RESP_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_SYNC_REQ_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_CTL_SYNC_REQ
|
|
||||||
USHORT Length; // 0
|
|
||||||
} __attribute__ ((packed)) QMICTL_SYNC_REQ_MSG, *PQMICTL_SYNC_REQ_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_SYNC_RESP_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_CTL_SYNC_RESP
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
|
|
||||||
USHORT TLVLength; // 0x0004
|
|
||||||
USHORT QMIResult;
|
|
||||||
USHORT QMIError;
|
|
||||||
} __attribute__ ((packed)) QMICTL_SYNC_RESP_MSG, *PQMICTL_SYNC_RESP_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_SYNC_IND_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_INDICATION
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_REVOKE_CLIENT_ID_IND
|
|
||||||
USHORT Length;
|
|
||||||
} __attribute__ ((packed)) QMICTL_SYNC_IND_MSG, *PQMICTL_SYNC_IND_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_LIBQMI_PROXY_OPEN_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_SET_DATA_FORMAT_RESP
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
|
|
||||||
USHORT TLVLength; // 0x0004
|
|
||||||
char device_path[0]; // result code
|
|
||||||
} __attribute__ ((packed)) QMICTL_LIBQMI_PROXY_OPEN_MSG, *PQMICTL_LIBQMI_PROXY_OPEN_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_MSG
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
// Message Header
|
|
||||||
QCQMICTL_MSG_HDR QMICTLMsgHdr;
|
|
||||||
QCQMICTL_MSG_HDR_RESP QMICTLMsgHdrRsp;
|
|
||||||
|
|
||||||
// QMICTL Message
|
|
||||||
QMICTL_SET_INSTANCE_ID_REQ_MSG SetInstanceIdReq;
|
|
||||||
QMICTL_SET_INSTANCE_ID_RESP_MSG SetInstanceIdRsp;
|
|
||||||
QMICTL_GET_VERSION_REQ_MSG GetVersionReq;
|
|
||||||
QMICTL_GET_VERSION_RESP_MSG GetVersionRsp;
|
|
||||||
QMICTL_GET_CLIENT_ID_REQ_MSG GetClientIdReq;
|
|
||||||
QMICTL_GET_CLIENT_ID_RESP_MSG GetClientIdRsp;
|
|
||||||
QMICTL_RELEASE_CLIENT_ID_REQ_MSG ReleaseClientIdReq;
|
|
||||||
QMICTL_RELEASE_CLIENT_ID_RESP_MSG ReleaseClientIdRsp;
|
|
||||||
QMICTL_REVOKE_CLIENT_ID_IND_MSG RevokeClientIdInd;
|
|
||||||
QMICTL_INVALID_CLIENT_ID_IND_MSG InvalidClientIdInd;
|
|
||||||
QMICTL_SET_DATA_FORMAT_REQ_MSG SetDataFormatReq;
|
|
||||||
QMICTL_SET_DATA_FORMAT_RESP_MSG SetDataFormatRsp;
|
|
||||||
QMICTL_SYNC_REQ_MSG SyncReq;
|
|
||||||
QMICTL_SYNC_RESP_MSG SyncRsp;
|
|
||||||
QMICTL_SYNC_IND_MSG SyncInd;
|
|
||||||
QMICTL_LIBQMI_PROXY_OPEN_MSG LibQmiProxyOpenReq;
|
|
||||||
};
|
|
||||||
} __attribute__ ((packed)) QMICTL_MSG, *PQMICTL_MSG;
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
#endif //QCQCTL_H
|
|
||||||
@@ -1,316 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2025 Quectel Wireless Solutions Co.,Ltd
|
|
||||||
|
|
||||||
Quectel hereby grants customers of Quectel a license to use, modify,
|
|
||||||
distribute and publish the Software in binary form provided that
|
|
||||||
customers shall have no right to reverse engineer, reverse assemble,
|
|
||||||
decompile or reduce to source code form any portion of the Software.
|
|
||||||
Under no circumstances may customers modify, demonstrate, use, deliver
|
|
||||||
or disclose any portion of the Software in source code form.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef USBQMI_H
|
|
||||||
#define USBQMI_H
|
|
||||||
|
|
||||||
typedef uint8_t uint8;
|
|
||||||
typedef int8_t int8;
|
|
||||||
typedef uint16_t uint16;
|
|
||||||
typedef int16_t int16;
|
|
||||||
typedef uint32_t uint32;
|
|
||||||
typedef uint64_t uint64;
|
|
||||||
|
|
||||||
typedef signed char CHAR;
|
|
||||||
typedef unsigned char UCHAR;
|
|
||||||
typedef short SHORT;
|
|
||||||
typedef unsigned short USHORT;
|
|
||||||
typedef int INT;
|
|
||||||
typedef unsigned int UINT;
|
|
||||||
typedef long LONG;
|
|
||||||
typedef unsigned int ULONG;
|
|
||||||
typedef unsigned long long ULONG64;
|
|
||||||
typedef signed char *PCHAR;
|
|
||||||
typedef unsigned char *PUCHAR;
|
|
||||||
typedef int *PINT;
|
|
||||||
typedef int BOOL;
|
|
||||||
|
|
||||||
#define TRUE (1 == 1)
|
|
||||||
#define FALSE (1 != 1)
|
|
||||||
|
|
||||||
#define QMICTL_SUPPORTED_MAJOR_VERSION 1
|
|
||||||
#define QMICTL_SUPPORTED_MINOR_VERSION 0
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
|
|
||||||
// ========= USB Control Message ==========
|
|
||||||
|
|
||||||
#define USB_CTL_MSG_TYPE_QMI 0x01
|
|
||||||
|
|
||||||
// USB Control Message
|
|
||||||
typedef struct _QCUSB_CTL_MSG_HDR
|
|
||||||
{
|
|
||||||
UCHAR IFType;
|
|
||||||
} __attribute__ ((packed)) QCUSB_CTL_MSG_HDR, *PQCUSB_CTL_MSG_HDR;
|
|
||||||
|
|
||||||
#define QCUSB_CTL_MSG_HDR_SIZE sizeof(QCUSB_CTL_MSG_HDR)
|
|
||||||
|
|
||||||
typedef struct _QCUSB_CTL_MSG
|
|
||||||
{
|
|
||||||
UCHAR IFType;
|
|
||||||
UCHAR Message;
|
|
||||||
} __attribute__ ((packed)) QCUSB_CTL_MSG, *PQCUSB_CTL_MSG;
|
|
||||||
|
|
||||||
#define QCTLV_TYPE_REQUIRED_PARAMETER 0x01
|
|
||||||
#define QCTLV_TYPE_RESULT_CODE 0x02
|
|
||||||
|
|
||||||
// ================= QMI ==================
|
|
||||||
|
|
||||||
// Define QMI Type
|
|
||||||
typedef enum _QMI_SERVICE_TYPE
|
|
||||||
{
|
|
||||||
QMUX_TYPE_CTL = 0x00,
|
|
||||||
QMUX_TYPE_WDS = 0x01,
|
|
||||||
QMUX_TYPE_DMS = 0x02,
|
|
||||||
QMUX_TYPE_NAS = 0x03,
|
|
||||||
QMUX_TYPE_QOS = 0x04,
|
|
||||||
QMUX_TYPE_WMS = 0x05,
|
|
||||||
QMUX_TYPE_PDS = 0x06,
|
|
||||||
QMUX_TYPE_UIM = 0x0B,
|
|
||||||
QMUX_TYPE_WDS_IPV6 = 0x11,
|
|
||||||
QMUX_TYPE_WDS_ADMIN = 0x1A,
|
|
||||||
QMUX_TYPE_COEX = 0x22,
|
|
||||||
QMUX_TYPE_MAX = 0xFF,
|
|
||||||
QMUX_TYPE_ALL = 0xFF
|
|
||||||
} QMI_SERVICE_TYPE;
|
|
||||||
|
|
||||||
typedef enum _QMI_RESULT_CODE_TYPE
|
|
||||||
{
|
|
||||||
QMI_RESULT_SUCCESS = 0x0000,
|
|
||||||
QMI_RESULT_FAILURE = 0x0001
|
|
||||||
} QMI_RESULT_CODE_TYPE;
|
|
||||||
|
|
||||||
typedef enum _QMI_ERROR_CODE_TYPE
|
|
||||||
{
|
|
||||||
QMI_ERR_NONE = 0x0000
|
|
||||||
,QMI_ERR_MALFORMED_MSG = 0x0001
|
|
||||||
,QMI_ERR_NO_MEMORY = 0x0002
|
|
||||||
,QMI_ERR_INTERNAL = 0x0003
|
|
||||||
,QMI_ERR_ABORTED = 0x0004
|
|
||||||
,QMI_ERR_CLIENT_IDS_EXHAUSTED = 0x0005
|
|
||||||
,QMI_ERR_UNABORTABLE_TRANSACTION = 0x0006
|
|
||||||
,QMI_ERR_INVALID_CLIENT_ID = 0x0007
|
|
||||||
,QMI_ERR_NO_THRESHOLDS = 0x0008
|
|
||||||
,QMI_ERR_INVALID_HANDLE = 0x0009
|
|
||||||
,QMI_ERR_INVALID_PROFILE = 0x000A
|
|
||||||
,QMI_ERR_INVALID_PINID = 0x000B
|
|
||||||
,QMI_ERR_INCORRECT_PIN = 0x000C
|
|
||||||
,QMI_ERR_NO_NETWORK_FOUND = 0x000D
|
|
||||||
,QMI_ERR_CALL_FAILED = 0x000E
|
|
||||||
,QMI_ERR_OUT_OF_CALL = 0x000F
|
|
||||||
,QMI_ERR_NOT_PROVISIONED = 0x0010
|
|
||||||
,QMI_ERR_MISSING_ARG = 0x0011
|
|
||||||
,QMI_ERR_ARG_TOO_LONG = 0x0013
|
|
||||||
,QMI_ERR_INVALID_TX_ID = 0x0016
|
|
||||||
,QMI_ERR_DEVICE_IN_USE = 0x0017
|
|
||||||
,QMI_ERR_OP_NETWORK_UNSUPPORTED = 0x0018
|
|
||||||
,QMI_ERR_OP_DEVICE_UNSUPPORTED = 0x0019
|
|
||||||
,QMI_ERR_NO_EFFECT = 0x001A
|
|
||||||
,QMI_ERR_NO_FREE_PROFILE = 0x001B
|
|
||||||
,QMI_ERR_INVALID_PDP_TYPE = 0x001C
|
|
||||||
,QMI_ERR_INVALID_TECH_PREF = 0x001D
|
|
||||||
,QMI_ERR_INVALID_PROFILE_TYPE = 0x001E
|
|
||||||
,QMI_ERR_INVALID_SERVICE_TYPE = 0x001F
|
|
||||||
,QMI_ERR_INVALID_REGISTER_ACTION = 0x0020
|
|
||||||
,QMI_ERR_INVALID_PS_ATTACH_ACTION = 0x0021
|
|
||||||
,QMI_ERR_AUTHENTICATION_FAILED = 0x0022
|
|
||||||
,QMI_ERR_PIN_BLOCKED = 0x0023
|
|
||||||
,QMI_ERR_PIN_PERM_BLOCKED = 0x0024
|
|
||||||
,QMI_ERR_SIM_NOT_INITIALIZED = 0x0025
|
|
||||||
,QMI_ERR_MAX_QOS_REQUESTS_IN_USE = 0x0026
|
|
||||||
,QMI_ERR_INCORRECT_FLOW_FILTER = 0x0027
|
|
||||||
,QMI_ERR_NETWORK_QOS_UNAWARE = 0x0028
|
|
||||||
,QMI_ERR_INVALID_QOS_ID = 0x0029
|
|
||||||
,QMI_ERR_INVALID_ID = 0x0029
|
|
||||||
,QMI_ERR_REQUESTED_NUM_UNSUPPORTED = 0x002A
|
|
||||||
,QMI_ERR_INTERFACE_NOT_FOUND = 0x002B
|
|
||||||
,QMI_ERR_FLOW_SUSPENDED = 0x002C
|
|
||||||
,QMI_ERR_INVALID_DATA_FORMAT = 0x002D
|
|
||||||
,QMI_ERR_GENERAL = 0x002E
|
|
||||||
,QMI_ERR_UNKNOWN = 0x002F
|
|
||||||
,QMI_ERR_INVALID_ARG = 0x0030
|
|
||||||
,QMI_ERR_INVALID_INDEX = 0x0031
|
|
||||||
,QMI_ERR_NO_ENTRY = 0x0032
|
|
||||||
,QMI_ERR_DEVICE_STORAGE_FULL = 0x0033
|
|
||||||
,QMI_ERR_DEVICE_NOT_READY = 0x0034
|
|
||||||
,QMI_ERR_NETWORK_NOT_READY = 0x0035
|
|
||||||
,QMI_ERR_CAUSE_CODE = 0x0036
|
|
||||||
,QMI_ERR_MESSAGE_NOT_SENT = 0x0037
|
|
||||||
,QMI_ERR_MESSAGE_DELIVERY_FAILURE = 0x0038
|
|
||||||
,QMI_ERR_INVALID_MESSAGE_ID = 0x0039
|
|
||||||
,QMI_ERR_ENCODING = 0x003A
|
|
||||||
,QMI_ERR_AUTHENTICATION_LOCK = 0x003B
|
|
||||||
,QMI_ERR_INVALID_TRANSITION = 0x003C
|
|
||||||
,QMI_ERR_NOT_A_MCAST_IFACE = 0x003D
|
|
||||||
,QMI_ERR_MAX_MCAST_REQUESTS_IN_USE = 0x003E
|
|
||||||
,QMI_ERR_INVALID_MCAST_HANDLE = 0x003F
|
|
||||||
,QMI_ERR_INVALID_IP_FAMILY_PREF = 0x0040
|
|
||||||
,QMI_ERR_SESSION_INACTIVE = 0x0041
|
|
||||||
,QMI_ERR_SESSION_INVALID = 0x0042
|
|
||||||
,QMI_ERR_SESSION_OWNERSHIP = 0x0043
|
|
||||||
,QMI_ERR_INSUFFICIENT_RESOURCES = 0x0044
|
|
||||||
,QMI_ERR_DISABLED = 0x0045
|
|
||||||
,QMI_ERR_INVALID_OPERATION = 0x0046
|
|
||||||
,QMI_ERR_INVALID_QMI_CMD = 0x0047
|
|
||||||
,QMI_ERR_TPDU_TYPE = 0x0048
|
|
||||||
,QMI_ERR_SMSC_ADDR = 0x0049
|
|
||||||
,QMI_ERR_INFO_UNAVAILABLE = 0x004A
|
|
||||||
,QMI_ERR_SEGMENT_TOO_LONG = 0x004B
|
|
||||||
,QMI_ERR_SEGMENT_ORDER = 0x004C
|
|
||||||
,QMI_ERR_BUNDLING_NOT_SUPPORTED = 0x004D
|
|
||||||
,QMI_ERR_OP_PARTIAL_FAILURE = 0x004E
|
|
||||||
,QMI_ERR_POLICY_MISMATCH = 0x004F
|
|
||||||
,QMI_ERR_SIM_FILE_NOT_FOUND = 0x0050
|
|
||||||
,QMI_ERR_EXTENDED_INTERNAL = 0x0051
|
|
||||||
,QMI_ERR_ACCESS_DENIED = 0x0052
|
|
||||||
,QMI_ERR_HARDWARE_RESTRICTED = 0x0053
|
|
||||||
,QMI_ERR_ACK_NOT_SENT = 0x0054
|
|
||||||
,QMI_ERR_INJECT_TIMEOUT = 0x0055
|
|
||||||
,QMI_ERR_INCOMPATIBLE_STATE = 0x005A
|
|
||||||
,QMI_ERR_FDN_RESTRICT = 0x005B
|
|
||||||
,QMI_ERR_SUPS_FAILURE_CAUSE = 0x005C
|
|
||||||
,QMI_ERR_NO_RADIO = 0x005D
|
|
||||||
,QMI_ERR_NOT_SUPPORTED = 0x005E
|
|
||||||
,QMI_ERR_NO_SUBSCRIPTION = 0x005F
|
|
||||||
,QMI_ERR_CARD_CALL_CONTROL_FAILED = 0x0060
|
|
||||||
,QMI_ERR_NETWORK_ABORTED = 0x0061
|
|
||||||
,QMI_ERR_MSG_BLOCKED = 0x0062
|
|
||||||
,QMI_ERR_INVALID_SESSION_TYPE = 0x0064
|
|
||||||
,QMI_ERR_INVALID_PB_TYPE = 0x0065
|
|
||||||
,QMI_ERR_NO_SIM = 0x0066
|
|
||||||
,QMI_ERR_PB_NOT_READY = 0x0067
|
|
||||||
,QMI_ERR_PIN_RESTRICTION = 0x0068
|
|
||||||
,QMI_ERR_PIN2_RESTRICTION = 0x0069
|
|
||||||
,QMI_ERR_PUK_RESTRICTION = 0x006A
|
|
||||||
,QMI_ERR_PUK2_RESTRICTION = 0x006B
|
|
||||||
,QMI_ERR_PB_ACCESS_RESTRICTED = 0x006C
|
|
||||||
,QMI_ERR_PB_DELETE_IN_PROG = 0x006D
|
|
||||||
,QMI_ERR_PB_TEXT_TOO_LONG = 0x006E
|
|
||||||
,QMI_ERR_PB_NUMBER_TOO_LONG = 0x006F
|
|
||||||
,QMI_ERR_PB_HIDDEN_KEY_RESTRICTION = 0x0070
|
|
||||||
} QMI_ERROR_CODE_TYPE;
|
|
||||||
|
|
||||||
#define QCQMI_CTL_FLAG_SERVICE 0x80
|
|
||||||
#define QCQMI_CTL_FLAG_CTL_POINT 0x00
|
|
||||||
|
|
||||||
typedef struct _QCQMI_HDR
|
|
||||||
{
|
|
||||||
UCHAR IFType;
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR CtlFlags; // reserved
|
|
||||||
UCHAR QMIType;
|
|
||||||
UCHAR ClientId;
|
|
||||||
} __attribute__ ((packed)) QCQMI_HDR, *PQCQMI_HDR;
|
|
||||||
|
|
||||||
#define QCQMI_HDR_SIZE (sizeof(QCQMI_HDR)-1)
|
|
||||||
|
|
||||||
typedef struct _QCQMI
|
|
||||||
{
|
|
||||||
UCHAR IFType;
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR CtlFlags; // reserved
|
|
||||||
UCHAR QMIType;
|
|
||||||
UCHAR ClientId;
|
|
||||||
UCHAR SDU;
|
|
||||||
} __attribute__ ((packed)) QCQMI, *PQCQMI;
|
|
||||||
|
|
||||||
typedef struct _QMI_SERVICE_VERSION
|
|
||||||
{
|
|
||||||
USHORT Major;
|
|
||||||
USHORT Minor;
|
|
||||||
USHORT AddendumMajor;
|
|
||||||
USHORT AddendumMinor;
|
|
||||||
} __attribute__ ((packed)) QMI_SERVICE_VERSION, *PQMI_SERVICE_VERSION;
|
|
||||||
|
|
||||||
// ================= QMUX ==================
|
|
||||||
|
|
||||||
#define QMUX_MSG_OVERHEAD_BYTES 4 // Type(USHORT) Length(USHORT) -- header
|
|
||||||
|
|
||||||
#define QMUX_BROADCAST_CID 0xFF
|
|
||||||
|
|
||||||
typedef struct _QCQMUX_HDR
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // 0: single QMUX Msg; 1:
|
|
||||||
USHORT TransactionId;
|
|
||||||
} __attribute__ ((packed)) QCQMUX_HDR, *PQCQMUX_HDR;
|
|
||||||
|
|
||||||
typedef struct _QCQMUX
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // 0: single QMUX Msg; 1:
|
|
||||||
USHORT TransactionId;
|
|
||||||
UCHAR Message; // Type(2), Length(2), Value
|
|
||||||
} __attribute__ ((packed)) QCQMUX, *PQCQMUX;
|
|
||||||
|
|
||||||
#define QCQMUX_HDR_SIZE sizeof(QCQMUX_HDR)
|
|
||||||
|
|
||||||
typedef struct _QCQMUX_MSG_HDR
|
|
||||||
{
|
|
||||||
USHORT Type;
|
|
||||||
USHORT Length;
|
|
||||||
} __attribute__ ((packed)) QCQMUX_MSG_HDR, *PQCQMUX_MSG_HDR;
|
|
||||||
|
|
||||||
#define QCQMUX_MSG_HDR_SIZE sizeof(QCQMUX_MSG_HDR)
|
|
||||||
|
|
||||||
typedef struct _QCQMUX_MSG_HDR_RESP
|
|
||||||
{
|
|
||||||
USHORT Type;
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // 0x02 - result code
|
|
||||||
USHORT TLVLength; // 4
|
|
||||||
USHORT QMUXResult; // QMI_RESULT_SUCCESS
|
|
||||||
// QMI_RESULT_FAILURE
|
|
||||||
USHORT QMUXError; // QMI_ERR_INVALID_ARG
|
|
||||||
// QMI_ERR_NO_MEMORY
|
|
||||||
// QMI_ERR_INTERNAL
|
|
||||||
// QMI_ERR_FAULT
|
|
||||||
} __attribute__ ((packed)) QCQMUX_MSG_HDR_RESP, *PQCQMUX_MSG_HDR_RESP;
|
|
||||||
|
|
||||||
typedef struct _QCQMUX_TLV
|
|
||||||
{
|
|
||||||
UCHAR Type;
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR Value;
|
|
||||||
} __attribute__ ((packed)) QCQMUX_TLV, *PQCQMUX_TLV;
|
|
||||||
|
|
||||||
typedef struct _QMI_TLV_HDR
|
|
||||||
{
|
|
||||||
UCHAR TLVType;
|
|
||||||
USHORT TLVLength;
|
|
||||||
} __attribute__ ((packed)) QMI_TLV_HDR, *PQMI_TLV_HDR;
|
|
||||||
|
|
||||||
typedef struct _QMI_TLV
|
|
||||||
{
|
|
||||||
UCHAR TLVType;
|
|
||||||
USHORT TLVLength;
|
|
||||||
union {
|
|
||||||
int8_t s8;
|
|
||||||
uint8_t u8;
|
|
||||||
int16_t s16;
|
|
||||||
uint16_t u16;
|
|
||||||
int32_t s32;
|
|
||||||
uint32_t u32;
|
|
||||||
uint64_t u64;
|
|
||||||
};
|
|
||||||
} __attribute__ ((packed)) QMI_TLV, *PQMI_TLV;
|
|
||||||
|
|
||||||
// QMUX Message Definitions -- QMI SDU
|
|
||||||
#define QMUX_CTL_FLAG_SINGLE_MSG 0x00
|
|
||||||
#define QMUX_CTL_FLAG_COMPOUND_MSG 0x01
|
|
||||||
#define QMUX_CTL_FLAG_TYPE_CMD 0x00
|
|
||||||
#define QMUX_CTL_FLAG_TYPE_RSP 0x02
|
|
||||||
#define QMUX_CTL_FLAG_TYPE_IND 0x04
|
|
||||||
#define QMUX_CTL_FLAG_MASK_COMPOUND 0x01
|
|
||||||
#define QMUX_CTL_FLAG_MASK_TYPE 0x06 // 00-cmd, 01-rsp, 10-ind
|
|
||||||
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
#endif // USBQMI_H
|
|
||||||
@@ -1,472 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2025 Quectel Wireless Solutions Co.,Ltd
|
|
||||||
|
|
||||||
Quectel hereby grants customers of Quectel a license to use, modify,
|
|
||||||
distribute and publish the Software in binary form provided that
|
|
||||||
customers shall have no right to reverse engineer, reverse assemble,
|
|
||||||
decompile or reduce to source code form any portion of the Software.
|
|
||||||
Under no circumstances may customers modify, demonstrate, use, deliver
|
|
||||||
or disclose any portion of the Software in source code form.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "QMIThread.h"
|
|
||||||
static char line[1024];
|
|
||||||
static pthread_mutex_t dumpQMIMutex = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
#undef dbg
|
|
||||||
#define dbg( format, arg... ) do {if (strlen(line) < sizeof(line)) snprintf(&line[strlen(line)], sizeof(line) - strlen(line), format, ## arg);} while (0)
|
|
||||||
|
|
||||||
PQMI_TLV_HDR GetTLV (PQCQMUX_MSG_HDR pQMUXMsgHdr, int TLVType);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
UINT type;
|
|
||||||
const char *name;
|
|
||||||
} QMI_NAME_T;
|
|
||||||
|
|
||||||
#define qmi_name_item(type) {type, #type}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static const QMI_NAME_T qmi_IFType[] = {
|
|
||||||
{USB_CTL_MSG_TYPE_QMI, "USB_CTL_MSG_TYPE_QMI"},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmi_CtlFlags[] = {
|
|
||||||
qmi_name_item(QMICTL_CTL_FLAG_CMD),
|
|
||||||
qmi_name_item(QCQMI_CTL_FLAG_SERVICE),
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmi_QMIType[] = {
|
|
||||||
qmi_name_item(QMUX_TYPE_CTL),
|
|
||||||
qmi_name_item(QMUX_TYPE_WDS),
|
|
||||||
qmi_name_item(QMUX_TYPE_DMS),
|
|
||||||
qmi_name_item(QMUX_TYPE_NAS),
|
|
||||||
qmi_name_item(QMUX_TYPE_QOS),
|
|
||||||
qmi_name_item(QMUX_TYPE_WMS),
|
|
||||||
qmi_name_item(QMUX_TYPE_PDS),
|
|
||||||
qmi_name_item(QMUX_TYPE_WDS_ADMIN),
|
|
||||||
qmi_name_item(QMUX_TYPE_COEX),
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmi_ctl_CtlFlags[] = {
|
|
||||||
qmi_name_item(QMICTL_FLAG_REQUEST),
|
|
||||||
qmi_name_item(QMICTL_FLAG_RESPONSE),
|
|
||||||
qmi_name_item(QMICTL_FLAG_INDICATION),
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmux_ctl_QMICTLType[] = {
|
|
||||||
// QMICTL Type
|
|
||||||
qmi_name_item(QMICTL_SET_INSTANCE_ID_REQ), // 0x0020
|
|
||||||
qmi_name_item(QMICTL_SET_INSTANCE_ID_RESP), // 0x0020
|
|
||||||
qmi_name_item(QMICTL_GET_VERSION_REQ), // 0x0021
|
|
||||||
qmi_name_item(QMICTL_GET_VERSION_RESP), // 0x0021
|
|
||||||
qmi_name_item(QMICTL_GET_CLIENT_ID_REQ), // 0x0022
|
|
||||||
qmi_name_item(QMICTL_GET_CLIENT_ID_RESP), // 0x0022
|
|
||||||
qmi_name_item(QMICTL_RELEASE_CLIENT_ID_REQ), // 0x0023
|
|
||||||
qmi_name_item(QMICTL_RELEASE_CLIENT_ID_RESP), // 0x0023
|
|
||||||
qmi_name_item(QMICTL_REVOKE_CLIENT_ID_IND), // 0x0024
|
|
||||||
qmi_name_item(QMICTL_INVALID_CLIENT_ID_IND), // 0x0025
|
|
||||||
qmi_name_item(QMICTL_SET_DATA_FORMAT_REQ), // 0x0026
|
|
||||||
qmi_name_item(QMICTL_SET_DATA_FORMAT_RESP), // 0x0026
|
|
||||||
qmi_name_item(QMICTL_SYNC_REQ), // 0x0027
|
|
||||||
qmi_name_item(QMICTL_SYNC_RESP), // 0x0027
|
|
||||||
qmi_name_item(QMICTL_SYNC_IND), // 0x0027
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmux_CtlFlags[] = {
|
|
||||||
qmi_name_item(QMUX_CTL_FLAG_TYPE_CMD),
|
|
||||||
qmi_name_item(QMUX_CTL_FLAG_TYPE_RSP),
|
|
||||||
qmi_name_item(QMUX_CTL_FLAG_TYPE_IND),
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmux_wds_Type[] = {
|
|
||||||
qmi_name_item(QMIWDS_SET_EVENT_REPORT_REQ), // 0x0001
|
|
||||||
qmi_name_item(QMIWDS_SET_EVENT_REPORT_RESP), // 0x0001
|
|
||||||
qmi_name_item(QMIWDS_EVENT_REPORT_IND), // 0x0001
|
|
||||||
qmi_name_item(QMIWDS_START_NETWORK_INTERFACE_REQ), // 0x0020
|
|
||||||
qmi_name_item(QMIWDS_START_NETWORK_INTERFACE_RESP), // 0x0020
|
|
||||||
qmi_name_item(QMIWDS_STOP_NETWORK_INTERFACE_REQ), // 0x0021
|
|
||||||
qmi_name_item(QMIWDS_STOP_NETWORK_INTERFACE_RESP), // 0x0021
|
|
||||||
qmi_name_item(QMIWDS_GET_PKT_SRVC_STATUS_REQ), // 0x0022
|
|
||||||
qmi_name_item(QMIWDS_GET_PKT_SRVC_STATUS_RESP), // 0x0022
|
|
||||||
qmi_name_item(QMIWDS_GET_PKT_SRVC_STATUS_IND), // 0x0022
|
|
||||||
qmi_name_item(QMIWDS_GET_CURRENT_CHANNEL_RATE_REQ), // 0x0023
|
|
||||||
qmi_name_item(QMIWDS_GET_CURRENT_CHANNEL_RATE_RESP), // 0x0023
|
|
||||||
qmi_name_item(QMIWDS_GET_PKT_STATISTICS_REQ), // 0x0024
|
|
||||||
qmi_name_item(QMIWDS_GET_PKT_STATISTICS_RESP), // 0x0024
|
|
||||||
qmi_name_item(QMIWDS_MODIFY_PROFILE_SETTINGS_REQ), // 0x0028
|
|
||||||
qmi_name_item(QMIWDS_MODIFY_PROFILE_SETTINGS_RESP), // 0x0028
|
|
||||||
qmi_name_item(QMIWDS_GET_PROFILE_SETTINGS_REQ), // 0x002B
|
|
||||||
qmi_name_item(QMIWDS_GET_PROFILE_SETTINGS_RESP), // 0x002BD
|
|
||||||
qmi_name_item(QMIWDS_GET_DEFAULT_SETTINGS_REQ), // 0x002C
|
|
||||||
qmi_name_item(QMIWDS_GET_DEFAULT_SETTINGS_RESP), // 0x002C
|
|
||||||
qmi_name_item(QMIWDS_GET_RUNTIME_SETTINGS_REQ), // 0x002D
|
|
||||||
qmi_name_item(QMIWDS_GET_RUNTIME_SETTINGS_RESP), // 0x002D
|
|
||||||
qmi_name_item(QMIWDS_GET_MIP_MODE_REQ), // 0x002F
|
|
||||||
qmi_name_item(QMIWDS_GET_MIP_MODE_RESP), // 0x002F
|
|
||||||
qmi_name_item(QMIWDS_GET_DATA_BEARER_REQ), // 0x0037
|
|
||||||
qmi_name_item(QMIWDS_GET_DATA_BEARER_RESP), // 0x0037
|
|
||||||
qmi_name_item(QMIWDS_DUN_CALL_INFO_REQ), // 0x0038
|
|
||||||
qmi_name_item(QMIWDS_DUN_CALL_INFO_RESP), // 0x0038
|
|
||||||
qmi_name_item(QMIWDS_DUN_CALL_INFO_IND), // 0x0038
|
|
||||||
qmi_name_item(QMIWDS_SET_CLIENT_IP_FAMILY_PREF_REQ), // 0x004D
|
|
||||||
qmi_name_item(QMIWDS_SET_CLIENT_IP_FAMILY_PREF_RESP), // 0x004D
|
|
||||||
qmi_name_item(QMIWDS_SET_AUTO_CONNECT_REQ), // 0x0051
|
|
||||||
qmi_name_item(QMIWDS_SET_AUTO_CONNECT_RESP), // 0x0051
|
|
||||||
qmi_name_item(QMIWDS_BIND_MUX_DATA_PORT_REQ), // 0x00A2
|
|
||||||
qmi_name_item(QMIWDS_BIND_MUX_DATA_PORT_RESP), // 0x00A2
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmux_dms_Type[] = {
|
|
||||||
// ======================= DMS ==============================
|
|
||||||
qmi_name_item(QMIDMS_SET_EVENT_REPORT_REQ), // 0x0001
|
|
||||||
qmi_name_item(QMIDMS_SET_EVENT_REPORT_RESP), // 0x0001
|
|
||||||
qmi_name_item(QMIDMS_EVENT_REPORT_IND), // 0x0001
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_CAP_REQ), // 0x0020
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_CAP_RESP), // 0x0020
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_MFR_REQ), // 0x0021
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_MFR_RESP), // 0x0021
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_MODEL_ID_REQ), // 0x0022
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_MODEL_ID_RESP), // 0x0022
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_REV_ID_REQ), // 0x0023
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_REV_ID_RESP), // 0x0023
|
|
||||||
qmi_name_item(QMIDMS_GET_MSISDN_REQ), // 0x0024
|
|
||||||
qmi_name_item(QMIDMS_GET_MSISDN_RESP), // 0x0024
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_SERIAL_NUMBERS_REQ), // 0x0025
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_SERIAL_NUMBERS_RESP), // 0x0025
|
|
||||||
qmi_name_item(QMIDMS_UIM_SET_PIN_PROTECTION_REQ), // 0x0027
|
|
||||||
qmi_name_item(QMIDMS_UIM_SET_PIN_PROTECTION_RESP), // 0x0027
|
|
||||||
qmi_name_item(QMIDMS_UIM_VERIFY_PIN_REQ), // 0x0028
|
|
||||||
qmi_name_item(QMIDMS_UIM_VERIFY_PIN_RESP), // 0x0028
|
|
||||||
qmi_name_item(QMIDMS_UIM_UNBLOCK_PIN_REQ), // 0x0029
|
|
||||||
qmi_name_item(QMIDMS_UIM_UNBLOCK_PIN_RESP), // 0x0029
|
|
||||||
qmi_name_item(QMIDMS_UIM_CHANGE_PIN_REQ), // 0x002A
|
|
||||||
qmi_name_item(QMIDMS_UIM_CHANGE_PIN_RESP), // 0x002A
|
|
||||||
qmi_name_item(QMIDMS_UIM_GET_PIN_STATUS_REQ), // 0x002B
|
|
||||||
qmi_name_item(QMIDMS_UIM_GET_PIN_STATUS_RESP), // 0x002B
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_HARDWARE_REV_REQ), // 0x002C
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_HARDWARE_REV_RESP), // 0x002C
|
|
||||||
qmi_name_item(QMIDMS_GET_OPERATING_MODE_REQ), // 0x002D
|
|
||||||
qmi_name_item(QMIDMS_GET_OPERATING_MODE_RESP), // 0x002D
|
|
||||||
qmi_name_item(QMIDMS_SET_OPERATING_MODE_REQ), // 0x002E
|
|
||||||
qmi_name_item(QMIDMS_SET_OPERATING_MODE_RESP), // 0x002E
|
|
||||||
qmi_name_item(QMIDMS_GET_ACTIVATED_STATUS_REQ), // 0x0031
|
|
||||||
qmi_name_item(QMIDMS_GET_ACTIVATED_STATUS_RESP), // 0x0031
|
|
||||||
qmi_name_item(QMIDMS_ACTIVATE_AUTOMATIC_REQ), // 0x0032
|
|
||||||
qmi_name_item(QMIDMS_ACTIVATE_AUTOMATIC_RESP), // 0x0032
|
|
||||||
qmi_name_item(QMIDMS_ACTIVATE_MANUAL_REQ), // 0x0033
|
|
||||||
qmi_name_item(QMIDMS_ACTIVATE_MANUAL_RESP), // 0x0033
|
|
||||||
qmi_name_item(QMIDMS_UIM_GET_ICCID_REQ), // 0x003C
|
|
||||||
qmi_name_item(QMIDMS_UIM_GET_ICCID_RESP), // 0x003C
|
|
||||||
qmi_name_item(QMIDMS_UIM_GET_CK_STATUS_REQ), // 0x0040
|
|
||||||
qmi_name_item(QMIDMS_UIM_GET_CK_STATUS_RESP), // 0x0040
|
|
||||||
qmi_name_item(QMIDMS_UIM_SET_CK_PROTECTION_REQ), // 0x0041
|
|
||||||
qmi_name_item(QMIDMS_UIM_SET_CK_PROTECTION_RESP), // 0x0041
|
|
||||||
qmi_name_item(QMIDMS_UIM_UNBLOCK_CK_REQ), // 0x0042
|
|
||||||
qmi_name_item(QMIDMS_UIM_UNBLOCK_CK_RESP), // 0x0042
|
|
||||||
qmi_name_item(QMIDMS_UIM_GET_IMSI_REQ), // 0x0043
|
|
||||||
qmi_name_item(QMIDMS_UIM_GET_IMSI_RESP), // 0x0043
|
|
||||||
qmi_name_item(QMIDMS_UIM_GET_STATE_REQ), // 0x0044
|
|
||||||
qmi_name_item(QMIDMS_UIM_GET_STATE_RESP), // 0x0044
|
|
||||||
qmi_name_item(QMIDMS_GET_BAND_CAP_REQ), // 0x0045
|
|
||||||
qmi_name_item(QMIDMS_GET_BAND_CAP_RESP), // 0x0045
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmux_qos_Type[] = {
|
|
||||||
qmi_name_item( QMI_QOS_SET_EVENT_REPORT_REQ), // 0x0001
|
|
||||||
qmi_name_item( QMI_QOS_SET_EVENT_REPORT_RESP), // 0x0001
|
|
||||||
qmi_name_item( QMI_QOS_SET_EVENT_REPORT_IND), // 0x0001
|
|
||||||
qmi_name_item( QMI_QOS_BIND_DATA_PORT_REQ), // 0x002B
|
|
||||||
qmi_name_item( QMI_QOS_BIND_DATA_PORT_RESP), // 0x002B
|
|
||||||
qmi_name_item( QMI_QOS_INDICATION_REGISTER_REQ), // 0x002F
|
|
||||||
qmi_name_item( QMI_QOS_INDICATION_REGISTER_RESP), // 0x002F
|
|
||||||
qmi_name_item( QMI_QOS_GLOBAL_QOS_FLOW_IND), // 0x0031
|
|
||||||
qmi_name_item( QMI_QOS_GET_QOS_INFO_REQ), // 0x0033
|
|
||||||
qmi_name_item( QMI_QOS_GET_QOS_INFO_RESP), // 0x0033
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmux_nas_Type[] = {
|
|
||||||
// ======================= NAS ==============================
|
|
||||||
qmi_name_item(QMINAS_SET_EVENT_REPORT_REQ), // 0x0002
|
|
||||||
qmi_name_item(QMINAS_SET_EVENT_REPORT_RESP), // 0x0002
|
|
||||||
qmi_name_item(QMINAS_EVENT_REPORT_IND), // 0x0002
|
|
||||||
qmi_name_item(QMINAS_GET_SIGNAL_STRENGTH_REQ), // 0x0020
|
|
||||||
qmi_name_item(QMINAS_GET_SIGNAL_STRENGTH_RESP), // 0x0020
|
|
||||||
qmi_name_item(QMINAS_PERFORM_NETWORK_SCAN_REQ), // 0x0021
|
|
||||||
qmi_name_item(QMINAS_PERFORM_NETWORK_SCAN_RESP), // 0x0021
|
|
||||||
qmi_name_item(QMINAS_INITIATE_NW_REGISTER_REQ), // 0x0022
|
|
||||||
qmi_name_item(QMINAS_INITIATE_NW_REGISTER_RESP), // 0x0022
|
|
||||||
qmi_name_item(QMINAS_INITIATE_ATTACH_REQ), // 0x0023
|
|
||||||
qmi_name_item(QMINAS_INITIATE_ATTACH_RESP), // 0x0023
|
|
||||||
qmi_name_item(QMINAS_GET_SERVING_SYSTEM_REQ), // 0x0024
|
|
||||||
qmi_name_item(QMINAS_GET_SERVING_SYSTEM_RESP), // 0x0024
|
|
||||||
qmi_name_item(QMINAS_SERVING_SYSTEM_IND), // 0x0024
|
|
||||||
qmi_name_item(QMINAS_GET_HOME_NETWORK_REQ), // 0x0025
|
|
||||||
qmi_name_item(QMINAS_GET_HOME_NETWORK_RESP), // 0x0025
|
|
||||||
qmi_name_item(QMINAS_GET_PREFERRED_NETWORK_REQ), // 0x0026
|
|
||||||
qmi_name_item(QMINAS_GET_PREFERRED_NETWORK_RESP), // 0x0026
|
|
||||||
qmi_name_item(QMINAS_SET_PREFERRED_NETWORK_REQ), // 0x0027
|
|
||||||
qmi_name_item(QMINAS_SET_PREFERRED_NETWORK_RESP), // 0x0027
|
|
||||||
qmi_name_item(QMINAS_GET_FORBIDDEN_NETWORK_REQ), // 0x0028
|
|
||||||
qmi_name_item(QMINAS_GET_FORBIDDEN_NETWORK_RESP), // 0x0028
|
|
||||||
qmi_name_item(QMINAS_SET_FORBIDDEN_NETWORK_REQ), // 0x0029
|
|
||||||
qmi_name_item(QMINAS_SET_FORBIDDEN_NETWORK_RESP), // 0x0029
|
|
||||||
qmi_name_item(QMINAS_SET_TECHNOLOGY_PREF_REQ), // 0x002A
|
|
||||||
qmi_name_item(QMINAS_SET_TECHNOLOGY_PREF_RESP), // 0x002A
|
|
||||||
qmi_name_item(QMINAS_GET_RF_BAND_INFO_REQ), // 0x0031
|
|
||||||
qmi_name_item(QMINAS_GET_RF_BAND_INFO_RESP), // 0x0031
|
|
||||||
qmi_name_item(QMINAS_GET_CELL_LOCATION_INFO_REQ),
|
|
||||||
qmi_name_item(QMINAS_GET_CELL_LOCATION_INFO_RESP),
|
|
||||||
qmi_name_item(QMINAS_GET_PLMN_NAME_REQ), // 0x0044
|
|
||||||
qmi_name_item(QMINAS_GET_PLMN_NAME_RESP), // 0x0044
|
|
||||||
qmi_name_item(QUECTEL_PACKET_TRANSFER_START_IND), // 0X100
|
|
||||||
qmi_name_item(QUECTEL_PACKET_TRANSFER_END_IND), // 0X101
|
|
||||||
qmi_name_item(QMINAS_GET_SYS_INFO_REQ), // 0x004D
|
|
||||||
qmi_name_item(QMINAS_GET_SYS_INFO_RESP), // 0x004D
|
|
||||||
qmi_name_item(QMINAS_SYS_INFO_IND), // 0x004D
|
|
||||||
qmi_name_item(QMINAS_GET_SIG_INFO_REQ),
|
|
||||||
qmi_name_item(QMINAS_GET_SIG_INFO_RESP),
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmux_wms_Type[] = {
|
|
||||||
// ======================= WMS ==============================
|
|
||||||
qmi_name_item(QMIWMS_SET_EVENT_REPORT_REQ), // 0x0001
|
|
||||||
qmi_name_item(QMIWMS_SET_EVENT_REPORT_RESP), // 0x0001
|
|
||||||
qmi_name_item(QMIWMS_EVENT_REPORT_IND), // 0x0001
|
|
||||||
qmi_name_item(QMIWMS_RAW_SEND_REQ), // 0x0020
|
|
||||||
qmi_name_item(QMIWMS_RAW_SEND_RESP), // 0x0020
|
|
||||||
qmi_name_item(QMIWMS_RAW_WRITE_REQ), // 0x0021
|
|
||||||
qmi_name_item(QMIWMS_RAW_WRITE_RESP), // 0x0021
|
|
||||||
qmi_name_item(QMIWMS_RAW_READ_REQ), // 0x0022
|
|
||||||
qmi_name_item(QMIWMS_RAW_READ_RESP), // 0x0022
|
|
||||||
qmi_name_item(QMIWMS_MODIFY_TAG_REQ), // 0x0023
|
|
||||||
qmi_name_item(QMIWMS_MODIFY_TAG_RESP), // 0x0023
|
|
||||||
qmi_name_item(QMIWMS_DELETE_REQ), // 0x0024
|
|
||||||
qmi_name_item(QMIWMS_DELETE_RESP), // 0x0024
|
|
||||||
qmi_name_item(QMIWMS_GET_MESSAGE_PROTOCOL_REQ), // 0x0030
|
|
||||||
qmi_name_item(QMIWMS_GET_MESSAGE_PROTOCOL_RESP), // 0x0030
|
|
||||||
qmi_name_item(QMIWMS_LIST_MESSAGES_REQ), // 0x0031
|
|
||||||
qmi_name_item(QMIWMS_LIST_MESSAGES_RESP), // 0x0031
|
|
||||||
qmi_name_item(QMIWMS_GET_SMSC_ADDRESS_REQ), // 0x0034
|
|
||||||
qmi_name_item(QMIWMS_GET_SMSC_ADDRESS_RESP), // 0x0034
|
|
||||||
qmi_name_item(QMIWMS_SET_SMSC_ADDRESS_REQ), // 0x0035
|
|
||||||
qmi_name_item(QMIWMS_SET_SMSC_ADDRESS_RESP), // 0x0035
|
|
||||||
qmi_name_item(QMIWMS_GET_STORE_MAX_SIZE_REQ), // 0x0036
|
|
||||||
qmi_name_item(QMIWMS_GET_STORE_MAX_SIZE_RESP), // 0x0036
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmux_wds_admin_Type[] = {
|
|
||||||
qmi_name_item(QMIWDS_ADMIN_SET_DATA_FORMAT_REQ), // 0x0020
|
|
||||||
qmi_name_item(QMIWDS_ADMIN_SET_DATA_FORMAT_RESP), // 0x0020
|
|
||||||
qmi_name_item(QMIWDS_ADMIN_GET_DATA_FORMAT_REQ), // 0x0021
|
|
||||||
qmi_name_item(QMIWDS_ADMIN_GET_DATA_FORMAT_RESP), // 0x0021
|
|
||||||
qmi_name_item(QMIWDS_ADMIN_SET_QMAP_SETTINGS_REQ), // 0x002B
|
|
||||||
qmi_name_item(QMIWDS_ADMIN_SET_QMAP_SETTINGS_RESP), // 0x002B
|
|
||||||
qmi_name_item(QMIWDS_ADMIN_GET_QMAP_SETTINGS_REQ), // 0x002C
|
|
||||||
qmi_name_item(QMIWDS_ADMIN_GET_QMAP_SETTINGS_RESP), // 0x002C
|
|
||||||
qmi_name_item(QMI_WDA_SET_LOOPBACK_CONFIG_REQ), // 0x002F
|
|
||||||
qmi_name_item(QMI_WDA_SET_LOOPBACK_CONFIG_RESP), // 0x002F
|
|
||||||
qmi_name_item(QMI_WDA_SET_LOOPBACK_CONFIG_IND), // 0x002F
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmux_uim_Type[] = {
|
|
||||||
qmi_name_item( QMIUIM_READ_TRANSPARENT_REQ), // 0x0020
|
|
||||||
qmi_name_item( QMIUIM_READ_TRANSPARENT_RESP), // 0x0020
|
|
||||||
qmi_name_item( QMIUIM_READ_TRANSPARENT_IND), // 0x0020
|
|
||||||
qmi_name_item( QMIUIM_READ_RECORD_REQ), // 0x0021
|
|
||||||
qmi_name_item( QMIUIM_READ_RECORD_RESP), // 0x0021
|
|
||||||
qmi_name_item( QMIUIM_READ_RECORD_IND), // 0x0021
|
|
||||||
qmi_name_item( QMIUIM_WRITE_TRANSPARENT_REQ), // 0x0022
|
|
||||||
qmi_name_item( QMIUIM_WRITE_TRANSPARENT_RESP), // 0x0022
|
|
||||||
qmi_name_item( QMIUIM_WRITE_TRANSPARENT_IND), // 0x0022
|
|
||||||
qmi_name_item( QMIUIM_WRITE_RECORD_REQ), // 0x0023
|
|
||||||
qmi_name_item( QMIUIM_WRITE_RECORD_RESP), // 0x0023
|
|
||||||
qmi_name_item( QMIUIM_WRITE_RECORD_IND), // 0x0023
|
|
||||||
qmi_name_item( QMIUIM_SET_PIN_PROTECTION_REQ), // 0x0025
|
|
||||||
qmi_name_item( QMIUIM_SET_PIN_PROTECTION_RESP), // 0x0025
|
|
||||||
qmi_name_item( QMIUIM_SET_PIN_PROTECTION_IND), // 0x0025
|
|
||||||
qmi_name_item( QMIUIM_VERIFY_PIN_REQ), // 0x0026
|
|
||||||
qmi_name_item( QMIUIM_VERIFY_PIN_RESP), // 0x0026
|
|
||||||
qmi_name_item( QMIUIM_VERIFY_PIN_IND), // 0x0026
|
|
||||||
qmi_name_item( QMIUIM_UNBLOCK_PIN_REQ), // 0x0027
|
|
||||||
qmi_name_item( QMIUIM_UNBLOCK_PIN_RESP), // 0x0027
|
|
||||||
qmi_name_item( QMIUIM_UNBLOCK_PIN_IND), // 0x0027
|
|
||||||
qmi_name_item( QMIUIM_CHANGE_PIN_REQ), // 0x0028
|
|
||||||
qmi_name_item( QMIUIM_CHANGE_PIN_RESP), // 0x0028
|
|
||||||
qmi_name_item( QMIUIM_CHANGE_PIN_IND), // 0x0028
|
|
||||||
qmi_name_item( QMIUIM_DEPERSONALIZATION_REQ), // 0x0029
|
|
||||||
qmi_name_item( QMIUIM_DEPERSONALIZATION_RESP), // 0x0029
|
|
||||||
qmi_name_item( QMIUIM_EVENT_REG_REQ), // 0x002E
|
|
||||||
qmi_name_item( QMIUIM_EVENT_REG_RESP), // 0x002E
|
|
||||||
qmi_name_item( QMIUIM_GET_CARD_STATUS_REQ), // 0x002F
|
|
||||||
qmi_name_item( QMIUIM_GET_CARD_STATUS_RESP), // 0x002F
|
|
||||||
qmi_name_item( QMIUIM_STATUS_CHANGE_IND), // 0x0032
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmux_coex_Type[] = {
|
|
||||||
qmi_name_item(QMI_COEX_GET_WWAN_STATE_REQ), // 0x0022
|
|
||||||
qmi_name_item(QMI_COEX_GET_WWAN_STATE_RESP), // 0x0022
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char * qmi_name_get(const QMI_NAME_T *table, size_t size, int type, const char *tag) {
|
|
||||||
static char unknow[40];
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (qmux_CtlFlags == table) {
|
|
||||||
if (!strcmp(tag, "_REQ"))
|
|
||||||
tag = "_CMD";
|
|
||||||
else if (!strcmp(tag, "_RESP"))
|
|
||||||
tag = "_RSP";
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < size; i++) {
|
|
||||||
if (table[i].type == (UINT)type) {
|
|
||||||
if (!tag || (strstr(table[i].name, tag)))
|
|
||||||
return table[i].name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sprintf(unknow, "unknow_%x", type);
|
|
||||||
return unknow;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define QMI_NAME(table, type) qmi_name_get(table, sizeof(table) / sizeof(table[0]), type, 0)
|
|
||||||
#define QMUX_NAME(table, type, tag) qmi_name_get(table, sizeof(table) / sizeof(table[0]), type, tag)
|
|
||||||
|
|
||||||
void dump_tlv(PQCQMUX_MSG_HDR pQMUXMsgHdr) {
|
|
||||||
int TLVFind = 0;
|
|
||||||
int i;
|
|
||||||
//dbg("QCQMUX_TLV-----------------------------------\n");
|
|
||||||
//dbg("{Type,\tLength,\tValue}\n");
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
PQMI_TLV_HDR TLVHdr = GetTLV(pQMUXMsgHdr, 0x1000 + (++TLVFind));
|
|
||||||
if (TLVHdr == NULL)
|
|
||||||
break;
|
|
||||||
|
|
||||||
//if ((TLVHdr->TLVType == 0x02) && ((USHORT *)(TLVHdr+1))[0])
|
|
||||||
{
|
|
||||||
dbg("{%02x,\t%04x,\t", TLVHdr->TLVType, le16_to_cpu(TLVHdr->TLVLength));
|
|
||||||
for (i = 0; i < le16_to_cpu(TLVHdr->TLVLength); i++) {
|
|
||||||
dbg("%02x ", ((UCHAR *)(TLVHdr+1))[i]);
|
|
||||||
}
|
|
||||||
dbg("}\n");
|
|
||||||
}
|
|
||||||
} // while
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump_ctl(PQCQMICTL_MSG_HDR CTLHdr) {
|
|
||||||
const char *tag;
|
|
||||||
|
|
||||||
//dbg("QCQMICTL_MSG--------------------------------------------\n");
|
|
||||||
//dbg("CtlFlags: %02x\t\t%s\n", CTLHdr->CtlFlags, QMI_NAME(qmi_ctl_CtlFlags, CTLHdr->CtlFlags));
|
|
||||||
dbg("TransactionId: %02x\n", CTLHdr->TransactionId);
|
|
||||||
switch (CTLHdr->CtlFlags) {
|
|
||||||
case QMICTL_FLAG_REQUEST: tag = "_REQ"; break;
|
|
||||||
case QMICTL_FLAG_RESPONSE: tag = "_RESP"; break;
|
|
||||||
case QMICTL_FLAG_INDICATION: tag = "_IND"; break;
|
|
||||||
default: tag = 0; break;
|
|
||||||
}
|
|
||||||
dbg("QMICTLType: %04x\t%s\n", le16_to_cpu(CTLHdr->QMICTLType),
|
|
||||||
QMUX_NAME(qmux_ctl_QMICTLType, le16_to_cpu(CTLHdr->QMICTLType), tag));
|
|
||||||
dbg("Length: %04x\n", le16_to_cpu(CTLHdr->Length));
|
|
||||||
|
|
||||||
dump_tlv((PQCQMUX_MSG_HDR)(&CTLHdr->QMICTLType));
|
|
||||||
}
|
|
||||||
|
|
||||||
int dump_qmux(QMI_SERVICE_TYPE serviceType, PQCQMUX_HDR QMUXHdr) {
|
|
||||||
PQCQMUX_MSG_HDR QMUXMsgHdr = (PQCQMUX_MSG_HDR) (QMUXHdr + 1);
|
|
||||||
const char *tag;
|
|
||||||
|
|
||||||
//dbg("QCQMUX--------------------------------------------\n");
|
|
||||||
switch (QMUXHdr->CtlFlags&QMUX_CTL_FLAG_MASK_TYPE) {
|
|
||||||
case QMUX_CTL_FLAG_TYPE_CMD: tag = "_REQ"; break;
|
|
||||||
case QMUX_CTL_FLAG_TYPE_RSP: tag = "_RESP"; break;
|
|
||||||
case QMUX_CTL_FLAG_TYPE_IND: tag = "_IND"; break;
|
|
||||||
default: tag = 0; break;
|
|
||||||
}
|
|
||||||
//dbg("CtlFlags: %02x\t\t%s\n", QMUXHdr->CtlFlags, QMUX_NAME(qmux_CtlFlags, QMUXHdr->CtlFlags, tag));
|
|
||||||
dbg("TransactionId: %04x\n", le16_to_cpu(QMUXHdr->TransactionId));
|
|
||||||
|
|
||||||
//dbg("QCQMUX_MSG_HDR-----------------------------------\n");
|
|
||||||
switch (serviceType) {
|
|
||||||
case QMUX_TYPE_DMS:
|
|
||||||
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
|
|
||||||
QMUX_NAME(qmux_dms_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
|
|
||||||
break;
|
|
||||||
case QMUX_TYPE_NAS:
|
|
||||||
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
|
|
||||||
QMUX_NAME(qmux_nas_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
|
|
||||||
break;
|
|
||||||
case QMUX_TYPE_WDS:
|
|
||||||
case QMUX_TYPE_WDS_IPV6:
|
|
||||||
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
|
|
||||||
QMUX_NAME(qmux_wds_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
|
|
||||||
break;
|
|
||||||
case QMUX_TYPE_WMS:
|
|
||||||
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
|
|
||||||
QMUX_NAME(qmux_wms_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
|
|
||||||
break;
|
|
||||||
case QMUX_TYPE_WDS_ADMIN:
|
|
||||||
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
|
|
||||||
QMUX_NAME(qmux_wds_admin_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
|
|
||||||
break;
|
|
||||||
case QMUX_TYPE_UIM:
|
|
||||||
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
|
|
||||||
QMUX_NAME(qmux_uim_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
|
|
||||||
break;
|
|
||||||
case QMUX_TYPE_PDS:
|
|
||||||
case QMUX_TYPE_QOS:
|
|
||||||
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
|
|
||||||
QMUX_NAME(qmux_qos_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
|
|
||||||
break;
|
|
||||||
case QMUX_TYPE_COEX:
|
|
||||||
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
|
|
||||||
QMUX_NAME(qmux_coex_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
|
|
||||||
break;
|
|
||||||
case QMUX_TYPE_CTL:
|
|
||||||
default:
|
|
||||||
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type), "PDS/QOS/CTL/unknown!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
dbg("Length: %04x\n", le16_to_cpu(QMUXMsgHdr->Length));
|
|
||||||
|
|
||||||
dump_tlv(QMUXMsgHdr);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump_qmi(void *dataBuffer, int dataLen)
|
|
||||||
{
|
|
||||||
PQCQMI_HDR QMIHdr = (PQCQMI_HDR)dataBuffer;
|
|
||||||
PQCQMUX_HDR QMUXHdr = (PQCQMUX_HDR) (QMIHdr + 1);
|
|
||||||
PQCQMICTL_MSG_HDR CTLHdr = (PQCQMICTL_MSG_HDR) (QMIHdr + 1);
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!debug_qmi)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&dumpQMIMutex);
|
|
||||||
line[0] = 0;
|
|
||||||
for (i = 0; i < dataLen; i++) {
|
|
||||||
dbg("%02x ", ((unsigned char *)dataBuffer)[i]);
|
|
||||||
}
|
|
||||||
dbg_time("%s", line);
|
|
||||||
line[0] = 0;
|
|
||||||
|
|
||||||
//dbg("QCQMI_HDR-----------------------------------------");
|
|
||||||
//dbg("IFType: %02x\t\t%s", QMIHdr->IFType, QMI_NAME(qmi_IFType, QMIHdr->IFType));
|
|
||||||
//dbg("Length: %04x", le16_to_cpu(QMIHdr->Length));
|
|
||||||
//dbg("CtlFlags: %02x\t\t%s", QMIHdr->CtlFlags, QMI_NAME(qmi_CtlFlags, QMIHdr->CtlFlags));
|
|
||||||
//dbg("QMIType: %02x\t\t%s", QMIHdr->QMIType, QMI_NAME(qmi_QMIType, QMIHdr->QMIType));
|
|
||||||
//dbg("ClientId: %02x", QMIHdr->ClientId);
|
|
||||||
|
|
||||||
if (QMIHdr->QMIType == QMUX_TYPE_CTL) {
|
|
||||||
dump_ctl(CTLHdr);
|
|
||||||
} else {
|
|
||||||
dump_qmux(QMIHdr->QMIType, QMUXHdr);
|
|
||||||
}
|
|
||||||
dbg_time("%s", line);
|
|
||||||
pthread_mutex_unlock(&dumpQMIMutex);
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,467 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2025 Quectel Wireless Solutions Co.,Ltd
|
|
||||||
|
|
||||||
Quectel hereby grants customers of Quectel a license to use, modify,
|
|
||||||
distribute and publish the Software in binary form provided that
|
|
||||||
customers shall have no right to reverse engineer, reverse assemble,
|
|
||||||
decompile or reduce to source code form any portion of the Software.
|
|
||||||
Under no circumstances may customers modify, demonstrate, use, deliver
|
|
||||||
or disclose any portion of the Software in source code form.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __QMI_THREAD_H__
|
|
||||||
#define __QMI_THREAD_H__
|
|
||||||
|
|
||||||
#define CONFIG_GOBINET
|
|
||||||
#define CONFIG_QMIWWAN
|
|
||||||
#define CONFIG_SIM
|
|
||||||
#define CONFIG_APN
|
|
||||||
#define CONFIG_VERSION
|
|
||||||
//#define CONFIG_SIGNALINFO
|
|
||||||
//#define CONFIG_CELLINFO
|
|
||||||
//#define CONFIG_COEX_WWAN_STATE
|
|
||||||
#define CONFIG_DEFAULT_PDP 1
|
|
||||||
//#define CONFIG_IMSI_ICCID
|
|
||||||
#define QUECTEL_UL_DATA_AGG
|
|
||||||
//#define QUECTEL_QMI_MERGE
|
|
||||||
//#define REBOOT_SIM_CARD_WHEN_APN_CHANGE
|
|
||||||
//#define REBOOT_SIM_CARD_WHEN_LONG_TIME_NO_PS 60 //unit is seconds
|
|
||||||
//#define CONFIG_QRTR
|
|
||||||
//#define CONFIG_ENABLE_QOS
|
|
||||||
//#define CONFIG_REG_QOS_IND
|
|
||||||
//#define CONFIG_GET_QOS_INFO
|
|
||||||
//#define CONFIG_GET_QOS_DATA_RATE
|
|
||||||
|
|
||||||
#if (defined(CONFIG_REG_QOS_IND) || defined(CONFIG_GET_QOS_INFO) || defined(CONFIG_GET_QOS_DATA_RATE))
|
|
||||||
#ifndef CONFIG_REG_QOS_IND
|
|
||||||
#define CONFIG_REG_QOS_IND
|
|
||||||
#endif
|
|
||||||
#ifndef CONFIG_ENABLE_QOS
|
|
||||||
#define CONFIG_ENABLE_QOS
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/epoll.h>
|
|
||||||
#include <poll.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "qendian.h"
|
|
||||||
#include "QCQMI.h"
|
|
||||||
#include "QCQCTL.h"
|
|
||||||
#include "QCQMUX.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
#define DEVICE_CLASS_UNKNOWN 0
|
|
||||||
#define DEVICE_CLASS_CDMA 1
|
|
||||||
#define DEVICE_CLASS_GSM 2
|
|
||||||
|
|
||||||
#define WWAN_DATA_CLASS_NONE 0x00000000
|
|
||||||
#define WWAN_DATA_CLASS_GPRS 0x00000001
|
|
||||||
#define WWAN_DATA_CLASS_EDGE 0x00000002 /* EGPRS */
|
|
||||||
#define WWAN_DATA_CLASS_UMTS 0x00000004
|
|
||||||
#define WWAN_DATA_CLASS_HSDPA 0x00000008
|
|
||||||
#define WWAN_DATA_CLASS_HSUPA 0x00000010
|
|
||||||
#define WWAN_DATA_CLASS_LTE 0x00000020
|
|
||||||
#define WWAN_DATA_CLASS_5G_NSA 0x00000040
|
|
||||||
#define WWAN_DATA_CLASS_5G_SA 0x00000080
|
|
||||||
#define WWAN_DATA_CLASS_1XRTT 0x00010000
|
|
||||||
#define WWAN_DATA_CLASS_1XEVDO 0x00020000
|
|
||||||
#define WWAN_DATA_CLASS_1XEVDO_REVA 0x00040000
|
|
||||||
#define WWAN_DATA_CLASS_1XEVDV 0x00080000
|
|
||||||
#define WWAN_DATA_CLASS_3XRTT 0x00100000
|
|
||||||
#define WWAN_DATA_CLASS_1XEVDO_REVB 0x00200000 /* for future use */
|
|
||||||
#define WWAN_DATA_CLASS_UMB 0x00400000
|
|
||||||
#define WWAN_DATA_CLASS_CUSTOM 0x80000000
|
|
||||||
|
|
||||||
struct wwan_data_class_str {
|
|
||||||
ULONG class;
|
|
||||||
const char *str;
|
|
||||||
};
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
typedef struct __IPV4 {
|
|
||||||
uint32_t Address;
|
|
||||||
uint32_t Gateway;
|
|
||||||
uint32_t SubnetMask;
|
|
||||||
uint32_t DnsPrimary;
|
|
||||||
uint32_t DnsSecondary;
|
|
||||||
uint32_t Mtu;
|
|
||||||
} IPV4_T;
|
|
||||||
|
|
||||||
typedef struct __IPV6 {
|
|
||||||
UCHAR Address[16];
|
|
||||||
UCHAR Gateway[16];
|
|
||||||
UCHAR SubnetMask[16];
|
|
||||||
UCHAR DnsPrimary[16];
|
|
||||||
UCHAR DnsSecondary[16];
|
|
||||||
UCHAR PrefixLengthIPAddr;
|
|
||||||
UCHAR PrefixLengthGateway;
|
|
||||||
ULONG Mtu;
|
|
||||||
} IPV6_T;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
UINT size;
|
|
||||||
UINT rx_urb_size;
|
|
||||||
UINT ep_type;
|
|
||||||
UINT iface_id;
|
|
||||||
UINT MuxId;
|
|
||||||
UINT ul_data_aggregation_max_datagrams; //0x17
|
|
||||||
UINT ul_data_aggregation_max_size ;//0x18
|
|
||||||
UINT dl_minimum_padding; //0x1A
|
|
||||||
} QMAP_SETTING;
|
|
||||||
|
|
||||||
//Configured downlink data aggregationprotocol
|
|
||||||
#define WDA_DL_DATA_AGG_DISABLED (0x00) //DL data aggregation is disabled (default)
|
|
||||||
#define WDA_DL_DATA_AGG_TLP_ENABLED (0x01) // DL TLP is enabled
|
|
||||||
#define WDA_DL_DATA_AGG_QC_NCM_ENABLED (0x02) // DL QC_NCM isenabled
|
|
||||||
#define WDA_DL_DATA_AGG_MBIM_ENABLED (0x03) // DL MBIM isenabled
|
|
||||||
#define WDA_DL_DATA_AGG_RNDIS_ENABLED (0x04) // DL RNDIS is enabled
|
|
||||||
#define WDA_DL_DATA_AGG_QMAP_ENABLED (0x05) // DL QMAP isenabled
|
|
||||||
#define WDA_DL_DATA_AGG_QMAP_V2_ENABLED (0x06) // DL QMAP V2 is enabled
|
|
||||||
#define WDA_DL_DATA_AGG_QMAP_V3_ENABLED (0x07) // DL QMAP V3 is enabled
|
|
||||||
#define WDA_DL_DATA_AGG_QMAP_V4_ENABLED (0x08) // DL QMAP V4 is enabled
|
|
||||||
#define WDA_DL_DATA_AGG_QMAP_V5_ENABLED (0x09) // DL QMAP V5 is enabled
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
unsigned int size;
|
|
||||||
unsigned int rx_urb_size;
|
|
||||||
unsigned int ep_type;
|
|
||||||
unsigned int iface_id;
|
|
||||||
unsigned int qmap_mode;
|
|
||||||
unsigned int qmap_version;
|
|
||||||
unsigned int dl_minimum_padding;
|
|
||||||
char ifname[8][16];
|
|
||||||
unsigned char mux_id[8];
|
|
||||||
} RMNET_INFO;
|
|
||||||
|
|
||||||
#define IpFamilyV4 (0x04)
|
|
||||||
#define IpFamilyV6 (0x06)
|
|
||||||
|
|
||||||
struct __PROFILE;
|
|
||||||
struct qmi_device_ops {
|
|
||||||
int (*init)(struct __PROFILE *profile);
|
|
||||||
int (*deinit)(void);
|
|
||||||
int (*send)(PQCQMIMSG pRequest);
|
|
||||||
void* (*read)(void *pData);
|
|
||||||
};
|
|
||||||
#ifdef CONFIG_QRTR
|
|
||||||
extern const struct qmi_device_ops qrtr_qmidev_ops;
|
|
||||||
#endif
|
|
||||||
extern const struct qmi_device_ops gobi_qmidev_ops;
|
|
||||||
extern const struct qmi_device_ops qmiwwan_qmidev_ops;
|
|
||||||
extern const struct qmi_device_ops mbim_dev_ops;
|
|
||||||
extern const struct qmi_device_ops atc_dev_ops;
|
|
||||||
extern int (*qmidev_send)(PQCQMIMSG pRequest);
|
|
||||||
|
|
||||||
struct usb_device_info {
|
|
||||||
int idVendor;
|
|
||||||
int idProduct;
|
|
||||||
int busnum;
|
|
||||||
int devnum;
|
|
||||||
int bNumInterfaces;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct usb_interface_info {
|
|
||||||
int bNumEndpoints;
|
|
||||||
int bInterfaceClass;
|
|
||||||
int bInterfaceSubClass;
|
|
||||||
int bInterfaceProtocol;
|
|
||||||
char driver[32];
|
|
||||||
};
|
|
||||||
|
|
||||||
#define LIBQMI_PROXY "qmi-proxy" //src/libqmi-glib/qmi-proxy.h
|
|
||||||
#define LIBMBIM_PROXY "mbim-proxy"
|
|
||||||
#define QUECTEL_QMI_PROXY "quectel-qmi-proxy"
|
|
||||||
#define QUECTEL_MBIM_PROXY "quectel-mbim-proxy"
|
|
||||||
#define QUECTEL_ATC_PROXY "quectel-atc-proxy"
|
|
||||||
#define QUECTEL_QRTR_PROXY "quectel-qrtr-proxy"
|
|
||||||
|
|
||||||
#ifndef bool
|
|
||||||
#define bool uint8_t
|
|
||||||
#endif
|
|
||||||
struct request_ops;
|
|
||||||
typedef struct __PROFILE {
|
|
||||||
//user input start
|
|
||||||
const char *apn;
|
|
||||||
const char *user;
|
|
||||||
const char *pd;
|
|
||||||
int auth;
|
|
||||||
int iptype;
|
|
||||||
const char *pincode;
|
|
||||||
char proxy[32];
|
|
||||||
int pdp;//pdp_context
|
|
||||||
int profile_index;//profile_index
|
|
||||||
int enable_bridge;
|
|
||||||
bool enable_ipv4;
|
|
||||||
bool enable_ipv6;
|
|
||||||
bool no_dhcp;
|
|
||||||
const char *logfile;
|
|
||||||
const char *usblogfile;
|
|
||||||
char expect_adapter[32];
|
|
||||||
int kill_pdp;
|
|
||||||
int replication_factor;
|
|
||||||
//user input end
|
|
||||||
|
|
||||||
char qmichannel[32];
|
|
||||||
char usbnet_adapter[32];
|
|
||||||
char qmapnet_adapter[32];
|
|
||||||
char driver_name[32];
|
|
||||||
int qmap_mode;
|
|
||||||
int qmap_size;
|
|
||||||
int qmap_version;
|
|
||||||
int curIpFamily;
|
|
||||||
int rawIP;
|
|
||||||
int muxid;
|
|
||||||
#ifdef CONFIG_ENABLE_QOS
|
|
||||||
UINT qos_id;
|
|
||||||
#endif
|
|
||||||
int wda_client;
|
|
||||||
uint32_t udhcpc_ip;
|
|
||||||
IPV4_T ipv4;
|
|
||||||
IPV6_T ipv6;
|
|
||||||
UINT PCSCFIpv4Addr1;
|
|
||||||
UINT PCSCFIpv4Addr2;
|
|
||||||
UCHAR PCSCFIpv6Addr1[16];
|
|
||||||
UCHAR PCSCFIpv6Addr2[16];
|
|
||||||
bool reattach_flag;
|
|
||||||
int hardware_interface;
|
|
||||||
int software_interface;
|
|
||||||
|
|
||||||
struct usb_device_info usb_dev;
|
|
||||||
struct usb_interface_info usb_intf;
|
|
||||||
|
|
||||||
int usbmon_fd;
|
|
||||||
FILE *usbmon_logfile_fp;
|
|
||||||
bool loopback_state;
|
|
||||||
|
|
||||||
char BaseBandVersion[64];
|
|
||||||
char old_apn[64];
|
|
||||||
char old_user[64];
|
|
||||||
char old_pd[64];
|
|
||||||
int old_auth;
|
|
||||||
int old_iptype;
|
|
||||||
|
|
||||||
const struct qmi_device_ops *qmi_ops;
|
|
||||||
const struct request_ops *request_ops;
|
|
||||||
RMNET_INFO rmnet_info;
|
|
||||||
BOOL bring_up_by_apn_name;
|
|
||||||
BOOL bring_up_by_apn_type;
|
|
||||||
int apn_type;
|
|
||||||
} PROFILE_T;
|
|
||||||
|
|
||||||
#ifdef QUECTEL_QMI_MERGE
|
|
||||||
#define MERGE_PACKET_IDENTITY 0x2c7c
|
|
||||||
#define MERGE_PACKET_VERSION 0x0001
|
|
||||||
#define MERGE_PACKET_MAX_PAYLOAD_SIZE 56
|
|
||||||
typedef struct __QMI_MSG_HEADER {
|
|
||||||
uint16_t idenity;
|
|
||||||
uint16_t version;
|
|
||||||
uint16_t cur_len;
|
|
||||||
uint16_t total_len;
|
|
||||||
} QMI_MSG_HEADER;
|
|
||||||
|
|
||||||
typedef struct __QMI_MSG_PACKET {
|
|
||||||
QMI_MSG_HEADER header;
|
|
||||||
uint16_t len;
|
|
||||||
char buf[4096];
|
|
||||||
} QMI_MSG_PACKET;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
SIM_ABSENT = 0,
|
|
||||||
SIM_NOT_READY = 1,
|
|
||||||
SIM_READY = 2, /* SIM_READY means the radio state is RADIO_STATE_SIM_READY */
|
|
||||||
SIM_PIN = 3,
|
|
||||||
SIM_PUK = 4,
|
|
||||||
SIM_NETWORK_PERSONALIZATION = 5,
|
|
||||||
SIM_BAD = 6,
|
|
||||||
} SIM_Status;
|
|
||||||
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
#define WDM_DEFAULT_BUFSIZE 256
|
|
||||||
#define RIL_REQUEST_QUIT 0x1000
|
|
||||||
#define RIL_INDICATE_DEVICE_CONNECTED 0x1002
|
|
||||||
#define RIL_INDICATE_DEVICE_DISCONNECTED 0x1003
|
|
||||||
#define RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED 0x1004
|
|
||||||
#define RIL_UNSOL_DATA_CALL_LIST_CHANGED 0x1005
|
|
||||||
#define MODEM_REPORT_RESET_EVENT 0x1006
|
|
||||||
#define RIL_UNSOL_LOOPBACK_CONFIG_IND 0x1007
|
|
||||||
#ifdef CONFIG_REG_QOS_IND
|
|
||||||
#define RIL_UNSOL_GLOBAL_QOS_FLOW_IND_QOS_ID 0x1008
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern pthread_mutex_t cm_command_mutex;
|
|
||||||
extern pthread_cond_t cm_command_cond;
|
|
||||||
extern unsigned int cm_recv_buf[1024];
|
|
||||||
extern int cm_open_dev(const char *dev);
|
|
||||||
extern int cm_open_proxy(const char *name);
|
|
||||||
extern int pthread_cond_timeout_np(pthread_cond_t *cond, pthread_mutex_t * mutex, unsigned msecs);
|
|
||||||
extern int QmiThreadSendQMITimeout(PQCQMIMSG pRequest, PQCQMIMSG *ppResponse, unsigned msecs, const char *funcname);
|
|
||||||
#define QmiThreadSendQMI(pRequest, ppResponse) QmiThreadSendQMITimeout(pRequest, ppResponse, 30 * 1000, __func__)
|
|
||||||
extern void QmiThreadRecvQMI(PQCQMIMSG pResponse);
|
|
||||||
extern void udhcpc_start(PROFILE_T *profile);
|
|
||||||
extern void udhcpc_stop(PROFILE_T *profile);
|
|
||||||
extern void ql_set_driver_link_state(PROFILE_T *profile, int link_state);
|
|
||||||
extern void ql_set_driver_qmap_setting(PROFILE_T *profile, QMAP_SETTING *qmap_settings);
|
|
||||||
extern void ql_get_driver_rmnet_info(PROFILE_T *profile, RMNET_INFO *rmnet_info);
|
|
||||||
extern void dump_qmi(void *dataBuffer, int dataLen);
|
|
||||||
extern void qmidevice_send_event_to_main(int triger_event);
|
|
||||||
extern void qmidevice_send_event_to_main_ext(int triger_event, void *data, unsigned len);
|
|
||||||
extern uint8_t qmi_over_mbim_get_client_id(uint8_t QMIType);
|
|
||||||
extern uint8_t qmi_over_mbim_release_client_id(uint8_t QMIType, uint8_t ClientId);
|
|
||||||
#ifdef CONFIG_REG_QOS_IND
|
|
||||||
extern UCHAR ql_get_global_qos_flow_ind_qos_id(PQCQMIMSG pResponse, UINT *qos_id);
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_GET_QOS_DATA_RATE
|
|
||||||
extern UCHAR ql_get_global_qos_flow_ind_data_rate(PQCQMIMSG pResponse, void *max_data_rate);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct request_ops {
|
|
||||||
int (*requestBaseBandVersion)(PROFILE_T *profile);
|
|
||||||
int (*requestSetEthMode)(PROFILE_T *profile);
|
|
||||||
int (*requestSetLoopBackState)(UCHAR loopback_state, ULONG replication_factor);
|
|
||||||
int (*requestGetSIMStatus)(SIM_Status *pSIMStatus);
|
|
||||||
int (*requestEnterSimPin)(const char *pPinCode);
|
|
||||||
int (*requestSetProfile)(PROFILE_T *profile); // 1 ~ success and apn change, 0 ~ success and no apn change, -1 ~ fail
|
|
||||||
int (*requestGetProfile)(PROFILE_T *profile);
|
|
||||||
int (*requestRegistrationState)(UCHAR *pPSAttachedState);
|
|
||||||
int (*requestSetupDataCall)(PROFILE_T *profile, int curIpFamily);
|
|
||||||
int (*requestQueryDataCall)(UCHAR *pConnectionStatus, int curIpFamily);
|
|
||||||
int (*requestDeactivateDefaultPDP)(PROFILE_T *profile, int curIpFamily);
|
|
||||||
int (*requestGetIPAddress)(PROFILE_T *profile, int curIpFamily);
|
|
||||||
int (*requestGetSignalInfo)(void);
|
|
||||||
int (*requestGetCellInfoList)(void);
|
|
||||||
int (*requestGetICCID)(void);
|
|
||||||
int (*requestGetIMSI)(void);
|
|
||||||
int (*requestRadioPower)(int state);
|
|
||||||
int (*requestRegisterQos)(PROFILE_T *profile);
|
|
||||||
int (*requestGetQosInfo)(PROFILE_T *profile);
|
|
||||||
int (*requestGetCoexWWANState)(void);
|
|
||||||
};
|
|
||||||
extern const struct request_ops qmi_request_ops;
|
|
||||||
extern const struct request_ops mbim_request_ops;
|
|
||||||
extern const struct request_ops atc_request_ops;
|
|
||||||
|
|
||||||
extern int get_driver_type(PROFILE_T *profile);
|
|
||||||
extern BOOL qmidevice_detect(char *qmichannel, char *usbnet_adapter, unsigned bufsize, PROFILE_T *profile);
|
|
||||||
int mhidevice_detect(char *qmichannel, char *usbnet_adapter, PROFILE_T *profile);
|
|
||||||
int atdevice_detect(char *atchannel, char *usbnet_adapter, PROFILE_T *profile);
|
|
||||||
extern int ql_bridge_mode_detect(PROFILE_T *profile);
|
|
||||||
extern int ql_enable_qmi_wwan_rawip_mode(PROFILE_T *profile);
|
|
||||||
extern int ql_qmap_mode_detect(PROFILE_T *profile);
|
|
||||||
#ifdef CONFIG_QRTR
|
|
||||||
extern int rtrmnet_ctl_new_vnd(char *devname, char *vndname, uint8_t muxid,
|
|
||||||
uint32_t qmap_version, uint32_t ul_agg_cnt, uint32_t ul_agg_size);
|
|
||||||
extern int rtrmnet_ctl_get_vnd(char *vndname, int *muxid,
|
|
||||||
int *qmap_version);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define qmidev_is_gobinet(_qmichannel) (strncmp(_qmichannel, "/dev/qcqmi", strlen("/dev/qcqmi")) == 0)
|
|
||||||
#define qmidev_is_qmiwwan(_qmichannel) (strncmp(_qmichannel, "/dev/cdc-wdm", strlen("/dev/cdc-wdm")) == 0)
|
|
||||||
#define qmidev_is_pciemhi(_qmichannel) (strncmp(_qmichannel, "/dev/mhi_", strlen("/dev/mhi_")) == 0)
|
|
||||||
|
|
||||||
#define driver_is_qmi(_drv_name) (strncasecmp(_drv_name, "qmi_wwan", strlen("qmi_wwan")) == 0)
|
|
||||||
#define driver_is_mbim(_drv_name) (strncasecmp(_drv_name, "cdc_mbim", strlen("cdc_mbim")) == 0)
|
|
||||||
|
|
||||||
extern FILE *logfilefp;
|
|
||||||
extern int debug_qmi;
|
|
||||||
extern int qmidevice_control_fd[2];
|
|
||||||
extern int g_donot_exit_when_modem_hangup;
|
|
||||||
extern void update_resolv_conf(int iptype, const char *ifname, const char *dns1, const char *dns2);
|
|
||||||
void update_ipv4_address(const char *ifname, const char *ip, const char *gw, unsigned prefix);
|
|
||||||
void update_ipv6_address(const char *ifname, const char *ip, const char *gw, unsigned prefix);
|
|
||||||
int reattach_driver(PROFILE_T *profile);
|
|
||||||
extern void no_trunc_strncpy(char *dest, const char *src, size_t dest_size);
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
DRV_INVALID,
|
|
||||||
SOFTWARE_QMI,
|
|
||||||
SOFTWARE_MBIM,
|
|
||||||
SOFTWARE_ECM_RNDIS_NCM,
|
|
||||||
SOFTWARE_QRTR,
|
|
||||||
HARDWARE_PCIE,
|
|
||||||
HARDWARE_USB,
|
|
||||||
HARDWARE_IPA,
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef USE_IPC_MSG_STATUS_IND
|
|
||||||
#include <sys/ipc.h>
|
|
||||||
#include <sys/msg.h>
|
|
||||||
#define MSG_FILE "/etc/passwd"
|
|
||||||
#define MSG_TYPE_IPC 1
|
|
||||||
#define MSGBUFFSZ 16
|
|
||||||
struct message
|
|
||||||
{
|
|
||||||
long mtype;
|
|
||||||
char mtext[MSGBUFFSZ];
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
QCM_PARA_CONFIG_QUERY = 1,
|
|
||||||
QCM_NETWORK_IPV4_CONNECTED,
|
|
||||||
QCM_NETWORK_IPV6_CONNECTED,
|
|
||||||
QCM_NETWORK_IPV4_DISCONNECTED,
|
|
||||||
QCM_NETWORK_IPV6_DISCONNECTED,
|
|
||||||
QCM_PREPARE_START_DAIL,
|
|
||||||
QCM_PREPARE_DAIL_FIAL,
|
|
||||||
QCM_PREPARE_DAIL_SUCC,
|
|
||||||
QCM_PREPARE_RESTART_DAIL,
|
|
||||||
QCM_PROCESS_EXIT,
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
SIG_EVENT_START,
|
|
||||||
SIG_EVENT_CHECK,
|
|
||||||
SIG_EVENT_STOP,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
DMS_OP_MODE_ONLINE,
|
|
||||||
DMS_OP_MODE_LOW_POWER,
|
|
||||||
DMS_OP_MODE_FACTORY_TEST_MODE,
|
|
||||||
DMS_OP_MODE_OFFLINE,
|
|
||||||
DMS_OP_MODE_RESETTING,
|
|
||||||
DMS_OP_MODE_SHUTTING_DOWN,
|
|
||||||
DMS_OP_MODE_PERSISTENT_LOW_POWER,
|
|
||||||
DMS_OP_MODE_MODE_ONLY_LOW_POWER,
|
|
||||||
DMS_OP_MODE_NET_TEST_GW,
|
|
||||||
}Device_operating_mode;
|
|
||||||
|
|
||||||
#ifdef CM_DEBUG
|
|
||||||
#define dbg_time(fmt, args...) do { \
|
|
||||||
fprintf(stdout, "[%15s-%04d: %s] " fmt "\n", __FILE__, __LINE__, get_time(), ##args); \
|
|
||||||
fflush(stdout);\
|
|
||||||
if (logfilefp) fprintf(logfilefp, "[%s-%04d: %s] " fmt "\n", __FILE__, __LINE__, get_time(), ##args); \
|
|
||||||
} while(0)
|
|
||||||
#else
|
|
||||||
#define dbg_time(fmt, args...) do { \
|
|
||||||
fprintf(stdout, "[%s] " fmt "\n", get_time(), ##args); \
|
|
||||||
fflush(stdout);\
|
|
||||||
if (logfilefp) fprintf(logfilefp, "[%s] " fmt "\n", get_time(), ##args); \
|
|
||||||
} while(0)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
@@ -1,454 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2025 Quectel Wireless Solutions Co.,Ltd
|
|
||||||
|
|
||||||
Quectel hereby grants customers of Quectel a license to use, modify,
|
|
||||||
distribute and publish the Software in binary form provided that
|
|
||||||
customers shall have no right to reverse engineer, reverse assemble,
|
|
||||||
decompile or reduce to source code form any portion of the Software.
|
|
||||||
Under no circumstances may customers modify, demonstrate, use, deliver
|
|
||||||
or disclose any portion of the Software in source code form.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include "QMIThread.h"
|
|
||||||
|
|
||||||
#ifdef CONFIG_QMIWWAN
|
|
||||||
static int cdc_wdm_fd = -1;
|
|
||||||
static UCHAR qmiclientId[QMUX_TYPE_ALL];
|
|
||||||
|
|
||||||
static UCHAR GetQCTLTransactionId(void) {
|
|
||||||
static int TransactionId = 0;
|
|
||||||
if (++TransactionId > 0xFF)
|
|
||||||
TransactionId = 1;
|
|
||||||
return TransactionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef USHORT (*CUSTOMQCTL)(PQMICTL_MSG pCTLMsg, void *arg);
|
|
||||||
|
|
||||||
static PQCQMIMSG ComposeQCTLMsg(USHORT QMICTLType, CUSTOMQCTL customQctlMsgFunction, void *arg) {
|
|
||||||
UCHAR QMIBuf[WDM_DEFAULT_BUFSIZE];
|
|
||||||
PQCQMIMSG pRequest = (PQCQMIMSG)QMIBuf;
|
|
||||||
int Length;
|
|
||||||
|
|
||||||
pRequest->QMIHdr.IFType = USB_CTL_MSG_TYPE_QMI;
|
|
||||||
pRequest->QMIHdr.CtlFlags = 0x00;
|
|
||||||
pRequest->QMIHdr.QMIType = QMUX_TYPE_CTL;
|
|
||||||
pRequest->QMIHdr.ClientId= 0x00;
|
|
||||||
|
|
||||||
pRequest->CTLMsg.QMICTLMsgHdr.CtlFlags = QMICTL_FLAG_REQUEST;
|
|
||||||
pRequest->CTLMsg.QMICTLMsgHdr.TransactionId = GetQCTLTransactionId();
|
|
||||||
pRequest->CTLMsg.QMICTLMsgHdr.QMICTLType = cpu_to_le16(QMICTLType);
|
|
||||||
if (customQctlMsgFunction)
|
|
||||||
pRequest->CTLMsg.QMICTLMsgHdr.Length = cpu_to_le16(customQctlMsgFunction(&pRequest->CTLMsg, arg) - sizeof(QCQMICTL_MSG_HDR));
|
|
||||||
else
|
|
||||||
pRequest->CTLMsg.QMICTLMsgHdr.Length = cpu_to_le16(0x0000);
|
|
||||||
|
|
||||||
pRequest->QMIHdr.Length = cpu_to_le16(le16_to_cpu(pRequest->CTLMsg.QMICTLMsgHdr.Length) + sizeof(QCQMICTL_MSG_HDR) + sizeof(QCQMI_HDR) - 1);
|
|
||||||
Length = le16_to_cpu(pRequest->QMIHdr.Length) + 1;
|
|
||||||
|
|
||||||
pRequest = (PQCQMIMSG)malloc(Length);
|
|
||||||
if (pRequest == NULL) {
|
|
||||||
dbg_time("%s fail to malloc", __func__);
|
|
||||||
} else {
|
|
||||||
memcpy(pRequest, QMIBuf, Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
static USHORT CtlGetVersionReq(PQMICTL_MSG QCTLMsg, void *arg)
|
|
||||||
{
|
|
||||||
(void)arg;
|
|
||||||
QCTLMsg->GetVersionReq.TLVType = QCTLV_TYPE_REQUIRED_PARAMETER;
|
|
||||||
QCTLMsg->GetVersionReq.TLVLength = cpu_to_le16(0x0001);
|
|
||||||
QCTLMsg->GetVersionReq.QMUXTypes = QMUX_TYPE_ALL;
|
|
||||||
return sizeof(QMICTL_GET_VERSION_REQ_MSG);
|
|
||||||
}
|
|
||||||
|
|
||||||
static USHORT CtlGetClientIdReq(PQMICTL_MSG QCTLMsg, void *arg) {
|
|
||||||
QCTLMsg->GetClientIdReq.TLVType = QCTLV_TYPE_REQUIRED_PARAMETER;
|
|
||||||
QCTLMsg->GetClientIdReq.TLVLength = cpu_to_le16(0x0001);
|
|
||||||
QCTLMsg->GetClientIdReq.QMIType = ((UCHAR *)arg)[0];
|
|
||||||
return sizeof(QMICTL_GET_CLIENT_ID_REQ_MSG);
|
|
||||||
}
|
|
||||||
|
|
||||||
static USHORT CtlReleaseClientIdReq(PQMICTL_MSG QCTLMsg, void *arg) {
|
|
||||||
QCTLMsg->ReleaseClientIdReq.TLVType = QCTLV_TYPE_REQUIRED_PARAMETER;
|
|
||||||
QCTLMsg->ReleaseClientIdReq.TLVLength = cpu_to_le16(0x0002);
|
|
||||||
QCTLMsg->ReleaseClientIdReq.QMIType = ((UCHAR *)arg)[0];
|
|
||||||
QCTLMsg->ReleaseClientIdReq.ClientId = ((UCHAR *)arg)[1] ;
|
|
||||||
return sizeof(QMICTL_RELEASE_CLIENT_ID_REQ_MSG);
|
|
||||||
}
|
|
||||||
|
|
||||||
static USHORT CtlLibQmiProxyOpenReq(PQMICTL_MSG QCTLMsg, void *arg)
|
|
||||||
{
|
|
||||||
(void)arg;
|
|
||||||
const char *device_path = (const char *)(arg);
|
|
||||||
QCTLMsg->LibQmiProxyOpenReq.TLVType = 0x01;
|
|
||||||
QCTLMsg->LibQmiProxyOpenReq.TLVLength = cpu_to_le16(strlen(device_path));
|
|
||||||
//strcpy(QCTLMsg->LibQmiProxyOpenReq.device_path, device_path);
|
|
||||||
//__builtin___strcpy_chk
|
|
||||||
memcpy(QCTLMsg->LibQmiProxyOpenReq.device_path, device_path, strlen(device_path));
|
|
||||||
return sizeof(QMICTL_LIBQMI_PROXY_OPEN_MSG) + (strlen(device_path));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int libqmi_proxy_open(const char *cdc_wdm) {
|
|
||||||
int ret;
|
|
||||||
PQCQMIMSG pResponse;
|
|
||||||
|
|
||||||
ret = QmiThreadSendQMI(ComposeQCTLMsg(QMI_MESSAGE_CTL_INTERNAL_PROXY_OPEN,
|
|
||||||
CtlLibQmiProxyOpenReq, (void *)cdc_wdm), &pResponse);
|
|
||||||
if (!ret && pResponse
|
|
||||||
&& pResponse->CTLMsg.QMICTLMsgHdrRsp.QMUXResult == 0
|
|
||||||
&& pResponse->CTLMsg.QMICTLMsgHdrRsp.QMUXError == 0) {
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pResponse)
|
|
||||||
free(pResponse);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int QmiWwanSendQMI(PQCQMIMSG pRequest) {
|
|
||||||
struct pollfd pollfds[]= {{cdc_wdm_fd, POLLOUT, 0}};
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (cdc_wdm_fd == -1) {
|
|
||||||
dbg_time("%s cdc_wdm_fd = -1", __func__);
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pRequest->QMIHdr.QMIType != QMUX_TYPE_CTL) {
|
|
||||||
pRequest->QMIHdr.ClientId = qmiclientId[pRequest->QMIHdr.QMIType];
|
|
||||||
if (pRequest->QMIHdr.ClientId == 0) {
|
|
||||||
dbg_time("QMIType %d has no clientID", pRequest->QMIHdr.QMIType);
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pRequest->QMIHdr.QMIType == QMUX_TYPE_WDS_IPV6)
|
|
||||||
pRequest->QMIHdr.QMIType = QMUX_TYPE_WDS;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
ret = poll(pollfds, sizeof(pollfds)/sizeof(pollfds[0]), 5000);
|
|
||||||
} while ((ret < 0) && (errno == EINTR));
|
|
||||||
|
|
||||||
if (pollfds[0].revents & POLLOUT) {
|
|
||||||
ssize_t nwrites = le16_to_cpu(pRequest->QMIHdr.Length) + 1;
|
|
||||||
ret = write(cdc_wdm_fd, pRequest, nwrites);
|
|
||||||
if (ret == nwrites) {
|
|
||||||
ret = 0;
|
|
||||||
} else {
|
|
||||||
dbg_time("%s write=%d, errno: %d (%s)", __func__, ret, errno, strerror(errno));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dbg_time("%s poll=%d, revents = 0x%x, errno: %d (%s)", __func__, ret, pollfds[0].revents, errno, strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static UCHAR QmiWwanGetClientID(UCHAR QMIType) {
|
|
||||||
PQCQMIMSG pResponse;
|
|
||||||
|
|
||||||
QmiThreadSendQMI(ComposeQCTLMsg(QMICTL_GET_CLIENT_ID_REQ, CtlGetClientIdReq, &QMIType), &pResponse);
|
|
||||||
|
|
||||||
if (pResponse) {
|
|
||||||
USHORT QMUXResult = cpu_to_le16(pResponse->CTLMsg.QMICTLMsgHdrRsp.QMUXResult); // QMI_RESULT_SUCCESS
|
|
||||||
USHORT QMUXError = cpu_to_le16(pResponse->CTLMsg.QMICTLMsgHdrRsp.QMUXError); // QMI_ERR_INVALID_ARG
|
|
||||||
//UCHAR QMIType = pResponse->CTLMsg.GetClientIdRsp.QMIType;
|
|
||||||
UCHAR ClientId = pResponse->CTLMsg.GetClientIdRsp.ClientId;
|
|
||||||
|
|
||||||
if (!QMUXResult && !QMUXError && (QMIType == pResponse->CTLMsg.GetClientIdRsp.QMIType)) {
|
|
||||||
switch (QMIType) {
|
|
||||||
case QMUX_TYPE_WDS: dbg_time("Get clientWDS = %d", ClientId); break;
|
|
||||||
case QMUX_TYPE_DMS: dbg_time("Get clientDMS = %d", ClientId); break;
|
|
||||||
case QMUX_TYPE_NAS: dbg_time("Get clientNAS = %d", ClientId); break;
|
|
||||||
case QMUX_TYPE_QOS: dbg_time("Get clientQOS = %d", ClientId); break;
|
|
||||||
case QMUX_TYPE_WMS: dbg_time("Get clientWMS = %d", ClientId); break;
|
|
||||||
case QMUX_TYPE_PDS: dbg_time("Get clientPDS = %d", ClientId); break;
|
|
||||||
case QMUX_TYPE_UIM: dbg_time("Get clientUIM = %d", ClientId); break;
|
|
||||||
case QMUX_TYPE_COEX: dbg_time("Get clientCOEX = %d", ClientId); break;
|
|
||||||
case QMUX_TYPE_WDS_ADMIN: dbg_time("Get clientWDA = %d", ClientId);
|
|
||||||
break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
return ClientId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int QmiWwanReleaseClientID(QMI_SERVICE_TYPE QMIType, UCHAR ClientId) {
|
|
||||||
UCHAR argv[] = {QMIType, ClientId};
|
|
||||||
QmiThreadSendQMI(ComposeQCTLMsg(QMICTL_RELEASE_CLIENT_ID_REQ, CtlReleaseClientIdReq, argv), NULL);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int QmiWwanInit(PROFILE_T *profile) {
|
|
||||||
unsigned i;
|
|
||||||
int ret;
|
|
||||||
PQCQMIMSG pResponse;
|
|
||||||
|
|
||||||
if (profile->proxy[0] && !strcmp(profile->proxy, LIBQMI_PROXY)) {
|
|
||||||
ret = libqmi_proxy_open(profile->qmichannel);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!profile->proxy[0]) {
|
|
||||||
for (i = 0; i < 10; i++) {
|
|
||||||
ret = QmiThreadSendQMITimeout(ComposeQCTLMsg(QMICTL_SYNC_REQ, NULL, NULL), NULL, 1 * 1000, __func__);
|
|
||||||
if (ret != ETIMEDOUT)
|
|
||||||
break;
|
|
||||||
sleep(1);
|
|
||||||
}
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
QmiThreadSendQMI(ComposeQCTLMsg(QMICTL_GET_VERSION_REQ, CtlGetVersionReq, NULL), &pResponse);
|
|
||||||
if (profile->qmap_mode) {
|
|
||||||
if (pResponse) {
|
|
||||||
if (pResponse->CTLMsg.QMICTLMsgHdrRsp.QMUXResult == 0 && pResponse->CTLMsg.QMICTLMsgHdrRsp.QMUXError == 0) {
|
|
||||||
uint8_t NumElements = 0;
|
|
||||||
|
|
||||||
for (NumElements = 0; NumElements < pResponse->CTLMsg.GetVersionRsp.NumElements; NumElements++) {
|
|
||||||
#if 0
|
|
||||||
dbg_time("QMUXType = %02x Version = %d.%d",
|
|
||||||
pResponse->CTLMsg.GetVersionRsp.TypeVersion[NumElements].QMUXType,
|
|
||||||
pResponse->CTLMsg.GetVersionRsp.TypeVersion[NumElements].MajorVersion,
|
|
||||||
pResponse->CTLMsg.GetVersionRsp.TypeVersion[NumElements].MinorVersion);
|
|
||||||
#endif
|
|
||||||
if (pResponse->CTLMsg.GetVersionRsp.TypeVersion[NumElements].QMUXType == QMUX_TYPE_WDS_ADMIN)
|
|
||||||
profile->qmap_version = (pResponse->CTLMsg.GetVersionRsp.TypeVersion[NumElements].MinorVersion > 16);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pResponse) free(pResponse);
|
|
||||||
qmiclientId[QMUX_TYPE_WDS] = QmiWwanGetClientID(QMUX_TYPE_WDS);
|
|
||||||
if (profile->enable_ipv6)
|
|
||||||
qmiclientId[QMUX_TYPE_WDS_IPV6] = QmiWwanGetClientID(QMUX_TYPE_WDS);
|
|
||||||
qmiclientId[QMUX_TYPE_DMS] = QmiWwanGetClientID(QMUX_TYPE_DMS);
|
|
||||||
qmiclientId[QMUX_TYPE_NAS] = QmiWwanGetClientID(QMUX_TYPE_NAS);
|
|
||||||
qmiclientId[QMUX_TYPE_UIM] = QmiWwanGetClientID(QMUX_TYPE_UIM);
|
|
||||||
qmiclientId[QMUX_TYPE_WDS_ADMIN] = QmiWwanGetClientID(QMUX_TYPE_WDS_ADMIN);
|
|
||||||
#ifdef CONFIG_COEX_WWAN_STATE
|
|
||||||
qmiclientId[QMUX_TYPE_COEX] = QmiWwanGetClientID(QMUX_TYPE_COEX);
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_ENABLE_QOS
|
|
||||||
qmiclientId[QMUX_TYPE_QOS] = QmiWwanGetClientID(QMUX_TYPE_QOS);
|
|
||||||
#endif
|
|
||||||
profile->wda_client = qmiclientId[QMUX_TYPE_WDS_ADMIN];
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int QmiWwanDeInit(void) {
|
|
||||||
unsigned int i;
|
|
||||||
for (i = 0; i < sizeof(qmiclientId)/sizeof(qmiclientId[0]); i++)
|
|
||||||
{
|
|
||||||
if (qmiclientId[i] != 0)
|
|
||||||
{
|
|
||||||
QmiWwanReleaseClientID((QMUX_TYPE_WDS_IPV6 == i ? QMUX_TYPE_WDS : i), qmiclientId[i]);
|
|
||||||
qmiclientId[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t qmi_proxy_read (int fd, void *buf, size_t size) {
|
|
||||||
ssize_t nreads;
|
|
||||||
PQCQMI_HDR pHdr = (PQCQMI_HDR)buf;
|
|
||||||
|
|
||||||
nreads = read(fd, pHdr, sizeof(QCQMI_HDR));
|
|
||||||
if (nreads == sizeof(QCQMI_HDR) && le16_to_cpu(pHdr->Length) < size) {
|
|
||||||
nreads += read(fd, pHdr+1, le16_to_cpu(pHdr->Length) + 1 - sizeof(QCQMI_HDR));
|
|
||||||
}
|
|
||||||
|
|
||||||
return nreads;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef QUECTEL_QMI_MERGE
|
|
||||||
static int QmiWwanMergeQmiRsp(void *buf, ssize_t *src_size) {
|
|
||||||
static QMI_MSG_PACKET s_QMIPacket;
|
|
||||||
QMI_MSG_HEADER *header = NULL;
|
|
||||||
ssize_t size = *src_size;
|
|
||||||
|
|
||||||
if((uint16_t)size < sizeof(QMI_MSG_HEADER))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
header = (QMI_MSG_HEADER *)buf;
|
|
||||||
if(le16_to_cpu(header->idenity) != MERGE_PACKET_IDENTITY || le16_to_cpu(header->version) != MERGE_PACKET_VERSION || le16_to_cpu(header->cur_len) > le16_to_cpu(header->total_len))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if(le16_to_cpu(header->cur_len) == le16_to_cpu(header->total_len)) {
|
|
||||||
*src_size = le16_to_cpu(header->total_len);
|
|
||||||
memcpy(buf, buf + sizeof(QMI_MSG_HEADER), *src_size);
|
|
||||||
s_QMIPacket.len = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(s_QMIPacket.buf + s_QMIPacket.len, buf + sizeof(QMI_MSG_HEADER), le16_to_cpu(header->cur_len));
|
|
||||||
s_QMIPacket.len += le16_to_cpu(header->cur_len);
|
|
||||||
|
|
||||||
if (le16_to_cpu(header->cur_len) < MERGE_PACKET_MAX_PAYLOAD_SIZE || s_QMIPacket.len >= le16_to_cpu(header->total_len)) {
|
|
||||||
memcpy(buf, s_QMIPacket.buf, s_QMIPacket.len);
|
|
||||||
*src_size = s_QMIPacket.len;
|
|
||||||
s_QMIPacket.len = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void * QmiWwanThread(void *pData) {
|
|
||||||
PROFILE_T *profile = (PROFILE_T *)pData;
|
|
||||||
const char *cdc_wdm = (const char *)profile->qmichannel;
|
|
||||||
int wait_for_request_quit = 0;
|
|
||||||
char num = cdc_wdm[strlen(cdc_wdm)-1];
|
|
||||||
|
|
||||||
if (profile->proxy[0]) {
|
|
||||||
if (!strncmp(profile->proxy, QUECTEL_QMI_PROXY, strlen(QUECTEL_QMI_PROXY))) {
|
|
||||||
snprintf(profile->proxy, sizeof(profile->proxy), "%s%c", QUECTEL_QMI_PROXY, num);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!strncmp(cdc_wdm, "/dev/mhi_IPCR", strlen("/dev/mhi_IPCR"))) {
|
|
||||||
snprintf(profile->proxy, sizeof(profile->proxy), "%s%c", QUECTEL_QRTR_PROXY, num);
|
|
||||||
}
|
|
||||||
else if (profile->qmap_mode > 1) {
|
|
||||||
snprintf(profile->proxy, sizeof(profile->proxy), "%s%c", QUECTEL_QMI_PROXY, num);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (profile->proxy[0])
|
|
||||||
cdc_wdm_fd = cm_open_proxy(profile->proxy);
|
|
||||||
else
|
|
||||||
cdc_wdm_fd = cm_open_dev(cdc_wdm);
|
|
||||||
|
|
||||||
if (cdc_wdm_fd == -1) {
|
|
||||||
dbg_time("%s Failed to open %s, errno: %d (%s)", __func__, cdc_wdm, errno, strerror(errno));
|
|
||||||
qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_DISCONNECTED);
|
|
||||||
pthread_exit(NULL);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbg_time("cdc_wdm_fd = %d", cdc_wdm_fd);
|
|
||||||
|
|
||||||
qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_CONNECTED);
|
|
||||||
while (1) {
|
|
||||||
struct pollfd pollfds[] = {{qmidevice_control_fd[1], POLLIN, 0}, {cdc_wdm_fd, POLLIN, 0}};
|
|
||||||
int ne, ret, nevents = sizeof(pollfds)/sizeof(pollfds[0]);
|
|
||||||
|
|
||||||
do {
|
|
||||||
ret = poll(pollfds, nevents, wait_for_request_quit ? 1000 : -1);
|
|
||||||
} while ((ret < 0) && (errno == EINTR));
|
|
||||||
|
|
||||||
if (ret == 0 && wait_for_request_quit) {
|
|
||||||
QmiThreadRecvQMI(NULL);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret <= 0) {
|
|
||||||
dbg_time("%s poll=%d, errno: %d (%s)", __func__, ret, errno, strerror(errno));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ne = 0; ne < nevents; ne++) {
|
|
||||||
int fd = pollfds[ne].fd;
|
|
||||||
short revents = pollfds[ne].revents;
|
|
||||||
|
|
||||||
//dbg_time("{%d, %x, %x}", pollfds[ne].fd, pollfds[ne].events, pollfds[ne].revents);
|
|
||||||
|
|
||||||
if (revents & (POLLERR | POLLHUP | POLLNVAL)) {
|
|
||||||
dbg_time("%s poll err/hup/inval", __func__);
|
|
||||||
dbg_time("poll fd = %d, events = 0x%04x", fd, revents);
|
|
||||||
if (fd == cdc_wdm_fd) {
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
if (revents & (POLLHUP | POLLNVAL)) //EC20 bug, Can get POLLERR
|
|
||||||
goto __QmiWwanThread_quit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((revents & POLLIN) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (fd == qmidevice_control_fd[1]) {
|
|
||||||
int triger_event;
|
|
||||||
if (read(fd, &triger_event, sizeof(triger_event)) == sizeof(triger_event)) {
|
|
||||||
//DBG("triger_event = 0x%x", triger_event);
|
|
||||||
switch (triger_event) {
|
|
||||||
case RIL_REQUEST_QUIT:
|
|
||||||
goto __QmiWwanThread_quit;
|
|
||||||
break;
|
|
||||||
case SIG_EVENT_STOP:
|
|
||||||
wait_for_request_quit = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fd == cdc_wdm_fd) {
|
|
||||||
ssize_t nreads;
|
|
||||||
PQCQMIMSG pResponse = (PQCQMIMSG)cm_recv_buf;
|
|
||||||
|
|
||||||
if (!profile->proxy[0])
|
|
||||||
nreads = read(fd, cm_recv_buf, sizeof(cm_recv_buf));
|
|
||||||
else
|
|
||||||
nreads = qmi_proxy_read(fd, cm_recv_buf, sizeof(cm_recv_buf));
|
|
||||||
//dbg_time("%s read=%d errno: %d (%s)", __func__, (int)nreads, errno, strerror(errno));
|
|
||||||
if (nreads <= 0) {
|
|
||||||
dbg_time("%s read=%d errno: %d (%s)", __func__, (int)nreads, errno, strerror(errno));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#ifdef QUECTEL_QMI_MERGE
|
|
||||||
if((profile->qmap_mode == 0 || profile->qmap_mode == 1) && QmiWwanMergeQmiRsp(cm_recv_buf, &nreads))
|
|
||||||
continue;
|
|
||||||
#endif
|
|
||||||
if (nreads != (le16_to_cpu(pResponse->QMIHdr.Length) + 1)) {
|
|
||||||
dbg_time("%s nreads=%d, pQCQMI->QMIHdr.Length = %d", __func__, (int)nreads, le16_to_cpu(pResponse->QMIHdr.Length));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
QmiThreadRecvQMI(pResponse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__QmiWwanThread_quit:
|
|
||||||
if (cdc_wdm_fd != -1) { close(cdc_wdm_fd); cdc_wdm_fd = -1; }
|
|
||||||
qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_DISCONNECTED);
|
|
||||||
QmiThreadRecvQMI(NULL); //main thread may pending on QmiThreadSendQMI()
|
|
||||||
dbg_time("%s exit", __func__);
|
|
||||||
pthread_exit(NULL);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct qmi_device_ops qmiwwan_qmidev_ops = {
|
|
||||||
.init = QmiWwanInit,
|
|
||||||
.deinit = QmiWwanDeInit,
|
|
||||||
.send = QmiWwanSendQMI,
|
|
||||||
.read = QmiWwanThread,
|
|
||||||
};
|
|
||||||
|
|
||||||
uint8_t qmi_over_mbim_get_client_id(uint8_t QMIType) {
|
|
||||||
return QmiWwanGetClientID(QMIType);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t qmi_over_mbim_release_client_id(uint8_t QMIType, uint8_t ClientId) {
|
|
||||||
return QmiWwanReleaseClientID(QMIType, ClientId);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,357 +0,0 @@
|
|||||||
Release Notes
|
|
||||||
|
|
||||||
[V1.6.8]
|
|
||||||
Date: 3/4/2025
|
|
||||||
enhancement:
|
|
||||||
1. add QMI dialing status report
|
|
||||||
fix:
|
|
||||||
1. fix some bugs
|
|
||||||
|
|
||||||
[V1.6.7]
|
|
||||||
Date: 5/17/2024
|
|
||||||
enhancement:
|
|
||||||
1. optimize -a parameter
|
|
||||||
fix:
|
|
||||||
1. fix the multiple dialing issue on the SDX35 platform
|
|
||||||
|
|
||||||
[V1.6.6]
|
|
||||||
Date: 1/12/2024
|
|
||||||
enhancement:
|
|
||||||
1. support SDX35 platform
|
|
||||||
|
|
||||||
[V1.6.5]
|
|
||||||
Date: 7/3/2023
|
|
||||||
enhancement:
|
|
||||||
1. Fix the issue of qmi client id leakage caused by kill 9 killing the client of quectel-qmi-proxy
|
|
||||||
2. Fix wds_ipv6 client ID can't be released issue
|
|
||||||
3. Fix wds_ipv6 client ID can't be released issue
|
|
||||||
4. Resolve PDP_ Context&Profile_ The issue of index mixing
|
|
||||||
5. Add parameter - d to obtain IP and DNS information through qmi
|
|
||||||
6. Fix mbim dialing. When the user does not specify apn through - s, prompt the user and exit the dialing program
|
|
||||||
7. Prioritize the use of IP commands for optimization, and use ifconfig if not available
|
|
||||||
8. Optimize and add/remove copyright
|
|
||||||
fix:
|
|
||||||
|
|
||||||
[V1.6.4]
|
|
||||||
Date: 9/7/2022
|
|
||||||
enhancement:
|
|
||||||
1. set cflags as -Wall -Wextra -Werror -O1, and fix compile errors
|
|
||||||
2. some code refactoring
|
|
||||||
3. add quectel-qrtr-proxy
|
|
||||||
fix:
|
|
||||||
1. netmask error when use ifconfig on little endian cpu
|
|
||||||
|
|
||||||
[V1.6.2]
|
|
||||||
Date: 11/18/2021
|
|
||||||
enhancement:
|
|
||||||
1. support 'LTE && WiFi Coexistence Solution via QMI'.
|
|
||||||
If customer want use this feature, need enable CONFIG_COEX_WWAN_STATE in QMIThread.h
|
|
||||||
|
|
||||||
[V1.6.1]
|
|
||||||
Date: 7/20/2021
|
|
||||||
enhancement:
|
|
||||||
1. add requestGetCellInfoList requestRadioPower
|
|
||||||
2. add QMI OVER MBIM
|
|
||||||
3. support qrtr and rmnet
|
|
||||||
4. support RG500U PCIE
|
|
||||||
5. add qos service && get qos flow data_rate_max func
|
|
||||||
fix:
|
|
||||||
1. mbim: increase mbim open timeout to 3 seconds. some modem take long time for open cmd.
|
|
||||||
2. support MsChapV2
|
|
||||||
3. mbim: invalid memory access when only get one DNS
|
|
||||||
4. some bug fix for use AT Command to setup data call
|
|
||||||
|
|
||||||
[V1.6.0.26]
|
|
||||||
Date: 4/22/2021
|
|
||||||
enhancement:
|
|
||||||
1. add lots of log file to show how to use this tool
|
|
||||||
2. support pcie mhi multiple call
|
|
||||||
3. at command: support EC200U/EC200T/EC200S/RG801H/RG500U/
|
|
||||||
fix:
|
|
||||||
1. mbim-proxy: fix errors on big endian cpu, ignore mbim open/close cmd from quectel-cm
|
|
||||||
|
|
||||||
[V1.6.0.25]
|
|
||||||
Date: 4/8/2021
|
|
||||||
enhancement:
|
|
||||||
fix:
|
|
||||||
1. fix compile error when use gcc 9.3.0
|
|
||||||
2. fix yocto 'QA Issue: No GNU_HASH in the ELF binary'
|
|
||||||
|
|
||||||
[V1.6.0.24]
|
|
||||||
Date: 3/9/2021
|
|
||||||
enhancement:
|
|
||||||
1. '-p [quectel-][qmi|mbim]-proxy', can connect to quectel/libqmi/libmbim's proxy, even only one data
|
|
||||||
2. set variable s_9x07 as 1 (from 0), most of modems are base on MDM90x7 and later QCOM chip.
|
|
||||||
fix:
|
|
||||||
1. define CHAR as signed char
|
|
||||||
2. mofidy Makefile to generate more compile warnnings and fix them
|
|
||||||
|
|
||||||
[V1.6.0.23]
|
|
||||||
Date: 2/26/2021
|
|
||||||
enhancement:
|
|
||||||
1. support 'AT+QNETDEVCTL' (not release)
|
|
||||||
fix:
|
|
||||||
1. modify help/usage
|
|
||||||
2. fix some memroy access error in mbim-cm.c
|
|
||||||
|
|
||||||
[V1.6.0.22]
|
|
||||||
Date: 2/4/2021
|
|
||||||
enhancement:
|
|
||||||
1. support connect to libqmi's qmi-proxy
|
|
||||||
2. only allow ' 0/1/2/none/pap/chap' for auth of '-s'
|
|
||||||
3. '-m iface-idx' bind QMAP data call to wwan0_<iface_idx>
|
|
||||||
fix:
|
|
||||||
|
|
||||||
[V1.6.0.21]
|
|
||||||
Date: 1/28/2021
|
|
||||||
enhancement:
|
|
||||||
1. print 5G signal
|
|
||||||
fix:
|
|
||||||
1. fix compile errors: -Werror=format-truncation=
|
|
||||||
|
|
||||||
[V1.6.0.20]
|
|
||||||
Date: 12/29/2020
|
|
||||||
enhancement:
|
|
||||||
1. Code refactoring
|
|
||||||
2. support 'AT+QNETDEVCTL' (not release)
|
|
||||||
fix:
|
|
||||||
|
|
||||||
[V1.6.0.19]
|
|
||||||
Date: 12/4/2020
|
|
||||||
enhancement:
|
|
||||||
1. if 'udhcpc's default.script' missed, directy set ip/dns/route by 'ip' co,mand
|
|
||||||
fix:
|
|
||||||
|
|
||||||
[V1.6.0.18]
|
|
||||||
Date: 12/4/2020
|
|
||||||
enhancement:
|
|
||||||
1. Code refactoring
|
|
||||||
fix:
|
|
||||||
|
|
||||||
[V1.6.0.17]
|
|
||||||
Date: 8/25/2020
|
|
||||||
enhancement:
|
|
||||||
1. support MBIM multi-call
|
|
||||||
2. support unisoc RG500U mbim
|
|
||||||
3. QUECTEL_QMI_MERGE: some SOC can not read more then 64 bytes (QMI)data via USB Endpoint 0
|
|
||||||
fix:
|
|
||||||
|
|
||||||
[V1.6.0.15]
|
|
||||||
Date: 7/24/2020
|
|
||||||
enhancement:
|
|
||||||
fix:
|
|
||||||
1. QMAP multi-call, AT+CFUN=4 then AT+CFUN=1, only one call can obtain IP by DHCP
|
|
||||||
|
|
||||||
[V1.6.0.14]
|
|
||||||
Date: 6/10/2020
|
|
||||||
enhancement:
|
|
||||||
1. support X55's GobiNet LOOPBACK
|
|
||||||
fix:
|
|
||||||
1. very old uclib do not support htole32 and pthread_condattr_setclock
|
|
||||||
2. pthread_cond_wait tv_nsec >= 1000000000U is wrong
|
|
||||||
3. do not close socket in udhcpc.c ifc_get_addr()
|
|
||||||
|
|
||||||
[V1.6.0.13]
|
|
||||||
Date: 6/9/2020
|
|
||||||
enhancement:
|
|
||||||
1. add some example for openwrt, marco 'QL_OPENWER_NETWORK_SETUP'
|
|
||||||
fix:
|
|
||||||
|
|
||||||
[V1.6.0.12]
|
|
||||||
Date: 5/29/2020
|
|
||||||
enhancement:
|
|
||||||
fix:
|
|
||||||
1. some EM12's usb-net-qmi/mbim interface is at 8 (not 4)
|
|
||||||
|
|
||||||
[V1.6.0.11]
|
|
||||||
Date: 5/28/2020
|
|
||||||
enhancement:
|
|
||||||
fix:
|
|
||||||
1. fix mbim debug on Big Endian CPU
|
|
||||||
|
|
||||||
[V1.6.0.10]
|
|
||||||
Date: 5/25/2020
|
|
||||||
enhancement:
|
|
||||||
fix:
|
|
||||||
1. set QMAP .ul_data_aggregation_max_datagrams to 11 (from 16)
|
|
||||||
|
|
||||||
[V1.6.0.9]
|
|
||||||
Date: 5/22/2020
|
|
||||||
enhancement:
|
|
||||||
fix:
|
|
||||||
1. dial fail when register to 5G-SA
|
|
||||||
|
|
||||||
[V1.6.0.8]
|
|
||||||
Date: 4/30/2020
|
|
||||||
enhancement:
|
|
||||||
1. support '-b' to seletc brige mode
|
|
||||||
fix:
|
|
||||||
|
|
||||||
[V1.6.0.7]
|
|
||||||
Date: 4/29/2020
|
|
||||||
enhancement:
|
|
||||||
1. support QMAP multi-call for qmi_wwan_q and pcie_mhi 's rmnet driver
|
|
||||||
fix:
|
|
||||||
|
|
||||||
[V1.6.0.6]
|
|
||||||
Date: 4/20/2020
|
|
||||||
enhancement:
|
|
||||||
1. support '-k pdn_idx' to hangup call '-n pdn_idx'
|
|
||||||
fix:
|
|
||||||
1. fix set dl_minimum_padding as 0, modems do not support this featrue
|
|
||||||
|
|
||||||
[V1.6.0.5]
|
|
||||||
Date: 4/10/2020
|
|
||||||
enhancement:
|
|
||||||
1. support X55's QMAPV5 for PCIE
|
|
||||||
fix:
|
|
||||||
|
|
||||||
[V1.6.0.3]
|
|
||||||
Date: 4/8/2020
|
|
||||||
enhancement:
|
|
||||||
1. support multi-modems all use multi-data-calls
|
|
||||||
fix:
|
|
||||||
|
|
||||||
[V1.6.0.2]
|
|
||||||
Date: 4/7/2020
|
|
||||||
enhancement:
|
|
||||||
1. support X55's QMAPV5 for USB
|
|
||||||
fix:
|
|
||||||
|
|
||||||
[V1.6.0.1]
|
|
||||||
Date: 4/1/2020
|
|
||||||
enhancement:
|
|
||||||
1. support QMAP UL AGG (multi data call)
|
|
||||||
fix:
|
|
||||||
1. some EM12's usb-net-qmi/mbim interface is at 8 (not 4)
|
|
||||||
|
|
||||||
[V1.5.9]
|
|
||||||
Date: 3/4/2020
|
|
||||||
enhancement:
|
|
||||||
1. support pcie mhi multi-APN data call
|
|
||||||
3. support QMAP UL AGG (single data call)
|
|
||||||
fix:
|
|
||||||
1. set 4 bytes aligned for mbim parameters, or cause dial mbim call fail
|
|
||||||
|
|
||||||
[V1.5.8]
|
|
||||||
Date: 2/18/2020
|
|
||||||
enhancement:
|
|
||||||
1. support '-l 14' X55's loopback function
|
|
||||||
fix:
|
|
||||||
|
|
||||||
[V1.5.7]
|
|
||||||
Date: 2/6/2020
|
|
||||||
enhancement:
|
|
||||||
1. support '-u usbmon_log_file' to catch usbmon log
|
|
||||||
fix:
|
|
||||||
|
|
||||||
[V1.5.6]
|
|
||||||
Date: 1/20/202
|
|
||||||
enhancement:
|
|
||||||
1. show driver name and version
|
|
||||||
2. support PCSCF
|
|
||||||
3. support bridge in mbim
|
|
||||||
fix:
|
|
||||||
|
|
||||||
[V1.5.5]
|
|
||||||
Date: 12/31/2019
|
|
||||||
enhancement:
|
|
||||||
fix:
|
|
||||||
1. fix some memory access bug in mbim-cm.c
|
|
||||||
|
|
||||||
[WCDMA<E_QConnectManager_Linux&Android_V1.5.4]
|
|
||||||
Date: 12/17/2019
|
|
||||||
enhancement:
|
|
||||||
1. Add copyright
|
|
||||||
2. auto detect pcie mhi /dev/mhi*
|
|
||||||
fix:
|
|
||||||
|
|
||||||
[WCDMA<E_QConnectManager_Linux&Android_V1.5.3]
|
|
||||||
Date: 2019/12/11
|
|
||||||
enhancement:
|
|
||||||
1. support show SignalInfo, controlled by macro CONFIG_SIGNALINFO
|
|
||||||
2. support show 5G_NSA/5G_NA
|
|
||||||
3. support Microsoft Extend MBIM message
|
|
||||||
fix:
|
|
||||||
1. quectel-qmi-proxy bugs on Big-Endian CPU
|
|
||||||
|
|
||||||
[WCDMA<E_QConnectManager_Linux&Android_V1.5.2]
|
|
||||||
Date: 12/2/2019
|
|
||||||
enhancement:
|
|
||||||
1. support requestGetSignalInfo()
|
|
||||||
fix:
|
|
||||||
|
|
||||||
[WCDMA<E_QConnectManager_Linux&Android_V1.4.1]
|
|
||||||
Date: 10/23/2019
|
|
||||||
enhancement:
|
|
||||||
1. support QMI_CTL_REVOKE_CLIENT_ID_IND (Quectel define QMI)
|
|
||||||
2. add copyright
|
|
||||||
fix:
|
|
||||||
1. remove SIGUSR
|
|
||||||
|
|
||||||
[WCDMA<E_QConnectManager_Linux&Android_V1.3.10]
|
|
||||||
Date: 10/14/2019
|
|
||||||
enhancement:
|
|
||||||
1. increase retry interval
|
|
||||||
fix:
|
|
||||||
|
|
||||||
[WCDMA<E_QConnectManager_Linux&Android_V1.2.1]
|
|
||||||
Date: 2019/02/26
|
|
||||||
enhancement:
|
|
||||||
1. Implement help message.
|
|
||||||
|
|
||||||
root@ubuntu:# ./quectel-CM -h
|
|
||||||
[02-26_10:39:21:353] Usage: ./quectel-CM [options]
|
|
||||||
[02-26_10:39:21:353] -s [apn [user password auth]] Set apn/user/password/auth get from your network provider
|
|
||||||
[02-26_10:39:21:353] -p pincode Verify sim card pin if sim card is locked
|
|
||||||
[02-26_10:39:21:353] -f logfilename Save log message of this program to file
|
|
||||||
[02-26_10:39:21:353] -i interface Specify network interface(default auto-detect)
|
|
||||||
[02-26_10:39:21:353] -4 IPv4 protocol
|
|
||||||
[02-26_10:39:21:353] -6 IPv6 protocol
|
|
||||||
[02-26_10:39:21:353] -m muxID Specify muxid when set multi-pdn data connection.
|
|
||||||
[02-26_10:39:21:353] -n channelID Specify channelID when set multi-pdn data connection(default 1).
|
|
||||||
[02-26_10:39:21:353] [Examples]
|
|
||||||
[02-26_10:39:21:353] Example 1: ./quectel-CM
|
|
||||||
[02-26_10:39:21:353] Example 2: ./quectel-CM -s 3gnet
|
|
||||||
[02-26_10:39:21:353] Example 3: ./quectel-CM -s 3gnet carl 1234 0 -p 1234 -f gobinet_log.txt
|
|
||||||
root@ubuntu:#
|
|
||||||
2. Support bridge mode when set multi-pdn data connections.
|
|
||||||
3. Host device can access network in bridge mode.
|
|
||||||
|
|
||||||
[WCDMA<E_QConnectManager_Linux&Android_V1.1.46]
|
|
||||||
Date: 2019/02/18
|
|
||||||
enhancement:
|
|
||||||
1. support only IPV6 data call. quectel-CM now support three dialing methods: IPV4 only, IPV6 only, IPV4V6.
|
|
||||||
./quectel-CM -4(or no argument) only IPV4
|
|
||||||
-6 only IPV6
|
|
||||||
-4 -6 IPV4 && IPV6
|
|
||||||
|
|
||||||
[WCDMA<E_QConnectManager_Linux&Android_V1.1.45]
|
|
||||||
Date: 2018/09/13
|
|
||||||
enhancement:
|
|
||||||
1. support EG12 PCIE interface
|
|
||||||
|
|
||||||
[WCDMA<E_QConnectManager_Linux&Android_V1.1.44]
|
|
||||||
Date: 2018/09/10
|
|
||||||
enhancement:
|
|
||||||
1. support setup IPV4&IPV6 data call.
|
|
||||||
|
|
||||||
[WCDMA<E_QConnectManager_Linux&Android_V1.1.43]
|
|
||||||
[WCDMA<E_QConnectManager_Linux&Android_V1.1.42]
|
|
||||||
Date: 2018/08/29
|
|
||||||
enhancement:
|
|
||||||
1. support QMI_WWAN's QMAP fucntion and bridge mode, please contact Quectel FAE to get qmi_wwan.c patch.
|
|
||||||
when enable QMI_WWAN's QMAP IP Mux function, must run 'quectel-qmi-proxy -d /dev/cdc-wdmX' before quectel-CM
|
|
||||||
|
|
||||||
[WCDMA<E_QConnectManager_Linux&Android_V1.1.41]
|
|
||||||
Date: 2018/05/24
|
|
||||||
enhancement:
|
|
||||||
1. fix a cdma data call error
|
|
||||||
|
|
||||||
[WCDMA<E_QConnectManager_Linux&Android_V1.1.40]
|
|
||||||
Date: 2018/05/12
|
|
||||||
enhancement:
|
|
||||||
1. support GobiNet's QMAP fucntion and bridge mode.
|
|
||||||
'Quectel_WCDMA<E_Linux&Android_GobiNet_Driver_V1.3.5' and later version is required to use QMAP and bridge mode.
|
|
||||||
for detail, please refer to GobiNet Driver
|
|
||||||
|
|
||||||
@@ -1,283 +0,0 @@
|
|||||||
/* //device/system/reference-ril/at_tok.c
|
|
||||||
**
|
|
||||||
** Copyright 2006, The Android Open Source Project
|
|
||||||
**
|
|
||||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
** you may not use this file except in compliance with the License.
|
|
||||||
** You may obtain a copy of the License at
|
|
||||||
**
|
|
||||||
** http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
**
|
|
||||||
** Unless required by applicable law or agreed to in writing, software
|
|
||||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
** See the License for the specific language governing permissions and
|
|
||||||
** limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "at_tok.h"
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts tokenizing an AT response string
|
|
||||||
* returns -1 if this is not a valid response string, 0 on success.
|
|
||||||
* updates *p_cur with current position
|
|
||||||
*/
|
|
||||||
int at_tok_start(char **p_cur)
|
|
||||||
{
|
|
||||||
if (*p_cur == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// skip prefix
|
|
||||||
// consume "^[^:]:"
|
|
||||||
|
|
||||||
*p_cur = strchr(*p_cur, ':');
|
|
||||||
|
|
||||||
if (*p_cur == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
(*p_cur)++;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void skipWhiteSpace(char **p_cur)
|
|
||||||
{
|
|
||||||
if (*p_cur == NULL) return;
|
|
||||||
|
|
||||||
while (**p_cur != '\0' && isspace(**p_cur)) {
|
|
||||||
(*p_cur)++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void skipNextComma(char **p_cur)
|
|
||||||
{
|
|
||||||
if (*p_cur == NULL) return;
|
|
||||||
|
|
||||||
while (**p_cur != '\0' && **p_cur != ',') {
|
|
||||||
(*p_cur)++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (**p_cur == ',') {
|
|
||||||
(*p_cur)++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static char * nextTok(char **p_cur)
|
|
||||||
{
|
|
||||||
char *ret = NULL;
|
|
||||||
|
|
||||||
skipWhiteSpace(p_cur);
|
|
||||||
|
|
||||||
if (*p_cur == NULL) {
|
|
||||||
ret = NULL;
|
|
||||||
} else if (**p_cur == '"') {
|
|
||||||
(*p_cur)++;
|
|
||||||
ret = strsep(p_cur, "\"");
|
|
||||||
skipNextComma(p_cur);
|
|
||||||
} else {
|
|
||||||
ret = strsep(p_cur, ",");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the next integer in the AT response line and places it in *p_out
|
|
||||||
* returns 0 on success and -1 on fail
|
|
||||||
* updates *p_cur
|
|
||||||
* "base" is the same as the base param in strtol
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int at_tok_nextint_base(char **p_cur, int *p_out, int base, int uns)
|
|
||||||
{
|
|
||||||
char *ret;
|
|
||||||
|
|
||||||
if (*p_cur == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = nextTok(p_cur);
|
|
||||||
|
|
||||||
if (ret == NULL) {
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
long l;
|
|
||||||
char *end;
|
|
||||||
|
|
||||||
if (uns)
|
|
||||||
l = strtoul(ret, &end, base);
|
|
||||||
else
|
|
||||||
l = strtol(ret, &end, base);
|
|
||||||
|
|
||||||
*p_out = (int)l;
|
|
||||||
|
|
||||||
if (end == ret) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the next base 10 integer in the AT response line
|
|
||||||
* and places it in *p_out
|
|
||||||
* returns 0 on success and -1 on fail
|
|
||||||
* updates *p_cur
|
|
||||||
*/
|
|
||||||
int at_tok_nextint(char **p_cur, int *p_out)
|
|
||||||
{
|
|
||||||
return at_tok_nextint_base(p_cur, p_out, 10, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the next base 16 integer in the AT response line
|
|
||||||
* and places it in *p_out
|
|
||||||
* returns 0 on success and -1 on fail
|
|
||||||
* updates *p_cur
|
|
||||||
*/
|
|
||||||
int at_tok_nexthexint(char **p_cur, int *p_out)
|
|
||||||
{
|
|
||||||
return at_tok_nextint_base(p_cur, p_out, 16, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int at_tok_nextbool(char **p_cur, char *p_out)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
ret = at_tok_nextint(p_cur, &result);
|
|
||||||
|
|
||||||
if (ret < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// booleans should be 0 or 1
|
|
||||||
if (!(result == 0 || result == 1)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p_out != NULL) {
|
|
||||||
*p_out = (char)result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int at_tok_nextstr(char **p_cur, char **p_out)
|
|
||||||
{
|
|
||||||
if (*p_cur == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*p_out = nextTok(p_cur);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** returns 1 on "has more tokens" and 0 if no */
|
|
||||||
int at_tok_hasmore(char **p_cur)
|
|
||||||
{
|
|
||||||
return ! (*p_cur == NULL || **p_cur == '\0');
|
|
||||||
}
|
|
||||||
|
|
||||||
int at_tok_count(const char *in_line)
|
|
||||||
{
|
|
||||||
int commas = 0;
|
|
||||||
const char *p;
|
|
||||||
|
|
||||||
if (!in_line)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (p = in_line; *p != '\0' ; p++) {
|
|
||||||
if (*p == ',') commas++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return commas;
|
|
||||||
}
|
|
||||||
|
|
||||||
//fmt: d ~ int, x ~ hexint, b ~ bool, s ~ str
|
|
||||||
int at_tok_scanf(const char *in_line, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
int n = 0;
|
|
||||||
int err;
|
|
||||||
va_list ap;
|
|
||||||
const char *p = fmt;
|
|
||||||
void *d;
|
|
||||||
void *dump;
|
|
||||||
static char s_line[1024];
|
|
||||||
char *line = s_line;
|
|
||||||
|
|
||||||
if (!in_line)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
strncpy(s_line, in_line, sizeof(s_line) - 1);
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
|
|
||||||
err = at_tok_start(&line);
|
|
||||||
if (err < 0) goto error;
|
|
||||||
|
|
||||||
for (; *p; p++) {
|
|
||||||
if (*p == ',' || *p == ' ')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (*p != '%') {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
p++;
|
|
||||||
|
|
||||||
d = va_arg(ap, void *);
|
|
||||||
if (!d)
|
|
||||||
d = &dump;
|
|
||||||
|
|
||||||
if (!at_tok_hasmore(&line))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (*line == '-' && *(line + 1) == ',') {
|
|
||||||
line += 2;
|
|
||||||
n++;
|
|
||||||
if (*p == 'd')
|
|
||||||
*(int *)d = -1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(*p) {
|
|
||||||
case 'd':
|
|
||||||
err = at_tok_nextint(&line, (int *)d);
|
|
||||||
if (err < 0) goto error;
|
|
||||||
break;
|
|
||||||
case 'x':
|
|
||||||
err = at_tok_nexthexint(&line, (int *)d);
|
|
||||||
if (err < 0) goto error;
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
err = at_tok_nextbool(&line, (char *)d);
|
|
||||||
if (err < 0) goto error;
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
err = at_tok_nextstr(&line, (char **)d); //if strdup(line), here return free memory to caller
|
|
||||||
if (err < 0) goto error;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto error;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
error:
|
|
||||||
//free(line);
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/* //device/system/reference-ril/at_tok.h
|
|
||||||
**
|
|
||||||
** Copyright 2006, The Android Open Source Project
|
|
||||||
**
|
|
||||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
** you may not use this file except in compliance with the License.
|
|
||||||
** You may obtain a copy of the License at
|
|
||||||
**
|
|
||||||
** http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
**
|
|
||||||
** Unless required by applicable law or agreed to in writing, software
|
|
||||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
** See the License for the specific language governing permissions and
|
|
||||||
** limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef AT_TOK_H
|
|
||||||
#define AT_TOK_H 1
|
|
||||||
|
|
||||||
int at_tok_start(char **p_cur);
|
|
||||||
int at_tok_nextint(char **p_cur, int *p_out);
|
|
||||||
int at_tok_nexthexint(char **p_cur, int *p_out);
|
|
||||||
|
|
||||||
int at_tok_nextbool(char **p_cur, char *p_out);
|
|
||||||
int at_tok_nextstr(char **p_cur, char **out);
|
|
||||||
|
|
||||||
int at_tok_hasmore(char **p_cur);
|
|
||||||
int at_tok_count(const char *in_line);
|
|
||||||
int at_tok_scanf(const char *line, const char *fmt, ...);
|
|
||||||
|
|
||||||
#endif /*AT_TOK_H */
|
|
||||||
|
|
||||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,152 +0,0 @@
|
|||||||
/* //device/system/reference-ril/atchannel.h
|
|
||||||
**
|
|
||||||
** Copyright 2006, The Android Open Source Project
|
|
||||||
**
|
|
||||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
** you may not use this file except in compliance with the License.
|
|
||||||
** You may obtain a copy of the License at
|
|
||||||
**
|
|
||||||
** http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
**
|
|
||||||
** Unless required by applicable law or agreed to in writing, software
|
|
||||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
** See the License for the specific language governing permissions and
|
|
||||||
** limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ATCHANNEL_H
|
|
||||||
#define ATCHANNEL_H 1
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* define AT_DEBUG to send AT traffic to /tmp/radio-at.log" */
|
|
||||||
#define AT_DEBUG 0
|
|
||||||
|
|
||||||
#if AT_DEBUG
|
|
||||||
extern void AT_DUMP(const char* prefix, const char* buff, int len);
|
|
||||||
#else
|
|
||||||
#define AT_DUMP(prefix,buff,len) do{}while(0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define AT_ERROR_GENERIC -1
|
|
||||||
#define AT_ERROR_COMMAND_PENDING -2
|
|
||||||
#define AT_ERROR_CHANNEL_CLOSED -3
|
|
||||||
#define AT_ERROR_TIMEOUT -4
|
|
||||||
#define AT_ERROR_INVALID_THREAD -5 /* AT commands may not be issued from
|
|
||||||
reader thread (or unsolicited response
|
|
||||||
callback */
|
|
||||||
#define AT_ERROR_INVALID_RESPONSE -6 /* eg an at_send_command_singleline that
|
|
||||||
did not get back an intermediate
|
|
||||||
response */
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
NO_RESULT, /* no intermediate response expected */
|
|
||||||
NUMERIC, /* a single intermediate response starting with a 0-9 */
|
|
||||||
SINGLELINE, /* a single intermediate response starting with a prefix */
|
|
||||||
MULTILINE /* multiple line intermediate response
|
|
||||||
starting with a prefix */
|
|
||||||
} ATCommandType;
|
|
||||||
|
|
||||||
/** a singly-lined list of intermediate responses */
|
|
||||||
typedef struct ATLine {
|
|
||||||
struct ATLine *p_next;
|
|
||||||
char *line;
|
|
||||||
} ATLine;
|
|
||||||
|
|
||||||
/** Free this with at_response_free() */
|
|
||||||
typedef struct {
|
|
||||||
int success; /* true if final response indicates
|
|
||||||
success (eg "OK") */
|
|
||||||
char *finalResponse; /* eg OK, ERROR */
|
|
||||||
ATLine *p_intermediates; /* any intermediate responses */
|
|
||||||
} ATResponse;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* a user-provided unsolicited response handler function
|
|
||||||
* this will be called from the reader thread, so do not block
|
|
||||||
* "s" is the line, and "sms_pdu" is either NULL or the PDU response
|
|
||||||
* for multi-line TS 27.005 SMS PDU responses (eg +CMT:)
|
|
||||||
*/
|
|
||||||
typedef void (*ATUnsolHandler)(const char *s, const char *sms_pdu);
|
|
||||||
|
|
||||||
int at_open(int fd, ATUnsolHandler h, int proxy);
|
|
||||||
void at_close();
|
|
||||||
|
|
||||||
/* This callback is invoked on the command thread.
|
|
||||||
You should reset or handshake here to avoid getting out of sync */
|
|
||||||
void at_set_on_timeout(void (*onTimeout)(void));
|
|
||||||
/* This callback is invoked on the reader thread (like ATUnsolHandler)
|
|
||||||
when the input stream closes before you call at_close
|
|
||||||
(not when you call at_close())
|
|
||||||
You should still call at_close()
|
|
||||||
It may also be invoked immediately from the current thread if the read
|
|
||||||
channel is already closed */
|
|
||||||
void at_set_on_reader_closed(void (*onClose)(void));
|
|
||||||
|
|
||||||
int at_send_command_singleline (const char *command,
|
|
||||||
const char *responsePrefix,
|
|
||||||
ATResponse **pp_outResponse);
|
|
||||||
|
|
||||||
int at_send_command_numeric (const char *command,
|
|
||||||
ATResponse **pp_outResponse);
|
|
||||||
|
|
||||||
int at_send_command_multiline (const char *command,
|
|
||||||
const char *responsePrefix,
|
|
||||||
ATResponse **pp_outResponse);
|
|
||||||
|
|
||||||
int at_send_command_raw (const char *command,
|
|
||||||
const char *raw_data, unsigned int raw_len,
|
|
||||||
const char *responsePrefix,
|
|
||||||
ATResponse **pp_outResponse);
|
|
||||||
|
|
||||||
int at_handshake();
|
|
||||||
|
|
||||||
int at_send_command (const char *command, ATResponse **pp_outResponse);
|
|
||||||
|
|
||||||
int at_send_command_sms (const char *command, const char *pdu,
|
|
||||||
const char *responsePrefix,
|
|
||||||
ATResponse **pp_outResponse);
|
|
||||||
|
|
||||||
void at_response_free(ATResponse *p_response);
|
|
||||||
|
|
||||||
int strStartsWith(const char *line, const char *prefix);
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
CME_ERROR_NON_CME = -1,
|
|
||||||
CME_SUCCESS = 0,
|
|
||||||
|
|
||||||
CME_OPERATION_NOT_ALLOWED = 3,
|
|
||||||
CME_OPERATION_NOT_SUPPORTED = 4,
|
|
||||||
CME_PH_SIM_PIN= 5,
|
|
||||||
CME_PH_FSIM_PIN = 6,
|
|
||||||
CME_PH_FSIM_PUK = 7,
|
|
||||||
CME_SIM_NOT_INSERTED =10,
|
|
||||||
CME_SIM_PIN_REQUIRED = 11,
|
|
||||||
CME_SIM_PUK_REQUIRED = 12,
|
|
||||||
CME_FAILURE = 13,
|
|
||||||
CME_SIM_BUSY = 14,
|
|
||||||
CME_SIM_WRONG = 15,
|
|
||||||
CME_INCORRECT_PASSWORD = 16,
|
|
||||||
CME_SIM_PIN2_REQUIRED = 17,
|
|
||||||
CME_SIM_PUK2_REQUIRED = 18,
|
|
||||||
CME_MEMORY_FULL = 20,
|
|
||||||
CME_INVALID_INDEX = 21,
|
|
||||||
CME_NOT_FOUND = 22,
|
|
||||||
CME_MEMORY_FAILURE = 23,
|
|
||||||
CME_STRING_TO_LONG = 24,
|
|
||||||
CME_INVALID_CHAR = 25,
|
|
||||||
CME_DIALSTR_TO_LONG = 26,
|
|
||||||
CME_INVALID_DIALCHAR = 27,
|
|
||||||
} AT_CME_Error;
|
|
||||||
|
|
||||||
AT_CME_Error at_get_cme_error(const ATResponse *p_response);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*ATCHANNEL_H*/
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
# -*- Autoconf -*-
|
|
||||||
# Process this file with autoconf to produce a configure script.
|
|
||||||
|
|
||||||
AC_PREREQ([2.61])
|
|
||||||
AC_INIT([quectel-CM], [1.0], [xxx@xxx.xxx])
|
|
||||||
AC_CONFIG_HEADERS([config.h])
|
|
||||||
|
|
||||||
# Checks for programs.
|
|
||||||
AC_PROG_CC
|
|
||||||
|
|
||||||
# Checks for libraries.
|
|
||||||
|
|
||||||
# Checks for header files.
|
|
||||||
|
|
||||||
# Checks for typedefs, structures, and compiler characteristics.
|
|
||||||
AC_ARG_WITH(sanitized-headers,
|
|
||||||
AS_HELP_STRING([--with-sanitized-headers=DIR],
|
|
||||||
[Specify the location of the sanitized Linux headers]),
|
|
||||||
[CPPFLAGS="$CPPFLAGS -idirafter $withval"])
|
|
||||||
|
|
||||||
AC_ARG_WITH([qrtr],
|
|
||||||
AC_HELP_STRING([--with-qrtr],
|
|
||||||
[enable qrtr, building which use qrtr]))
|
|
||||||
|
|
||||||
if (test "x${with_qrtr}" = "xyes"); then
|
|
||||||
#AC_DEFINE(ENABLE_USEQTRT, 1, [Define if uses qrtr])
|
|
||||||
AC_CHECK_HEADERS([linux/qrtr.h linux/rmnet_data.h])
|
|
||||||
fi
|
|
||||||
|
|
||||||
AM_CONDITIONAL(USE_QRTR, test "x${with_qrtr}" = "xyes")
|
|
||||||
|
|
||||||
AC_ARG_WITH([msm-ipc],
|
|
||||||
AC_HELP_STRING([--with-msm-ipc],
|
|
||||||
[enable msm-ipc, building which use qrtr]))
|
|
||||||
|
|
||||||
if (test "x${with_msm_ipc}" = "xyes"); then
|
|
||||||
#AC_DEFINE(ENABLE_USEQTRT, 1, [Define if uses qrtr])
|
|
||||||
AC_CHECK_HEADERS([linux/msm_ipc.h linux/rmnet_data.h])
|
|
||||||
fi
|
|
||||||
|
|
||||||
AM_CONDITIONAL(USE_MSM_IPC, test "x${with_msm_ipc}" = "xyes")
|
|
||||||
|
|
||||||
# Checks for library functions.
|
|
||||||
|
|
||||||
# Does not strictly follow GNU Coding standards
|
|
||||||
AM_INIT_AUTOMAKE([foreign subdir-objects])
|
|
||||||
AC_CONFIG_FILES([Makefile])
|
|
||||||
AC_OUTPUT
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# Busybox udhcpc dispatcher script. Copyright (C) 2009 by Axel Beckert.
|
|
||||||
#
|
|
||||||
# Based on the busybox example scripts and the old udhcp source
|
|
||||||
# package default.* scripts.
|
|
||||||
|
|
||||||
RESOLV_CONF="/etc/resolv.conf"
|
|
||||||
|
|
||||||
case $1 in
|
|
||||||
bound|renew)
|
|
||||||
[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
|
|
||||||
[ -n "$subnet" ] && NETMASK="netmask $subnet"
|
|
||||||
|
|
||||||
/sbin/ifconfig $interface $ip $BROADCAST $NETMASK
|
|
||||||
|
|
||||||
if [ -n "$router" ]; then
|
|
||||||
echo "$0: Resetting default routes"
|
|
||||||
while /sbin/route del default gw 0.0.0.0 dev $interface; do :; done
|
|
||||||
|
|
||||||
metric=0
|
|
||||||
for i in $router; do
|
|
||||||
/sbin/route add default gw $i dev $interface metric $metric
|
|
||||||
metric=$(($metric + 1))
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Update resolver configuration file
|
|
||||||
R=""
|
|
||||||
[ -n "$domain" ] && R="domain $domain
|
|
||||||
"
|
|
||||||
for i in $dns; do
|
|
||||||
echo "$0: Adding DNS $i"
|
|
||||||
R="${R}nameserver $i
|
|
||||||
"
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ -x /sbin/resolvconf ]; then
|
|
||||||
echo -n "$R" | resolvconf -a "${interface}.udhcpc"
|
|
||||||
else
|
|
||||||
echo -n "$R" > "$RESOLV_CONF"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
|
|
||||||
deconfig)
|
|
||||||
if [ -x /sbin/resolvconf ]; then
|
|
||||||
resolvconf -d "${interface}.udhcpc"
|
|
||||||
fi
|
|
||||||
/sbin/ifconfig $interface 0.0.0.0
|
|
||||||
;;
|
|
||||||
|
|
||||||
leasefail)
|
|
||||||
echo "$0: Lease failed: $message"
|
|
||||||
;;
|
|
||||||
|
|
||||||
nak)
|
|
||||||
echo "$0: Received a NAK: $message"
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
|
||||||
echo "$0: Unknown udhcpc command: $1";
|
|
||||||
exit 1;
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# Busybox udhcpc dispatcher script. Copyright (C) 2009 by Axel Beckert.
|
|
||||||
#
|
|
||||||
# Based on the busybox example scripts and the old udhcp source
|
|
||||||
# package default.* scripts.
|
|
||||||
|
|
||||||
RESOLV_CONF="/etc/resolv.conf"
|
|
||||||
IPCMD=`which ip`
|
|
||||||
|
|
||||||
case $1 in
|
|
||||||
bound|renew)
|
|
||||||
$IPCMD address add broadcast $broadcast $ip/$subnet dev $interface
|
|
||||||
|
|
||||||
if [ -n "$router" ]; then
|
|
||||||
echo "$0: Resetting default routes"
|
|
||||||
while $IPCMD route del default dev $interface; do :; done
|
|
||||||
|
|
||||||
metric=0
|
|
||||||
for i in $router; do
|
|
||||||
$IPCMD route add default dev $interface via $router metric $metric
|
|
||||||
metric=$(($metric + 1))
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Update resolver configuration file
|
|
||||||
R=""
|
|
||||||
[ -n "$domain" ] && R="domain $domain
|
|
||||||
"
|
|
||||||
for i in $dns; do
|
|
||||||
echo "$0: Adding DNS $i"
|
|
||||||
R="${R}nameserver $i
|
|
||||||
"
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ -x /sbin/resolvconf ]; then
|
|
||||||
echo -n "$R" | resolvconf -a "${interface}.udhcpc"
|
|
||||||
else
|
|
||||||
echo -n "$R" > "$RESOLV_CONF"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
|
|
||||||
deconfig)
|
|
||||||
if [ -x /sbin/resolvconf ]; then
|
|
||||||
resolvconf -d "${interface}.udhcpc"
|
|
||||||
fi
|
|
||||||
$IPCMD address flush dev $interface
|
|
||||||
;;
|
|
||||||
|
|
||||||
leasefail)
|
|
||||||
echo "$0: Lease failed: $message"
|
|
||||||
;;
|
|
||||||
|
|
||||||
nak)
|
|
||||||
echo "$0: Received a NAK: $message"
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
|
||||||
echo "$0: Unknown udhcpc command: $1";
|
|
||||||
exit 1;
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
@@ -1,756 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2025 Quectel Wireless Solutions Co.,Ltd
|
|
||||||
|
|
||||||
Quectel hereby grants customers of Quectel a license to use, modify,
|
|
||||||
distribute and publish the Software in binary form provided that
|
|
||||||
customers shall have no right to reverse engineer, reverse assemble,
|
|
||||||
decompile or reduce to source code form any portion of the Software.
|
|
||||||
Under no circumstances may customers modify, demonstrate, use, deliver
|
|
||||||
or disclose any portion of the Software in source code form.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <strings.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <linux/usbdevice_fs.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
#include "QMIThread.h"
|
|
||||||
#include "ethtool-copy.h"
|
|
||||||
|
|
||||||
#define USB_CLASS_VENDOR_SPEC 0xff
|
|
||||||
#define USB_CLASS_COMM 2
|
|
||||||
#define USB_CDC_SUBCLASS_ACM 0x02
|
|
||||||
#define USB_CDC_SUBCLASS_ETHERNET 0x06
|
|
||||||
#define USB_CDC_SUBCLASS_NCM 0x0d
|
|
||||||
#define USB_CDC_SUBCLASS_MBIM 0x0e
|
|
||||||
#define USB_CLASS_WIRELESS_CONTROLLER 0xe0
|
|
||||||
|
|
||||||
#define CM_MAX_PATHLEN 256
|
|
||||||
|
|
||||||
#define CM_INVALID_VAL (~((int)0))
|
|
||||||
|
|
||||||
static int RDNIS_MODEL = 0;
|
|
||||||
|
|
||||||
/* get first line from file 'fname'
|
|
||||||
* And convert the content into a hex number, then return this number */
|
|
||||||
static int file_get_value(const char *fname, int base)
|
|
||||||
{
|
|
||||||
FILE *fp = NULL;
|
|
||||||
long num;
|
|
||||||
char buff[32 + 1] = {'\0'};
|
|
||||||
char *endptr = NULL;
|
|
||||||
|
|
||||||
fp = fopen(fname, "r");
|
|
||||||
if (!fp) goto error;
|
|
||||||
if (fgets(buff, sizeof(buff), fp) == NULL)
|
|
||||||
goto error;
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
num = (int)strtol(buff, &endptr, base);
|
|
||||||
if (errno == ERANGE && (num == LONG_MAX || num == LONG_MIN))
|
|
||||||
goto error;
|
|
||||||
/* if there is no digit in buff */
|
|
||||||
if (endptr == buff)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (debug_qmi)
|
|
||||||
dbg_time("(%s) = %lx", fname, num);
|
|
||||||
return (int)num;
|
|
||||||
|
|
||||||
error:
|
|
||||||
if (fp) fclose(fp);
|
|
||||||
return CM_INVALID_VAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This function will search the directory 'dirname' and return the first child.
|
|
||||||
* '.' and '..' is ignored by default
|
|
||||||
*/
|
|
||||||
static int dir_get_child(const char *dirname, char *buff, unsigned bufsize, const char *prefix)
|
|
||||||
{
|
|
||||||
struct dirent *entptr = NULL;
|
|
||||||
DIR *dirptr;
|
|
||||||
|
|
||||||
buff[0] = 0;
|
|
||||||
|
|
||||||
dirptr = opendir(dirname);
|
|
||||||
if (!dirptr)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
while ((entptr = readdir(dirptr))) {
|
|
||||||
if (entptr->d_name[0] == '.')
|
|
||||||
continue;
|
|
||||||
if (prefix && strlen(prefix) && strncmp(entptr->d_name, prefix, strlen(prefix)))
|
|
||||||
continue;
|
|
||||||
snprintf(buff, bufsize, "%.31s", entptr->d_name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
closedir(dirptr);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int conf_get_val(const char *fname, const char *key)
|
|
||||||
{
|
|
||||||
char buff[128] = {'\0'};
|
|
||||||
FILE *fp = fopen(fname, "r");
|
|
||||||
if (!fp)
|
|
||||||
return CM_INVALID_VAL;
|
|
||||||
|
|
||||||
while (fgets(buff, sizeof(buff)-1, fp)) {
|
|
||||||
char prefix[128] = {'\0'};
|
|
||||||
char tail[128] = {'\0'};
|
|
||||||
/* To eliminate cppcheck warnning: Assume string length is no more than 15 */
|
|
||||||
sscanf(buff, "%15[^=]=%15s", prefix, tail);
|
|
||||||
if (!strncasecmp(prefix, key, strlen(key))) {
|
|
||||||
fclose(fp);
|
|
||||||
return atoi(tail);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
return CM_INVALID_VAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void query_usb_device_info(char *path, struct usb_device_info *p) {
|
|
||||||
size_t offset = strlen(path);
|
|
||||||
|
|
||||||
memset(p, 0, sizeof(*p));
|
|
||||||
|
|
||||||
path[offset] = '\0';
|
|
||||||
strcat(path, "/idVendor");
|
|
||||||
p->idVendor = file_get_value(path, 16);
|
|
||||||
|
|
||||||
if (p->idVendor == CM_INVALID_VAL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
path[offset] = '\0';
|
|
||||||
strcat(path, "/idProduct");
|
|
||||||
p->idProduct = file_get_value(path, 16);
|
|
||||||
|
|
||||||
path[offset] = '\0';
|
|
||||||
strcat(path, "/busnum");
|
|
||||||
p->busnum = file_get_value(path, 10);
|
|
||||||
|
|
||||||
path[offset] = '\0';
|
|
||||||
strcat(path, "/devnum");
|
|
||||||
p->devnum = file_get_value(path, 10);
|
|
||||||
|
|
||||||
path[offset] = '\0';
|
|
||||||
strcat(path, "/bNumInterfaces");
|
|
||||||
p->bNumInterfaces = file_get_value(path, 10);
|
|
||||||
|
|
||||||
path[offset] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
static void query_usb_interface_info(char *path, struct usb_interface_info *p) {
|
|
||||||
char driver[128];
|
|
||||||
size_t offset = strlen(path);
|
|
||||||
int n;
|
|
||||||
|
|
||||||
memset(p, 0, sizeof(*p));
|
|
||||||
|
|
||||||
path[offset] = '\0';
|
|
||||||
strcat(path, "/bNumEndpoints");
|
|
||||||
p->bInterfaceClass = file_get_value(path, 16);
|
|
||||||
|
|
||||||
path[offset] = '\0';
|
|
||||||
strcat(path, "/bInterfaceClass");
|
|
||||||
p->bInterfaceClass = file_get_value(path, 16);
|
|
||||||
|
|
||||||
path[offset] = '\0';
|
|
||||||
strcat(path, "/bInterfaceSubClass");
|
|
||||||
p->bInterfaceSubClass = file_get_value(path, 16);
|
|
||||||
|
|
||||||
path[offset] = '\0';
|
|
||||||
strcat(path, "/bInterfaceProtocol");
|
|
||||||
p->bInterfaceProtocol = file_get_value(path, 16);
|
|
||||||
|
|
||||||
path[offset] = '\0';
|
|
||||||
strcat(path, "/driver");
|
|
||||||
n = readlink(path, driver, sizeof(driver));
|
|
||||||
if (n > 0) {
|
|
||||||
driver[n] = 0;
|
|
||||||
if (debug_qmi) dbg_time("driver -> %s", driver);
|
|
||||||
n = strlen(driver);
|
|
||||||
while (n > 0) {
|
|
||||||
if (driver[n] == '/')
|
|
||||||
break;
|
|
||||||
n--;
|
|
||||||
}
|
|
||||||
strncpy(p->driver, &driver[n+1], sizeof(p->driver) - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
path[offset] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
static int detect_path_cdc_wdm_or_qcqmi(char *path, char *devname, size_t bufsize)
|
|
||||||
{
|
|
||||||
size_t offset = strlen(path);
|
|
||||||
char tmp[32];
|
|
||||||
|
|
||||||
devname[0] = 0;
|
|
||||||
|
|
||||||
if (access(path, R_OK))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
path[offset] = '\0';
|
|
||||||
strcat(path, "/GobiQMI");
|
|
||||||
if (!access(path, R_OK))
|
|
||||||
goto step_1;
|
|
||||||
|
|
||||||
path[offset] = '\0';
|
|
||||||
strcat(path, "/usbmisc");
|
|
||||||
if (!access(path, R_OK))
|
|
||||||
goto step_1;
|
|
||||||
|
|
||||||
path[offset] = '\0';
|
|
||||||
strcat(path, "/usb");
|
|
||||||
if (!access(path, R_OK))
|
|
||||||
goto step_1;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
step_1:
|
|
||||||
/* get device(qcqmiX|cdc-wdmX) */
|
|
||||||
if (debug_qmi) dbg_time("%s", path);
|
|
||||||
dir_get_child(path, tmp, sizeof(tmp), NULL);
|
|
||||||
if (tmp[0] == '\0')
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* There is a chance that, no device(qcqmiX|cdc-wdmX) is generated. We should warn user about that! */
|
|
||||||
snprintf(devname, bufsize, "/dev/%s", tmp);
|
|
||||||
if (access(devname, R_OK | F_OK) && errno == ENOENT)
|
|
||||||
{
|
|
||||||
int major, minor;
|
|
||||||
|
|
||||||
dbg_time("access %s failed, errno: %d (%s)", devname, errno, strerror(errno));
|
|
||||||
strcat(path, "/");
|
|
||||||
strcat(path, tmp);
|
|
||||||
strcat(path, "/uevent");
|
|
||||||
major = conf_get_val(path, "MAJOR");
|
|
||||||
minor = conf_get_val(path, "MINOR");
|
|
||||||
|
|
||||||
if(major == CM_INVALID_VAL || minor == CM_INVALID_VAL)
|
|
||||||
dbg_time("get major and minor failed");
|
|
||||||
else if (mknod(devname, S_IFCHR|0666, (((major & 0xfff) << 8) | (minor & 0xff) | ((minor & 0xfff00) << 12))))
|
|
||||||
dbg_time("please mknod %s c %d %d", devname, major, minor);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* To detect the device info of the modem.
|
|
||||||
* return:
|
|
||||||
* FALSE -> fail
|
|
||||||
* TRUE -> ok
|
|
||||||
*/
|
|
||||||
BOOL qmidevice_detect(char *qmichannel, char *usbnet_adapter, unsigned bufsize, PROFILE_T *profile) {
|
|
||||||
struct dirent* ent = NULL;
|
|
||||||
DIR *pDir;
|
|
||||||
const char *rootdir = "/sys/bus/usb/devices";
|
|
||||||
struct {
|
|
||||||
char path[255*2];
|
|
||||||
} *pl;
|
|
||||||
pl = (typeof(pl)) malloc(sizeof(*pl));
|
|
||||||
memset(pl, 0x00, sizeof(*pl));
|
|
||||||
|
|
||||||
pDir = opendir(rootdir);
|
|
||||||
if (!pDir) {
|
|
||||||
dbg_time("opendir %s failed: %s", rootdir, strerror(errno));
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((ent = readdir(pDir)) != NULL) {
|
|
||||||
char netcard[32+1] = {'\0'};
|
|
||||||
char devname[32+5] = {'\0'}; //+strlen("/dev/")
|
|
||||||
int netIntf;
|
|
||||||
int driver_type;
|
|
||||||
|
|
||||||
if (ent->d_name[0] == 'u')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
snprintf(pl->path, sizeof(pl->path), "%s/%s", rootdir, ent->d_name);
|
|
||||||
query_usb_device_info(pl->path, &profile->usb_dev);
|
|
||||||
if (profile->usb_dev.idVendor == CM_INVALID_VAL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (profile->usb_dev.idVendor == 0x2c7c || profile->usb_dev.idVendor == 0x05c6) {
|
|
||||||
dbg_time("Find %s/%s idVendor=0x%x idProduct=0x%x, bus=0x%03x, dev=0x%03x",
|
|
||||||
rootdir, ent->d_name, profile->usb_dev.idVendor, profile->usb_dev.idProduct,
|
|
||||||
profile->usb_dev.busnum, profile->usb_dev.devnum);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get network interface */
|
|
||||||
/* NOTICE: there is a case that, bNumberInterface=6, but the net interface is 8 */
|
|
||||||
/* toolchain-mips_24kc_gcc-5.4.0_musl donot support GLOB_BRACE */
|
|
||||||
/* RG500U's MBIM is at inteface 0 */
|
|
||||||
for (netIntf = 0; netIntf < (profile->usb_dev.bNumInterfaces + 8); netIntf++) {
|
|
||||||
snprintf(pl->path, sizeof(pl->path), "%s/%s:1.%d/net", rootdir, ent->d_name, netIntf);
|
|
||||||
dir_get_child(pl->path, netcard, sizeof(netcard), NULL);
|
|
||||||
if (netcard[0])
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (netcard[0] == '\0') { //for centos 2.6.x
|
|
||||||
const char *n= "usb0";
|
|
||||||
const char *c = "qcqmi0";
|
|
||||||
|
|
||||||
snprintf(pl->path, sizeof(pl->path), "%s/%s:1.4/net:%s", rootdir, ent->d_name, n);
|
|
||||||
if (!access(pl->path, F_OK)) {
|
|
||||||
snprintf(pl->path, sizeof(pl->path), "%s/%s:1.4/GobiQMI:%s", rootdir, ent->d_name, c);
|
|
||||||
if (!access(pl->path, F_OK)) {
|
|
||||||
snprintf(qmichannel, bufsize, "/dev/%s", c);
|
|
||||||
snprintf(usbnet_adapter, bufsize, "%s", n);
|
|
||||||
snprintf(pl->path, sizeof(pl->path), "%s/%s:1.4", rootdir, ent->d_name);
|
|
||||||
query_usb_interface_info(pl->path, &profile->usb_intf);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (netcard[0] == '\0')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* not '-i iface' */
|
|
||||||
if (usbnet_adapter[0] && strcmp(usbnet_adapter, netcard))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
snprintf(pl->path, sizeof(pl->path), "%s/%s:1.%d", rootdir, ent->d_name, netIntf);
|
|
||||||
query_usb_interface_info(pl->path, &profile->usb_intf);
|
|
||||||
driver_type = get_driver_type(profile);
|
|
||||||
|
|
||||||
if (driver_type == SOFTWARE_QMI || driver_type == SOFTWARE_MBIM) {
|
|
||||||
detect_path_cdc_wdm_or_qcqmi(pl->path, devname, sizeof(devname));
|
|
||||||
}
|
|
||||||
else if (driver_type == SOFTWARE_ECM_RNDIS_NCM)
|
|
||||||
{
|
|
||||||
int atIntf = -1;
|
|
||||||
|
|
||||||
if (profile->usb_dev.idVendor == 0x2c7c) { //Quectel
|
|
||||||
switch (profile->usb_dev.idProduct) { //EC200U
|
|
||||||
case 0x0901: //EC200U
|
|
||||||
case 0x0902: //EC200D
|
|
||||||
case 0x8101: //RG801H
|
|
||||||
atIntf = 2;
|
|
||||||
break;
|
|
||||||
case 0x0900: //RG500U
|
|
||||||
atIntf = 4;
|
|
||||||
break;
|
|
||||||
case 0x6026: //EC200T
|
|
||||||
case 0x6005: //EC200A
|
|
||||||
case 0x6002: //EC200S
|
|
||||||
case 0x6001: //EC100Y
|
|
||||||
atIntf = 3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x6007: //EG915Q\EG800Q
|
|
||||||
if(RDNIS_MODEL == 1)
|
|
||||||
atIntf = 5;
|
|
||||||
else
|
|
||||||
atIntf = 3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
dbg_time("unknow at interface for USB idProduct:%04x\n", profile->usb_dev.idProduct);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (atIntf != -1) {
|
|
||||||
snprintf(pl->path, sizeof(pl->path), "%s/%s:1.%d", rootdir, ent->d_name, atIntf);
|
|
||||||
dir_get_child(pl->path, devname, sizeof(devname), "tty");
|
|
||||||
if (devname[0] && !strcmp(devname, "tty")) {
|
|
||||||
snprintf(pl->path, sizeof(pl->path), "%s/%s:1.%d/tty", rootdir, ent->d_name, atIntf);
|
|
||||||
dir_get_child(pl->path, devname, sizeof(devname), "tty");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (netcard[0] && devname[0]) {
|
|
||||||
if (devname[0] == '/')
|
|
||||||
snprintf(qmichannel, bufsize, "%s", devname);
|
|
||||||
else
|
|
||||||
snprintf(qmichannel, bufsize, "/dev/%s", devname);
|
|
||||||
snprintf(usbnet_adapter, bufsize, "%s", netcard);
|
|
||||||
dbg_time("Auto find qmichannel = %s", qmichannel);
|
|
||||||
dbg_time("Auto find usbnet_adapter = %s", usbnet_adapter);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closedir(pDir);
|
|
||||||
|
|
||||||
if (qmichannel[0] == '\0' || usbnet_adapter[0] == '\0') {
|
|
||||||
dbg_time("network interface '%s' or qmidev '%s' is not exist", usbnet_adapter, qmichannel);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
free(pl);
|
|
||||||
return TRUE;
|
|
||||||
error:
|
|
||||||
free(pl);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mhidevice_detect(char *qmichannel, char *usbnet_adapter, PROFILE_T *profile) {
|
|
||||||
struct dirent* ent = NULL;
|
|
||||||
DIR *pDir;
|
|
||||||
const char *rootdir_mhi[] = {"/sys/bus/mhi_q/devices", "/sys/bus/mhi/devices", NULL};
|
|
||||||
int i = 0;
|
|
||||||
char path[256];
|
|
||||||
int find = 0;
|
|
||||||
|
|
||||||
while (rootdir_mhi[i]) {
|
|
||||||
const char *rootdir = rootdir_mhi[i++];
|
|
||||||
|
|
||||||
pDir = opendir(rootdir);
|
|
||||||
if (!pDir) {
|
|
||||||
if (errno != ENOENT)
|
|
||||||
dbg_time("opendir %s failed: %s", rootdir, strerror(errno));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((ent = readdir(pDir)) != NULL) {
|
|
||||||
char netcard[32] = {'\0'};
|
|
||||||
char devname[32] = {'\0'};
|
|
||||||
int software_interface = SOFTWARE_QMI;
|
|
||||||
char *pNode = NULL;
|
|
||||||
|
|
||||||
pNode = strstr(ent->d_name, "_IP_HW0"); //0306_00.01.00_IP_HW0
|
|
||||||
if (!pNode)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
snprintf(path, sizeof(path), "%s/%.32s/net", rootdir, ent->d_name);
|
|
||||||
dir_get_child(path, netcard, sizeof(netcard), NULL);
|
|
||||||
if (!netcard[0])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (usbnet_adapter[0] && strcmp(netcard, usbnet_adapter)) //not '-i x'
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!strcmp(rootdir, "/sys/bus/mhi/devices")) {
|
|
||||||
snprintf(path, sizeof(path), "%s/%.13s_IPCR", rootdir, ent->d_name); // 13 is sizeof(0306_00.01.00)
|
|
||||||
if (!access(path, F_OK)) {
|
|
||||||
/* we also need 'cat /dev/mhi_0306_00.01.00_pipe_14' to enable rmnet as like USB's DTR
|
|
||||||
or will get error 'requestSetEthMode QMUXResult = 0x1, QMUXError = 0x46' */
|
|
||||||
sprintf(usbnet_adapter, "%s", netcard);
|
|
||||||
sprintf(qmichannel, "qrtr-%d", 3); // 3 is sdx modem's node id
|
|
||||||
profile->software_interface = SOFTWARE_QRTR;
|
|
||||||
find = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(path, sizeof(path), "%s/%.13s_IPCR", rootdir, ent->d_name);
|
|
||||||
if (access(path, F_OK)) {
|
|
||||||
snprintf(path, sizeof(path), "%s/%.13s_QMI0", rootdir, ent->d_name);
|
|
||||||
if (access(path, F_OK)) {
|
|
||||||
snprintf(path, sizeof(path), "%s/%.13s_MBIM", rootdir, ent->d_name);
|
|
||||||
if (!access(path, F_OK))
|
|
||||||
software_interface = SOFTWARE_MBIM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (access(path, F_OK))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
strncat(path, "/mhi_uci_q", sizeof(path)-1);
|
|
||||||
dir_get_child(path, devname, sizeof(devname), NULL);
|
|
||||||
if (!devname[0])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
sprintf(usbnet_adapter, "%s", netcard);
|
|
||||||
sprintf(qmichannel, "/dev/%s", devname);
|
|
||||||
profile->software_interface = software_interface;
|
|
||||||
find = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
closedir(pDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
return find;
|
|
||||||
}
|
|
||||||
|
|
||||||
int atdevice_detect(char *atchannel, char *usbnet_adapter, PROFILE_T *profile) {
|
|
||||||
if (!access("/sys/class/net/sipa_dummy0", F_OK)) {
|
|
||||||
strcpy(usbnet_adapter, "sipa_dummy0");
|
|
||||||
snprintf(profile->qmapnet_adapter, sizeof(profile->qmapnet_adapter), "%s%d", "pcie", profile->pdp - 1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dbg_time("atdevice_detect failed");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!access("/dev/stty_nr31", F_OK)) {
|
|
||||||
strcpy(atchannel, "/dev/stty_nr31");
|
|
||||||
profile->software_interface = SOFTWARE_ECM_RNDIS_NCM;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
error:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int get_driver_type(PROFILE_T *profile)
|
|
||||||
{
|
|
||||||
/* QMI_WWAN */
|
|
||||||
if (profile->usb_intf.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
|
|
||||||
return SOFTWARE_QMI;
|
|
||||||
}
|
|
||||||
else if (profile->usb_intf.bInterfaceClass == USB_CLASS_COMM) {
|
|
||||||
switch (profile->usb_intf.bInterfaceSubClass) {
|
|
||||||
case USB_CDC_SUBCLASS_MBIM:
|
|
||||||
return SOFTWARE_MBIM;
|
|
||||||
break;
|
|
||||||
case USB_CDC_SUBCLASS_ETHERNET:
|
|
||||||
case USB_CDC_SUBCLASS_NCM:
|
|
||||||
return SOFTWARE_ECM_RNDIS_NCM;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (profile->usb_intf.bInterfaceClass == USB_CLASS_WIRELESS_CONTROLLER) {
|
|
||||||
if (profile->usb_intf.bInterfaceSubClass == 1 && profile->usb_intf.bInterfaceProtocol == 3) {
|
|
||||||
RDNIS_MODEL = 1;//Some modules in RNDIS mode the usb port definition is different, adding a marker bit to distinguish.
|
|
||||||
return SOFTWARE_ECM_RNDIS_NCM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dbg_time("%s unknow bInterfaceClass=%d, bInterfaceSubClass=%d", __func__,
|
|
||||||
profile->usb_intf.bInterfaceClass, profile->usb_intf.bInterfaceSubClass);
|
|
||||||
return DRV_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct usbfs_getdriver
|
|
||||||
{
|
|
||||||
unsigned int interface;
|
|
||||||
char driver[255 + 1];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct usbfs_ioctl
|
|
||||||
{
|
|
||||||
int ifno; /* interface 0..N ; negative numbers reserved */
|
|
||||||
int ioctl_code; /* MUST encode size + direction of data so the
|
|
||||||
* macros in <asm/ioctl.h> give correct values */
|
|
||||||
void *data; /* param buffer (in, or out) */
|
|
||||||
};
|
|
||||||
|
|
||||||
#define IOCTL_USBFS_DISCONNECT _IO('U', 22)
|
|
||||||
#define IOCTL_USBFS_CONNECT _IO('U', 23)
|
|
||||||
|
|
||||||
int usbfs_is_kernel_driver_alive(int fd, int ifnum)
|
|
||||||
{
|
|
||||||
struct usbfs_getdriver getdrv;
|
|
||||||
getdrv.interface = ifnum;
|
|
||||||
if (ioctl(fd, USBDEVFS_GETDRIVER, &getdrv) < 0) {
|
|
||||||
dbg_time("%s ioctl USBDEVFS_GETDRIVER failed, kernel driver may be inactive", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
dbg_time("%s find interface %d has match the driver %s", __func__, ifnum, getdrv.driver);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void usbfs_detach_kernel_driver(int fd, int ifnum)
|
|
||||||
{
|
|
||||||
struct usbfs_ioctl operate;
|
|
||||||
operate.data = NULL;
|
|
||||||
operate.ifno = ifnum;
|
|
||||||
operate.ioctl_code = IOCTL_USBFS_DISCONNECT;
|
|
||||||
if (ioctl(fd, USBDEVFS_IOCTL, &operate) < 0) {
|
|
||||||
dbg_time("%s detach kernel driver failed", __func__);
|
|
||||||
} else {
|
|
||||||
dbg_time("%s detach kernel driver success", __func__);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void usbfs_attach_kernel_driver(int fd, int ifnum)
|
|
||||||
{
|
|
||||||
struct usbfs_ioctl operate;
|
|
||||||
operate.data = NULL;
|
|
||||||
operate.ifno = ifnum;
|
|
||||||
operate.ioctl_code = IOCTL_USBFS_CONNECT;
|
|
||||||
if (ioctl(fd, USBDEVFS_IOCTL, &operate) < 0) {
|
|
||||||
dbg_time("%s detach kernel driver failed", __func__);
|
|
||||||
} else {
|
|
||||||
dbg_time("%s detach kernel driver success", __func__);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int reattach_driver(PROFILE_T *profile)
|
|
||||||
{
|
|
||||||
int ifnum = 4;
|
|
||||||
int fd;
|
|
||||||
char devpath[128] = {'\0'};
|
|
||||||
snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d/%03d", profile->usb_dev.busnum, profile->usb_dev.devnum);
|
|
||||||
fd = open(devpath, O_RDWR | O_NOCTTY);
|
|
||||||
if (fd < 0)
|
|
||||||
{
|
|
||||||
dbg_time("%s fail to open %s", __func__, devpath);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
usbfs_detach_kernel_driver(fd, ifnum);
|
|
||||||
usbfs_attach_kernel_driver(fd, ifnum);
|
|
||||||
close(fd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SIOCETHTOOL 0x8946
|
|
||||||
int ql_get_netcard_driver_info(const char *devname)
|
|
||||||
{
|
|
||||||
int fd = -1;
|
|
||||||
struct ethtool_drvinfo drvinfo;
|
|
||||||
struct ifreq ifr; /* ifreq suitable for ethtool ioctl */
|
|
||||||
|
|
||||||
memset(&ifr, 0, sizeof(ifr));
|
|
||||||
strcpy(ifr.ifr_name, devname);
|
|
||||||
|
|
||||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
||||||
if (fd < 0) {
|
|
||||||
dbg_time("Cannot get control socket: errno(%d)(%s)", errno, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
drvinfo.cmd = ETHTOOL_GDRVINFO;
|
|
||||||
ifr.ifr_data = (void *)&drvinfo;
|
|
||||||
|
|
||||||
if (ioctl(fd, SIOCETHTOOL, &ifr) < 0) {
|
|
||||||
dbg_time("ioctl() error: errno(%d)(%s)", errno, strerror(errno));
|
|
||||||
close(fd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbg_time("netcard driver = %s, driver version = %s", drvinfo.driver, drvinfo.version);
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ql_get_netcard_carrier_state(const char *devname)
|
|
||||||
{
|
|
||||||
int fd = -1;
|
|
||||||
struct ethtool_value edata;
|
|
||||||
struct ifreq ifr; /* ifreq suitable for ethtool ioctl */
|
|
||||||
|
|
||||||
memset(&ifr, 0, sizeof(ifr));
|
|
||||||
strcpy(ifr.ifr_name, devname);
|
|
||||||
|
|
||||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
||||||
if (fd < 0) {
|
|
||||||
dbg_time("Cannot get control socket: errno(%d)(%s)", errno, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
edata.cmd = ETHTOOL_GLINK;
|
|
||||||
edata.data = 0;
|
|
||||||
ifr.ifr_data = (void *)&edata;
|
|
||||||
|
|
||||||
if (ioctl(fd, SIOCETHTOOL, &ifr) < 0) {
|
|
||||||
dbg_time("ioctl('%s') error: errno(%d)(%s)", devname, errno, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!edata.data)
|
|
||||||
dbg_time("netcard carrier = %d", edata.data);
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
return edata.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *catch_log(void *arg)
|
|
||||||
{
|
|
||||||
PROFILE_T *profile = (PROFILE_T *)arg;
|
|
||||||
int nreads = 0;
|
|
||||||
char tbuff[256+32];
|
|
||||||
char filter[32];
|
|
||||||
size_t tsize = strlen(get_time()) + 1;
|
|
||||||
|
|
||||||
snprintf(filter, sizeof(filter), ":%d:%03d:", profile->usb_dev.busnum, profile->usb_dev.devnum);
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
nreads = read(profile->usbmon_fd, tbuff + tsize, sizeof(tbuff) - tsize - 1);
|
|
||||||
if (nreads <= 0) {
|
|
||||||
if (nreads == -1 && errno == EINTR)
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
tbuff[tsize+nreads] = '\0'; // printf("%s", buff);
|
|
||||||
|
|
||||||
if (!strstr(tbuff+tsize, filter))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
snprintf(tbuff, sizeof(tbuff), "%s", get_time());
|
|
||||||
tbuff[tsize-1] = ' ';
|
|
||||||
|
|
||||||
fwrite(tbuff, strlen(tbuff), 1, profile->usbmon_logfile_fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ql_capture_usbmon_log(PROFILE_T *profile, const char *log_path)
|
|
||||||
{
|
|
||||||
char usbmon_path[256];
|
|
||||||
pthread_t pt;
|
|
||||||
pthread_attr_t attr;
|
|
||||||
|
|
||||||
if (access("/sys/module/usbmon", F_OK)) {
|
|
||||||
dbg_time("usbmon is not load, please execute \"modprobe usbmon\" or \"insmod usbmon.ko\"");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (access("/sys/kernel/debug/usb", F_OK)) {
|
|
||||||
dbg_time("debugfs is not mount, please execute \"mount -t debugfs none_debugs /sys/kernel/debug\"");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(usbmon_path, sizeof(usbmon_path), "/sys/kernel/debug/usb/usbmon/%du", profile->usb_dev.busnum);
|
|
||||||
profile->usbmon_fd = open(usbmon_path, O_RDONLY);
|
|
||||||
if (profile->usbmon_fd < 0) {
|
|
||||||
dbg_time("open %s error(%d) (%s)", usbmon_path, errno, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(usbmon_path, sizeof(usbmon_path), "cat /sys/kernel/debug/usb/devices >> %s", log_path);
|
|
||||||
if (system(usbmon_path) == -1) {};
|
|
||||||
|
|
||||||
profile->usbmon_logfile_fp = fopen(log_path, "wb");
|
|
||||||
if (!profile->usbmon_logfile_fp) {
|
|
||||||
dbg_time("open %s error(%d) (%s)", log_path, errno, strerror(errno));
|
|
||||||
close(profile->usbmon_fd);
|
|
||||||
profile->usbmon_fd = -1;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_attr_init(&attr);
|
|
||||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
||||||
|
|
||||||
pthread_create(&pt, &attr, catch_log, (void *)profile);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ql_stop_usbmon_log(PROFILE_T *profile) {
|
|
||||||
if (profile->usbmon_fd > 0)
|
|
||||||
close(profile->usbmon_fd);
|
|
||||||
if (profile->usbmon_logfile_fp)
|
|
||||||
fclose(profile->usbmon_logfile_fp);
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -1,71 +0,0 @@
|
|||||||
root@ZhuoTK:/# dmesg
|
|
||||||
[ 788.920000] usb 1-1.3: new high-speed USB device number 4 using ehci-platform
|
|
||||||
[ 789.160000] cdc_mbim 1-1.3:1.4: cdc-wdm0: USB WDM device
|
|
||||||
[ 789.170000] cdc_mbim 1-1.3:1.4 wwan0: register 'cdc_mbim' at usb-101c0000.ehci-1.3, CDC MBIM, a2:58:dc:4d:dd:ca
|
|
||||||
|
|
||||||
root@ZhuoTK:/# quectel-CM -s cmnet &
|
|
||||||
[04-13_05:24:38:767] Quectel_QConnectManager_Linux_V1.6.0.25
|
|
||||||
[04-13_05:24:38:769] Find /sys/bus/usb/devices/1-1.3 idVendor=0x2c7c idProduct=0x125, bus=0x001, dev=0x004
|
|
||||||
[04-13_05:24:38:771] Auto find qmichannel = /dev/cdc-wdm0
|
|
||||||
[04-13_05:24:38:771] Auto find usbnet_adapter = wwan0
|
|
||||||
[04-13_05:24:38:771] netcard driver = cdc_mbim, driver version = 22-Aug-2005
|
|
||||||
[04-13_05:24:38:771] Modem works in MBIM mode
|
|
||||||
[04-13_05:24:38:779] cdc_wdm_fd = 7
|
|
||||||
[04-13_05:24:38:779] mbim_open_device()
|
|
||||||
[04-13_05:24:39:624] mbim_device_caps_query()
|
|
||||||
[04-13_05:24:39:656] DeviceId: 866758045439136
|
|
||||||
[04-13_05:24:39:656] FirmwareInfo: EC25EFAR06A11M4G
|
|
||||||
[04-13_05:24:39:656] HardwareInfo: QUECTEL Mobile Broadband Modul
|
|
||||||
[04-13_05:24:39:657] mbim_device_services_query()
|
|
||||||
[04-13_05:24:39:688] mbim_set_radio_state( 1 )
|
|
||||||
[04-13_05:24:39:721] HwRadioState: 1, SwRadioState: 1
|
|
||||||
[04-13_05:24:39:721] mbim_subscriber_status_query()
|
|
||||||
[04-13_05:24:39:784] SubscriberId: 460028563800461
|
|
||||||
[04-13_05:24:39:784] SimIccId: 89860015120716380461
|
|
||||||
[04-13_05:24:39:785] SubscriberReadyState NotInitialized -> Initialized
|
|
||||||
[04-13_05:24:39:785] mbim_register_state_query()
|
|
||||||
[04-13_05:24:39:816] RegisterState Unknown -> Home
|
|
||||||
[04-13_05:24:39:816] mbim_packet_service_query()
|
|
||||||
[04-13_05:24:39:848] PacketServiceState Unknown -> Attached
|
|
||||||
[04-13_05:24:39:848] mbim_query_connect(sessionID=0)
|
|
||||||
[04-13_05:24:39:880] ActivationState Unknown -> Deactivated
|
|
||||||
[04-13_05:24:39:881] ifconfig wwan0 0.0.0.0
|
|
||||||
[04-13_05:24:39:899] ifconfig wwan0 down
|
|
||||||
[04-13_05:24:39:913] mbim_set_connect(onoff=1, sessionID=0)
|
|
||||||
[04-13_05:24:39:976] ActivationState Deactivated -> Activated
|
|
||||||
[04-13_05:24:39:977] mbim_ip_config(sessionID=0)
|
|
||||||
[04-13_05:24:40:008] < SessionId = 0
|
|
||||||
[04-13_05:24:40:008] < IPv4ConfigurationAvailable = 0xf
|
|
||||||
[04-13_05:24:40:008] < IPv6ConfigurationAvailable = 0x0
|
|
||||||
[04-13_05:24:40:008] < IPv4AddressCount = 0x1
|
|
||||||
[04-13_05:24:40:008] < IPv4AddressOffset = 0x3c
|
|
||||||
[04-13_05:24:40:009] < IPv6AddressCount = 0x0
|
|
||||||
[04-13_05:24:40:009] < IPv6AddressOffset = 0x0
|
|
||||||
[04-13_05:24:40:009] < IPv4 = 10.129.90.29/30
|
|
||||||
[04-13_05:24:40:009] < gw = 10.129.90.30
|
|
||||||
[04-13_05:24:40:009] < dns1 = 211.138.180.2
|
|
||||||
[04-13_05:24:40:009 < dns2 = 211.138.180.3
|
|
||||||
[04-13_05:24:40:009] < ipv4 mtu = 1500
|
|
||||||
[04-13_05:24:40:041] ifconfig wwan0 up
|
|
||||||
[04-13_05:24:40:063] ip -4 address flush dev wwan0
|
|
||||||
[04-13_05:24:40:073] ip -4 address add 10.129.90.29/30 dev wwan0
|
|
||||||
[04-13_05:24:40:084] ip -4 route add default via 10.129.90.30 dev wwan0
|
|
||||||
|
|
||||||
root@ZhuoTK:/# ifconfig wwan0
|
|
||||||
wwan0 Link encap:Ethernet HWaddr A2:58:DC:4D:DD:CA
|
|
||||||
inet addr:10.129.90.29 Bcast:0.0.0.0 Mask:255.255.255.252
|
|
||||||
inet6 addr: fe80::a058:dcff:fe4d:ddca/64 Scope:Link
|
|
||||||
UP BROADCAST RUNNING NOARP MULTICAST MTU:1500 Metric:1
|
|
||||||
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
|
|
||||||
TX packets:5 errors:0 dropped:0 overruns:0 carrier:0
|
|
||||||
collisions:0 txqueuelen:1000
|
|
||||||
RX bytes:0 (0.0 B) TX bytes:380 (380.0 B)
|
|
||||||
|
|
||||||
root@ZhuoTK:/# ip ro show
|
|
||||||
default via 10.129.90.30 dev wwan0
|
|
||||||
10.129.90.28/30 dev wwan0 proto kernel scope link src 10.129.90.29
|
|
||||||
192.168.1.0/24 dev br-lan proto kernel scope link src 192.168.1.251
|
|
||||||
|
|
||||||
root@ZhuoTK:/# ping www.qq.com
|
|
||||||
PING www.qq.com (183.194.238.117): 56 data bytes
|
|
||||||
64 bytes from 183.194.238.117: seq=0 ttl=53 time=58.674 ms
|
|
||||||
@@ -1,168 +0,0 @@
|
|||||||
root@ZhuoTK:/# dmesg
|
|
||||||
[ 788.920000] usb 1-1.3: new high-speed USB device number 4 using ehci-platform
|
|
||||||
[ 789.160000] cdc_mbim 1-1.3:1.4: cdc-wdm0: USB WDM device
|
|
||||||
[ 789.170000] cdc_mbim 1-1.3:1.4 wwan0: register 'cdc_mbim' at usb-101c0000.ehci-1.3, CDC MBIM, a2:58:dc:4d:dd:ca
|
|
||||||
|
|
||||||
root@ZhuoTK:/# ip link add link wwan0 name wwan0.1 type vlan id 1
|
|
||||||
root@ZhuoTK:/# ip link add link wwan0 name wwan0.2 type vlan id 2
|
|
||||||
root@ZhuoTK:/# ifconfig wwan0.1
|
|
||||||
wwan0.1 Link encap:Ethernet HWaddr A2:58:DC:4D:DD:CA
|
|
||||||
BROADCAST NOARP MULTICAST MTU:1500 Metric:1
|
|
||||||
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
|
|
||||||
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
|
|
||||||
collisions:0 txqueuelen:0
|
|
||||||
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
|
|
||||||
|
|
||||||
root@ZhuoTK:/# ifconfig wwan0.2
|
|
||||||
wwan0.2 Link encap:Ethernet HWaddr A2:58:DC:4D:DD:CA
|
|
||||||
BROADCAST NOARP MULTICAST MTU:1500 Metric:1
|
|
||||||
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
|
|
||||||
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
|
|
||||||
collisions:0 txqueuelen:0
|
|
||||||
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
|
|
||||||
|
|
||||||
root@ZhuoTK:/# quectel-mbim-proxy &
|
|
||||||
root@ZhuoTK:/# [04-13_07:04:27:543] mbim_dev_fd=3
|
|
||||||
[04-13_07:04:27:543] mbim_send_open_msg()
|
|
||||||
[04-13_07:04:28:321] receive MBIM_OPEN_DONE, status=0
|
|
||||||
[04-13_07:04:28:321] mbim_server_fd=4
|
|
||||||
|
|
||||||
root@ZhuoTK:/# quectel-CM -n 1 -s cmnet &
|
|
||||||
[04-13_07:04:34:256] Quectel_QConnectManager_Linux_V1.6.0.25
|
|
||||||
[04-13_07:04:34:259] Find /sys/bus/usb/devices/1-1.3 idVendor=0x2c7c idProduct=0x125, bus=0x001, dev=0x004
|
|
||||||
[04-13_07:04:34:260] Auto find qmichannel = /dev/cdc-wdm0
|
|
||||||
[04-13_07:04:34:260] Auto find usbnet_adapter = wwan0
|
|
||||||
[04-13_07:04:34:260] netcard driver = cdc_mbim, driver version = 22-Aug-2005
|
|
||||||
[04-13_07:04:34:261] mbim_qmap_mode = 4, vlan_id = 0x01, qmap_netcard = wwan0.1
|
|
||||||
[04-13_07:04:34:261] Modem works in MBIM mode
|
|
||||||
[04-13_07:04:34:261] handle_client_connect client_fd=5, client_idx=1
|
|
||||||
[04-13_07:04:34:262] connect to quectel-mbim-proxy sockfd = 7
|
|
||||||
[04-13_07:04:34:262] cdc_wdm_fd = 7
|
|
||||||
[04-13_07:04:34:262] mbim_open_device()
|
|
||||||
[04-13_07:04:35:106] mbim_device_caps_query()
|
|
||||||
[04-13_07:04:35:139] DeviceId: 866758045439136
|
|
||||||
[04-13_07:04:35:139] FirmwareInfo: EC25EFAR06A11M4G
|
|
||||||
[04-13_07:04:35:139] HardwareInfo: QUECTEL Mobile Broadband Modul
|
|
||||||
[04-13_07:04:35:139] mbim_device_services_query()
|
|
||||||
[04-13_07:04:35:170] mbim_set_radio_state( 1 )
|
|
||||||
[04-13_07:04:35:202] HwRadioState: 1, SwRadioState: 1
|
|
||||||
[04-13_07:04:35:202] mbim_subscriber_status_query()
|
|
||||||
[04-13_07:04:35:267] SubscriberId: 460028563800461
|
|
||||||
[04-13_07:04:35:267] SimIccId: 89860015120716380461
|
|
||||||
[04-13_07:04:35:267] SubscriberReadyState NotInitialized -> Initialized
|
|
||||||
[04-13_07:04:35:267] mbim_register_state_query()
|
|
||||||
[04-13_07:04:35:297] RegisterState Unknown -> Home
|
|
||||||
[04-13_07:04:35:298] mbim_packet_service_query()
|
|
||||||
[04-13_07:04:35:329] PacketServiceState Unknown -> Attached
|
|
||||||
[04-13_07:04:35:330] mbim_query_connect(sessionID=1)
|
|
||||||
[04-13_07:04:35:361] ActivationState Unknown -> Deactivated
|
|
||||||
[04-13_07:04:35:362] ifconfig wwan0.1 0.0.0.0
|
|
||||||
[04-13_07:04:35:373] ifconfig wwan0.1 down
|
|
||||||
[04-13_07:04:35:383] mbim_set_connect(onoff=1, sessionID=1)
|
|
||||||
[04-13_07:04:35:426] ActivationState Deactivated -> Activated
|
|
||||||
[04-13_07:04:35:426] mbim_ip_config(sessionID=1)
|
|
||||||
[04-13_07:04:35:457] < SessionId = 1
|
|
||||||
[04-13_07:04:35:457] < IPv4ConfigurationAvailable = 0xf
|
|
||||||
[04-13_07:04:35:457] < IPv6ConfigurationAvailable = 0x0
|
|
||||||
[04-13_07:04:35:457] < IPv4AddressCount = 0x1
|
|
||||||
[04-13_07:04:35:458] < IPv4AddressOffset = 0x3c
|
|
||||||
[04-13_07:04:35:458] < IPv6AddressCount = 0x0
|
|
||||||
[04-13_07:04:35:458] < IPv6AddressOffset = 0x0
|
|
||||||
[04-13_07:04:35:458] < IPv4 = 10.129.90.29/30
|
|
||||||
[04-13_07:04:35:458] < gw = 10.129.90.30
|
|
||||||
[04-13_07:04:35:458] < dns1 = 211.138.180.2
|
|
||||||
[04-13_07:04:35:458] < dns2 = 211.138.180.3
|
|
||||||
[04-13_07:04:35:458] < ipv4 mtu = 1500
|
|
||||||
[04-13_07:04:35:489] ifconfig wwan0 up
|
|
||||||
[04-13_07:04:35:509] ifconfig wwan0.1 down
|
|
||||||
[04-13_07:04:35:522] ifconfig wwan0.1 up
|
|
||||||
[04-13_07:04:35:535] ip -4 address flush dev wwan0.1
|
|
||||||
[04-13_07:04:35:545] ip -4 address add 10.129.90.29/30 dev wwan0.1
|
|
||||||
[04-13_07:04:35:556] ip -4 route add default via 10.129.90.30 dev wwan0.1
|
|
||||||
|
|
||||||
root@ZhuoTK:/# quectel-CM -n 2 -s 4gnet &
|
|
||||||
[04-13_07:04:45:150] Quectel_QConnectManager_Linux_V1.6.0.25
|
|
||||||
[04-13_07:04:45:152] Find /sys/bus/usb/devices/1-1.3 idVendor=0x2c7c idProduct=0x125, bus=0x001, dev=0x004
|
|
||||||
[04-13_07:04:45:154] Auto find qmichannel = /dev/cdc-wdm0
|
|
||||||
[04-13_07:04:45:154] Auto find usbnet_adapter = wwan0
|
|
||||||
[04-13_07:04:45:154] netcard driver = cdc_mbim, driver version = 22-Aug-2005
|
|
||||||
[04-13_07:04:45:155] mbim_qmap_mode = 4, vlan_id = 0x02, qmap_netcard = wwan0.2
|
|
||||||
[04-13_07:04:45:155] Modem works in MBIM mode
|
|
||||||
[04-13_07:04:45:155] handle_client_connect client_fd=6, client_idx=2
|
|
||||||
[04-13_07:04:45:156] connect to quectel-mbim-proxy sockfd = 7
|
|
||||||
[04-13_07:04:45:156] cdc_wdm_fd = 7
|
|
||||||
[04-13_07:04:45:156] mbim_open_device()
|
|
||||||
[04-13_07:04:46:025] mbim_device_caps_query()
|
|
||||||
[04-13_07:04:46:056] DeviceId: 866758045439136
|
|
||||||
[04-13_07:04:46:056] FirmwareInfo: EC25EFAR06A11M4G
|
|
||||||
[04-13_07:04:46:056] HardwareInfo: QUECTEL Mobile Broadband Modul
|
|
||||||
[04-13_07:04:46:056] mbim_device_services_query()
|
|
||||||
[04-13_07:04:46:088] mbim_set_radio_state( 1 )
|
|
||||||
[04-13_07:04:46:119] HwRadioState: 1, SwRadioState: 1
|
|
||||||
[04-13_07:04:46:119] mbim_subscriber_status_query()
|
|
||||||
[04-13_07:04:46:183] SubscriberId: 460028563800461
|
|
||||||
[04-13_07:04:46:184] SimIccId: 89860015120716380461
|
|
||||||
[04-13_07:04:46:184] SubscriberReadyState NotInitialized -> Initialized
|
|
||||||
[04-13_07:04:46:184] mbim_register_state_query()
|
|
||||||
[04-13_07:04:46:216] RegisterState Unknown -> Home
|
|
||||||
[04-13_07:04:46:216] mbim_packet_service_query()
|
|
||||||
[04-13_07:04:46:248] PacketServiceState Unknown -> Attached
|
|
||||||
[04-13_07:04:46:248] mbim_query_connect(sessionID=2)
|
|
||||||
[04-13_07:04:46:280] ActivationState Unknown -> Deactivated
|
|
||||||
[04-13_07:04:46:280] ifconfig wwan0.2 0.0.0.0
|
|
||||||
[04-13_07:04:46:291] ifconfig wwan0.2 down
|
|
||||||
[04-13_07:04:46:304] mbim_set_connect(onoff=1, sessionID=2)
|
|
||||||
[04-13_07:04:46:504] ActivationState Deactivated -> Activated
|
|
||||||
[04-13_07:04:46:505] mbim_ip_config(sessionID=2)
|
|
||||||
[04-13_07:04:46:537] < SessionId = 2
|
|
||||||
[04-13_07:04:46:537] < IPv4ConfigurationAvailable = 0xf
|
|
||||||
[04-13_07:04:46:537] < IPv6ConfigurationAvailable = 0x0
|
|
||||||
[04-13_07:04:46:538] < IPv4AddressCount = 0x1
|
|
||||||
[04-13_07:04:46:538] < IPv4AddressOffset = 0x3c
|
|
||||||
[04-13_07:04:46:538] < IPv6AddressCount = 0x0
|
|
||||||
[04-13_07:04:46:538] < IPv6AddressOffset = 0x0
|
|
||||||
[04-13_07:04:46:538] < IPv4 = 10.129.37.205/30
|
|
||||||
[04-13_07:04:46:538] < gw = 10.129.37.206
|
|
||||||
[04-13_07:04:46:538] < dns1 = 211.138.180.2
|
|
||||||
[04-13_07:04:46:538] < dns2 = 211.138.180.3
|
|
||||||
[04-13_07:04:46:538] < ipv4 mtu = 1500
|
|
||||||
[04-13_07:04:46:569] ifconfig wwan0 up
|
|
||||||
[04-13_07:04:46:579] ifconfig wwan0.2 up
|
|
||||||
[04-13_07:04:46:592] ip -4 address flush dev wwan0.2
|
|
||||||
[04-13_07:04:46:602] ip -4 address add 10.129.37.205/30 dev wwan0.2
|
|
||||||
[04-13_07:04:46:613] ip -4 route add default via 10.129.37.206 dev wwan0.2
|
|
||||||
|
|
||||||
root@ZhuoTK:/# ifconfig wwan0.1
|
|
||||||
wwan0.1 Link encap:Ethernet HWaddr A2:58:DC:4D:DD:CA
|
|
||||||
inet addr:10.129.90.29 Bcast:0.0.0.0 Mask:255.255.255.252
|
|
||||||
inet6 addr: fe80::a058:dcff:fe4d:ddca/64 Scope:Link
|
|
||||||
UP BROADCAST RUNNING NOARP MULTICAST MTU:1500 Metric:1
|
|
||||||
RX packets:4 errors:0 dropped:0 overruns:0 frame:0
|
|
||||||
TX packets:13 errors:0 dropped:0 overruns:0 carrier:0
|
|
||||||
collisions:0 txqueuelen:0
|
|
||||||
RX bytes:304 (304.0 B) TX bytes:1170 (1.1 KiB)
|
|
||||||
|
|
||||||
root@ZhuoTK:/# ifconfig wwan0.2
|
|
||||||
wwan0.2 Link encap:Ethernet HWaddr A2:58:DC:4D:DD:CA
|
|
||||||
inet addr:10.129.37.205 Bcast:0.0.0.0 Mask:255.255.255.252
|
|
||||||
inet6 addr: fe80::a058:dcff:fe4d:ddca/64 Scope:Link
|
|
||||||
UP BROADCAST RUNNING NOARP MULTICAST MTU:1500 Metric:1
|
|
||||||
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
|
|
||||||
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
|
|
||||||
collisions:0 txqueuelen:0
|
|
||||||
RX bytes:0 (0.0 B) TX bytes:720 (720.0 B)
|
|
||||||
|
|
||||||
root@ZhuoTK:/# ip ro del 8.8.8.8/32
|
|
||||||
RTNETLINK answers: No such process
|
|
||||||
root@ZhuoTK:/# ip ro add 8.8.8.8/32 dev wwan0.1
|
|
||||||
root@ZhuoTK:/# ping 8.8.8.8
|
|
||||||
PING 8.8.8.8 (8.8.8.8): 56 data bytes
|
|
||||||
64 bytes from 8.8.8.8: seq=0 ttl=52 time=98.584 ms
|
|
||||||
|
|
||||||
root@ZhuoTK:/# ip ro del 8.8.8.8/32
|
|
||||||
root@ZhuoTK:/# ip ro del 8.8.8.8/32
|
|
||||||
RTNETLINK answers: No such process
|
|
||||||
root@ZhuoTK:/# ip ro add 8.8.8.8/32 dev wwan0.2
|
|
||||||
root@ZhuoTK:/# ping 8.8.8.8
|
|
||||||
PING 8.8.8.8 (8.8.8.8): 56 data bytes
|
|
||||||
64 bytes from 8.8.8.8: seq=0 ttl=111 time=101.770 ms
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
# ./quectel-CM -s cmnet &
|
|
||||||
[04-21_17:35:14:362] Quectel_QConnectManager_Linux_V1.6.0.26
|
|
||||||
[04-21_17:35:14:363] Find /sys/bus/usb/devices/2-4 idVendor=0x2c7c idProduct=0x8101, bus=0x002, dev=0x016
|
|
||||||
[04-21_17:35:14:363] Auto find qmichannel = /dev/ttyUSB0
|
|
||||||
[04-21_17:35:14:363] Auto find usbnet_adapter = usb0
|
|
||||||
[04-21_17:35:14:363] netcard driver = cdc_ncm, driver version = 22-Aug-2005
|
|
||||||
[04-21_17:35:14:363] Modem works in ECM_RNDIS_NCM mode
|
|
||||||
[04-21_17:35:14:371] atc_fd = 7
|
|
||||||
[04-21_17:35:14:371] AT> ATE0Q0V1
|
|
||||||
[04-21_17:35:14:372] AT< RDATE0Q0V1
|
|
||||||
[04-21_17:35:14:372] AT< COMMAND NOT SUPPORT
|
|
||||||
[04-21_17:35:15:373] AT> AT+QCFG="usbnet"
|
|
||||||
[04-21_17:35:15:373] AT< +QCFG: "usbnet",5
|
|
||||||
[04-21_17:35:15:373] AT< OK
|
|
||||||
[04-21_17:35:15:373] AT> AT+QNETDEVCTL=?
|
|
||||||
[04-21_17:35:15:374] AT< +QNETDEVCTL: (1-11),(0,1),(0,1)
|
|
||||||
[04-21_17:35:15:374] AT< OK
|
|
||||||
[04-21_17:35:15:374] AT> AT+CGREG=2
|
|
||||||
[04-21_17:35:15:376] AT< OK
|
|
||||||
[04-21_17:35:15:376] AT> AT+CEREG=2
|
|
||||||
[04-21_17:35:15:381] AT< OK
|
|
||||||
[04-21_17:35:15:381] AT> AT+C5GREG=2
|
|
||||||
[04-21_17:35:15:384] AT< OK
|
|
||||||
[04-21_17:35:15:384] AT> AT+QNETDEVSTATUS=?
|
|
||||||
[04-21_17:35:15:385] AT< +QNETDEVSTATUS: (1-11)
|
|
||||||
[04-21_17:35:15:385] AT< OK
|
|
||||||
[04-21_17:35:15:385] AT> AT+QCFG="NAT"
|
|
||||||
[04-21_17:35:15:385] AT< +QCFG: "nat",0
|
|
||||||
[04-21_17:35:15:385] AT< OK
|
|
||||||
[04-21_17:35:15:385] AT> AT+CGMR
|
|
||||||
[04-21_17:35:15:386] AT< RG801HEAAAR03A01M8G
|
|
||||||
[04-21_17:35:15:386] AT< OK
|
|
||||||
[04-21_17:35:15:386] AT> AT+CPIN?
|
|
||||||
[04-21_17:35:15:388] AT< +CPIN: READY
|
|
||||||
[04-21_17:35:15:388] AT< OK
|
|
||||||
[04-21_17:35:15:389] AT> AT+QCCID
|
|
||||||
[04-21_17:35:15:393] AT< +QCCID: 89860015120716380461
|
|
||||||
[04-21_17:35:15:393] AT< OK
|
|
||||||
[04-21_17:35:15:393] requestGetICCID 89860015120716380461
|
|
||||||
[04-21_17:35:15:393] AT> AT+CIMI
|
|
||||||
[04-21_17:35:15:409] AT< 460028563800461
|
|
||||||
[04-21_17:35:15:409] AT< OK
|
|
||||||
[04-21_17:35:15:409] requestGetIMSI 460028563800461
|
|
||||||
[04-21_17:35:15:409] AT> AT+QICSGP=1
|
|
||||||
[04-21_17:35:15:411] AT< +QICSGP: 1,1,"cment","","",0,,0,
|
|
||||||
[04-21_17:35:15:411] AT< OK
|
|
||||||
[04-21_17:35:15:411] AT> AT+QICSGP=1
|
|
||||||
[04-21_17:35:15:415] AT< +QICSGP: 1,1,"cment","","",0,,0,
|
|
||||||
[04-21_17:35:15:415] AT< OK
|
|
||||||
[04-21_17:35:15:415] AT> AT+COPS=3,0;+COPS?;+COPS=3,1;+COPS?;+COPS=3,2;+COPS?
|
|
||||||
[04-21_17:35:15:421] AT< +COPS: 0,0,"CHINA MOBILE",12
|
|
||||||
[04-21_17:35:15:421] AT< +COPS: 0,1,"CMCC",12
|
|
||||||
[04-21_17:35:15:421] AT< +COPS: 0,2,"46000",12
|
|
||||||
[04-21_17:35:15:421] AT< OK
|
|
||||||
[04-21_17:35:15:421] AT> AT+C5GREG?
|
|
||||||
[04-21_17:35:15:424] AT< +C5GREG: 2,1,"46550B","0000000170C23000",11,1,"01"
|
|
||||||
[04-21_17:35:15:424] AT< OK
|
|
||||||
[04-21_17:35:15:424] AT> at+cops?
|
|
||||||
[04-21_17:35:15:427] AT< +COPS: 0,2,"46000",12
|
|
||||||
[04-21_17:35:15:427] AT< OK
|
|
||||||
[04-21_17:35:15:427] AT> at+qeng="servingcell"
|
|
||||||
[04-21_17:35:15:441] AT< +QENG: "servingcell","NOCONN","NR5G-SA","TDD",460,00,170C23000,901,46550B,504990,41,-,-54,-10,16,-,-
|
|
||||||
[04-21_17:35:15:441] AT< OK
|
|
||||||
[04-21_17:35:15:441] AT> AT+QNETDEVSTATUS=1
|
|
||||||
[04-21_17:35:15:445] AT< ERROR
|
|
||||||
[04-21_17:35:15:445] ifconfig usb0 0.0.0.0
|
|
||||||
[04-21_17:35:15:446] ifconfig usb0 down
|
|
||||||
[04-21_17:35:15:448] AT> AT+QNETDEVCTL=1,1,0
|
|
||||||
[04-21_17:35:15:454] AT< OK
|
|
||||||
[04-21_17:35:15:456] AT> AT+QNETDEVSTATUS=1
|
|
||||||
[04-21_17:35:15:458] AT< ERROR
|
|
||||||
[04-21_17:35:15:989] AT< +QNETDEVSTATUS:1,1,"IPV4"
|
|
||||||
[04-21_17:35:16:459] AT> AT+QNETDEVSTATUS=1
|
|
||||||
[04-21_17:35:16:461] AT< +QNETDEVSTATUS: 4F10190A,E0FFFFFF,4110190A,4110190A,02B48AD3,03B48AD3, 85600, 85600
|
|
||||||
[04-21_17:35:16:461] AT< OK
|
|
||||||
[04-21_17:35:16:461] AT> AT+QNETDEVSTATUS=1
|
|
||||||
[04-21_17:35:16:462] AT< +QNETDEVSTATUS: 4F10190A,E0FFFFFF,4110190A,4110190A,02B48AD3,03B48AD3, 85600, 85600
|
|
||||||
[04-21_17:35:16:462] AT< OK
|
|
||||||
[04-21_17:35:16:462] requestGetIPAddress 10.25.16.79
|
|
||||||
[04-21_17:35:16:462] AT> at+cops?
|
|
||||||
[04-21_17:35:16:463] AT< +COPS: 0,2,"46000",12
|
|
||||||
[04-21_17:35:16:463] AT< OK
|
|
||||||
[04-21_17:35:16:463] AT> at+qeng="servingcell"
|
|
||||||
[04-21_17:35:16:465] AT< +QENG: "servingcell","CONNECT","NR5G-SA","TDD",460,00,170C23000,901,46550B,504990,41,-,-52,-11,15,-,-
|
|
||||||
[04-21_17:35:16:465] AT< OK
|
|
||||||
[04-21_17:35:16:465] AT> AT+QNETDEVSTATUS=1
|
|
||||||
[04-21_17:35:16:466] AT< +QNETDEVSTATUS: 4F10190A,E0FFFFFF,4110190A,4110190A,02B48AD3,03B48AD3, 85600, 85600
|
|
||||||
[04-21_17:35:16:466] AT< OK
|
|
||||||
[04-21_17:35:16:466] ifconfig usb0 up
|
|
||||||
[04-21_17:35:16:470] busybox udhcpc -f -n -q -t 5 -i usb0
|
|
||||||
udhcpc: started, v1.30.1
|
|
||||||
udhcpc: sending discover
|
|
||||||
udhcpc: sending select for 10.25.16.79
|
|
||||||
udhcpc: lease of 10.25.16.79 obtained, lease time 518400
|
|
||||||
[04-21_17:35:16:602] /etc/udhcpc/default.script: Resetting default routes
|
|
||||||
SIOCDELRT: No such process
|
|
||||||
SIOCADDRT: Network is unreachable
|
|
||||||
[04-21_17:35:16:606] /etc/udhcpc/default.script: Adding DNS 211.138.180.2
|
|
||||||
[04-21_17:35:16:606] /etc/udhcpc/default.script: Adding DNS 211.138.180.3
|
|
||||||
[04-21_17:35:16:655] AT> at+cops?
|
|
||||||
[04-21_17:35:16:656] AT< +COPS: 0,2,"46000",12
|
|
||||||
[04-21_17:35:16:656] AT< OK
|
|
||||||
[04-21_17:35:16:656] AT> at+qeng="servingcell"
|
|
||||||
[04-21_17:35:16:657] AT< +QENG: "servingcell","CONNECT","NR5G-SA","TDD",460,00,170C23000,901,46550B,504990,41,-,-50,-11,17,-,-
|
|
||||||
[04-21_17:35:16:658] AT< OK
|
|
||||||
err = 16
|
|
||||||
[04-21_17:35:16:658] AT> AT+QNETDEVSTATUS=1
|
|
||||||
[04-21_17:35:16:659] AT< +QNETDEVSTATUS: 4F10190A,E0FFFFFF,4110190A,4110190A,02B48AD3,03B48AD3, 85600, 85600
|
|
||||||
[04-21_17:35:16:659] AT< OK
|
|
||||||
|
|
||||||
root@carl-ThinkPad-X1-Carbon-7th:/home/carl/q/quectel-CM# ifconfig usb0
|
|
||||||
usb0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
|
|
||||||
inet 10.25.16.79 netmask 255.255.255.224 broadcast 10.25.16.95
|
|
||||||
inet6 fe80::5c98:e9d4:c82d:5f prefixlen 64 scopeid 0x20<link>
|
|
||||||
ether 0c:5b:8f:27:9a:64 txqueuelen 1000 (Ethernet)
|
|
||||||
RX packets 7 bytes 1656 (1.6 KB)
|
|
||||||
RX errors 0 dropped 0 overruns 0 frame 0
|
|
||||||
TX packets 32 bytes 5112 (5.1 KB)
|
|
||||||
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
|
|
||||||
|
|
||||||
root@carl-ThinkPad-X1-Carbon-7th:/home/carl/q/quectel-CM# [04-21_17:35:31:670] AT> at+cops?
|
|
||||||
[04-21_17:35:31:671] AT< +COPS: 0,2,"46000",12
|
|
||||||
[04-21_17:35:31:671] AT< OK
|
|
||||||
[04-21_17:35:31:671] AT> at+qeng="servingcell"
|
|
||||||
[04-21_17:35:31:673] AT< +QENG: "servingcell","CONNECT","NR5G-SA","TDD",460,00,170C23000,901,46550B,504990,41,-,-48,-10,17,-,-
|
|
||||||
[04-21_17:35:31:673] AT< OK
|
|
||||||
[04-21_17:35:31:673] AT> AT+QNETDEVSTATUS=1
|
|
||||||
[04-21_17:35:31:674] AT< +QNETDEVSTATUS: 4F10190A,E0FFFFFF,4110190A,4110190A,02B48AD3,03B48AD3, 85600, 85600
|
|
||||||
[04-21_17:35:31:674] AT< OK
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
root@ZhuoTK:/# dmesg
|
|
||||||
[ 230.590000] GobiNet 1-1.3:1.4 usb0: register 'GobiNet' at usb-101c0000.ehci-1.3, GobiNet Ethernet Device, 02:50:f4:00:00:00
|
|
||||||
[ 230.600000] creating qcqmi0
|
|
||||||
|
|
||||||
root@ZhuoTK:/# quectel-CM -s cmnet &
|
|
||||||
[04-13_03:24:58:213] Quectel_QConnectManager_Linux_V1.6.0.25
|
|
||||||
[04-13_03:24:58:216] Find /sys/bus/usb/devices/1-1.3 idVendor=0x2c7c idProduct=0x125, bus=0x001, dev=0x004
|
|
||||||
[04-13_03:24:58:218] Auto find qmichannel = /dev/qcqmi0
|
|
||||||
[04-13_03:24:58:218] Auto find usbnet_adapter = usb0
|
|
||||||
[04-13_03:24:58:218] netcard driver = GobiNet, driver version = V1.6.2.13
|
|
||||||
[04-13_03:24:58:219] Modem works in QMI mode
|
|
||||||
[04-13_03:24:58:260] Get clientWDS = 7
|
|
||||||
[04-13_03:24:58:292] Get clientDMS = 8
|
|
||||||
[04-13_03:24:58:324] Get clientNAS = 9
|
|
||||||
[04-13_03:24:58:355] Get clientUIM = 10
|
|
||||||
[04-13_03:24:58:388] Get clientWDA = 11
|
|
||||||
[04-13_03:24:58:420] requestBaseBandVersion EC25EFAR06A11M4G
|
|
||||||
[04-13_03:24:58:548] requestGetSIMStatus SIMStatus: SIM_READY
|
|
||||||
[04-13_03:24:58:549] requestSetProfile[1] cmnet///0
|
|
||||||
[04-13_03:24:58:613] requestGetProfile[1] cmnet///0
|
|
||||||
[04-13_03:24:58:645] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: LTE
|
|
||||||
[04-13_03:24:58:677] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
|
||||||
[04-13_03:24:58:677] ifconfig usb0 0.0.0.0
|
|
||||||
[04-13_03:24:58:696] ifconfig usb0 down
|
|
||||||
[04-13_03:24:59:028] requestSetupDataCall WdsConnectionIPv4Handle: 0x87245bd0
|
|
||||||
[04-13_03:24:59:189] ifconfig usb0 up
|
|
||||||
[04-13_03:24:59:214] you are use OpenWrt?
|
|
||||||
[04-13_03:24:59:215] should not calling udhcpc manually?
|
|
||||||
[04-13_03:24:59:215] should modify /etc/config/network as below?
|
|
||||||
[04-13_03:24:59:215] config interface wan
|
|
||||||
[04-13_03:24:59:215] option ifname usb0
|
|
||||||
[04-13_03:24:59:215] option proto dhcp
|
|
||||||
[04-13_03:24:59:215] should use "/sbin/ifstaus wan" to check usb0 's status?
|
|
||||||
[04-13_03:24:59:216] busybox udhcpc -f -n -q -t 5 -i usb0
|
|
||||||
[04-13_03:24:59:226] udhcpc (v1.23.2) started
|
|
||||||
[04-13_03:24:59:238] Sending discover...
|
|
||||||
[04-13_03:24:59:248] Sending select for 10.198.78.154...
|
|
||||||
[04-13_03:24:59:251] Lease of 10.198.78.154 obtained, lease time 7200
|
|
||||||
[04-13_03:24:59:257] udhcpc: ifconfig usb0 10.198.78.154 netmask 255.255.255.252 broadcast +
|
|
||||||
[04-13_03:24:59:266] udhcpc: setting default routers: 10.198.78.153
|
|
||||||
|
|
||||||
root@ZhuoTK:/# ifconfig usb0
|
|
||||||
usb0 Link encap:Ethernet HWaddr 02:50:F4:00:00:00
|
|
||||||
inet addr:10.198.78.154 Mask:255.255.255.252
|
|
||||||
inet6 addr: fe80::50:f4ff:fe00:0/64 Scope:Link
|
|
||||||
UP RUNNING NOARP MTU:1500 Metric:1
|
|
||||||
RX packets:6 errors:0 dropped:0 overruns:0 frame:0
|
|
||||||
TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
|
|
||||||
collisions:0 txqueuelen:1000
|
|
||||||
RX bytes:916 (916.0 B) TX bytes:960 (960.0 B)
|
|
||||||
|
|
||||||
root@ZhuoTK:/# ip ro show
|
|
||||||
default via 10.198.78.153 dev usb0
|
|
||||||
10.198.78.152/30 dev usb0 proto kernel scope link src 10.198.78.154
|
|
||||||
192.168.1.0/24 dev br-lan proto kernel scope link src 192.168.1.251
|
|
||||||
|
|
||||||
root@ZhuoTK:/# killall quectel-CM
|
|
||||||
[04-13_03:25:38:779] requestDeactivateDefaultPDP WdsConnectionIPv4Handle
|
|
||||||
[04-13_03:25:39:061] ifconfig usb0 0.0.0.0
|
|
||||||
[04-13_03:25:39:072] ifconfig usb0 down
|
|
||||||
[04-13_03:25:39:284] GobiNetThread exit
|
|
||||||
[04-13_03:25:39:285] qmi_main exit
|
|
||||||
Loaded 100 of 276 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user