mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-29 08:25:13 +08:00
🍓 Sync 2026-06-04 16:10:22
This commit is contained in:
1 parent
50aabfee18
commit
2e06461e78
289 files changed
+114950
-145
No files matched your search
@@ -0,0 +1,22 @@
|
||||
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))
|
||||
@@ -0,0 +1,75 @@
|
||||
--- 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;
|
||||
@@ -0,0 +1,30 @@
|
||||
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;
|
||||
@@ -0,0 +1,38 @@
|
||||
obj-m += qmi_wwan_f.o
|
||||
|
||||
PWD := $(shell pwd)
|
||||
OUTPUTDIR=/lib/modules/`uname -r`/kernel/drivers/net/usb/
|
||||
|
||||
ifeq ($(ARCH),)
|
||||
ARCH := $(shell uname -m)
|
||||
endif
|
||||
ifeq ($(CROSS_COMPILE),)
|
||||
CROSS_COMPILE :=
|
||||
endif
|
||||
ifeq ($(KDIR),)
|
||||
KDIR := /lib/modules/$(shell uname -r)/build
|
||||
ifeq ($(ARCH),i686)
|
||||
ifeq ($(wildcard $KDIR/arch/$ARCH),)
|
||||
ARCH=i386
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(findstring &,${PWD}),)
|
||||
$(warning "${PWD}")
|
||||
$(warning "current directory contain special char '&' !")
|
||||
$(error "please remove it!")
|
||||
endif
|
||||
|
||||
default:
|
||||
$(MAKE) ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} -C $(KDIR) M=$(PWD) modules
|
||||
|
||||
install: default
|
||||
cp $(PWD)/qmi_wwan_f.ko /lib/modules/$(shell uname -r)/kernel/drivers/net/usb/
|
||||
depmod
|
||||
modprobe -r qmi_wwan_f
|
||||
modprobe -r qmi_wwan
|
||||
modprobe qmi_wwan_f
|
||||
clean:
|
||||
rm -rf *~ .tmp_versions modules.order Module.symvers
|
||||
find . -type f -name "*~" -o -name "*.o" -o -name "*.ko" -o -name "*.cmd" -o -name "*.mod.c" | xargs rm -rf
|
||||
File diff suppressed because it is too large.
Load diff
@@ -11,8 +11,8 @@ LUCI_DESCRIPTION:=LuCI JS interface for the modemband. The package allows set LT
|
||||
LUCI_DEPENDS:=+modemband
|
||||
|
||||
PKG_NAME:=luci-app-modemband
|
||||
PKG_VERSION:=1.0.25.20240519
|
||||
PKG_RELEASE:=1
|
||||
PKG_VERSION:=1.0.24
|
||||
PKG_RELEASE:=2
|
||||
PKG_MAINTAINER:=Rafał Wabik <4Rafal@gmail.com>
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
@@ -12,29 +12,29 @@
|
||||
Copyright 2022-2024 Rafał Wabik - IceG - From eko.one.pl forum
|
||||
*/
|
||||
|
||||
var CBISelectswitch = form.DummyValue.extend({
|
||||
renderWidget: function(section_id, option_id, cfgvalue) {
|
||||
var section = this.section;
|
||||
return E([], [
|
||||
E('span', { 'class': 'control-group' }, [
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-apply',
|
||||
'click': ui.createHandlerFn(this, function() {
|
||||
var dropdown = section.getUIElement(section_id, 'set_5gnsabands');
|
||||
dropdown.setValue([]);
|
||||
}),
|
||||
}, _('Deselect all')),
|
||||
' ',
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-action important',
|
||||
'click': ui.createHandlerFn(this, function() {
|
||||
var dropdown = section.getUIElement(section_id, 'set_5gnsabands');
|
||||
dropdown.setValue(Object.keys(dropdown.choices));
|
||||
})
|
||||
}, _('Select all'))
|
||||
])
|
||||
]);
|
||||
},
|
||||
var CBISelectswitch = form.DummyValue.extend({
|
||||
renderWidget: function(section_id, option_id, cfgvalue) {
|
||||
var section = this.section;
|
||||
return E([], [
|
||||
E('span', { 'class': 'control-group' }, [
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-apply',
|
||||
'click': ui.createHandlerFn(this, function() {
|
||||
var dropdown = section.getUIElement(section_id, 'set_5gnsabands');
|
||||
dropdown.setValue([]);
|
||||
}),
|
||||
}, _('Deselect all')),
|
||||
' ',
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-action important',
|
||||
'click': ui.createHandlerFn(this, function() {
|
||||
var dropdown = section.getUIElement(section_id, 'set_5gnsabands');
|
||||
dropdown.setValue(Object.keys(dropdown.choices));
|
||||
})
|
||||
}, _('Select all'))
|
||||
])
|
||||
]);
|
||||
},
|
||||
});
|
||||
|
||||
var BANDmagic = form.DummyValue.extend({
|
||||
@@ -176,14 +176,14 @@ function handleAction(ev) {
|
||||
if (ev === 'reload') {
|
||||
location.reload();
|
||||
}
|
||||
if (ev === 'resetbandz') {
|
||||
if (ev === 'resetbandz') {
|
||||
if (confirm(_('Do you really want to set up all possible bands for the modem?')))
|
||||
{
|
||||
fs.exec_direct('/usr/bin/modemband.sh', [ 'setbands5gnsa', 'default' ]);
|
||||
|
||||
return uci.load('modemband').then(function() {
|
||||
var nuser = (uci.get('modemband', '@modemband[0]', 'notify'));
|
||||
|
||||
|
||||
if ( nuser != '1' || nuser == null ) {
|
||||
ui.addNotification(null, E('p', _('The new bands settings have been sent to the modem. If the changes are not visible, a restart of the connection, modem or router may be required.')), 'info');
|
||||
}
|
||||
@@ -202,7 +202,7 @@ function handleAction(ev) {
|
||||
if (ev === 'restartwan') {
|
||||
return uci.load('modemband').then(function() {
|
||||
var wname = (uci.get('modemband', '@modemband[0]', 'iface'));
|
||||
|
||||
|
||||
if (wname.includes('@')) {
|
||||
wname = wname.replace(/@/g, '')
|
||||
};
|
||||
@@ -251,7 +251,7 @@ return view.extend({
|
||||
modemen = modemen.includes('n0') == true ? modemen = _('Bands are disabled...') : modemen.trim();
|
||||
|
||||
|
||||
for (var i = 0; i < json.supported5gnsa.length; i++)
|
||||
for (var i = 0; i < json.supported5gnsa.length; i++)
|
||||
{
|
||||
var txtband = json.supported5gnsa[i].band.toString();
|
||||
var numb = txtband.match(/\d+$/);
|
||||
@@ -259,18 +259,18 @@ return view.extend({
|
||||
sbands = sbands.replace('undefined', '');
|
||||
}
|
||||
sbands = sbands.trim();
|
||||
|
||||
|
||||
|
||||
|
||||
pollData: poll.add(function() {
|
||||
return L.resolveDefault(fs.exec_direct('/usr/bin/modemband.sh', [ 'json' ]))
|
||||
.then(function(res) {
|
||||
var json = JSON.parse(res);
|
||||
//modemen = _('Waiting for device...');
|
||||
if ( json != null ) {
|
||||
if ( json != null ) {
|
||||
|
||||
var renderHTML = "";
|
||||
var view = document.getElementById("modemlteb");
|
||||
for (var i = 0; i < json.enabled5gnsa.length; i++)
|
||||
for (var i = 0; i < json.enabled5gnsa.length; i++)
|
||||
{
|
||||
var txtband = json.enabled5gnsa[i].toString();
|
||||
var numb = txtband.match(/\d+$/);
|
||||
@@ -288,7 +288,7 @@ return view.extend({
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (json.error.includes('No supported') == true) {
|
||||
modemen = '-';
|
||||
@@ -305,7 +305,7 @@ return view.extend({
|
||||
} catch (err) {
|
||||
console.log('Error: ', err.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var info = _('Configuration modem frequency bands. More information about the modemband application on the %seko.one.pl forum%s.').format('<a href="https://eko.one.pl/?p=openwrt-modemband" target="_blank">', '</a>');
|
||||
|
||||
@@ -347,21 +347,21 @@ return view.extend({
|
||||
else {
|
||||
|
||||
s.tab('bandset', _('Preferred bands settings'));
|
||||
|
||||
|
||||
o = s.taboption('bandset', cbiRichListValue, 'set_5gnsabands',
|
||||
_('Modification of the bands'),
|
||||
_('Modification of the bands'),
|
||||
_("Select the preferred band(s) for the modem."));
|
||||
for (var i = 0; i < json.supported5gnsa.length; i++)
|
||||
for (var i = 0; i < json.supported5gnsa.length; i++)
|
||||
{
|
||||
o.value(json.supported5gnsa[i].band, _('n')+json.supported5gnsa[i].band,json.supported5gnsa[i].txt);
|
||||
}
|
||||
|
||||
|
||||
o.multiple = true;
|
||||
o.placeholder = _('Please select a band(s)');
|
||||
o.cfgvalue = function(section_id) {
|
||||
return L.toArray((json.enabled5gnsa).join(' '));
|
||||
};
|
||||
|
||||
|
||||
o = s.taboption('bandset', CBISelectswitch, '_switch', _('Band selection switch'));
|
||||
|
||||
s = m.section(form.TypedSection);
|
||||
@@ -383,7 +383,7 @@ return view.extend({
|
||||
|
||||
o = s.taboption('opt1', SYSTmagic);
|
||||
}
|
||||
|
||||
|
||||
return m.render();
|
||||
},
|
||||
|
||||
@@ -396,7 +396,7 @@ return view.extend({
|
||||
args.push(data.modemband.set_5gnsabands);
|
||||
var ax = args.toString();
|
||||
ax = ax.replace(/,/g, ' ')
|
||||
|
||||
|
||||
ax.length >= 1 ? fs.exec_direct('/usr/bin/modemband.sh', [ 'setbands5gnsa', ax ]) : ui.addNotification(null, E('p', _('Check if you have selected the bands correctly.')), 'info');
|
||||
|
||||
return uci.load('modemband').then(function() {
|
||||
@@ -404,20 +404,20 @@ return view.extend({
|
||||
var mrestart = (uci.get('modemband', '@modemband[0]', 'modemrestart'));
|
||||
var cmdrestart = (uci.get('modemband', '@modemband[0]', 'restartcmd'));
|
||||
var wname = (uci.get('modemband', '@modemband[0]', 'iface'));
|
||||
|
||||
|
||||
if (wname.includes('@')) {
|
||||
wname = wname.replace(/@/g, '')
|
||||
};
|
||||
|
||||
|
||||
var sport = (uci.get('modemband', '@modemband[0]', 'set_port'));
|
||||
var nuser = (uci.get('modemband', '@modemband[0]', 'notify'));
|
||||
|
||||
|
||||
if ( ax.length >= 1 ) {
|
||||
if ( nuser != '1' || nuser == null ) {
|
||||
ui.addNotification(null, E('p', _('The new bands settings have been sent to the modem. If the changes are not visible, a restart of the connection, modem or router may be required.')), 'info');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (wrestart == '1') {
|
||||
fs.exec('/sbin/ifdown', [ wname ]);
|
||||
fs.exec('sleep 3');
|
||||
|
||||
@@ -13,29 +13,29 @@
|
||||
*/
|
||||
|
||||
|
||||
var CBISelectswitch = form.DummyValue.extend({
|
||||
renderWidget: function(section_id, option_id, cfgvalue) {
|
||||
var section = this.section;
|
||||
return E([], [
|
||||
E('span', { 'class': 'control-group' }, [
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-apply',
|
||||
'click': ui.createHandlerFn(this, function() {
|
||||
var dropdown = section.getUIElement(section_id, 'set_5gsabands');
|
||||
dropdown.setValue([]);
|
||||
}),
|
||||
}, _('Deselect all')),
|
||||
' ',
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-action important',
|
||||
'click': ui.createHandlerFn(this, function() {
|
||||
var dropdown = section.getUIElement(section_id, 'set_5gsabands');
|
||||
dropdown.setValue(Object.keys(dropdown.choices));
|
||||
})
|
||||
}, _('Select all'))
|
||||
])
|
||||
]);
|
||||
},
|
||||
var CBISelectswitch = form.DummyValue.extend({
|
||||
renderWidget: function(section_id, option_id, cfgvalue) {
|
||||
var section = this.section;
|
||||
return E([], [
|
||||
E('span', { 'class': 'control-group' }, [
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-apply',
|
||||
'click': ui.createHandlerFn(this, function() {
|
||||
var dropdown = section.getUIElement(section_id, 'set_5gsabands');
|
||||
dropdown.setValue([]);
|
||||
}),
|
||||
}, _('Deselect all')),
|
||||
' ',
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-action important',
|
||||
'click': ui.createHandlerFn(this, function() {
|
||||
var dropdown = section.getUIElement(section_id, 'set_5gsabands');
|
||||
dropdown.setValue(Object.keys(dropdown.choices));
|
||||
})
|
||||
}, _('Select all'))
|
||||
])
|
||||
]);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -178,14 +178,14 @@ function handleAction(ev) {
|
||||
if (ev === 'reload') {
|
||||
location.reload();
|
||||
}
|
||||
if (ev === 'resetbandz') {
|
||||
if (ev === 'resetbandz') {
|
||||
if (confirm(_('Do you really want to set up all possible bands for the modem?')))
|
||||
{
|
||||
fs.exec_direct('/usr/bin/modemband.sh', [ 'setbands5gsa', 'default' ]);
|
||||
|
||||
return uci.load('modemband').then(function() {
|
||||
var nuser = (uci.get('modemband', '@modemband[0]', 'notify'));
|
||||
|
||||
|
||||
if ( nuser != '1' || nuser == null ) {
|
||||
ui.addNotification(null, E('p', _('The new bands settings have been sent to the modem. If the changes are not visible, a restart of the connection, modem or router may be required.')), 'info');
|
||||
}
|
||||
@@ -204,7 +204,7 @@ function handleAction(ev) {
|
||||
if (ev === 'restartwan') {
|
||||
return uci.load('modemband').then(function() {
|
||||
var wname = (uci.get('modemband', '@modemband[0]', 'iface'));
|
||||
|
||||
|
||||
if (wname.includes('@')) {
|
||||
wname = wname.replace(/@/g, '')
|
||||
};
|
||||
@@ -243,7 +243,7 @@ return view.extend({
|
||||
else {
|
||||
|
||||
var modem = json.modem;
|
||||
for (var i = 0; i < json.enabled5gsa.length; i++)
|
||||
for (var i = 0; i < json.enabled5gsa.length; i++)
|
||||
{
|
||||
var txtband = json.enabled5gsa[i].toString();
|
||||
var numb = txtband.match(/\d+$/);
|
||||
@@ -252,7 +252,7 @@ return view.extend({
|
||||
}
|
||||
modemen = modemen.includes('n0') == true ? modemen = _('Bands are disabled...') : modemen = modemen.trim();
|
||||
|
||||
for (var i = 0; i < json.supported5gsa.length; i++)
|
||||
for (var i = 0; i < json.supported5gsa.length; i++)
|
||||
{
|
||||
var txtband = json.supported5gsa[i].band.toString();
|
||||
var numb = txtband.match(/\d+$/);
|
||||
@@ -260,17 +260,17 @@ return view.extend({
|
||||
sbands = sbands.replace('undefined', '');
|
||||
}
|
||||
sbands = sbands.trim();
|
||||
|
||||
|
||||
pollData: poll.add(function() {
|
||||
return L.resolveDefault(fs.exec_direct('/usr/bin/modemband.sh', [ 'json' ]))
|
||||
.then(function(res) {
|
||||
var json = JSON.parse(res);
|
||||
//modemen = _('Waiting for device...');
|
||||
if ( json != null ) {
|
||||
if ( json != null ) {
|
||||
|
||||
var renderHTML = "";
|
||||
var view = document.getElementById("modemlteb");
|
||||
for (var i = 0; i < json.enabled5gsa.length; i++)
|
||||
for (var i = 0; i < json.enabled5gsa.length; i++)
|
||||
{
|
||||
var txtband = json.enabled5gsa[i].toString();
|
||||
var numb = txtband.match(/\d+$/);
|
||||
@@ -288,7 +288,7 @@ return view.extend({
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (json.error.includes('No supported') == true) {
|
||||
modemen = '-';
|
||||
@@ -305,7 +305,7 @@ return view.extend({
|
||||
} catch (err) {
|
||||
console.log('Error: ', err.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var info = _('Configuration modem frequency bands. More information about the modemband application on the %seko.one.pl forum%s.').format('<a href="https://eko.one.pl/?p=openwrt-modemband" target="_blank">', '</a>');
|
||||
|
||||
@@ -347,15 +347,15 @@ return view.extend({
|
||||
else {
|
||||
|
||||
s.tab('bandset', _('Preferred bands settings'));
|
||||
|
||||
|
||||
o = s.taboption('bandset', cbiRichListValue, 'set_5gsabands',
|
||||
_('Modification of the bands'),
|
||||
_('Modification of the bands'),
|
||||
_("Select the preferred band(s) for the modem."));
|
||||
for (var i = 0; i < json.supported5gsa.length; i++)
|
||||
for (var i = 0; i < json.supported5gsa.length; i++)
|
||||
{
|
||||
o.value(json.supported5gsa[i].band, _('n')+json.supported5gsa[i].band,json.supported5gsa[i].txt);
|
||||
}
|
||||
|
||||
|
||||
o.multiple = true;
|
||||
o.placeholder = _('Please select a band(s)');
|
||||
o.cfgvalue = function(section_id) {
|
||||
@@ -383,7 +383,7 @@ return view.extend({
|
||||
|
||||
o = s.taboption('opt1', SYSTmagic);
|
||||
}
|
||||
|
||||
|
||||
return m.render();
|
||||
},
|
||||
|
||||
@@ -396,7 +396,7 @@ return view.extend({
|
||||
args.push(data.modemband.set_5gsabands);
|
||||
var ax = args.toString();
|
||||
ax = ax.replace(/,/g, ' ')
|
||||
|
||||
|
||||
ax.length >= 1 ? fs.exec_direct('/usr/bin/modemband.sh', [ 'setbands5gsa', ax ]) : ui.addNotification(null, E('p', _('Check if you have selected the bands correctly.')), 'info');
|
||||
|
||||
return uci.load('modemband').then(function() {
|
||||
@@ -404,20 +404,20 @@ return view.extend({
|
||||
var mrestart = (uci.get('modemband', '@modemband[0]', 'modemrestart'));
|
||||
var cmdrestart = (uci.get('modemband', '@modemband[0]', 'restartcmd'));
|
||||
var wname = (uci.get('modemband', '@modemband[0]', 'iface'));
|
||||
|
||||
|
||||
if (wname.includes('@')) {
|
||||
wname = wname.replace(/@/g, '')
|
||||
};
|
||||
|
||||
|
||||
var sport = (uci.get('modemband', '@modemband[0]', 'set_port'));
|
||||
var nuser = (uci.get('modemband', '@modemband[0]', 'notify'));
|
||||
|
||||
|
||||
if ( ax.length >= 1 ) {
|
||||
if ( nuser != '1' || nuser == null ) {
|
||||
ui.addNotification(null, E('p', _('The new bands settings have been sent to the modem. If the changes are not visible, a restart of the connection, modem or router may be required.')), 'info');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (wrestart == '1') {
|
||||
fs.exec('/sbin/ifdown', [ wname ]);
|
||||
fs.exec('sleep 3');
|
||||
|
||||
@@ -12,29 +12,29 @@
|
||||
Copyright 2022-2024 Rafał Wabik - IceG - From eko.one.pl forum
|
||||
*/
|
||||
|
||||
var CBISelectswitch = form.DummyValue.extend({
|
||||
renderWidget: function(section_id, option_id, cfgvalue) {
|
||||
var section = this.section;
|
||||
return E([], [
|
||||
E('span', { 'class': 'control-group' }, [
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-apply',
|
||||
'click': ui.createHandlerFn(this, function() {
|
||||
var dropdown = section.getUIElement(section_id, 'set_bands');
|
||||
dropdown.setValue([]);
|
||||
}),
|
||||
}, _('Deselect all')),
|
||||
' ',
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-action important',
|
||||
'click': ui.createHandlerFn(this, function() {
|
||||
var dropdown = section.getUIElement(section_id, 'set_bands');
|
||||
dropdown.setValue(Object.keys(dropdown.choices));
|
||||
})
|
||||
}, _('Select all'))
|
||||
])
|
||||
]);
|
||||
},
|
||||
var CBISelectswitch = form.DummyValue.extend({
|
||||
renderWidget: function(section_id, option_id, cfgvalue) {
|
||||
var section = this.section;
|
||||
return E([], [
|
||||
E('span', { 'class': 'control-group' }, [
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-apply',
|
||||
'click': ui.createHandlerFn(this, function() {
|
||||
var dropdown = section.getUIElement(section_id, 'set_bands');
|
||||
dropdown.setValue([]);
|
||||
}),
|
||||
}, _('Deselect all')),
|
||||
' ',
|
||||
E('button', {
|
||||
'class': 'cbi-button cbi-button-action important',
|
||||
'click': ui.createHandlerFn(this, function() {
|
||||
var dropdown = section.getUIElement(section_id, 'set_bands');
|
||||
dropdown.setValue(Object.keys(dropdown.choices));
|
||||
})
|
||||
}, _('Select all'))
|
||||
])
|
||||
]);
|
||||
},
|
||||
});
|
||||
|
||||
var BANDmagic = form.DummyValue.extend({
|
||||
@@ -224,14 +224,14 @@ function handleAction(ev) {
|
||||
if (ev === 'reload') {
|
||||
location.reload();
|
||||
}
|
||||
if (ev === 'resetbandz') {
|
||||
if (ev === 'resetbandz') {
|
||||
if (confirm(_('Do you really want to set up all possible bands for the modem?')))
|
||||
{
|
||||
fs.exec_direct('/usr/bin/modemband.sh', [ 'setbands', 'default' ]);
|
||||
|
||||
return uci.load('modemband').then(function() {
|
||||
var nuser = (uci.get('modemband', '@modemband[0]', 'notify'));
|
||||
|
||||
|
||||
if ( nuser != '1' || nuser == null ) {
|
||||
ui.addNotification(null, E('p', _('The new bands settings have been sent to the modem. If the changes are not visible, a restart of the connection, modem or router may be required.')), 'info');
|
||||
}
|
||||
@@ -250,7 +250,7 @@ function handleAction(ev) {
|
||||
if (ev === 'restartwan') {
|
||||
return uci.load('modemband').then(function() {
|
||||
var wname = (uci.get('modemband', '@modemband[0]', 'iface'));
|
||||
|
||||
|
||||
if (wname.includes('@')) {
|
||||
wname = wname.replace(/@/g, '')
|
||||
};
|
||||
@@ -265,7 +265,7 @@ function handleAction(ev) {
|
||||
//var sport = (uci.get('modemband', '@modemband[0]', 'set_port'));
|
||||
fs.exec_direct('/usr/bin/sms_tool', [ '-d' , '/dev/ttyUSB1' , 'at' , 'AT+ZULCA=1' ]);
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
if (ev === 'offupload') {
|
||||
return uci.load('modemband').then(function() {
|
||||
@@ -304,7 +304,7 @@ return view.extend({
|
||||
else {
|
||||
|
||||
var modem = json.modem;
|
||||
for (var i = 0; i < json.enabled.length; i++)
|
||||
for (var i = 0; i < json.enabled.length; i++)
|
||||
{
|
||||
var txtband = json.enabled[i].toString();
|
||||
var numb = txtband.match(/\d+$/);
|
||||
@@ -313,7 +313,7 @@ return view.extend({
|
||||
}
|
||||
modemen = modemen.trim();
|
||||
|
||||
for (var i = 0; i < json.supported.length; i++)
|
||||
for (var i = 0; i < json.supported.length; i++)
|
||||
{
|
||||
var txtband = json.supported[i].band.toString();
|
||||
var numb = txtband.match(/\d+$/);
|
||||
@@ -321,17 +321,17 @@ return view.extend({
|
||||
sbands = sbands.replace('undefined', '');
|
||||
}
|
||||
sbands = sbands.trim();
|
||||
|
||||
|
||||
pollData: poll.add(function() {
|
||||
return L.resolveDefault(fs.exec_direct('/usr/bin/modemband.sh', [ 'json' ]))
|
||||
.then(function(res) {
|
||||
var json = JSON.parse(res);
|
||||
//modemen = _('Waiting for device...');
|
||||
if ( json != null ) {
|
||||
if ( json != null ) {
|
||||
|
||||
var renderHTML = "";
|
||||
var view = document.getElementById("modemlteb");
|
||||
for (var i = 0; i < json.enabled.length; i++)
|
||||
for (var i = 0; i < json.enabled.length; i++)
|
||||
{
|
||||
var txtband = json.enabled[i].toString();
|
||||
var numb = txtband.match(/\d+$/);
|
||||
@@ -349,7 +349,7 @@ return view.extend({
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (json.error.includes('No supported') == true) {
|
||||
modemen = '-';
|
||||
@@ -365,7 +365,7 @@ return view.extend({
|
||||
} catch (err) {
|
||||
console.log('Error: ', err.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var info = _('Configuration modem frequency bands. More information about the modemband application on the %seko.one.pl forum%s.').format('<a href="https://eko.one.pl/?p=openwrt-modemband" target="_blank">', '</a>');
|
||||
|
||||
@@ -408,23 +408,23 @@ return view.extend({
|
||||
}
|
||||
else {
|
||||
s.tab('bandset', _('Preferred bands settings'));
|
||||
|
||||
|
||||
o = s.taboption('bandset', cbiRichListValue, 'set_bands',
|
||||
_('Modification of the bands'),
|
||||
_('Modification of the bands'),
|
||||
_("Select the preferred band(s) for the modem."));
|
||||
|
||||
for (var i = 0; i < json.supported.length; i++)
|
||||
for (var i = 0; i < json.supported.length; i++)
|
||||
{
|
||||
o.value(json.supported[i].band, _('B')+json.supported[i].band,json.supported[i].txt);
|
||||
}
|
||||
|
||||
|
||||
o.multiple = true;
|
||||
o.placeholder = _('Please select a band(s)');
|
||||
|
||||
o.cfgvalue = function(section_id) {
|
||||
return L.toArray((json.enabled).join(' '));
|
||||
};
|
||||
|
||||
|
||||
o = s.taboption('bandset', CBISelectswitch, '_switch', _('Band selection switch'));
|
||||
|
||||
s = m.section(form.TypedSection);
|
||||
@@ -466,7 +466,7 @@ return view.extend({
|
||||
'</em></div>';
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
return m.render();
|
||||
},
|
||||
|
||||
@@ -479,7 +479,7 @@ return view.extend({
|
||||
args.push(data.modemband.set_bands);
|
||||
var ax = args.toString();
|
||||
ax = ax.replace(/,/g, ' ')
|
||||
|
||||
|
||||
ax.length >= 1 ? fs.exec_direct('/usr/bin/modemband.sh', [ 'setbands', ax ]) : ui.addNotification(null, E('p', _('Check if you have selected the bands correctly.')), 'info');
|
||||
|
||||
return uci.load('modemband').then(function() {
|
||||
@@ -487,20 +487,20 @@ return view.extend({
|
||||
var mrestart = (uci.get('modemband', '@modemband[0]', 'modemrestart'));
|
||||
var cmdrestart = (uci.get('modemband', '@modemband[0]', 'restartcmd'));
|
||||
var wname = (uci.get('modemband', '@modemband[0]', 'iface'));
|
||||
|
||||
|
||||
if (wname.includes('@')) {
|
||||
wname = wname.replace(/@/g, '')
|
||||
};
|
||||
|
||||
|
||||
var sport = (uci.get('modemband', '@modemband[0]', 'set_port'));
|
||||
var nuser = (uci.get('modemband', '@modemband[0]', 'notify'));
|
||||
|
||||
|
||||
if ( ax.length >= 1 ) {
|
||||
if ( nuser != '1' || nuser == null ) {
|
||||
ui.addNotification(null, E('p', _('The new bands settings have been sent to the modem. If the changes are not visible, a restart of the connection, modem or router may be required.')), 'info');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (wrestart == '1') {
|
||||
fs.exec('/sbin/ifdown', [ wname ]);
|
||||
fs.exec('sleep 3');
|
||||
|
||||
@@ -33,7 +33,7 @@ return view.extend({
|
||||
o.noaliases = false;
|
||||
o.default = 'wan';
|
||||
*/
|
||||
|
||||
|
||||
o = s.option(widgets.NetworkSelect, 'iface', _('Interface'),
|
||||
_('Network interface for Internet access.')
|
||||
);
|
||||
@@ -42,11 +42,11 @@ return view.extend({
|
||||
o.rmempty = false;
|
||||
o.default = 'wan';
|
||||
|
||||
o = s.option(form.Value, 'set_port', _('Port for communication with the modem'),
|
||||
o = s.option(form.Value, 'set_port', _('Port for communication with the modem'),
|
||||
_("Select one of the available ttyUSBX ports."));
|
||||
devs.sort((a, b) => a.name > b.name);
|
||||
devs.forEach(dev => o.value('/dev/' + dev.name));
|
||||
|
||||
|
||||
o.placeholder = _('Please select a port');
|
||||
o.rmempty = false;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
/*
|
||||
Copyright 2022-2024 Rafał Wabik - IceG - From eko.one.pl forum
|
||||
|
||||
|
||||
MIT License
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
'require form';
|
||||
'require network';
|
||||
|
||||
const callFileList = rpc.declare({
|
||||
var callFileList = rpc.declare({
|
||||
object: 'file',
|
||||
method: 'list',
|
||||
params: [ 'path' ],
|
||||
expect: { entries: [] },
|
||||
filter: function(list, params) {
|
||||
let rv = [];
|
||||
for (let i = 0; i < list.length; i++)
|
||||
var rv = [];
|
||||
for (var i = 0; i < list.length; i++)
|
||||
if (list[i].name.match(/^cdc-wdm/))
|
||||
rv.push(params.path + list[i].name);
|
||||
return rv.sort();
|
||||
@@ -31,7 +31,7 @@ return network.registerProtocol('quectel', {
|
||||
return this._ubus('l3_device') || 'quectel-%s'.format(this.sid);
|
||||
},
|
||||
|
||||
getPackageName: function() {
|
||||
getOpkgPackage: function() {
|
||||
return 'quectel-cm';
|
||||
},
|
||||
|
||||
@@ -52,14 +52,14 @@ return network.registerProtocol('quectel', {
|
||||
},
|
||||
|
||||
renderFormOptions: function(s) {
|
||||
let dev = this.getL3Device() || this.getDevice(), o;
|
||||
var dev = this.getL3Device() || this.getDevice(), o;
|
||||
|
||||
o = s.taboption('general', form.Value, '_modem_device', _('Modem device'));
|
||||
o.ucioption = 'device';
|
||||
o.rmempty = false;
|
||||
o.load = function(section_id) {
|
||||
return callFileList('/dev/').then(L.bind(function(devices) {
|
||||
for (let i = 0; i < devices.length; i++)
|
||||
for (var i = 0; i < devices.length; i++)
|
||||
this.value(devices[i]);
|
||||
return form.Value.prototype.load.apply(this, [section_id]);
|
||||
}, this));
|
||||
@@ -99,7 +99,7 @@ return network.registerProtocol('quectel', {
|
||||
|
||||
o = s.taboption('advanced', form.Value, 'delay', _('Modem init timeout'),
|
||||
_('Maximum amount of seconds to wait for the modem to become ready'));
|
||||
o.placeholder = '10';
|
||||
o.placeholder = '20';
|
||||
o.datatype = 'min(1)';
|
||||
|
||||
o = s.taboption('advanced', form.Value, 'mtu', _('Override MTU'));
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
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))
|
||||
@@ -0,0 +1,135 @@
|
||||
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).
|
||||
@@ -0,0 +1,518 @@
|
||||
#!/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
|
||||
@@ -0,0 +1,8 @@
|
||||
_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
|
||||
@@ -0,0 +1,10 @@
|
||||
_DEVICE=/dev/ttyUSB2
|
||||
_DEFAULT_LTE_BANDS="1 3 5 7 8 20"
|
||||
|
||||
getinfo() {
|
||||
echo "Quectel EC20"
|
||||
}
|
||||
|
||||
# +QCFG: "band",0xdf,0x800d5,0x3f
|
||||
|
||||
. $RES/_quectel_common
|
||||
@@ -0,0 +1,36 @@
|
||||
_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"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
# +GTUSBMODE: 40
|
||||
_DEVICE=/dev/ttyUSB2
|
||||
|
||||
. $RES/_fibocom_fm350_common
|
||||
@@ -0,0 +1,4 @@
|
||||
# +GTUSBMODE: 41
|
||||
_DEVICE=/dev/ttyUSB4
|
||||
|
||||
. $RES/_fibocom_fm350_common
|
||||
@@ -0,0 +1,38 @@
|
||||
_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
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
_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
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
_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
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
_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
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
_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
|
||||
@@ -0,0 +1,15 @@
|
||||
_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
|
||||
@@ -0,0 +1,8 @@
|
||||
_DEVICE=/dev/ttyACM0
|
||||
_DEFAULT_LTE_BANDS="1 3 7 8 20 38"
|
||||
|
||||
getinfo() {
|
||||
echo "ZTE MF286R"
|
||||
}
|
||||
|
||||
. $RES/_zte_common
|
||||
@@ -0,0 +1,31 @@
|
||||
_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
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
_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
|
||||
@@ -0,0 +1,8 @@
|
||||
_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
|
||||
@@ -0,0 +1,83 @@
|
||||
_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"
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
_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,"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
_DEVICE=/dev/ttyUSB2
|
||||
_DEFAULT_LTE_BANDS="1 3 5 7 8 20 38 40 41"
|
||||
|
||||
getinfo() {
|
||||
echo "Quectel EC25"
|
||||
}
|
||||
|
||||
. $RES/_quectel_common
|
||||
@@ -0,0 +1,10 @@
|
||||
_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
|
||||
@@ -0,0 +1,10 @@
|
||||
_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
|
||||
@@ -0,0 +1,8 @@
|
||||
_DEVICE=/dev/ttyUSB2
|
||||
_DEFAULT_LTE_BANDS="1 3 5 7 8 20 28 38 40 41"
|
||||
|
||||
getinfo() {
|
||||
echo "Quectel EG18-EA"
|
||||
}
|
||||
|
||||
. $RES/_quectel_common
|
||||
@@ -0,0 +1,26 @@
|
||||
_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"
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
_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"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
_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
|
||||
@@ -0,0 +1,12 @@
|
||||
_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
|
||||
@@ -0,0 +1,12 @@
|
||||
_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
|
||||
@@ -0,0 +1,12 @@
|
||||
_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
|
||||
@@ -0,0 +1,12 @@
|
||||
_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
|
||||
@@ -0,0 +1,12 @@
|
||||
_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
|
||||
@@ -0,0 +1,15 @@
|
||||
_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
|
||||
@@ -0,0 +1,12 @@
|
||||
_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
|
||||
@@ -0,0 +1,8 @@
|
||||
_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
|
||||
@@ -0,0 +1,57 @@
|
||||
_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
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
# 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
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
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"
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
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"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
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"
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
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"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
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"
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=quectel-cm
|
||||
PKG_VERSION:=1.6.8
|
||||
PKG_RELEASE:=3
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/cmake.mk
|
||||
|
||||
define Package/quectel-cm
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
SUBMENU:=WWAN
|
||||
TITLE:=Qconnector Manager for Quectel WWAN modules
|
||||
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
|
||||
|
||||
define Package/quectel-cm/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/quectel-CM $(1)/usr/bin/quectel-cm
|
||||
$(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
|
||||
|
||||
$(eval $(call BuildPackage,quectel-cm))
|
||||
@@ -0,0 +1,138 @@
|
||||
#!/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
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#!/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
|
||||
@@ -0,0 +1,24 @@
|
||||
#!/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
|
||||
@@ -0,0 +1,29 @@
|
||||
--- 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;
|
||||
@@ -0,0 +1,8 @@
|
||||
--- 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)
|
||||
@@ -0,0 +1,15 @@
|
||||
--- 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
|
||||
@@ -0,0 +1,36 @@
|
||||
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)
|
||||
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
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
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
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
|
||||
@@ -0,0 +1,22 @@
|
||||
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
|
||||
@@ -0,0 +1,7 @@
|
||||
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.
|
||||
@@ -0,0 +1,389 @@
|
||||
/*
|
||||
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
|
||||
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
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
|
||||
@@ -0,0 +1,472 @@
|
||||
/*
|
||||
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
@@ -0,0 +1,467 @@
|
||||
/*
|
||||
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
|
||||
@@ -0,0 +1,454 @@
|
||||
/*
|
||||
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
|
||||
|
||||
@@ -0,0 +1,357 @@
|
||||
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
|
||||
|
||||
@@ -0,0 +1,283 @@
|
||||
/* //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;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/* //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
@@ -0,0 +1,152 @@
|
||||
/* //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*/
|
||||
@@ -0,0 +1,48 @@
|
||||
# -*- 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
|
||||
@@ -0,0 +1,63 @@
|
||||
#!/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
|
||||
@@ -0,0 +1,61 @@
|
||||
#!/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
|
||||
@@ -0,0 +1,756 @@
|
||||
/*
|
||||
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
@@ -0,0 +1,71 @@
|
||||
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
|
||||
@@ -0,0 +1,168 @@
|
||||
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
|
||||
@@ -0,0 +1,129 @@
|
||||
# ./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
|
||||
@@ -0,0 +1,62 @@
|
||||
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
|
||||
@@ -0,0 +1,60 @@
|
||||
root@ZhuoTK:/# insmod GobiNet.ko
|
||||
[ 80.460000] GobiNet: Quectel_Linux&Android_GobiNet_Driver_V1.6.2.13
|
||||
[ 80.460000] usbcore: registered new interface driver GobiNet
|
||||
[ 97.710000] usb 1-1.3: new high-speed USB device number 3 using ehci-platform
|
||||
[ 97.930000] usb 1-1.3: GSM modem (1-port) converter now attached to ttyUSB103
|
||||
[ 97.950000] GobiNet 1-1.3:1.4 usb0: register 'GobiNet' at usb-101c0000.ehci-1.3, GobiNet Ethernet Device, 02:50:f4:00:00:00
|
||||
[ 97.960000] creating qcqmi0
|
||||
|
||||
root@ZhuoTK:/# brctl addbr br0
|
||||
root@ZhuoTK:/# brctl addif br0 eth0.1
|
||||
root@ZhuoTK:/# brctl addif br0 usb0
|
||||
root@ZhuoTK:/# brctl show
|
||||
bridge name bridge id STP enabled interfaces
|
||||
br0 8000.00ca019197b9 no eth0.1
|
||||
usb0
|
||||
|
||||
root@ZhuoTK:/# quectel-CM -s cment -b &
|
||||
[04-13_05:13:18:213] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-13_05:13:18:216] Find /sys/bus/usb/devices/1-1.3 idVendor=0x2c7c idProduct=0x125, bus=0x001, dev=0x003
|
||||
[ 122.270000] net usb0: bridge_mode change to 0x1
|
||||
[04-13_05:13:18:218] Auto find qmichannel = /dev/qcqmi0
|
||||
[04-13_05:13:18:218] Auto find usbnet_adapter = usb0
|
||||
[04-13_05:13:18:218] netcard driver = GobiNet, driver version = V1.6.2.13
|
||||
[04-13_05:13:18:224] Modem works in QMI mode
|
||||
[04-13_05:13:18:251] Get clientWDS = 7
|
||||
[04-13_05:13:18:282] Get clientDMS = 8
|
||||
[04-13_05:13:18:316] Get clientNAS = 9
|
||||
[04-13_05:13:18:347] Get clientUIM = 10
|
||||
[04-13_05:13:18:379] Get clientWDA = 11
|
||||
[04-13_05:13:18:411] requestBaseBandVersion EC25EFAR06A11M4G
|
||||
[04-13_05:13:18:539] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-13_05:13:18:540] requestSetProfile[1] cment///0
|
||||
[04-13_05:13:18:603] requestGetProfile[1] cment///0
|
||||
[04-13_05:13:18:637] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: LTE
|
||||
[04-13_05:13:18:666] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[04-13_05:13:18:667] ifconfig usb0 0.0.0.0
|
||||
[04-13_05:13:18:687] ifconfig usb0 down
|
||||
[04-13_05:13:19:083] requestSetupDataCall WdsConnectionIPv4Handle: 0x8724d220
|
||||
[04-13_05:13:19:243] ifconfig usb0 up
|
||||
[04-13_05:13:19:270] echo '0xa218480' > /sys/class/net/usb0/bridge_ipv4
|
||||
|
||||
root@ZhuoTK:/# ifconfig br0 up
|
||||
[ 135.530000] usb0 PC Mac Address: 00:0e:c6:a6:6c:f1
|
||||
[ 135.570000] usb0 PC Mac Address: 00:0e:c6:a6:6c:f1
|
||||
[ 135.580000] usb0 PC Mac Address: 00:0e:c6:a6:6c:f1
|
||||
[ 135.610000] usb0 sip = 10.33.132.128, tip=10.33.132.129, ipv4=10.33.132.128
|
||||
[ 135.620000] usb0 sip = 10.33.132.128, tip=10.33.132.129, ipv4=10.33.132.128
|
||||
[ 135.910000] usb0 sip = 0.0.0.0, tip=10.33.132.128, ipv4=10.33.132.128
|
||||
[ 136.000000] usb0 sip = 10.33.132.128, tip=10.33.132.129, ipv4=10.33.132.128
|
||||
[ 136.910000] usb0 sip = 0.0.0.0, tip=10.33.132.128, ipv4=10.33.132.128
|
||||
[ 137.910000] usb0 sip = 0.0.0.0, tip=10.33.132.128, ipv4=10.33.132.128
|
||||
[ 138.740000] usb0 sip = 10.33.132.128, tip=10.33.132.129, ipv4=10.33.132.128
|
||||
[ 138.910000] usb0 sip = 10.33.132.128, tip=10.33.132.128, ipv4=10.33.132.128
|
||||
[ 139.000000] usb0 sip = 10.33.132.128, tip=10.33.132.129, ipv4=10.33.132.128
|
||||
[ 140.860000] usb0 sip = 10.33.132.128, tip=10.33.132.129, ipv4=10.33.132.128
|
||||
[ 143.160000] br0: port 2(usb0) entered forwarding state
|
||||
[ 143.160000] br0: port 1(eth0.1) entered forwarding state
|
||||
[ 148.870000] usb0 sip = 10.33.132.128, tip=10.33.132.129, ipv4=10.33.132.128
|
||||
[ 149.010000] usb0 sip = 10.33.132.128, tip=10.33.132.129, ipv4=10.33.132.128
|
||||
[ 165.630000] usb0 sip = 10.33.132.128, tip=10.33.132.129, ipv4=10.33.132.128
|
||||
@@ -0,0 +1,45 @@
|
||||
root@ZhuoTK:/# insmod GobiNet.ko qmap_mode=1
|
||||
[ 798.480000] GobiNet: Quectel_Linux&Android_GobiNet_Driver_V1.6.2.13
|
||||
[ 798.490000] GobiNet 1-1.3:1.4 usb0: register 'GobiNet' at usb-101c0000.ehci-1.3, GobiNet Ethernet Device, 02:50:f4:00:00:00
|
||||
[ 798.510000] creating qcqmi0
|
||||
[ 798.510000] usbcore: registered new interface driver GobiNet
|
||||
[ 799.620000] GobiNet::QMIWDASetDataFormat qmap settings qmap_version=5, rx_size=4096, tx_size=4096
|
||||
[ 799.630000] GobiNet::QMIWDASetDataFormat qmap settings ul_data_aggregation_max_size=4096, ul_data_aggregation_max_datagrams=16
|
||||
|
||||
root@ZhuoTK:/# quectel-CM -s cmnet &
|
||||
[04-13_03:32:31:248] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-13_03:32:31:251] Find /sys/bus/usb/devices/1-1.3 idVendor=0x2c7c idProduct=0x125, bus=0x001, dev=0x005
|
||||
[04-13_03:32:31:253] Auto find qmichannel = /dev/qcqmi0
|
||||
[04-13_03:32:31:253] Auto find usbnet_adapter = usb0
|
||||
[04-13_03:32:31:253] netcard driver = GobiNet, driver version = V1.6.2.13
|
||||
[04-13_03:32:31:253] qmap_mode = 1, qmap_version = 5, qmap_size = 4096, muxid = 0x81, qmap_netcard = usb0
|
||||
[04-13_03:32:31:254] Modem works in QMI mode
|
||||
[04-13_03:32:31:289] Get clientWDS = 7
|
||||
[04-13_03:32:31:320] Get clientDMS = 8
|
||||
[04-13_03:32:31:353] Get clientNAS = 9
|
||||
[04-13_03:32:31:385] Get clientUIM = 10
|
||||
[04-13_03:32:31:417] requestBaseBandVersion EC25EFAR06A11M4G
|
||||
[04-13_03:32:31:545] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-13_03:32:31:545] requestSetProfile[1] cmnet///0
|
||||
[04-13_03:32:31:609] requestGetProfile[1] cmnet///0
|
||||
[04-13_03:32:31:641] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: LTE
|
||||
[04-13_03:32:31:673] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[04-13_03:32:31:674] ifconfig usb0 0.0.0.0
|
||||
[04-13_03:32:31:698] ifconfig usb0 down
|
||||
[04-13_03:32:31:770] requestSetupDataCall WdsConnectionIPv4Handle: 0x872481a0
|
||||
[ 857.000000] net usb0: link_state 0x0 -> 0x1
|
||||
[04-13_03:32:31:902] ifconfig usb0 up
|
||||
[04-13_03:32:31:928] you are use OpenWrt?
|
||||
[04-13_03:32:31:928] should not calling udhcpc manually?
|
||||
[04-13_03:32:31:928] should modify /etc/config/network as below?
|
||||
[04-13_03:32:31:928] config interface wan
|
||||
[04-13_03:32:31:928] option ifname usb0
|
||||
[04-13_03:32:31:929] option proto dhcp
|
||||
[04-13_03:32:31:929] should use "/sbin/ifstaus wan" to check usb0 's status?
|
||||
[04-13_03:32:31:929] busybox udhcpc -f -n -q -t 5 -i usb0
|
||||
[04-13_03:32:31:939] udhcpc (v1.23.2) started
|
||||
[04-13_03:32:31:951] Sending discover...
|
||||
[04-13_03:32:31:956] Sending select for 10.199.102.71...
|
||||
[04-13_03:32:31:959] Lease of 10.199.102.71 obtained, lease time 7200
|
||||
[04-13_03:32:31:964] udhcpc: ifconfig usb0 10.199.102.71 netmask 255.255.255.240 broadcast +
|
||||
[04-13_03:32:31:974] udhcpc: setting default routers: 10.199.102.72
|
||||
@@ -0,0 +1,62 @@
|
||||
root@ZhuoTK:/# insmod GobiNet.ko qmap_mode=1
|
||||
[ 41.540000] GobiNet: Quectel_Linux&Android_GobiNet_Driver_V1.6.2.13
|
||||
[ 41.550000] GobiNet 1-1.3:1.4 usb0: register 'GobiNet' at usb-101c0000.ehci-1.3, GobiNet Ethernet Device, 02:50:f4:00:00:00
|
||||
[ 41.570000] creating qcqmi0
|
||||
[ 41.570000] usbcore: registered new interface driver GobiNet
|
||||
[ 42.700000] GobiNet::QMIWDASetDataFormat qmap settings qmap_version=5, rx_size=4096, tx_size=4096
|
||||
[ 42.710000] GobiNet::QMIWDASetDataFormat qmap settings ul_data_aggregation_max_size=4096, ul_data_aggregation_max_datagrams=16
|
||||
|
||||
root@ZhuoTK:/# brctl addbr br0
|
||||
root@ZhuoTK:/# brctl addif br0 eth0.1
|
||||
root@ZhuoTK:/# brctl addif br0 usb0
|
||||
root@ZhuoTK:/# brctl show
|
||||
bridge name bridge id STP enabled interfaces
|
||||
br0 8000.00ca019197b9 no eth0.1
|
||||
usb0
|
||||
|
||||
root@ZhuoTK:/# quectel-CM -s cmnet -b &
|
||||
# [04-13_05:12:29:338] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-13_05:12:29:340] Find /sys/bus/usb/devices/1-1.3 idVendor=0x2c7c idProduct=0x125, bus=0x001, dev=0x003
|
||||
[ 73.380000] net usb0: bridge_mode change to 0x1
|
||||
[04-13_05:12:29:342] Auto find qmichannel = /dev/qcqmi0
|
||||
[04-13_05:12:29:342] Auto find usbnet_adapter = usb0
|
||||
[04-13_05:12:29:342] netcard driver = GobiNet, driver version = V1.6.2.13
|
||||
[04-13_05:12:29:343] qmap_mode = 1, qmap_version = 5, qmap_size = 4096, muxid = 0x81, qmap_netcard = usb0
|
||||
[04-13_05:12:29:348] Modem works in QMI mode
|
||||
[04-13_05:12:29:382] Get clientWDS = 7
|
||||
[04-13_05:12:29:414] Get clientDMS = 8
|
||||
[04-13_05:12:29:447] Get clientNAS = 9
|
||||
[04-13_05:12:29:479] Get clientUIM = 10
|
||||
[04-13_05:12:29:512] requestBaseBandVersion EC25EFAR06A11M4G
|
||||
[04-13_05:12:29:640] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-13_05:12:29:640] requestSetProfile[1] cmnet///0
|
||||
[04-13_05:12:29:704] requestGetProfile[1] cmnet///0
|
||||
[04-13_05:12:29:735] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: LTE
|
||||
[04-13_05:12:29:767] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[04-13_05:12:29:768] ifconfig usb0 0.0.0.0
|
||||
[04-13_05:12:29:792] ifconfig usb0 down
|
||||
[04-13_05:12:29:863] requestSetupDataCall WdsConnectionIPv4Handle: 0x8724d820
|
||||
[ 74.030000] net usb0: link_state 0x0 -> 0x1
|
||||
[04-13_05:12:29:996] ifconfig usb0 up
|
||||
[04-13_05:12:30:022] echo '0xa16b769' > /sys/class/net/usb0/bridge_ipv4
|
||||
|
||||
root@ZhuoTK:/# ifconfig br0 up
|
||||
[ 82.210000] br0: port 2(usb0) entered forwarding state
|
||||
[ 82.210000] br0: port 2(usb0) entered forwarding state
|
||||
[ 82.220000] br0: port 1(eth0.1) entered forwarding state
|
||||
[ 82.220000] br0: port 1(eth0.1) entered forwarding state
|
||||
[ 88.830000] rt305x-esw 10110000.esw: link changed 0x01
|
||||
[ 89.010000] usb0 PC Mac Address: 00:0e:c6:a6:6c:f1
|
||||
[ 89.040000] usb0 PC Mac Address: 00:0e:c6:a6:6c:f1
|
||||
[ 89.050000] usb0 PC Mac Address: 00:0e:c6:a6:6c:f1
|
||||
[ 89.120000] usb0 sip = 10.22.183.105, tip=10.22.183.106, ipv4=10.22.183.105
|
||||
[ 89.350000] usb0 sip = 0.0.0.0, tip=10.22.183.105, ipv4=10.22.183.105
|
||||
[ 89.400000] usb0 sip = 10.22.183.105, tip=10.22.183.106, ipv4=10.22.183.105
|
||||
[ 89.520000] usb0 sip = 10.22.183.105, tip=10.22.183.106, ipv4=10.22.183.105
|
||||
[ 90.350000] usb0 sip = 0.0.0.0, tip=10.22.183.105, ipv4=10.22.183.105
|
||||
[ 91.350000] usb0 sip = 0.0.0.0, tip=10.22.183.105, ipv4=10.22.183.105
|
||||
[ 92.350000] usb0 sip = 10.22.183.105, tip=10.22.183.105, ipv4=10.22.183.105
|
||||
[ 92.430000] usb0 sip = 10.22.183.105, tip=10.22.183.106, ipv4=10.22.183.105
|
||||
[ 92.660000] usb0 sip = 10.22.183.105, tip=10.22.183.106, ipv4=10.22.183.105
|
||||
[ 97.240000] br0: port 2(usb0) entered forwarding state
|
||||
[ 97.240000] br0: port 1(eth0.1) entered forwarding state
|
||||
@@ -0,0 +1,146 @@
|
||||
root@ZhuoTK:/# insmod GobiNet.ko qmap_mode=4
|
||||
[ 970.380000] GobiNet: Quectel_Linux&Android_GobiNet_Driver_V1.6.2.13
|
||||
[ 970.380000] usbcore: registered new interface driver GobiNet
|
||||
[ 989.620000] usb 1-1.3: new high-speed USB device number 6 using ehci-platform
|
||||
[ 989.860000] GobiNet 1-1.3:1.4 usb0: register 'GobiNet' at usb-101c0000.ehci-1.3, GobiNet Ethernet Device, 02:50:f4:00:00:00
|
||||
[ 989.870000] creating qcqmi0
|
||||
[ 989.880000] GobiNet::qmap_register_device usb0.1
|
||||
[ 989.880000] GobiNet::qmap_register_device usb0.2
|
||||
[ 989.890000] GobiNet::qmap_register_device usb0.3
|
||||
[ 989.890000] GobiNet::qmap_register_device usb0.4
|
||||
[ 994.820000] GobiNet::QMIWDASetDataFormat qmap settings qmap_version=5, rx_size=4096, tx_size=4096
|
||||
[ 994.830000] GobiNet::QMIWDASetDataFormat qmap settings ul_data_aggregation_max_size=4096, ul_data_aggregation_max_datagrams=16
|
||||
|
||||
root@ZhuoTK:/# quectel-CM -n 1 -s cmnet &
|
||||
[04-13_03:35:31:878] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-13_03:35:31:881] Find /sys/bus/usb/devices/1-1.3 idVendor=0x2c7c idProduct=0x125, bus=0x001, dev=0x006
|
||||
[04-13_03:35:31:882] Auto find qmichannel = /dev/qcqmi0
|
||||
[04-13_03:35:31:882] Auto find usbnet_adapter = usb0
|
||||
[04-13_03:35:31:883] netcard driver = GobiNet, driver version = V1.6.2.13
|
||||
[04-13_03:35:31:883] qmap_mode = 4, qmap_version = 5, qmap_size = 4096, muxid = 0x81, qmap_netcard = usb0.1
|
||||
[04-13_03:35:31:883] Modem works in QMI mode
|
||||
[04-13_03:35:31:896] Get clientWDS = 7
|
||||
[04-13_03:35:31:927] Get clientDMS = 8
|
||||
[04-13_03:35:31:959] Get clientNAS = 9
|
||||
[04-13_03:35:31:992] Get clientUIM = 10
|
||||
[04-13_03:35:32:024] requestBaseBandVersion EC25EFAR06A11M4G
|
||||
[04-13_03:35:32:152] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-13_03:35:32:152] requestSetProfile[1] cmnet///0
|
||||
[04-13_03:35:32:216] requestGetProfile[1] cmnet///0
|
||||
[04-13_03:35:32:248] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: LTE
|
||||
[04-13_03:35:32:279] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[04-13_03:35:32:280] ifconfig usb0 down
|
||||
[04-13_03:35:32:290] ifconfig usb0.1 0.0.0.0
|
||||
[04-13_03:35:32:301] ifconfig usb0.1 down
|
||||
[04-13_03:35:32:344] requestSetupDataCall WdsConnectionIPv4Handle: 0x8723eef0
|
||||
[ 1037.570000] net usb0: link_state 0x0 -> 0x1
|
||||
[04-13_03:35:32:477] ifconfig usb0 up
|
||||
[04-13_03:35:32:496] ifconfig usb0.1 up
|
||||
[04-13_03:35:32:508] you are use OpenWrt?
|
||||
[04-13_03:35:32:509] should not calling udhcpc manually?
|
||||
[04-13_03:35:32:509] should modify /etc/config/network as below?
|
||||
[04-13_03:35:32:509] config interface wan
|
||||
[04-13_03:35:32:509] option ifname usb0.1
|
||||
[04-13_03:35:32:509] option proto dhcp
|
||||
[04-13_03:35:32:509] should use "/sbin/ifstaus wan" to check usb0.1 's status?
|
||||
[04-13_03:35:32:510] busybox udhcpc -f -n -q -t 5 -i usb0.1
|
||||
[04-13_03:35:32:520] udhcpc (v1.23.2) started
|
||||
[04-13_03:35:32:532] Sending discover...
|
||||
[04-13_03:35:32:540] Sending select for 10.187.142.20...
|
||||
[04-13_03:35:32:545] Lease of 10.187.142.20 obtained, lease time 7200
|
||||
[04-13_03:35:32:550] udhcpc: ifconfig usb0.1 10.187.142.20 netmask 255.255.255.248 broadcast +
|
||||
[04-13_03:35:32:560] udhcpc: setting default routers: 10.187.142.21
|
||||
|
||||
root@ZhuoTK:/# quectel-CM -n 2 -s 4gnet &
|
||||
[04-13_03:35:38:766] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-13_03:35:38:769] Find /sys/bus/usb/devices/1-1.3 idVendor=0x2c7c idProduct=0x125, bus=0x001, dev=0x006
|
||||
[04-13_03:35:38:770] Auto find qmichannel = /dev/qcqmi0
|
||||
[04-13_03:35:38:770] Auto find usbnet_adapter = usb0
|
||||
[04-13_03:35:38:771] netcard driver = GobiNet, driver version = V1.6.2.13
|
||||
[04-13_03:35:38:771] qmap_mode = 4, qmap_version = 5, qmap_size = 4096, muxid = 0x82, qmap_netcard = usb0.2
|
||||
[04-13_03:35:38:771] Modem works in QMI mode
|
||||
[04-13_03:35:38:809] Get clientWDS = 7
|
||||
[04-13_03:35:38:841] Get clientDMS = 8
|
||||
[04-13_03:35:38:873] Get clientNAS = 9
|
||||
[04-13_03:35:38:905] Get clientUIM = 10
|
||||
[04-13_03:35:38:937] requestBaseBandVersion EC25EFAR06A11M4G
|
||||
[04-13_03:35:39:065] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-13_03:35:39:065] requestSetProfile[2] 4gnet///0
|
||||
[04-13_03:35:39:129] requestGetProfile[2] 4gnet///0
|
||||
[04-13_03:35:39:161] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: LTE
|
||||
[04-13_03:35:39:193] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[04-13_03:35:39:193] ifconfig usb0.2 0.0.0.0
|
||||
[04-13_03:35:39:206] ifconfig usb0.2 down
|
||||
[04-13_03:35:39:417] requestSetupDataCall WdsConnectionIPv4Handle: 0x87252eb0
|
||||
[ 1044.650000] net usb0: link_state 0x1 -> 0x3
|
||||
[04-13_03:35:39:550] ifconfig usb0 up
|
||||
[04-13_03:35:39:560] ifconfig usb0.2 up
|
||||
[04-13_03:35:39:573] you are use OpenWrt?
|
||||
[04-13_03:35:39:573] should not calling udhcpc manually?
|
||||
[04-13_03:35:39:573] should modify /etc/config/network as below?
|
||||
[04-13_03:35:39:573] config interface wan
|
||||
[04-13_03:35:39:573] option ifname usb0.2
|
||||
[04-13_03:35:39:573] option proto dhcp
|
||||
[04-13_03:35:39:573] should use "/sbin/ifstaus wan" to check usb0.2 's status?
|
||||
[04-13_03:35:39:574] busybox udhcpc -f -n -q -t 5 -i usb0.2
|
||||
[04-13_03:35:39:585] udhcpc (v1.23.2) started
|
||||
[04-13_03:35:39:597] Sending discover...
|
||||
[04-13_03:35:39:601] Sending select for 10.197.125.183...
|
||||
[04-13_03:35:39:606] Lease of 10.197.125.183 obtained, lease time 7200
|
||||
[04-13_03:35:39:611] udhcpc: ifconfig usb0.2 10.197.125.183 netmask 255.255.255.240 broadcast +
|
||||
[04-13_03:35:39:621] udhcpc: setting default routers: 10.197.125.184
|
||||
|
||||
root@ZhuoTK:/# ifconfig usb0.1
|
||||
usb0.1 Link encap:Ethernet HWaddr 02:50:F4:00:00:00
|
||||
inet addr:10.187.142.20 Mask:255.255.255.248
|
||||
inet6 addr: fe80::50:f4ff:fe00:0/64 Scope:Link
|
||||
UP RUNNING NOARP MTU:1500 Metric:1
|
||||
RX packets:4 errors:0 dropped:0 overruns:0 frame:0
|
||||
TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:764 (764.0 B) TX bytes:1824 (1.7 KiB)
|
||||
|
||||
root@ZhuoTK:/# ifconfig usb0.2
|
||||
usb0.2 Link encap:Ethernet HWaddr 02:50:F4:00:00:00
|
||||
inet addr:10.197.125.183 Mask:255.255.255.240
|
||||
inet6 addr: fe80::50:f4ff:fe00:0/64 Scope:Link
|
||||
UP RUNNING NOARP MTU:1500 Metric:1
|
||||
RX packets:3 errors:0 dropped:0 overruns:0 frame:0
|
||||
TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:688 (688.0 B) TX bytes:1224 (1.1 KiB)
|
||||
|
||||
root@ZhuoTK:/# ip ro add 8.8.8.8/32 dev usb0.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=74.450 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 usb0.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=52 time=257.851 ms
|
||||
|
||||
root@ZhuoTK:/# quectel-CM -k 2
|
||||
[04-13_03:39:16:986] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-13_03:39:16:988] /proc/2294/cmdline: quectel-CM -n 2 -s 4gnet
|
||||
[04-13_03:39:16:988] send SIGINT to process 2294
|
||||
[04-13_03:39:16:989] requestDeactivateDefaultPDP WdsConnectionIPv4Handle
|
||||
[ 1262.310000] net usb0: link_state 0x3 -> 0x1
|
||||
[04-13_03:39:17:216] ifconfig usb0.2 0.0.0.0
|
||||
[04-13_03:39:17:228] ifconfig usb0.2 down
|
||||
[04-13_03:39:17:370] GobiNetThread exit
|
||||
[04-13_03:39:17:371] qmi_main exit
|
||||
|
||||
[2]+ Done quectel-CM -n 2 -s 4gnet
|
||||
|
||||
root@ZhuoTK:/# ifconfig usb0.2
|
||||
usb0.2 Link encap:Ethernet HWaddr 02:50:F4:00:00:00
|
||||
NOARP MTU:1500 Metric:1
|
||||
RX packets:30 errors:0 dropped:0 overruns:0 frame:0
|
||||
TX packets:35 errors:0 dropped:0 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:2816 (2.7 KiB) TX bytes:3408 (3.3 KiB)
|
||||
@@ -0,0 +1,114 @@
|
||||
root@ZhuoTK:/# insmod GobiNet.ko qmap_mode=4
|
||||
[ 42.120000] GobiNet: Quectel_Linux&Android_GobiNet_Driver_V1.6.2.13
|
||||
[ 42.130000] GobiNet 1-1.3:1.4 usb0: register 'GobiNet' at usb-101c0000.ehci-1.3, GobiNet Ethernet Device, 02:50:f4:00:00:00
|
||||
[ 42.140000] creating qcqmi0
|
||||
[ 42.150000] GobiNet::qmap_register_device usb0.1
|
||||
[ 42.150000] GobiNet::qmap_register_device usb0.2
|
||||
[ 42.160000] GobiNet::qmap_register_device usb0.3
|
||||
[ 42.160000] GobiNet::qmap_register_device usb0.4
|
||||
[ 42.170000] usbcore: registered new interface driver GobiNet
|
||||
[ 43.270000] GobiNet::QMIWDASetDataFormat qmap settings qmap_version=5, rx_size=4096, tx_size=4096
|
||||
[ 43.280000] GobiNet::QMIWDASetDataFormat qmap settings ul_data_aggregation_max_size=4096, ul_data_aggregation_max_datagrams=16
|
||||
|
||||
root@ZhuoTK:/# brctl addbr br0
|
||||
root@ZhuoTK:/# brctl addif br0 eth0.1
|
||||
root@ZhuoTK:/# brctl addif br0 usb0.1
|
||||
root@ZhuoTK:/# brctl show
|
||||
bridge name bridge id STP enabled interfaces
|
||||
br0 8000.00ca019197b9 no eth0.1
|
||||
usb0.1
|
||||
|
||||
root@ZhuoTK:/# quectel-CM -n 1 -s cmnet -b &
|
||||
[04-13_05:12:42:155] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-13_05:12:42:158] Find /sys/bus/usb/devices/1-1.3 idVendor=0x2c7c idProduct=0x125, bus=0x001, dev=0x003
|
||||
[ 86.130000] net usb0.1: bridge_mode change to 0x1
|
||||
[04-13_05:12:42:159] Auto find qmichannel = /dev/qcqmi0
|
||||
[04-13_05:12:42:160] Auto find usbnet_adapter = usb0
|
||||
[04-13_05:12:42:160] netcard driver = GobiNet, driver version = V1.6.2.13
|
||||
[04-13_05:12:42:160] qmap_mode = 4, qmap_version = 5, qmap_size = 4096, muxid = 0x81, qmap_netcard = usb0.1
|
||||
[04-13_05:12:42:166] Modem works in QMI mode
|
||||
[04-13_05:12:42:181] Get clientWDS = 7
|
||||
[04-13_05:12:42:213] Get clientDMS = 8
|
||||
[04-13_05:12:42:246] Get clientNAS = 9
|
||||
[04-13_05:12:42:278] Get clientUIM = 10
|
||||
[04-13_05:12:42:310] requestBaseBandVersion EC25EFAR06A11M4G
|
||||
[04-13_05:12:42:438] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-13_05:12:42:439] requestSetProfile[1] cmnet///0
|
||||
[04-13_05:12:42:502] requestGetProfile[1] cmnet///0
|
||||
[04-13_05:12:42:534] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: LTE
|
||||
[04-13_05:12:42:565] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[04-13_05:12:42:566] ifconfig usb0 down
|
||||
[04-13_05:12:42:576] ifconfig usb0.1 0.0.0.0
|
||||
[04-13_05:12:42:587] ifconfig usb0.1 down
|
||||
[04-13_05:12:42:629] requestSetupDataCall WdsConnectionIPv4Handle: 0x8724d740
|
||||
[ 86.730000] net usb0: link_state 0x0 -> 0x1
|
||||
[04-13_05:12:42:762] ifconfig usb0 up
|
||||
[04-13_05:12:42:782] ifconfig usb0.1 up
|
||||
[04-13_05:12:42:794] echo '0xa16b769' > /sys/class/net/usb0.1/bridge_ipv4
|
||||
|
||||
root@ZhuoTK:/# ifconfig br0 up
|
||||
[ 98.270000] usb0.1 PC Mac Address: 00:0e:c6:a6:6c:f1
|
||||
[ 98.360000] usb0.1 sip = 0.0.0.0, tip=10.22.183.105, ipv4=10.22.183.105
|
||||
[ 98.370000] usb0.1 sip = 10.22.183.105, tip=10.22.183.106, ipv4=10.22.183.105
|
||||
[ 99.360000] usb0.1 sip = 0.0.0.0, tip=10.22.183.105, ipv4=10.22.183.105
|
||||
[ 100.360000] usb0.1 sip = 0.0.0.0, tip=10.22.183.105, ipv4=10.22.183.105
|
||||
[ 100.500000] usb0.1 sip = 10.22.183.105, tip=10.22.183.106, ipv4=10.22.183.105
|
||||
|
||||
root@ZhuoTK:/# quectel-CM -n 2 -s 4gnet &
|
||||
[04-13_05:13:05:715] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-13_05:13:05:717] Find /sys/bus/usb/devices/1-1.3 idVendor=0x2c7c idProduct=0x125, bus=0x001, dev=0x003
|
||||
[04-13_05:13:05:719] Auto find qmichannel = /dev/qcqmi0
|
||||
[04-13_05:13:05:719] Auto find usbnet_adapter = usb0
|
||||
[04-13_05:13:05:719] netcard driver = GobiNet, driver version = V1.6.2.13
|
||||
[04-13_05:13:05:719] qmap_mode = 4, qmap_version = 5, qmap_size = 4096, muxid = 0x82, qmap_netcard = usb0.2
|
||||
[04-13_05:13:05:720] Modem works in QMI mode
|
||||
[04-13_05:13:05:734] Get clientWDS = 7
|
||||
[04-13_05:13:05:766] Get clientDMS = 8
|
||||
[04-13_05:13:05:798] Get clientNAS = 9
|
||||
[04-13_05:13:05:830] Get clientUIM = 10
|
||||
[04-13_05:13:05:861] requestBaseBandVersion EC25EFAR06A11M4G
|
||||
[04-13_05:13:05:990] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-13_05:13:05:991] requestSetProfile[2] 4gnet///0
|
||||
[04-13_05:13:06:054] requestGetProfile[2] 4gnet///0
|
||||
[04-13_05:13:06:086] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: LTE
|
||||
[04-13_05:13:06:118] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[04-13_05:13:06:119] ifconfig usb0.2 0.0.0.0
|
||||
[04-13_05:13:06:131] ifconfig usb0.2 down
|
||||
[04-13_05:13:06:375] requestSetupDataCall WdsConnectionIPv4Handle: 0x872b8c50
|
||||
[ 110.470000] net usb0: link_state 0x1 -> 0x3
|
||||
[04-13_05:13:06:507] ifconfig usb0 up
|
||||
[04-13_05:13:06:518] ifconfig usb0.2 up
|
||||
[04-13_05:13:06:539] you are use OpenWrt?
|
||||
[04-13_05:13:06:540] should not calling udhcpc manually?
|
||||
[04-13_05:13:06:540] should modify /etc/config/network as below?
|
||||
[04-13_05:13:06:540] config interface wan
|
||||
[04-13_05:13:06:540] option ifname usb0.2
|
||||
[04-13_05:13:06:540] option proto dhcp
|
||||
[04-13_05:13:06:540] should use "/sbin/ifstaus wan" to check usb0.2 's status?
|
||||
[04-13_05:13:06:540] busybox udhcpc -f -n -q -t 5 -i usb0.2
|
||||
[04-13_05:13:06:554] udhcpc (v1.23.2) started
|
||||
[04-13_05:13:06:614] Sending discover...
|
||||
[04-13_05:13:06:619] Sending select for 10.22.58.141...
|
||||
[04-13_05:13:06:623] Lease of 10.22.58.141 obtained, lease time 7200
|
||||
[04-13_05:13:06:629] udhcpc: ifconfig usb0.2 10.22.58.141 netmask 255.255.255.252 broadcast +
|
||||
[04-13_05:13:06:638] udhcpc: setting default routers: 10.22.58.142
|
||||
|
||||
root@ZhuoTK:/# ifconfig usb0.2
|
||||
usb0.2 Link encap:Ethernet HWaddr 02:50:F4:00:00:00
|
||||
inet addr:10.22.58.141 Mask:255.255.255.252
|
||||
inet6 addr: fe80::50:f4ff:fe00:0/64 Scope:Link
|
||||
UP RUNNING NOARP MTU:1500 Metric:1
|
||||
RX packets:2 errors:0 dropped:0 overruns:0 frame:0
|
||||
TX packets:7 errors:0 dropped:0 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:612 (612.0 B) TX bytes:1064 (1.0 KiB)
|
||||
|
||||
root@ZhuoTK:/# ip ro show
|
||||
default via 10.22.58.142 dev usb0.2
|
||||
10.22.58.140/30 dev usb0.2 proto kernel scope link src 10.22.58.141
|
||||
192.168.1.0/24 dev br-lan proto kernel scope link src 192.168.1.251
|
||||
|
||||
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=69.822 ms
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
root@OpenWrt:/# lspci
|
||||
00:00.0 Class 0604: 17cb:1001
|
||||
01:00.0 Class ff00: 17cb:0306
|
||||
|
||||
root@OpenWrt:/# insmod pcie_mhi.ko mhi_mbim_enabled=1
|
||||
[ 63.094154] mhi_init Quectel_Linux_PCIE_MHI_Driver_V1.3.0.17
|
||||
[ 63.094739] mhi_pci_probe pci_dev->name = 0000:01:00.0, domain=0, bus=1, slot=0, vendor=17CB, device=0306
|
||||
[ 63.099373] mhi_q 0000:01:00.0: BAR 0: assigned [mem 0x48000000-0x48000fff 64bit]
|
||||
[ 63.108476] mhi_q 0000:01:00.0: enabling device (0140 -> 0142)
|
||||
[ 63.293451] [I][mhi_netdev_enable_iface] Prepare the channels for transfer
|
||||
[ 63.324757] [I][mhi_netdev_enable_iface] Exited.
|
||||
[ 63.326265] rmnet_vnd_register_device(rmnet_mhi0.1)=0
|
||||
|
||||
root@OpenWrt:/# quectel-CM -s cment &
|
||||
[04-13_09:25:23:910] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-13_09:25:23:912] network interface '' or qmidev '' is not exist
|
||||
[04-13_09:25:23:912] netcard driver = pcie_mhi, driver version = V1.3.0.17
|
||||
[04-13_09:25:23:913] mbim_qmap_mode = 1, vlan_id = 0x00, qmap_netcard = rmnet_mhi0.1
|
||||
[04-13_09:25:23:913] Modem works in MBIM mode
|
||||
[04-13_09:25:23:965] cdc_wdm_fd = 7
|
||||
[04-13_09:25:23:965] mbim_open_device()
|
||||
[04-13_09:25:24:549] mbim_device_caps_query()
|
||||
[04-13_09:25:24:575] DeviceId: 869710030002905
|
||||
[04-13_09:25:24:575] FirmwareInfo: RM500QGLABR10A03M4G_01.001.03
|
||||
[04-13_09:25:24:575] HardwareInfo: RM500QGL_VH
|
||||
[04-13_09:25:24:576] mbim_device_services_query()
|
||||
[04-13_09:25:24:585] mbim_set_radio_state( 1 )
|
||||
[04-13_09:25:24:588] HwRadioState: 1, SwRadioState: 1
|
||||
[04-13_09:25:24:588] mbim_subscriber_status_query()
|
||||
[04-13_09:25:24:612] SubscriberId: 460028563800461
|
||||
[04-13_09:25:24:612] SimIccId: 89860015120716380461
|
||||
[04-13_09:25:24:613] SubscriberReadyState NotInitialized -> Initialized
|
||||
[04-13_09:25:24:613] mbim_register_state_query()
|
||||
[04-13_09:25:24:617] RegisterState Unknown -> Home
|
||||
[04-13_09:25:24:617] mbim_packet_service_query()
|
||||
[04-13_09:25:24:619] PacketServiceState Unknown -> Attached
|
||||
[04-13_09:25:24:619] CurrentDataClass = 5G_NSA
|
||||
[04-13_09:25:24:620] mbim_query_connect(sessionID=0)
|
||||
[04-13_09:25:24:631] ActivationState Unknown -> Deactivated
|
||||
[04-13_09:25:24:631] ifconfig rmnet_mhi0 down
|
||||
[04-13_09:25:24:657] ifconfig rmnet_mhi0.1 0.0.0.0
|
||||
ifconfig: SIOCSIFFLAGS: Network is down
|
||||
[04-13_09:25:24:681] ifconfig rmnet_mhi0.1 down
|
||||
[04-13_09:25:24:705] mbim_register_state_query()
|
||||
[04-13_09:25:24:709] mbim_packet_service_query()
|
||||
[04-13_09:25:24:713] CurrentDataClass = 5G_NSA
|
||||
[04-13_09:25:24:713] mbim_set_connect(onoff=1, sessionID=0)
|
||||
[04-13_09:25:25:096] ActivationState Deactivated -> Activated
|
||||
[04-13_09:25:25:097] mbim_ip_config(sessionID=0)
|
||||
[04-13_09:25:25:100] < SessionId = 0
|
||||
[04-13_09:25:25:100] < IPv4ConfigurationAvailable = 0xf
|
||||
[04-13_09:25:25:100] < IPv6ConfigurationAvailable = 0x0
|
||||
[04-13_09:25:25:101] < IPv4AddressCount = 0x1
|
||||
[04-13_09:25:25:101] < IPv4AddressOffset = 0x3c
|
||||
[04-13_09:25:25:101] < IPv6AddressCount = 0x0
|
||||
[04-13_09:25:25:102] < IPv6AddressOffset = 0x0
|
||||
[04-13_09:25:25:102] < IPv4 = 10.190.166.229/30
|
||||
[04-13_09:25:25:103] < gw = 10.190.166.230
|
||||
[04-13_09:25:25:103] < dns1 = 211.138.180.2
|
||||
[04-13_09:25:25:103] < dns2 = 211.138.180.3
|
||||
[04-13_09:25:25:104] < ipv4 mtu = 1500
|
||||
[04-13_09:25:25:112] ifconfig rmnet_mhi0 up
|
||||
[04-13_09:25:25:141] ifconfig rmnet_mhi0.1 up
|
||||
[04-13_09:25:25:170] ip -4 address flush dev rmnet_mhi0.1
|
||||
[04-13_09:25:25:190] ip -4 address add 10.190.166.229/30 dev rmnet_mhi0.1
|
||||
[04-13_09:25:25:213] ip -4 route add default via 10.190.166.230 dev rmnet_mhi0.1
|
||||
|
||||
root@OpenWrt:/# ifconfig rmnet_mhi0.1
|
||||
rmnet_mhi0.1 Link encap:Ethernet HWaddr 02:50:F4:00:00:00
|
||||
inet addr:10.190.166.229 Mask:255.255.255.252
|
||||
inet6 addr: fe80::50:f4ff:fe00:0/64 Scope:Link
|
||||
UP RUNNING NOARP MTU:1500 Metric:1
|
||||
RX packets:19 errors:0 dropped:0 overruns:0 frame:0
|
||||
TX packets:29 errors:0 dropped:0 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:2326 (2.2 KiB) TX bytes:2991 (2.9 KiB)
|
||||
|
||||
root@OpenWrt:/# 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=278.561 ms
|
||||
@@ -0,0 +1,170 @@
|
||||
root@OpenWrt:/# lspci
|
||||
00:00.0 Class 0604: 17cb:1001
|
||||
01:00.0 Class ff00: 17cb:0304
|
||||
root@OpenWrt:/# insmod pcie_mhi.ko mhi_mbim_enabled=1 qmap_mode=4
|
||||
[ 76.596827] mhi_init Quectel_Linux_PCIE_MHI_Driver_V1.3.0.17
|
||||
[ 76.598596] mhi_pci_probe pci_dev->name = 0000:01:00.0, domain=0, bus=1, slot=0, vendor=17CB, device=0304
|
||||
[ 76.602863] mhi_q 0000:01:00.0: BAR 0: assigned [mem 0x48000000-0x48000fff 64bit]
|
||||
[ 76.611323] mhi_q 0000:01:00.0: enabling device (0140 -> 0142)
|
||||
[ 76.760239] [I][mhi_netdev_enable_iface] Prepare the channels for transfer
|
||||
[ 76.828699] [I][mhi_netdev_enable_iface] Exited.
|
||||
[ 76.832727] rmnet_vnd_register_device(rmnet_mhi0.1)=0
|
||||
[ 76.836596] rmnet_vnd_register_device(rmnet_mhi0.2)=0
|
||||
[ 76.841170] rmnet_vnd_register_device(rmnet_mhi0.3)=0
|
||||
[ 76.846373] rmnet_vnd_register_device(rmnet_mhi0.4)=0
|
||||
|
||||
root@OpenWrt:~# quectel-mbim-proxy -d /dev/mhi_MBIM &
|
||||
root@OpenWrt:~# [04-14_03:05:36:296] mbim_dev_fd=3
|
||||
[04-14_03:05:36:297] mbim_send_open_msg()
|
||||
[04-14_03:05:36:669] receive MBIM_OPEN_DONE, status=0
|
||||
[04-14_03:05:36:670] mbim_server_fd=4
|
||||
|
||||
root@OpenWrt:~# quectel-CM -n 1 -s cmnet &
|
||||
[04-14_03:05:45:955] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-14_03:05:45:956] network interface '' or qmidev '' is not exist
|
||||
[04-14_03:05:45:957] netcard driver = pcie_mhi, driver version = V1.3.0.17
|
||||
[04-14_03:05:45:957] mbim_qmap_mode = 4, vlan_id = 0x01, qmap_netcard = rmnet_mhi0.1
|
||||
[04-14_03:05:45:958] Modem works in MBIM mode
|
||||
[04-14_03:05:45:959] connect to quectel-mbim-proxy sockfd = 7
|
||||
[04-14_03:05:45:959] handle_client_connect client_fd=5, client_idx=1
|
||||
[04-14_03:05:45:959] cdc_wdm_fd = 7
|
||||
[04-14_03:05:45:960] mbim_open_device()
|
||||
[04-14_03:05:45:961] mbim_device_caps_query()
|
||||
[04-14_03:05:45:967] DeviceId: 860459050041596
|
||||
[04-14_03:05:45:968] FirmwareInfo: EM120RGLAPR02A03M4G_01.001.07
|
||||
|
||||
[04-14_03:05:45:968] HardwareInfo: EM120R_GL
|
||||
[04-14_03:05:45:968] mbim_device_services_query()
|
||||
[04-14_03:05:45:972] mbim_set_radio_state( 1 )
|
||||
[04-14_03:05:45:976] HwRadioState: 1, SwRadioState: 1
|
||||
[04-14_03:05:45:976] mbim_subscriber_status_query()
|
||||
[04-14_03:05:45:985] SubscriberId: 460028563800461
|
||||
[04-14_03:05:45:985] SimIccId: 89860015120716380461
|
||||
[04-14_03:05:45:986] SubscriberReadyState NotInitialized -> Initialized
|
||||
[04-14_03:05:45:986] mbim_register_state_query()
|
||||
[04-14_03:05:45:991] RegisterState Unknown -> Home
|
||||
[04-14_03:05:45:991] mbim_packet_service_query()
|
||||
[04-14_03:05:45:995] PacketServiceState Unknown -> Attached
|
||||
[04-14_03:05:45:996] mbim_query_connect(sessionID=1)
|
||||
[04-14_03:05:46:000] ActivationState Unknown -> Deactivated
|
||||
[04-14_03:05:46:000] ifconfig rmnet_mhi0 down
|
||||
[04-14_03:05:46:024] ifconfig rmnet_mhi0.1 0.0.0.0
|
||||
ifconfig: SIOCSIFFLAGS: Network is down
|
||||
[04-14_03:05:46:049] ifconfig rmnet_mhi0.1 down
|
||||
[04-14_03:05:46:072] mbim_set_connect(onoff=1, sessionID=1)
|
||||
[04-14_03:05:46:099] ActivationState Deactivated -> Activated
|
||||
[04-14_03:05:46:099] mbim_ip_config(sessionID=1)
|
||||
[ 222.484298] net rmnet_mhi0: link_state 0x0 -> 0x1
|
||||
[04-14_03:05:46:103] < SessionId = 1
|
||||
[04-14_03:05:46:104] < IPv4ConfigurationAvailable = 0xf
|
||||
[04-14_03:05:46:104] < IPv6ConfigurationAvailable = 0x0
|
||||
[04-14_03:05:46:104] < IPv4AddressCount = 0x1
|
||||
[04-14_03:05:46:105] < IPv4AddressOffset = 0x3c
|
||||
[ 222.507775] [I][mhi_netdev_open] Opened net dev interface
|
||||
[04-14_03:05:46:105] < IPv6AddressCount = 0x0
|
||||
[04-14_03:05:46:105] < IPv6AddressOffset = 0x0
|
||||
[04-14_03:05:46:106] < IPv4 = 10.38.21.158/30
|
||||
[04-14_03:05:46:106] < gw = 10.38.21.157
|
||||
[04-14_03:05:46:106] < dns1 = 211.138.180.2
|
||||
[04-14_03:05:46:107] < dns2 = 211.138.180.3
|
||||
[04-14_03:05:46:107] < ipv4 mtu = 1500
|
||||
[04-14_03:05:46:112] ifconfig rmnet_mhi0 up
|
||||
[04-14_03:05:46:140] ifconfig rmnet_mhi0.1 up
|
||||
[04-14_03:05:46:168] ip -4 address flush dev rmnet_mhi0.1
|
||||
[04-14_03:05:46:190] ip -4 address add 10.38.21.158/30 dev rmnet_mhi0.1
|
||||
[04-14_03:05:46:212] ip -4 route add default via 10.38.21.157 dev rmnet_mhi0.1
|
||||
[04-14_03:05:50:730] handle_client_connect client_fd=6, client_idx=2
|
||||
[ 227.558631] net rmnet_mhi0: link_state 0x1 -> 0x3
|
||||
|
||||
root@OpenWrt:~# quectel-CM -n 2 -s 4gnet
|
||||
[04-14_03:05:50:725] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-14_03:05:50:726] network interface '' or qmidev '' is not exist
|
||||
[04-14_03:05:50:727] netcard driver = pcie_mhi, driver version = V1.3.0.17
|
||||
[04-14_03:05:50:728] mbim_qmap_mode = 4, vlan_id = 0x02, qmap_netcard = rmnet_mhi0.2
|
||||
[04-14_03:05:50:729] Modem works in MBIM mode
|
||||
[04-14_03:05:50:730] connect to quectel-mbim-proxy sockfd = 8
|
||||
[04-14_03:05:50:730] cdc_wdm_fd = 8
|
||||
[04-14_03:05:50:731] mbim_open_device()
|
||||
[04-14_03:05:50:732] mbim_device_caps_query()
|
||||
[04-14_03:05:50:738] DeviceId: 860459050041596
|
||||
[04-14_03:05:50:739] FirmwareInfo: EM120RGLAPR02A03M4G_01.001.07
|
||||
|
||||
[04-14_03:05:50:739] HardwareInfo: EM120R_GL
|
||||
[04-14_03:05:50:740] mbim_device_services_query()
|
||||
[04-14_03:05:50:744] mbim_set_radio_state( 1 )
|
||||
[04-14_03:05:50:747] HwRadioState: 1, SwRadioState: 1
|
||||
[04-14_03:05:50:747] mbim_subscriber_status_query()
|
||||
[04-14_03:05:50:757] SubscriberId: 460028563800461
|
||||
[04-14_03:05:50:758] SimIccId: 89860015120716380461
|
||||
[04-14_03:05:50:758] SubscriberReadyState NotInitialized -> Initialized
|
||||
[04-14_03:05:50:759] mbim_register_state_query()
|
||||
[04-14_03:05:50:763] RegisterState Unknown -> Home
|
||||
[04-14_03:05:50:764] mbim_packet_service_query()
|
||||
[04-14_03:05:50:768] PacketServiceState Unknown -> Attached
|
||||
[04-14_03:05:50:769] mbim_query_connect(sessionID=2)
|
||||
[04-14_03:05:50:772] ActivationState Unknown -> Deactivated
|
||||
[04-14_03:05:50:773] ifconfig rmnet_mhi0.2 0.0.0.0
|
||||
[04-14_03:05:50:799] ifconfig rmnet_mhi0.2 down
|
||||
[04-14_03:05:50:834] mbim_set_connect(onoff=1, sessionID=2)
|
||||
[04-14_03:05:51:170] ActivationState Deactivated -> Activated
|
||||
[04-14_03:05:51:171] mbim_ip_config(sessionID=2)
|
||||
[04-14_03:05:51:174] < SessionId = 2
|
||||
[04-14_03:05:51:174] < IPv4ConfigurationAvailable = 0xf
|
||||
[04-14_03:05:51:175] < IPv6ConfigurationAvailable = 0x0
|
||||
[04-14_03:05:51:175] < IPv4AddressCount = 0x1
|
||||
[04-14_03:05:51:175] < IPv4AddressOffset = 0x3c
|
||||
[04-14_03:05:51:176] < IPv6AddressCount = 0x0
|
||||
[04-14_03:05:51:176] < IPv6AddressOffset = 0x0
|
||||
[04-14_03:05:51:176] < IPv4 = 10.36.109.217/30
|
||||
[04-14_03:05:51:177] < gw = 10.36.109.218
|
||||
[04-14_03:05:51:177] < dns1 = 211.138.180.2
|
||||
[04-14_03:05:51:178] < dns2 = 211.138.180.3
|
||||
[04-14_03:05:51:178] < ipv4 mtu = 1500
|
||||
[04-14_03:05:51:182] ifconfig rmnet_mhi0 up
|
||||
[04-14_03:05:51:206] ifconfig rmnet_mhi0.2 up
|
||||
[04-14_03:05:51:233] ip -4 address flush dev rmnet_mhi0.2
|
||||
[04-14_03:05:51:254] ip -4 address add 10.36.109.217/30 dev rmnet_mhi0.2
|
||||
[04-14_03:05:51:277] ip -4 route add default via 10.36.109.218 dev rmnet_mhi0.2
|
||||
|
||||
root@OpenWrt:~# ifconfig rmnet_mhi0.1
|
||||
rmnet_mhi0.1 Link encap:Ethernet HWaddr 02:50:F4:00:00:00
|
||||
inet addr:10.38.21.158 Mask:255.255.255.252
|
||||
inet6 addr: fe80::50:f4ff:fe00:0/64 Scope:Link
|
||||
UP RUNNING NOARP MTU:1500 Metric:1
|
||||
RX packets:37 errors:0 dropped:0 overruns:0 frame:0
|
||||
TX packets:29 errors:0 dropped:0 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:9907 (9.6 KiB) TX bytes:2764 (2.6 KiB)
|
||||
|
||||
root@OpenWrt:~# ifconfig rmnet_mhi0.2
|
||||
rmnet_mhi0.2 Link encap:Ethernet HWaddr 02:50:F4:00:00:00
|
||||
inet addr:10.36.109.217 Mask:255.255.255.252
|
||||
inet6 addr: fe80::50:f4ff:fe00:0/64 Scope:Link
|
||||
UP RUNNING NOARP MTU:1500 Metric:1
|
||||
RX packets:5 errors:0 dropped:0 overruns:0 frame:0
|
||||
TX packets:18 errors:0 dropped:0 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:344 (344.0 B) TX bytes:1152 (1.1 KiB)
|
||||
|
||||
root@OpenWrt:~# ip ro del 8.8.8.8/32
|
||||
RTNETLINK answers: No such process
|
||||
root@OpenWrt:~# ip ro add 8.8.8.8/32 dev rmnet_mhi0.1
|
||||
root@OpenWrt:~# 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=73.248 ms
|
||||
|
||||
root@OpenWrt:~# ip ro del 8.8.8.8/32
|
||||
root@OpenWrt:~# ip ro del 8.8.8.8/32
|
||||
RTNETLINK answers: No such process
|
||||
root@OpenWrt:~# ip ro add 8.8.8.8/32 dev rmnet_mhi0.2
|
||||
root@OpenWrt:~# 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=99.637 ms
|
||||
|
||||
root@OpenWrt:~# quectel-CM -k 2
|
||||
[04-14_03:06:58:912] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-14_03:06:59:063] /proc/3565/cmdline: quectel-CM -n 2 -s 4gnet
|
||||
[04-14_03:06:59:064] send SIGINT to process 3565
|
||||
[ 295.719442] net rmnet_mhi0: link_state 0x3 -> 0x1
|
||||
[04-14_03:06:59:407] proxy_loop poll fd = 6, revents = 0011
|
||||
[04-14_03:06:59:408] handle_client_disconnect client_fd=6, client_idx=2
|
||||
@@ -0,0 +1,127 @@
|
||||
root@OpenWrt:/# cat /sys/class/net/rmnet_mhi0/qmap_mode
|
||||
1
|
||||
root@OpenWrt:/# cat /sys/module/pcie_mhi/parameters/mhi_mbim_enabled
|
||||
0
|
||||
root@OpenWrt:/# dmesg | grep mhi
|
||||
[ 18.442226] mhi_init Quectel_Linux_PCIE_MHI_Driver_V1.3.0.17
|
||||
[ 18.443032] mhi_pci_probe pci_dev->name = 0000:01:00.0, domain=0, bus=1, slot=0, vendor=17CB, device=0306
|
||||
[ 18.447488] mhi_q 0000:01:00.0: BAR 0: assigned [mem 0x48000000-0x48000fff 64bit]
|
||||
[ 18.456563] mhi_q 0000:01:00.0: enabling device (0140 -> 0142)
|
||||
[ 18.464184] [I][mhi_init_pci_dev] msi_required = 5, msi_allocated = 5, msi_irq = 197
|
||||
[ 18.464215] [I][mhi_power_up] dev_state:RESET
|
||||
[ 18.464225] [I][mhi_async_power_up] Requested to power on
|
||||
[ 18.464432] [I][mhi_alloc_coherent] size = 114688, dma_handle = 8d400000
|
||||
[ 18.464445] [I][mhi_init_dev_ctxt] mhi_ctxt->ctrl_seg = d1766000
|
||||
[ 18.466003] [I][mhi_async_power_up] dev_state:RESET ee:AMSS
|
||||
[ 18.466080] [I][mhi_pm_st_worker] Transition to state:READY
|
||||
[ 18.466109] [I][mhi_pm_st_worker] INVALID_EE -> AMSS
|
||||
[ 18.466135] [I][mhi_ready_state_transition] Waiting to enter READY state
|
||||
[ 18.466224] [I][mhi_async_power_up] Power on setup success
|
||||
[ 18.466265] [I][mhi_pci_probe] Return successful
|
||||
[ 18.577299] [I][mhi_intvec_threaded_handlr] device ee:AMSS dev_state:READY, pm_state:POR
|
||||
[ 18.577312] [I][mhi_ready_state_transition] Device in READY State
|
||||
[ 18.577325] [I][mhi_intvec_threaded_handlr] device ee:AMSS dev_state:READY, INVALID_EE
|
||||
[ 18.577329] [I][mhi_tryset_pm_state] Transition to pm state from:POR to:POR
|
||||
[ 18.577337] [I][mhi_init_mmio] Initializing MMIO
|
||||
[ 18.577344] [I][mhi_init_mmio] CHDBOFF:0x300
|
||||
[ 18.577361] [I][mhi_init_mmio] ERDBOFF:0x700
|
||||
[ 18.577372] [I][mhi_init_mmio] Programming all MMIO values.
|
||||
[ 18.690834] [I][mhi_dump_tre] carl_ev evt_state_change mhistate=2
|
||||
[ 18.690854] [I][mhi_process_ctrl_ev_ring] MHI state change event to state:M0
|
||||
[ 18.690866] [I][mhi_pm_m0_transition] Entered With State:READY PM_STATE:POR
|
||||
[ 18.690879] [I][mhi_tryset_pm_state] Transition to pm state from:POR to:M0
|
||||
[ 18.694229] [I][mhi_dump_tre] carl_ev evt_ee_state execenv=2
|
||||
[ 18.694241] [I][mhi_process_ctrl_ev_ring] MHI EE received event:AMSS
|
||||
[ 18.694293] [I][mhi_pm_st_worker] Transition to state:MISSION MODE
|
||||
[ 18.694310] [I][mhi_pm_st_worker] INVALID_EE -> AMSS
|
||||
[ 18.694319] [I][mhi_pm_mission_mode_transition] Processing Mission Mode Transition
|
||||
[ 18.694341] [I][mhi_init_timesync] No timesync capability found
|
||||
[ 18.694350] [I][mhi_pm_mission_mode_transition] Adding new devices
|
||||
[ 18.696365] [I][mhi_dtr_probe] Enter for DTR control channel
|
||||
[ 18.696383] [I][__mhi_prepare_channel] Entered: preparing channel:18
|
||||
[ 18.703113] [I][mhi_dump_tre] carl_ev evt_cmd_comp code=1, type=33
|
||||
[ 18.703164] [I][__mhi_prepare_channel] Chan:18 successfully moved to start state
|
||||
[ 18.703174] [I][__mhi_prepare_channel] Entered: preparing channel:19
|
||||
[ 18.710681] [I][mhi_dump_tre] carl_ev evt_cmd_comp code=1, type=33
|
||||
[ 18.710734] [I][__mhi_prepare_channel] Chan:19 successfully moved to start state
|
||||
[ 18.710804] [I][mhi_dtr_probe] Exit with ret:0
|
||||
[ 18.711774] [I][mhi_netdev_enable_iface] Prepare the channels for transfer
|
||||
[ 18.711811] [I][__mhi_prepare_channel] Entered: preparing channel:100
|
||||
[ 18.732097] [I][mhi_dump_tre] carl_ev evt_cmd_comp code=1, type=33
|
||||
[ 18.732151] [I][__mhi_prepare_channel] Chan:100 successfully moved to start state
|
||||
[ 18.732162] [I][__mhi_prepare_channel] Entered: preparing channel:101
|
||||
[ 18.744170] [I][mhi_dump_tre] carl_ev evt_cmd_comp code=1, type=33
|
||||
[ 18.744219] [I][__mhi_prepare_channel] Chan:101 successfully moved to start state
|
||||
[ 18.749132] [I][mhi_netdev_enable_iface] Exited.
|
||||
[ 18.750306] rmnet_vnd_register_device(rmnet_mhi0.1)=0
|
||||
[ 18.752927] [I][mhi_pm_mission_mode_transition] Exit with ret:0
|
||||
|
||||
root@OpenWrt:/# busybox microcom /dev/mhi_DUN
|
||||
at+cpin?
|
||||
+CPIN: READY
|
||||
|
||||
OK
|
||||
at+cops?
|
||||
+COPS: 0,0,"CHINA MOBILE",13
|
||||
|
||||
OK
|
||||
at+csq
|
||||
+csq: 23,99
|
||||
|
||||
OK
|
||||
|
||||
root@OpenWrt:/# quectel-CM -s cmnet &
|
||||
[04-13_09:26:58:077] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-13_09:26:58:078] network interface '' or qmidev '' is not exist
|
||||
[04-13_09:26:58:079] netcard driver = pcie_mhi, driver version = V1.3.0.17
|
||||
[04-13_09:26:58:080] qmap_mode = 1, qmap_version = 9, qmap_size = 16384, muxid = 0x81, qmap_netcard = rmnet_mhi0.1
|
||||
[04-13_09:26:58:080] Modem works in QMI mode
|
||||
[04-13_09:26:58:131] cdc_wdm_fd = 7
|
||||
[04-13_09:26:59:132] QmiWwanInit message timeout
|
||||
[04-13_09:27:00:140] Get clientWDS = 15
|
||||
[04-13_09:27:00:144] Get clientDMS = 1
|
||||
[04-13_09:27:00:147] Get clientNAS = 4
|
||||
[04-13_09:27:00:151] Get clientUIM = 1
|
||||
[04-13_09:27:00:155] Get clientWDA = 1
|
||||
[04-13_09:27:00:158] requestBaseBandVersion RM500QGLABR10A03M4G
|
||||
[04-13_09:27:00:161] qmap_settings.rx_urb_size = 16384
|
||||
[04-13_09:27:00:162] qmap_settings.ul_data_aggregation_max_datagrams = 11
|
||||
[04-13_09:27:00:162] qmap_settings.ul_data_aggregation_max_size = 8192
|
||||
[04-13_09:27:00:163] qmap_settings.dl_minimum_padding = 0
|
||||
[04-13_09:27:00:176] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-13_09:27:00:177] requestSetProfile[1] cmnet///0
|
||||
[04-13_09:27:00:190] requestGetProfile[1] cmnet///0
|
||||
[04-13_09:27:00:193] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: 5G_NSA
|
||||
[04-13_09:27:00:197] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[04-13_09:27:00:198] ifconfig rmnet_mhi0 down
|
||||
[04-13_09:27:00:222] ifconfig rmnet_mhi0.1 0.0.0.0
|
||||
[04-13_09:27:00:247] ifconfig rmnet_mhi0.1 down
|
||||
[04-13_09:27:00:281] requestSetupDataCall WdsConnectionIPv4Handle: 0x1228bb20
|
||||
[ 245.284909] net rmnet_mhi0: link_state 0x0 -> 0x1
|
||||
[04-13_09:27:00:293] ifconfig rmnet_mhi0 up
|
||||
[ 245.308696] [I][mhi_netdev_open] Opened net dev interface
|
||||
[04-13_09:27:00:318] ifconfig rmnet_mhi0.1 up
|
||||
[04-13_09:27:00:353] you are use OpenWrt?
|
||||
[04-13_09:27:00:354] should not calling udhcpc manually?
|
||||
[04-13_09:27:00:354] should modify /etc/config/network as below?
|
||||
[04-13_09:27:00:355] config interface wan
|
||||
[04-13_09:27:00:355] option ifname rmnet_mhi0.1
|
||||
[04-13_09:27:00:355] option proto dhcp
|
||||
[04-13_09:27:00:356] should use "/sbin/ifstaus wan" to check rmnet_mhi0.1 's status?
|
||||
[04-13_09:27:00:356] busybox udhcpc -f -n -q -t 5 -i rmnet_mhi0.1
|
||||
udhcpc: started, v1.28.3
|
||||
udhcpc: sending discover
|
||||
udhcpc: sending select for 10.128.73.23
|
||||
udhcpc: lease of 10.128.73.23 obtained, lease time 7200
|
||||
[04-13_09:27:00:710] udhcpc: ifconfig rmnet_mhi0.1 10.128.73.23 netmask 255.255.255.240 broadcast +
|
||||
[04-13_09:27:00:742] udhcpc: setting default routers: 10.128.73.24
|
||||
|
||||
root@OpenWrt:/# ifconfig rmnet_mhi0.1
|
||||
rmnet_mhi0.1 Link encap:Ethernet HWaddr 02:50:F4:00:00:00
|
||||
inet addr:10.128.73.23 Mask:255.255.255.240
|
||||
inet6 addr: fe80::50:f4ff:fe00:0/64 Scope:Link
|
||||
UP RUNNING NOARP MTU:1500 Metric:1
|
||||
RX packets:2 errors:0 dropped:0 overruns:0 frame:0
|
||||
TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:612 (612.0 B) TX bytes:684 (684.0 B)
|
||||
@@ -0,0 +1,76 @@
|
||||
root@OpenWrt:/# lspci
|
||||
00:00.0 Class 0604: 17cb:1001
|
||||
01:00.0 Class ff00: 17cb:0306
|
||||
|
||||
root@OpenWrt:~# insmod pcie_mhi.ko
|
||||
[ 77.949271] mhi_init Quectel_Linux_PCIE_MHI_Driver_V1.3.0.17
|
||||
[ 77.950949] mhi_pci_probe pci_dev->name = 0000:01:00.0, domain=0, bus=1, slot=0, vendor=17CB, device=0306
|
||||
[ 77.955331] mhi_q 0000:01:00.0: BAR 0: assigned [mem 0x48000000-0x48000fff 64bit]
|
||||
[ 77.963756] mhi_q 0000:01:00.0: enabling device (0140 -> 0142)
|
||||
[ 78.048911] [I][mhi_netdev_enable_iface] Prepare the channels for transfer
|
||||
[ 78.092304] [I][mhi_netdev_enable_iface] Exited.
|
||||
[ 78.096580] rmnet_vnd_register_device(rmnet_mhi0.1)=0
|
||||
|
||||
root@OpenWrt:~# brctl addbr br0
|
||||
root@OpenWrt:~# brctl addif br0 rmnet_mhi0.1
|
||||
root@OpenWrt:~# brctl addif br0 eth1
|
||||
[ 250.017213] device eth1 entered promiscuous mode
|
||||
root@OpenWrt:~# brctl show
|
||||
bridge name bridge id STP enabled interfaces
|
||||
br0 8000.00001c353487 no eth1
|
||||
rmnet_mhi0.1
|
||||
|
||||
root@OpenWrt:~# quectel-CM -s cmnet -b &
|
||||
[04-14_06:43:28:473] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-14_06:43:28:474] network interface '' or qmidev '' is not exist
|
||||
[04-14_06:43:28:475] netcard driver = pcie_mhi, driver version = V1.3.0.17
|
||||
[04-14_06:43:28:476] qmap_mode = 1, qmap_version = 9, qmap_size = 16384, muxid = 0x81, qmap_netcard = rmnet_mhi0.1
|
||||
[04-14_06:43:28:477] Modem works in QMI mode
|
||||
[04-14_06:43:28:531] cdc_wdm_fd = 7
|
||||
[04-14_06:43:29:532] QmiWwanInit message timeout
|
||||
[04-14_06:43:30:540] Get clientWDS = 15
|
||||
[04-14_06:43:30:543] Get clientDMS = 1
|
||||
[04-14_06:43:30:546] Get clientNAS = 4
|
||||
[04-14_06:43:30:550] Get clientUIM = 1
|
||||
[04-14_06:43:30:553] Get clientWDA = 1
|
||||
[04-14_06:43:30:557] requestBaseBandVersion RM500QGLABR10A03M4G
|
||||
[04-14_06:43:30:560] qmap_settings.rx_urb_size = 16384
|
||||
[04-14_06:43:30:561] qmap_settings.ul_data_aggregation_max_datagrams = 11
|
||||
[04-14_06:43:30:561] qmap_settings.ul_data_aggregation_max_size = 8192
|
||||
[04-14_06:43:30:561] qmap_settings.dl_minimum_padding = 0
|
||||
[04-14_06:43:30:575] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-14_06:43:30:575] requestSetProfile[1] cmnet///0
|
||||
[04-14_06:43:30:588] requestGetProfile[1] cmnet///0
|
||||
[04-14_06:43:30:591] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: 5G_NSA
|
||||
[04-14_06:43:30:595] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[04-14_06:43:30:595] ifconfig rmnet_mhi0 down
|
||||
[04-14_06:43:30:620] ifconfig rmnet_mhi0.1 0.0.0.0
|
||||
ifconfig: SIOCSIFFLAGS: Network is down
|
||||
[04-14_06:43:30:644] ifconfig rmnet_mhi0.1 down
|
||||
[04-14_06:43:30:679] requestSetupDataCall WdsConnectionIPv4Handle: 0xb41f47d0
|
||||
[ 263.869899] net rmnet_mhi0: link_state 0x0 -> 0x1
|
||||
[04-14_06:43:30:693] ifconfig rmnet_mhi0 up
|
||||
[ 263.892647] [I][mhi_netdev_open] Opened net dev interface
|
||||
[04-14_06:43:30:718] ifconfig rmnet_mhi0.1 up
|
||||
[04-14_06:43:30:746] echo '0xa59316b' > /sys/class/net/rmnet_mhi0.1/bridge_ipv4
|
||||
|
||||
root@OpenWrt:~# ifconfig br0 up
|
||||
[ 268.800026] br0: port 2(eth1) entered forwarding state
|
||||
[ 268.800336] br0: port 2(eth1) entered forwarding state
|
||||
[ 268.804251] br0: port 1(rmnet_mhi0.1) entered forwarding state
|
||||
[ 268.809465] br0: port 1(rmnet_mhi0.1) entered forwarding state
|
||||
[ 283.845790] br0: port 2(eth1) entered forwarding state
|
||||
|
||||
[ 296.512489] rmnet_mhi0.1 PC Mac Address: 00:0e:c6:a6:6c:f1
|
||||
[ 296.515756] rmnet_mhi0.1 PC Mac Address: 00:0e:c6:a6:6c:f1
|
||||
[ 296.586584] rmnet_mhi0.1 sip = 10.89.49.107, tip=10.89.49.108, ipv4=10.89.49.107
|
||||
[ 296.672356] rmnet_mhi0.1 sip = 10.89.49.107, tip=10.89.49.108, ipv4=10.89.49.107
|
||||
[ 296.792061] rmnet_mhi0.1 sip = 10.89.49.107, tip=10.89.49.108, ipv4=10.89.49.107
|
||||
[ 296.832822] rmnet_mhi0.1 sip = 10.89.49.107, tip=10.89.49.108, ipv4=10.89.49.107
|
||||
[ 296.941073] rmnet_mhi0.1 sip = 0.0.0.0, tip=10.89.49.107, ipv4=10.89.49.107
|
||||
[ 297.941310] rmnet_mhi0.1 sip = 0.0.0.0, tip=10.89.49.107, ipv4=10.89.49.107
|
||||
[ 298.941528] rmnet_mhi0.1 sip = 0.0.0.0, tip=10.89.49.107, ipv4=10.89.49.107
|
||||
[ 299.941704] rmnet_mhi0.1 sip = 10.89.49.107, tip=10.89.49.107, ipv4=10.89.49.107
|
||||
[ 300.024484] rmnet_mhi0.1 sip = 10.89.49.107, tip=10.89.49.108, ipv4=10.89.49.107
|
||||
[ 300.051995] rmnet_mhi0.1 sip = 10.89.49.107, tip=10.89.49.108, ipv4=10.89.49.107
|
||||
[ 303.915933] rmnet_mhi0.1 sip = 10.89.49.107, tip=10.89.49.108, ipv4=10.89.49.107
|
||||
@@ -0,0 +1,138 @@
|
||||
root@OpenWrt:/# lspci
|
||||
00:00.0 Class 0604: 17cb:1001
|
||||
01:00.0 Class ff00: 17cb:0306
|
||||
|
||||
root@OpenWrt:/# insmod pcie_mhi.ko qmap_mode=4
|
||||
[ 61.988878] mhi_init Quectel_Linux_PCIE_MHI_Driver_V1.3.0.17
|
||||
[ 61.989484] mhi_pci_probe pci_dev->name = 0000:01:00.0, domain=0, bus=1, slot=0, vendor=17CB, device=0306
|
||||
[ 61.994039] mhi_q 0000:01:00.0: BAR 0: assigned [mem 0x48000000-0x48000fff 64bit]
|
||||
[ 62.003208] mhi_q 0000:01:00.0: enabling device (0140 -> 0142)
|
||||
[ 62.191947] [I][mhi_netdev_enable_iface] Prepare the channels for transfer
|
||||
[ 62.224065] [I][mhi_netdev_enable_iface] Exited.
|
||||
[ 62.225619] rmnet_vnd_register_device(rmnet_mhi0.1)=0
|
||||
[ 62.229289] rmnet_vnd_register_device(rmnet_mhi0.2)=0
|
||||
[ 62.234378] rmnet_vnd_register_device(rmnet_mhi0.3)=0
|
||||
[ 62.240039] rmnet_vnd_register_device(rmnet_mhi0.4)=0
|
||||
|
||||
root@OpenWrt:/# quectel-qmi-proxy -d /dev/mhi_QMI0 &
|
||||
[04-13_09:25:12:278] Will use cdc-wdm='/dev/mhi_QMI0', proxy='quectel-qmi-proxy0'
|
||||
[04-13_09:25:12:297] qmi_proxy_init enter
|
||||
[04-13_09:25:12:297] qmi_proxy_loop enter thread_id 0xb6e88d44
|
||||
[04-13_09:25:14:298] qmi_proxy_init succful
|
||||
[04-13_09:25:14:299] local server: quectel-qmi-proxy0 sockfd = 4
|
||||
[04-13_09:25:14:299] qmi_proxy_server_fd = 4
|
||||
|
||||
root@OpenWrt:/# quectel-CM -n 1 -s cmnet &
|
||||
[04-13_09:25:32:336] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-13_09:25:32:337] network interface '' or qmidev '' is not exist
|
||||
[04-13_09:25:32:338] netcard driver = pcie_mhi, driver version = V1.3.0.17
|
||||
[04-13_09:25:32:339] qmap_mode = 4, qmap_version = 9, qmap_size = 16384, muxid = 0x81, qmap_netcard = rmnet_mhi0.1
|
||||
[04-13_09:25:32:340] Modem works in QMI mode
|
||||
[04-13_09:25:32:341] connect to quectel-qmi-proxy0 sockfd = 7
|
||||
[04-13_09:25:32:342] cdc_wdm_fd = 7
|
||||
[04-13_09:25:32:380] requestBaseBandVersion RM500QGLABR10A03M4G
|
||||
[04-13_09:25:32:382] qmap_settings.rx_urb_size = 16384
|
||||
[04-13_09:25:32:383] qmap_settings.ul_data_aggregation_max_datagrams = 11
|
||||
[04-13_09:25:32:383] qmap_settings.ul_data_aggregation_max_size = 8192
|
||||
[04-13_09:25:32:384] qmap_settings.dl_minimum_padding = 0
|
||||
[04-13_09:25:32:394] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-13_09:25:32:395] requestSetProfile[1] cmnet///0
|
||||
[04-13_09:25:32:409] requestGetProfile[1] cmnet///0
|
||||
[04-13_09:25:32:414] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: 5G_NSA
|
||||
[04-13_09:25:32:418] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[04-13_09:25:32:419] ifconfig rmnet_mhi0 down
|
||||
[04-13_09:25:32:448] ifconfig rmnet_mhi0.1 0.0.0.0
|
||||
[04-13_09:25:32:473] ifconfig rmnet_mhi0.1 down
|
||||
[04-13_09:25:32:514] requestSetupDataCall WdsConnectionIPv4Handle: 0x2313a2a0
|
||||
[ 121.648172] net rmnet_mhi0: link_state 0x0 -> 0x1
|
||||
[04-13_09:25:32:525] ifconfig rmnet_mhi0 up
|
||||
[ 121.671210] [I][mhi_netdev_open] Opened net dev interface
|
||||
[04-13_09:25:32:551] ifconfig rmnet_mhi0.1 up
|
||||
[04-13_09:25:32:586] you are use OpenWrt?
|
||||
[04-13_09:25:32:587] should not calling udhcpc manually?
|
||||
[04-13_09:25:32:587] should modify /etc/config/network as below?
|
||||
[04-13_09:25:32:587] config interface wan
|
||||
[04-13_09:25:32:588] option ifname rmnet_mhi0.1
|
||||
[04-13_09:25:32:588] option proto dhcp
|
||||
[04-13_09:25:32:589] should use "/sbin/ifstaus wan" to check rmnet_mhi0.1 's status?
|
||||
[04-13_09:25:32:589] busybox udhcpc -f -n -q -t 5 -i rmnet_mhi0.1
|
||||
udhcpc: started, v1.28.3
|
||||
udhcpc: sending discover
|
||||
udhcpc: sending select for 10.174.91.70
|
||||
udhcpc: lease of 10.174.91.70 obtained, lease time 7200
|
||||
[04-13_09:25:32:980] udhcpc: ifconfig rmnet_mhi0.1 10.174.91.70 netmask 255.255.255.252 broadcast +
|
||||
[04-13_09:25:33:007] udhcpc: setting default routers: 10.174.91.69
|
||||
|
||||
root@OpenWrt:/# quectel-CM -n 2 -s 4gnet &
|
||||
[04-13_09:25:42:976] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-13_09:25:42:977] network interface '' or qmidev '' is not exist
|
||||
[04-13_09:25:42:978] netcard driver = pcie_mhi, driver version = V1.3.0.17
|
||||
[04-13_09:25:42:978] qmap_mode = 4, qmap_version = 9, qmap_size = 16384, muxid = 0x82, qmap_netcard = rmnet_mhi0.2
|
||||
[04-13_09:25:42:979] Modem works in QMI mode
|
||||
[04-13_09:25:42:981] connect to quectel-qmi-proxy0 sockfd = 7
|
||||
[04-13_09:25:42:982] cdc_wdm_fd = 7
|
||||
[04-13_09:25:43:010] requestBaseBandVersion RM500QGLABR10A03M4G
|
||||
[04-13_09:25:43:013] qmap_settings.rx_urb_size = 16384
|
||||
[04-13_09:25:43:014] qmap_settings.ul_data_aggregation_max_datagrams = 11
|
||||
[04-13_09:25:43:014] qmap_settings.ul_data_aggregation_max_size = 8192
|
||||
[04-13_09:25:43:015] qmap_settings.dl_minimum_padding = 0
|
||||
[04-13_09:25:43:030] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-13_09:25:43:030] requestSetProfile[2] 4gnet///0
|
||||
[04-13_09:25:43:046] requestGetProfile[2] 4gnet///0
|
||||
[04-13_09:25:43:050] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: 5G_NSA
|
||||
[04-13_09:25:43:054] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[04-13_09:25:43:055] ifconfig rmnet_mhi0.2 0.0.0.0
|
||||
[04-13_09:25:43:082] ifconfig rmnet_mhi0.2 down
|
||||
[04-13_09:25:43:507] requestSetupDataCall WdsConnectionIPv4Handle: 0x2332a780
|
||||
[ 132.641313] net rmnet_mhi0: link_state 0x1 -> 0x3
|
||||
[04-13_09:25:43:519] ifconfig rmnet_mhi0 up
|
||||
[04-13_09:25:43:543] ifconfig rmnet_mhi0.2 up
|
||||
[04-13_09:25:43:570] you are use OpenWrt?
|
||||
[04-13_09:25:43:570] should not calling udhcpc manually?
|
||||
[04-13_09:25:43:571] should modify /etc/config/network as below?
|
||||
[04-13_09:25:43:571] config interface wan
|
||||
[04-13_09:25:43:571] option ifname rmnet_mhi0.2
|
||||
[04-13_09:25:43:572] option proto dhcp
|
||||
[04-13_09:25:43:572] should use "/sbin/ifstaus wan" to check rmnet_mhi0.2 's status?
|
||||
[04-13_09:25:43:573] busybox udhcpc -f -n -q -t 5 -i rmnet_mhi0.2
|
||||
udhcpc: started, v1.28.3
|
||||
udhcpc: sending discover
|
||||
udhcpc: sending select for 10.163.253.197
|
||||
udhcpc: lease of 10.163.253.197 obtained, lease time 7200
|
||||
[04-13_09:25:43:810] udhcpc: ifconfig rmnet_mhi0.2 10.163.253.197 netmask 255.255.255.252 broadcast +
|
||||
[04-13_09:25:43:836] udhcpc: setting default routers: 10.163.253.198
|
||||
|
||||
root@OpenWrt:/# ifconfig rmnet_mhi0.1
|
||||
rmnet_mhi0.1 Link encap:Ethernet HWaddr 02:50:F4:00:00:00
|
||||
inet addr:10.174.91.70 Mask:255.255.255.252
|
||||
inet6 addr: fe80::50:f4ff:fe00:0/64 Scope:Link
|
||||
UP RUNNING NOARP MTU:1500 Metric:1
|
||||
RX packets:2 errors:0 dropped:0 overruns:0 frame:0
|
||||
TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:612 (612.0 B) TX bytes:1380 (1.3 KiB)
|
||||
|
||||
root@OpenWrt:/# ifconfig rmnet_mhi0.2
|
||||
rmnet_mhi0.2 Link encap:Ethernet HWaddr 02:50:F4:00:00:00
|
||||
inet addr:10.163.253.197 Mask:255.255.255.252
|
||||
inet6 addr: fe80::50:f4ff:fe00:0/64 Scope:Link
|
||||
UP RUNNING NOARP MTU:1500 Metric:1
|
||||
RX packets:2 errors:0 dropped:0 overruns:0 frame:0
|
||||
TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:612 (612.0 B) TX bytes:684 (684.0 B)
|
||||
|
||||
root@OpenWrt:/# ip ro del 8.8.8.8/32
|
||||
RTNETLINK answers: No such process
|
||||
root@OpenWrt:/# ip ro add 8.8.8.8/32 dev rmnet_mhi0.1
|
||||
root@OpenWrt:/# 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=390.869 ms
|
||||
|
||||
root@OpenWrt:/# ip ro del 8.8.8.8/32
|
||||
root@OpenWrt:/# ip ro del 8.8.8.8/32
|
||||
RTNETLINK answers: No such process
|
||||
root@OpenWrt:/# ip ro add 8.8.8.8/32 dev rmnet_mhi0.2
|
||||
root@OpenWrt:/# 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=314.395 ms
|
||||
@@ -0,0 +1,147 @@
|
||||
root@OpenWrt:~# lspci
|
||||
00:00.0 Class 0604: 17cb:1001
|
||||
01:00.0 Class ff00: 17cb:0306
|
||||
root@OpenWrt:~#
|
||||
|
||||
root@OpenWrt:~# insmod pcie_mhi.ko qmap_mode=4
|
||||
[ 200.906104] mhi_init Quectel_Linux_PCIE_MHI_Driver_V1.3.0.17
|
||||
[ 200.907913] mhi_pci_probe pci_dev->name = 0000:01:00.0, domain=0, bus=1, slot=0, vendor=17CB, device=0306
|
||||
[ 200.912164] mhi_q 0000:01:00.0: BAR 0: assigned [mem 0x48000000-0x48000fff 64bit]
|
||||
[ 200.920593] mhi_q 0000:01:00.0: enabling device (0140 -> 0142)
|
||||
root@OpenWrt:~# [ 201.112214] [I][mhi_netdev_enable_iface] Prepare the channels for transfer
|
||||
[ 201.154640] [I][mhi_netdev_enable_iface] Exited.
|
||||
[ 201.159271] rmnet_vnd_register_device(rmnet_mhi0.1)=0
|
||||
[ 201.162953] rmnet_vnd_register_device(rmnet_mhi0.2)=0
|
||||
[ 201.167698] rmnet_vnd_register_device(rmnet_mhi0.3)=0
|
||||
[ 201.172178] rmnet_vnd_register_device(rmnet_mhi0.4)=0
|
||||
|
||||
root@OpenWrt:~# brctl addbr br0
|
||||
root@OpenWrt:~# brctl addif br0 eth1
|
||||
root@OpenWrt:~# brctl addif br0 rmnet_mhi0.2
|
||||
root@OpenWrt:~# brctl show
|
||||
bridge name bridge id STP enabled interfaces
|
||||
br0 8000.00001c353487 no eth1
|
||||
rmnet_mhi0.2
|
||||
|
||||
root@OpenWrt:~# quectel-qmi-proxy -d /dev/mhi_QMI0 &
|
||||
[04-14_06:44:01:556] Will use cdc-wdm='/dev/mhi_QMI0', proxy='quectel-qmi-proxy0'
|
||||
[04-14_06:44:01:573] qmi_proxy_init enter
|
||||
[04-14_06:44:01:573] qmi_proxy_loop enter thread_id 0xb6f20d44
|
||||
[04-14_06:44:03:574] qmi_proxy_init succful
|
||||
[04-14_06:44:03:574] local server: quectel-qmi-proxy0 sockfd = 4
|
||||
[04-14_06:44:03:575] qmi_proxy_server_fd = 4
|
||||
|
||||
|
||||
root@OpenWrt:~# quectel-CM -n 1 -s cmnet &
|
||||
[04-14_06:47:53:303] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-14_06:47:53:314] network interface '' or qmidev '' is not exist
|
||||
[04-14_06:47:53:315] netcard driver = pcie_mhi, driver version = V1.3.0.17
|
||||
[04-14_06:47:53:316] qmap_mode = 4, qmap_version = 9, qmap_size = 16384, muxid = 0x81, qmap_netcard = rmnet_mhi0.1
|
||||
[04-14_06:47:53:316] Modem works in QMI mode
|
||||
[04-14_06:47:53:318] connect to quectel-qmi-proxy0 sockfd = 7
|
||||
[04-14_06:47:53:318] cdc_wdm_fd = 7
|
||||
[04-14_06:47:53:326] Get clientWDS = 15
|
||||
[04-14_06:47:53:329] Get clientDMS = 2
|
||||
[04-14_06:47:53:334] Get clientNAS = 4
|
||||
[04-14_06:47:53:338] Get clientUIM = 1
|
||||
[04-14_06:47:53:343] Get clientWDA = 1
|
||||
[04-14_06:47:53:347] requestBaseBandVersion RM500QGLABR10A03M4G
|
||||
[04-14_06:47:53:351] qmap_settings.rx_urb_size = 16384
|
||||
[04-14_06:47:53:352] qmap_settings.ul_data_aggregation_max_datagrams = 11
|
||||
[04-14_06:47:53:352] qmap_settings.ul_data_aggregation_max_size = 8192
|
||||
[04-14_06:47:53:352] qmap_settings.dl_minimum_padding = 0
|
||||
[04-14_06:47:53:369] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-14_06:47:53:370] requestSetProfile[1] cmnet///0
|
||||
[04-14_06:47:53:402] requestGetProfile[1] cmnet///0
|
||||
[04-14_06:47:53:407] requestRegistrationState2 MCC: 0, MNC: 0, PS: Detached, DataCap: UNKNOW
|
||||
[04-14_06:47:53:411] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[04-14_06:47:53:412] ifconfig rmnet_mhi0 down
|
||||
[04-14_06:47:53:436] ifconfig rmnet_mhi0.1 0.0.0.0
|
||||
[04-14_06:47:53:460] ifconfig rmnet_mhi0.1 down
|
||||
[04-14_06:48:26:399] requestRegistrationState2 MCC: 460, MNC: 0, PS: Detached, DataCap: UNKNOW
|
||||
[04-14_06:48:26:405] requestRegistrationState2 MCC: 460, MNC: 0, PS: Detached, DataCap: UNKNOW
|
||||
[04-14_06:48:26:411] requestRegistrationState2 MCC: 460, MNC: 0, PS: Detached, DataCap: UNKNOW
|
||||
[04-14_06:48:26:970] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: 5G_NSA
|
||||
[04-14_06:48:26:992] requestSetupDataCall WdsConnectionIPv4Handle: 0x34176710
|
||||
[04-14_06:48:27:005] ifconfig rmnet_mhi0 up
|
||||
[04-14_06:48:27:031] ifconfig rmnet_mhi0.1 up
|
||||
[04-14_06:48:27:057] you are use OpenWrt?
|
||||
[04-14_06:48:27:057] should not calling udhcpc manually?
|
||||
[04-14_06:48:27:080] should use "/sbin/ifstaus wan" to check rmnet_mhi0.1 's status?
|
||||
[04-14_06:48:27:081] busybox udhcpc -f -n -q -t 5 -i rmnet_mhi0.1
|
||||
[04-14_06:48:27:363] udhcpc: ifconfig rmnet_mhi0.1 10.245.22.3 netmask 255.255.255.248 broadcast +
|
||||
[04-14_06:48:27:398] udhcpc: setting default routers: 10.245.22.4
|
||||
[04-14_06:48:27:491] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: 5G_NSA
|
||||
|
||||
root@OpenWrt:~# quectel-CM -n 2 -s 4gnet -b &
|
||||
[04-14_06:48:06:842] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-14_06:48:06:853] network interface '' or qmidev '' is not exist
|
||||
[04-14_06:48:06:854] netcard driver = pcie_mhi, driver version = V1.3.0.17
|
||||
[04-14_06:48:06:855] qmap_mode = 4, qmap_version = 9, qmap_size = 16384, muxid = 0x82, qmap_netcard = rmnet_mhi0.2
|
||||
[04-14_06:48:06:855] Modem works in QMI mode
|
||||
[04-14_06:48:06:857] connect to quectel-qmi-proxy0 sockfd = 7
|
||||
[04-14_06:48:06:858] cdc_wdm_fd = 7
|
||||
[04-14_06:48:06:864] Get clientWDS = 16
|
||||
[04-14_06:48:06:867] Get clientDMS = 3
|
||||
[04-14_06:48:06:871] Get clientNAS = 5
|
||||
[04-14_06:48:06:874] Get clientUIM = 2
|
||||
[04-14_06:48:06:879] Get clientWDA = 2
|
||||
[04-14_06:48:06:886] requestBaseBandVersion RM500QGLABR10A03M4G
|
||||
[04-14_06:48:06:891] qmap_settings.rx_urb_size = 16384
|
||||
[04-14_06:48:06:891] qmap_settings.ul_data_aggregation_max_datagrams = 11
|
||||
[04-14_06:48:06:892] qmap_settings.ul_data_aggregation_max_size = 8192
|
||||
[04-14_06:48:06:892] qmap_settings.dl_minimum_padding = 0
|
||||
[04-14_06:48:06:909] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-14_06:48:06:909] requestSetProfile[2] 4gnet///0
|
||||
[04-14_06:48:06:940] requestGetProfile[2] 4gnet///0
|
||||
[04-14_06:48:06:944] requestRegistrationState2 MCC: 0, MNC: 0, PS: Detached, DataCap: UNKNOW
|
||||
[04-14_06:48:06:949] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[04-14_06:48:06:949] ifconfig rmnet_mhi0 down
|
||||
[04-14_06:48:06:973] ifconfig rmnet_mhi0.2 0.0.0.0
|
||||
[04-14_06:48:06:998] ifconfig rmnet_mhi0.2 down
|
||||
[04-14_06:48:26:400] requestRegistrationState2 MCC: 460, MNC: 0, PS: Detached, DataCap: UNKNOW
|
||||
[04-14_06:48:26:405] requestRegistrationState2 MCC: 460, MNC: 0, PS: Detached, DataCap: UNKNOW
|
||||
[04-14_06:48:26:411] requestRegistrationState2 MCC: 460, MNC: 0, PS: Detached, DataCap: UNKNOW
|
||||
[04-14_06:48:26:970] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: 5G_NSA
|
||||
[04-14_06:48:27:220] requestSetupDataCall WdsConnectionIPv4Handle: 0x341450a0
|
||||
[04-14_06:48:27:228] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: 5G_NSA
|
||||
[04-14_06:48:27:238] ifconfig rmnet_mhi0 up
|
||||
[04-14_06:48:27:263] ifconfig rmnet_mhi0.2 up
|
||||
[04-14_06:48:27:313] echo '0xaf51be9' > /sys/class/net/rmnet_mhi0.2/bridge_ipv4
|
||||
|
||||
root@OpenWrt:~# ifconfig rmnet_mhi0.1
|
||||
rmnet_mhi0.1 Link encap:Ethernet HWaddr 02:50:F4:00:00:00
|
||||
inet addr:10.245.22.3 Mask:255.255.255.248
|
||||
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:1836 (1.7 KiB) TX bytes:2052 (2.0 KiB)
|
||||
|
||||
root@OpenWrt:~# ifconfig rmnet_mhi0.2
|
||||
rmnet_mhi0.2 Link encap:Ethernet HWaddr 02:50:F4:00:00:00
|
||||
inet6 addr: fe80::50:f4ff:fe00:0/64 Scope:Link
|
||||
UP RUNNING NOARP MTU:1500 Metric:1
|
||||
RX packets:347 errors:0 dropped:0 overruns:0 frame:0
|
||||
TX packets:795 errors:0 dropped:0 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:119871 (117.0 KiB) TX bytes:121254 (118.4 KiB)
|
||||
|
||||
root@OpenWrt:~# ifconfig br0 up
|
||||
[ 520.005476] rmnet_mhi0.2 PC Mac Address: 00:0e:c6:a6:6c:f1
|
||||
[ 520.025896] rmnet_mhi0.2 PC Mac Address: 00:0e:c6:a6:6c:f1
|
||||
[ 520.028002] rmnet_mhi0.2 PC Mac Address: 00:0e:c6:a6:6c:f1
|
||||
[ 520.144371] rmnet_mhi0.2 sip = 10.245.27.233, tip=10.245.27.234, ipv4=10.245.27.233
|
||||
[ 520.410052] rmnet_mhi0.2 sip = 0.0.0.0, tip=10.245.27.233, ipv4=10.245.27.233
|
||||
[ 520.414504] rmnet_mhi0.2 sip = 10.245.27.233, tip=10.245.27.234, ipv4=10.245.27.233
|
||||
[ 520.847074] rmnet_mhi0.2 sip = 10.245.27.233, tip=10.245.27.234, ipv4=10.245.27.233
|
||||
[ 521.410241] rmnet_mhi0.2 sip = 0.0.0.0, tip=10.245.27.233, ipv4=10.245.27.233
|
||||
[ 522.410455] rmnet_mhi0.2 sip = 0.0.0.0, tip=10.245.27.233, ipv4=10.245.27.233
|
||||
[ 522.822594] rmnet_mhi0.2 sip = 10.245.27.233, tip=10.245.27.234, ipv4=10.245.27.233
|
||||
[ 523.410638] rmnet_mhi0.2 sip = 10.245.27.233, tip=10.245.27.233, ipv4=10.245.27.233
|
||||
[ 523.510028] rmnet_mhi0.2 sip = 10.245.27.233, tip=10.245.27.234, ipv4=10.245.27.233
|
||||
[ 523.997961] rmnet_mhi0.2 sip = 10.245.27.233, tip=10.245.27.234, ipv4=10.245.27.233
|
||||
[ 543.799483] rmnet_mhi0.2 sip = 10.245.27.233, tip=10.245.27.234, ipv4=10.245.27.233
|
||||
[ 543.929301] rmnet_mhi0.2 sip = 10.245.27.233, tip=10.245.27.234, ipv4=10.245.27.233
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
root@ZhuoTK:/# dmesg
|
||||
[ 15.840000] qmi_wwan_q 1-1.3:1.4: cdc-wdm0: USB WDM device
|
||||
[ 15.860000] qmi_wwan_q 1-1.3:1.4: Quectel Android work on RawIP mode
|
||||
[ 15.860000] qmi_wwan_q 1-1.3:1.4: rx_urb_size = 1520
|
||||
[ 15.870000] qmi_wwan_q 1-1.3:1.4 wwan0: register 'qmi_wwan_q' at usb-101c0000.ehci-1.3, WWAN/QMI device, da:0b:ce:b2:db:21
|
||||
|
||||
root@ZhuoTK:/# quectel-CM -s cment &
|
||||
[04-13_03:20:20:456] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-13_03:20:20:459] Find /sys/bus/usb/devices/1-1.3 idVendor=0x2c7c idProduct=0x125, bus=0x001, dev=0x003
|
||||
[04-13_03:20:20:460] Auto find qmichannel = /dev/cdc-wdm0
|
||||
[04-13_03:20:20:460] Auto find usbnet_adapter = wwan0
|
||||
[04-13_03:20:20:461] netcard driver = qmi_wwan_q, driver version = V1.2.0.23
|
||||
[04-13_03:20:20:461] Modem works in QMI mode
|
||||
[04-13_03:20:20:469] cdc_wdm_fd = 7
|
||||
[04-13_03:20:20:547] Get clientWDS = 4
|
||||
[04-13_03:20:20:579] Get clientDMS = 1
|
||||
[04-13_03:20:20:611] Get clientNAS = 4
|
||||
[04-13_03:20:20:643] Get clientUIM = 1
|
||||
[04-13_03:20:20:675] Get clientWDA = 1
|
||||
[04-13_03:20:20:707] requestBaseBandVersion EC25EFAR06A11M4G
|
||||
[04-13_03:20:20:836] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-13_03:20:20:836] requestSetProfile[1] cment///0
|
||||
[04-13_03:20:20:899] requestGetProfile[1] cment///0
|
||||
[04-13_03:20:20:931] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: LTE
|
||||
[04-13_03:20:20:963] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[04-13_03:20:20:963] ifconfig wwan0 0.0.0.0
|
||||
[04-13_03:20:20:976] ifconfig wwan0 down
|
||||
[04-13_03:20:21:186] requestSetupDataCall WdsConnectionIPv4Handle: 0x8723e780
|
||||
[04-13_03:20:21:316] ifconfig wwan0 up
|
||||
[04-13_03:20:21:329] you are use OpenWrt?
|
||||
[04-13_03:20:21:330] should not calling udhcpc manually?
|
||||
[04-13_03:20:21:330] should modify /etc/config/network as below?
|
||||
[04-13_03:20:21:330] config interface wan
|
||||
[04-13_03:20:21:330] option ifname wwan0
|
||||
[04-13_03:20:21:330] option proto dhcp
|
||||
[04-13_03:20:21:330] should use "/sbin/ifstaus wan" to check wwan0 's status?
|
||||
[04-13_03:20:21:331] busybox udhcpc -f -n -q -t 5 -i wwan0
|
||||
[04-13_03:20:21:341] udhcpc (v1.23.2) started
|
||||
[04-13_03:20:21:353] Sending discover...
|
||||
[04-13_03:20:21:362] Sending select for 10.90.1.113...
|
||||
[04-13_03:20:21:365] Lease of 10.90.1.113 obtained, lease time 7200
|
||||
[04-13_03:20:21:370] udhcpc: ifconfig wwan0 10.90.1.113 netmask 255.255.255.252 broadcast +
|
||||
[04-13_03:20:21:380] udhcpc: setting default routers: 10.90.1.114
|
||||
|
||||
root@ZhuoTK:/# ifconfig wwan0
|
||||
wwan0 Link encap:Ethernet HWaddr 00:CA:01:91:97:BA
|
||||
inet addr:10.90.1.113 Mask:255.255.255.252
|
||||
inet6 addr: fe80::2ca:1ff:fe91:97ba/64 Scope:Link
|
||||
UP RUNNING NOARP MTU:1500 Metric:1
|
||||
RX packets:38 errors:0 dropped:0 overruns:0 frame:0
|
||||
TX packets:46 errors:0 dropped:0 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:5244 (5.1 KiB) TX bytes:6964 (6.8 KiB)
|
||||
|
||||
root@ZhuoTK:/# ip ro show
|
||||
default via 10.90.1.114 dev wwan0
|
||||
10.90.1.112/30 dev wwan0 proto kernel scope link src 10.90.1.113
|
||||
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:20:46:130] requestDeactivateDefaultPDP WdsConnectionIPv4Handle
|
||||
[04-13_03:20:46:406] ifconfig wwan0 0.0.0.0
|
||||
[04-13_03:20:46:418] ifconfig wwan0 down
|
||||
[04-13_03:20:46:600] QmiWwanThread exit
|
||||
[04-13_03:20:46:600] qmi_main exit
|
||||
Loaded 100 of 289 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user