mirror of
https://github.com/qosmio/nss-packages.git
synced 2025-12-16 16:21:53 +00:00
cleanup, initial commit
This commit is contained in:
parent
4b1cb1d940
commit
0c0f106c6b
@ -8,7 +8,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=PCI Modem Server
|
||||
LUCI_DEPENDS:=+kmod-pcie_mhi +pciutils +quectel-CM-5G
|
||||
LUCI_DEPENDS:=+kmod-pcie_mhi +pciutils +quectel-cm
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
|
||||
@ -8,11 +8,11 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=Modem Server
|
||||
LUCI_DEPENDS:=+luci-compat +quectel-CM-5G +kmod-usb-acm \
|
||||
LUCI_DEPENDS:=+luci-compat +quectel-cm +kmod-usb-acm \
|
||||
+kmod-usb-net-cdc-ether +kmod-usb-net-cdc-mbim \
|
||||
+kmod-usb-net-qmi-wwan +kmod-usb-net-rndis \
|
||||
+kmod-usb-serial-option +kmod-usb-wdm \
|
||||
+kmod-qmi_wwan_f +kmod-qmi_wwan_q
|
||||
+kmod-qmi_wwan_q
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
|
||||
8
wwan/app/luci-proto-quectel/Makefile
Normal file
8
wwan/app/luci-proto-quectel/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=Support for Quectel WWAN modules
|
||||
LUCI_DEPENDS:=+quectel-cm
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
@ -0,0 +1,124 @@
|
||||
'use strict';
|
||||
'require rpc';
|
||||
'require form';
|
||||
'require network';
|
||||
|
||||
var callFileList = rpc.declare({
|
||||
object: 'file',
|
||||
method: 'list',
|
||||
params: [ 'path' ],
|
||||
expect: { entries: [] },
|
||||
filter: function(list, params) {
|
||||
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();
|
||||
}
|
||||
});
|
||||
|
||||
network.registerPatternVirtual(/^quectel-.+$/);
|
||||
network.registerErrorCode('CALL_FAILED', _('Call failed'));
|
||||
network.registerErrorCode('NO_CID', _('Unable to obtain client ID'));
|
||||
network.registerErrorCode('PLMN_FAILED', _('Setting PLMN failed'));
|
||||
|
||||
return network.registerProtocol('quectel', {
|
||||
getI18n: function() {
|
||||
return _('Quectel Cellular');
|
||||
},
|
||||
|
||||
getIfname: function() {
|
||||
return this._ubus('l3_device') || 'quectel-%s'.format(this.sid);
|
||||
},
|
||||
|
||||
getOpkgPackage: function() {
|
||||
return 'quectel-cm';
|
||||
},
|
||||
|
||||
isFloating: function() {
|
||||
return true;
|
||||
},
|
||||
|
||||
isVirtual: function() {
|
||||
return true;
|
||||
},
|
||||
|
||||
getDevices: function() {
|
||||
return null;
|
||||
},
|
||||
|
||||
containsDevice: function(ifname) {
|
||||
return (network.getIfnameOf(ifname) == this.getIfname());
|
||||
},
|
||||
|
||||
renderFormOptions: function(s) {
|
||||
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 (var i = 0; i < devices.length; i++)
|
||||
this.value(devices[i]);
|
||||
return form.Value.prototype.load.apply(this, [section_id]);
|
||||
}, this));
|
||||
};
|
||||
|
||||
o = s.taboption('general', form.Value, 'apn', _('APN'));
|
||||
o.validate = function(section_id, value) {
|
||||
if (value == null || value == '')
|
||||
return true;
|
||||
|
||||
if (!/^[a-zA-Z0-9\-.]*[a-zA-Z0-9]$/.test(value))
|
||||
return _('Invalid APN provided');
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
o = s.taboption('general', form.Value, 'pincode', _('PIN'));
|
||||
o.datatype = 'and(uinteger,minlength(4),maxlength(8))';
|
||||
|
||||
o = s.taboption('general', form.ListValue, 'auth', _('Authentication Type'));
|
||||
o.value('mschapv2', 'MsChapV2');
|
||||
o.value('pap', 'PAP');
|
||||
o.value('chap', 'CHAP');
|
||||
o.value('none', 'NONE');
|
||||
o.default = 'none';
|
||||
|
||||
o = s.taboption('general', form.Value, 'username', _('PAP/CHAP username'));
|
||||
o.depends('auth', 'pap');
|
||||
o.depends('auth', 'chap');
|
||||
o.depends('auth', 'mschapv2');
|
||||
|
||||
o = s.taboption('general', form.Value, 'password', _('PAP/CHAP password'));
|
||||
o.depends('auth', 'pap');
|
||||
o.depends('auth', 'chap');
|
||||
o.depends('auth', 'mschapv2');
|
||||
o.password = true;
|
||||
|
||||
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.datatype = 'min(1)';
|
||||
|
||||
o = s.taboption('advanced', form.Value, 'mtu', _('Override MTU'));
|
||||
o.placeholder = dev ? (dev.getMTU() || '1500') : '1500';
|
||||
o.datatype = 'max(9200)';
|
||||
|
||||
o = s.taboption('general', form.ListValue, 'pdptype', _('PDP Type'));
|
||||
o.value('ipv4v6', 'IPv4/IPv6');
|
||||
o.value('ipv4', 'IPv4');
|
||||
o.value('ipv6', 'IPv6');
|
||||
o.default = 'ipv4v6';
|
||||
|
||||
o = s.taboption('advanced', form.Flag, 'defaultroute', _('Use default gateway'),
|
||||
_('If unchecked, no default route is configured'));
|
||||
o.default = o.enabled;
|
||||
|
||||
o = s.taboption('advanced', form.Value, 'metric', _('Use gateway metric'));
|
||||
o.placeholder = '0';
|
||||
o.datatype = 'uinteger';
|
||||
o.depends('defaultroute', '1');
|
||||
}
|
||||
});
|
||||
35
wwan/app/quectel-cm/Makefile
Normal file
35
wwan/app/quectel-cm/Makefile
Normal file
@ -0,0 +1,35 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=quectel-cm
|
||||
PKG_VERSION:=1.6.5
|
||||
PKG_RELEASE:=2
|
||||
|
||||
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-qmi_wwan_q \
|
||||
+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))
|
||||
138
wwan/app/quectel-cm/files/quectel.sh
Normal file
138
wwan/app/quectel-cm/files/quectel.sh
Normal file
@ -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" = "ip" -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" = "ip" ] || [ "$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
|
||||
}
|
||||
24
wwan/app/quectel-cm/files/smp-affinity-mhi-pcie.sh
Normal file
24
wwan/app/quectel-cm/files/smp-affinity-mhi-pcie.sh
Normal file
@ -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
|
||||
24
wwan/app/quectel-cm/files/smp-affinity-qmi-usb.sh
Normal file
24
wwan/app/quectel-cm/files/smp-affinity-qmi-usb.sh
Normal file
@ -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
|
||||
@ -1,36 +1,36 @@
|
||||
cmake_minimum_required(VERSION 2.4)
|
||||
cmake_minimum_required(VERSION 2.4)
|
||||
|
||||
project(quectel-CM)
|
||||
project(quectel-CM)
|
||||
add_definitions(-Wall -Wextra -Werror -O1)
|
||||
option(USE_QRTR "Enable QRTR" OFF)
|
||||
option(USE_QRTR "Enable QRTR" OFF)
|
||||
|
||||
set( QL_CM_SRC
|
||||
QmiWwanCM.c GobiNetCM.c main.c MPQMUX.c QMIThread.c util.c qmap_bridge_mode.c mbim-cm.c device.c
|
||||
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)
|
||||
if(USE_QRTR)
|
||||
add_definitions(-DCONFIG_QRTR)
|
||||
set( QRTR_SRC qrtr.c rmnetctl.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_executable(quectel-CM ${QL_CM_SRC} ${QRTR_SRC})
|
||||
target_link_libraries(quectel-CM PUBLIC pthread)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
target_link_libraries(quectel-qrtr-proxy PUBLIC pthread)
|
||||
install (TARGETS quectel-qrtr-proxy DESTINATION bin)
|
||||
@ -1,246 +1,246 @@
|
||||
/******************************************************************************
|
||||
@file GobiNetCM.c
|
||||
@brief GobiNet driver.
|
||||
|
||||
DESCRIPTION
|
||||
Connectivity Management Tool for USB network adapter of Quectel wireless cellular modules.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
None.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||
Quectel Wireless Solution Proprietary and Confidential.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
||||
#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 -1;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
/******************************************************************************
|
||||
@file GobiNetCM.c
|
||||
@brief GobiNet driver.
|
||||
|
||||
DESCRIPTION
|
||||
Connectivity Management Tool for USB network adapter of Quectel wireless cellular modules.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
None.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||
Quectel Wireless Solution Proprietary and Confidential.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
||||
#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 -1;
|
||||
}
|
||||
|
||||
if (ioctl(ClientId, IOCTL_QMI_GET_SERVICE_FILE, QMIType) != 0) {
|
||||
dbg_time("failed to get ClientID for 0x%02x errno: %d (%s)", QMIType, errno, strerror(errno));
|
||||
close(ClientId);
|
||||
ClientId = 0;
|
||||
}
|
||||
|
||||
switch (QMIType) {
|
||||
case QMUX_TYPE_WDS: dbg_time("Get clientWDS = %d", ClientId); break;
|
||||
case QMUX_TYPE_DMS: dbg_time("Get clientDMS = %d", ClientId); break;
|
||||
case QMUX_TYPE_NAS: dbg_time("Get clientNAS = %d", ClientId); break;
|
||||
case QMUX_TYPE_QOS: dbg_time("Get clientQOS = %d", ClientId); break;
|
||||
case QMUX_TYPE_WMS: dbg_time("Get clientWMS = %d", ClientId); break;
|
||||
case QMUX_TYPE_PDS: dbg_time("Get clientPDS = %d", ClientId); break;
|
||||
case QMUX_TYPE_UIM: dbg_time("Get clientUIM = %d", ClientId); break;
|
||||
case QMUX_TYPE_COEX: dbg_time("Get clientCOEX = %d", ClientId); break;
|
||||
case QMUX_TYPE_WDS_ADMIN: dbg_time("Get clientWDA = %d", ClientId);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return ClientId;
|
||||
}
|
||||
|
||||
static int GobiNetDeInit(void) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < sizeof(qmiclientId)/sizeof(qmiclientId[0]); i++)
|
||||
{
|
||||
if (qmiclientId[i] != 0)
|
||||
{
|
||||
close(qmiclientId[i]);
|
||||
qmiclientId[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void * GobiNetThread(void *pData) {
|
||||
PROFILE_T *profile = (PROFILE_T *)pData;
|
||||
const char *qcqmi = (const char *)profile->qmichannel;
|
||||
int wait_for_request_quit = 0;
|
||||
|
||||
qmiclientId[QMUX_TYPE_WDS] = GobiNetGetClientID(qcqmi, QMUX_TYPE_WDS);
|
||||
if (profile->enable_ipv6)
|
||||
qmiclientId[QMUX_TYPE_WDS_IPV6] = GobiNetGetClientID(qcqmi, QMUX_TYPE_WDS);
|
||||
qmiclientId[QMUX_TYPE_DMS] = GobiNetGetClientID(qcqmi, QMUX_TYPE_DMS);
|
||||
qmiclientId[QMUX_TYPE_NAS] = GobiNetGetClientID(qcqmi, QMUX_TYPE_NAS);
|
||||
qmiclientId[QMUX_TYPE_UIM] = GobiNetGetClientID(qcqmi, QMUX_TYPE_UIM);
|
||||
#ifdef CONFIG_COEX_WWAN_STATE
|
||||
qmiclientId[QMUX_TYPE_COEX] = GobiNetGetClientID(qcqmi, QMUX_TYPE_COEX);
|
||||
#endif
|
||||
if (profile->qmap_mode == 0 || profile->loopback_state) {//when QMAP enabled, set data format in GobiNet Driver
|
||||
qmiclientId[QMUX_TYPE_WDS_ADMIN] = GobiNetGetClientID(qcqmi, QMUX_TYPE_WDS_ADMIN);
|
||||
profile->wda_client = qmiclientId[QMUX_TYPE_WDS_ADMIN];
|
||||
}
|
||||
|
||||
//donot check clientWDA, there is only one client for WDA, if quectel-CM is killed by SIGKILL, i cannot get client ID for WDA again!
|
||||
if (qmiclientId[QMUX_TYPE_WDS] == 0) /*|| (clientWDA == -1)*/ {
|
||||
GobiNetDeInit();
|
||||
dbg_time("%s Failed to open %s, errno: %d (%s)", __func__, qcqmi, errno, strerror(errno));
|
||||
qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_DISCONNECTED);
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_CONNECTED);
|
||||
|
||||
while (1) {
|
||||
struct pollfd pollfds[16] = {{qmidevice_control_fd[1], POLLIN, 0}};
|
||||
int ne, ret, nevents = 1;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < sizeof(qmiclientId)/sizeof(qmiclientId[0]); i++)
|
||||
{
|
||||
if (qmiclientId[i] != 0)
|
||||
{
|
||||
pollfds[nevents].fd = qmiclientId[i];
|
||||
pollfds[nevents].events = POLLIN;
|
||||
pollfds[nevents].revents = 0;
|
||||
nevents++;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
ret = poll(pollfds, nevents, wait_for_request_quit ? 1000: -1);
|
||||
} while ((ret < 0) && (errno == EINTR));
|
||||
|
||||
if (ret == 0 && wait_for_request_quit) {
|
||||
QmiThreadRecvQMI(NULL); //main thread may pending on QmiThreadSendQMI()
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ret <= 0) {
|
||||
dbg_time("%s poll=%d, errno: %d (%s)", __func__, ret, errno, strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
for (ne = 0; ne < nevents; ne++) {
|
||||
int fd = pollfds[ne].fd;
|
||||
short revents = pollfds[ne].revents;
|
||||
|
||||
if (revents & (POLLERR | POLLHUP | POLLNVAL)) {
|
||||
dbg_time("%s poll err/hup/inval", __func__);
|
||||
dbg_time("epoll fd = %d, events = 0x%04x", fd, revents);
|
||||
if (fd == qmidevice_control_fd[1]) {
|
||||
} else {
|
||||
}
|
||||
if (revents & (POLLERR | POLLHUP | POLLNVAL))
|
||||
goto __GobiNetThread_quit;
|
||||
}
|
||||
|
||||
if ((revents & POLLIN) == 0)
|
||||
continue;
|
||||
|
||||
if (fd == qmidevice_control_fd[1]) {
|
||||
int triger_event;
|
||||
if (read(fd, &triger_event, sizeof(triger_event)) == sizeof(triger_event)) {
|
||||
//DBG("triger_event = 0x%x", triger_event);
|
||||
switch (triger_event) {
|
||||
case RIL_REQUEST_QUIT:
|
||||
goto __GobiNetThread_quit;
|
||||
break;
|
||||
case SIG_EVENT_STOP:
|
||||
wait_for_request_quit = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
{
|
||||
ssize_t nreads;
|
||||
PQCQMIMSG pResponse = (PQCQMIMSG)cm_recv_buf;
|
||||
|
||||
nreads = read(fd, &pResponse->MUXMsg, sizeof(cm_recv_buf) - sizeof(QCQMI_HDR));
|
||||
if (nreads <= 0)
|
||||
{
|
||||
dbg_time("%s read=%d errno: %d (%s)", __func__, (int)nreads, errno, strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(qmiclientId)/sizeof(qmiclientId[0]); i++)
|
||||
{
|
||||
if (qmiclientId[i] == fd)
|
||||
{
|
||||
pResponse->QMIHdr.QMIType = i;
|
||||
}
|
||||
}
|
||||
|
||||
pResponse->QMIHdr.IFType = USB_CTL_MSG_TYPE_QMI;
|
||||
pResponse->QMIHdr.Length = cpu_to_le16(nreads + sizeof(QCQMI_HDR) - 1);
|
||||
pResponse->QMIHdr.CtlFlags = 0x00;
|
||||
pResponse->QMIHdr.ClientId = (fd&0xFF) ? fd&0xFF : pResponse->QMIHdr.QMIType;;
|
||||
|
||||
QmiThreadRecvQMI(pResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__GobiNetThread_quit:
|
||||
GobiNetDeInit();
|
||||
qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_DISCONNECTED);
|
||||
QmiThreadRecvQMI(NULL); //main thread may pending on QmiThreadSendQMI()
|
||||
dbg_time("%s exit", __func__);
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct qmi_device_ops gobi_qmidev_ops = {
|
||||
.deinit = GobiNetDeInit,
|
||||
.send = GobiNetSendQMI,
|
||||
.read = GobiNetThread,
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -1,46 +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
|
||||
ifneq ($(CROSS_COMPILE),)
|
||||
CROSS-COMPILE:=$(CROSS_COMPILE)
|
||||
endif
|
||||
#CROSS-COMPILE:=/workspace/buildroot/buildroot-qemu_mips_malta_defconfig/output/host/usr/bin/mips-buildroot-linux-uclibc-
|
||||
#CROSS-COMPILE:=/workspace/buildroot/buildroot-qemu_arm_vexpress_defconfig/output/host/usr/bin/arm-buildroot-linux-uclibcgnueabi-
|
||||
#CROSS-COMPILE:=/workspace/buildroot-git/qemu_mips64_malta/output/host/usr/bin/mips-gnu-linux-
|
||||
ifeq ($(CC),cc)
|
||||
CC:=$(CROSS-COMPILE)gcc
|
||||
endif
|
||||
LD:=$(CROSS-COMPILE)ld
|
||||
|
||||
QL_CM_SRC=QmiWwanCM.c GobiNetCM.c main.c QCQMUX.c QMIThread.c util.c qmap_bridge_mode.c mbim-cm.c device.c
|
||||
QL_CM_SRC+=atc.c atchannel.c at_tok.c
|
||||
#QL_CM_SRC+=qrtr.c rmnetctl.c
|
||||
ifeq (1,1)
|
||||
QL_CM_DHCP=udhcpc.c
|
||||
else
|
||||
LIBMNL=libmnl/ifutils.c libmnl/attr.c libmnl/callback.c libmnl/nlmsg.c libmnl/socket.c
|
||||
DHCP=libmnl/dhcp/dhcpclient.c libmnl/dhcp/dhcpmsg.c libmnl/dhcp/packet.c
|
||||
QL_CM_DHCP=udhcpc_netlink.c
|
||||
QL_CM_DHCP+=${LIBMNL}
|
||||
endif
|
||||
|
||||
CFLAGS += -Wall -Wextra -Werror -O1 #-s
|
||||
LDFLAGS += -lpthread -ldl -lrt
|
||||
|
||||
release: clean qmi-proxy mbim-proxy atc-proxy #qrtr-proxy
|
||||
$(CC) ${CFLAGS} ${QL_CM_SRC} ${QL_CM_DHCP} -o quectel-CM ${LDFLAGS}
|
||||
|
||||
debug: clean
|
||||
$(CC) ${CFLAGS} -g -DCM_DEBUG ${QL_CM_SRC} ${QL_CM_DHCP} -o quectel-CM -lpthread -ldl -lrt
|
||||
|
||||
qmi-proxy:
|
||||
$(CC) ${CFLAGS} quectel-qmi-proxy.c -o quectel-qmi-proxy ${LDFLAGS}
|
||||
|
||||
mbim-proxy:
|
||||
$(CC) ${CFLAGS} quectel-mbim-proxy.c -o quectel-mbim-proxy ${LDFLAGS}
|
||||
|
||||
qrtr-proxy:
|
||||
$(CC) ${CFLAGS} quectel-qrtr-proxy.c -o quectel-qrtr-proxy ${LDFLAGS}
|
||||
|
||||
atc-proxy:
|
||||
$(CC) ${CFLAGS} quectel-atc-proxy.c atchannel.c at_tok.c util.c -o quectel-atc-proxy ${LDFLAGS}
|
||||
|
||||
clean:
|
||||
rm -rf *.o libmnl/*.o quectel-CM quectel-qmi-proxy quectel-mbim-proxy quectel-atc-proxy
|
||||
@ -1,17 +1,17 @@
|
||||
bin_PROGRAMS = quectel-CM
|
||||
QL_CM_SRC=QmiWwanCM.c GobiNetCM.c main.c MPQMUX.c QMIThread.c util.c qmap_bridge_mode.c mbim-cm.c device.c
|
||||
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
|
||||
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}
|
||||
quectel_CM_SOURCES = ${QL_CM_SRC} ${QL_CM_DHCP}
|
||||
|
||||
bin_PROGRAMS += quectel-qmi-proxy
|
||||
quectel_qmi_proxy_SOURCES = quectel-qmi-proxy.c
|
||||
@ -1,7 +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.
|
||||
This program is totally open souce code, and public domain software for customers of Quectel company.
|
||||
|
||||
The APIs of QMI WWAMN interfaces are defined by Qualcomm. And this program complies with Qualcomm QMI WWAN interfaces specification.
|
||||
|
||||
Customers are free to modify the source codes and redistribute them.
|
||||
|
||||
For those who is not Quectel's customer, all rights are closed, and any copying and commercial development over this progrma is not allowed.
|
||||
@ -1,394 +1,394 @@
|
||||
/******************************************************************************
|
||||
@file QCQCTL.h
|
||||
|
||||
DESCRIPTION
|
||||
This module contains QMI QCTL module.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
None.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||
Quectel Wireless Solution Proprietary and Confidential.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#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)
|
||||
|
||||
/******************************************************************************
|
||||
@file QCQCTL.h
|
||||
|
||||
DESCRIPTION
|
||||
This module contains QMI QCTL module.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
None.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||
Quectel Wireless Solution Proprietary and Confidential.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#ifndef QCQCTL_H
|
||||
#define QCQCTL_H
|
||||
|
||||
#include "QCQMI.h"
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
// ================= QMICTL ==================
|
||||
|
||||
// QMICTL Control Flags
|
||||
#define QMICTL_CTL_FLAG_CMD 0x00
|
||||
#define QMICTL_CTL_FLAG_RSP 0x01
|
||||
#define QMICTL_CTL_FLAG_IND 0x02
|
||||
|
||||
#if 0
|
||||
typedef struct _QMICTL_TRANSACTION_ITEM
|
||||
{
|
||||
LIST_ENTRY List;
|
||||
UCHAR TransactionId; // QMICTL transaction id
|
||||
PVOID Context; // Adapter or IocDev
|
||||
PIRP Irp;
|
||||
} QMICTL_TRANSACTION_ITEM, *PQMICTL_TRANSACTION_ITEM;
|
||||
#endif
|
||||
|
||||
typedef struct _QCQMICTL_MSG_HDR
|
||||
{
|
||||
UCHAR CtlFlags; // 00-cmd, 01-rsp, 10-ind
|
||||
UCHAR TransactionId;
|
||||
USHORT QMICTLType;
|
||||
USHORT Length;
|
||||
} __attribute__ ((packed)) QCQMICTL_MSG_HDR, *PQCQMICTL_MSG_HDR;
|
||||
|
||||
#define QCQMICTL_MSG_HDR_SIZE sizeof(QCQMICTL_MSG_HDR)
|
||||
|
||||
typedef struct _QCQMICTL_MSG_HDR_RESP
|
||||
{
|
||||
UCHAR CtlFlags; // 00-cmd, 01-rsp, 10-ind
|
||||
UCHAR TransactionId;
|
||||
USHORT QMICTLType;
|
||||
USHORT Length;
|
||||
UCHAR TLVType; // 0x02 - result code
|
||||
USHORT TLVLength; // 4
|
||||
USHORT QMUXResult; // QMI_RESULT_SUCCESS
|
||||
// QMI_RESULT_FAILURE
|
||||
USHORT QMUXError; // QMI_ERR_INVALID_ARG
|
||||
// QMI_ERR_NO_MEMORY
|
||||
// QMI_ERR_INTERNAL
|
||||
// QMI_ERR_FAULT
|
||||
} __attribute__ ((packed)) QCQMICTL_MSG_HDR_RESP, *PQCQMICTL_MSG_HDR_RESP;
|
||||
|
||||
typedef struct _QCQMICTL_MSG
|
||||
{
|
||||
UCHAR CtlFlags; // 00-cmd, 01-rsp, 10-ind
|
||||
UCHAR TransactionId;
|
||||
USHORT QMICTLType;
|
||||
USHORT Length;
|
||||
UCHAR Payload;
|
||||
} __attribute__ ((packed)) QCQMICTL_MSG, *PQCQMICTL_MSG;
|
||||
|
||||
// TLV Header
|
||||
typedef struct _QCQMICTL_TLV_HDR
|
||||
{
|
||||
UCHAR TLVType;
|
||||
USHORT TLVLength;
|
||||
} __attribute__ ((packed)) QCQMICTL_TLV_HDR, *PQCQMICTL_TLV_HDR;
|
||||
|
||||
#define QCQMICTL_TLV_HDR_SIZE sizeof(QCQMICTL_TLV_HDR)
|
||||
|
||||
// QMICTL Type
|
||||
#define QMICTL_SET_INSTANCE_ID_REQ 0x0020
|
||||
#define QMICTL_SET_INSTANCE_ID_RESP 0x0020
|
||||
#define QMICTL_GET_VERSION_REQ 0x0021
|
||||
#define QMICTL_GET_VERSION_RESP 0x0021
|
||||
#define QMICTL_GET_CLIENT_ID_REQ 0x0022
|
||||
#define QMICTL_GET_CLIENT_ID_RESP 0x0022
|
||||
#define QMICTL_RELEASE_CLIENT_ID_REQ 0x0023
|
||||
#define QMICTL_RELEASE_CLIENT_ID_RESP 0x0023
|
||||
#define QMICTL_REVOKE_CLIENT_ID_IND 0x0024
|
||||
#define QMICTL_INVALID_CLIENT_ID_IND 0x0025
|
||||
#define QMICTL_SET_DATA_FORMAT_REQ 0x0026
|
||||
#define QMICTL_SET_DATA_FORMAT_RESP 0x0026
|
||||
#define QMICTL_SYNC_REQ 0x0027
|
||||
#define QMICTL_SYNC_RESP 0x0027
|
||||
#define QMICTL_SYNC_IND 0x0027
|
||||
#define QMI_MESSAGE_CTL_INTERNAL_PROXY_OPEN 0xFF00
|
||||
|
||||
#define QMICTL_FLAG_REQUEST 0x00
|
||||
#define QMICTL_FLAG_RESPONSE 0x01
|
||||
#define QMICTL_FLAG_INDICATION 0x02
|
||||
|
||||
// QMICTL Message Definitions
|
||||
|
||||
typedef struct _QMICTL_SET_INSTANCE_ID_REQ_MSG
|
||||
{
|
||||
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
|
||||
UCHAR TransactionId;
|
||||
USHORT QMICTLType; // QMICTL_SET_INSTANCE_ID_REQ
|
||||
USHORT Length; // 4
|
||||
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
|
||||
USHORT TLVLength; // 1
|
||||
UCHAR Value; // Host-unique QMI instance for this device driver
|
||||
} __attribute__ ((packed)) QMICTL_SET_INSTANCE_ID_REQ_MSG, *PQMICTL_SET_INSTANCE_ID_REQ_MSG;
|
||||
|
||||
typedef struct _QMICTL_SET_INSTANCE_ID_RESP_MSG
|
||||
{
|
||||
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
|
||||
UCHAR TransactionId;
|
||||
USHORT QMICTLType; // QMICTL_SET_INSTANCE_ID_RESP
|
||||
USHORT Length;
|
||||
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
|
||||
USHORT TLVLength; // 0x0004
|
||||
USHORT QMIResult;
|
||||
USHORT QMIError;
|
||||
UCHAR TLV2Type; // QCTLV_TYPE_REQUIRED_PARAMETER
|
||||
USHORT TLV2Length; // 0x0002
|
||||
USHORT QMI_ID; // Upper byte is assigned by MSM,
|
||||
// lower assigned by host
|
||||
} __attribute__ ((packed)) QMICTL_SET_INSTANCE_ID_RESP_MSG, *PQMICTL_SET_INSTANCE_ID_RESP_MSG;
|
||||
|
||||
typedef struct _QMICTL_GET_VERSION_REQ_MSG
|
||||
{
|
||||
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
|
||||
UCHAR TransactionId;
|
||||
USHORT QMICTLType; // QMICTL_GET_VERSION_REQ
|
||||
USHORT Length; // 0
|
||||
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
|
||||
USHORT TLVLength; // var
|
||||
UCHAR QMUXTypes; // List of one byte QMUX_TYPE values
|
||||
// 0xFF returns a list of versions for all
|
||||
// QMUX_TYPEs implemented on the device
|
||||
} __attribute__ ((packed)) QMICTL_GET_VERSION_REQ_MSG, *PQMICTL_GET_VERSION_REQ_MSG;
|
||||
|
||||
typedef struct _QMUX_TYPE_VERSION_STRUCT
|
||||
{
|
||||
UCHAR QMUXType;
|
||||
USHORT MajorVersion;
|
||||
USHORT MinorVersion;
|
||||
} __attribute__ ((packed)) QMUX_TYPE_VERSION_STRUCT, *PQMUX_TYPE_VERSION_STRUCT;
|
||||
|
||||
typedef struct _ADDENDUM_VERSION_PREAMBLE
|
||||
{
|
||||
UCHAR LabelLength;
|
||||
UCHAR Label;
|
||||
} __attribute__ ((packed)) ADDENDUM_VERSION_PREAMBLE, *PADDENDUM_VERSION_PREAMBLE;
|
||||
|
||||
#define QMICTL_GET_VERSION_RSP_TLV_TYPE_VERSION 0x01
|
||||
#define QMICTL_GET_VERSION_RSP_TLV_TYPE_ADD_VERSION 0x10
|
||||
|
||||
typedef struct _QMICTL_GET_VERSION_RESP_MSG
|
||||
{
|
||||
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
|
||||
UCHAR TransactionId;
|
||||
USHORT QMICTLType; // QMICTL_GET_VERSION_RESP
|
||||
USHORT Length;
|
||||
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
|
||||
USHORT TLVLength; // 0x0004
|
||||
USHORT QMIResult;
|
||||
USHORT QMIError;
|
||||
UCHAR TLV2Type; // QCTLV_TYPE_REQUIRED_PARAMETER
|
||||
USHORT TLV2Length; // var
|
||||
UCHAR NumElements; // Num of QMUX_TYPE_VERSION_STRUCT
|
||||
QMUX_TYPE_VERSION_STRUCT TypeVersion[0];
|
||||
} __attribute__ ((packed)) QMICTL_GET_VERSION_RESP_MSG, *PQMICTL_GET_VERSION_RESP_MSG;
|
||||
|
||||
typedef struct _QMICTL_GET_CLIENT_ID_REQ_MSG
|
||||
{
|
||||
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
|
||||
UCHAR TransactionId;
|
||||
USHORT QMICTLType; // QMICTL_GET_CLIENT_ID_REQ
|
||||
USHORT Length;
|
||||
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
|
||||
USHORT TLVLength; // 1
|
||||
UCHAR QMIType; // QMUX type
|
||||
} __attribute__ ((packed)) QMICTL_GET_CLIENT_ID_REQ_MSG, *PQMICTL_GET_CLIENT_ID_REQ_MSG;
|
||||
|
||||
typedef struct _QMICTL_GET_CLIENT_ID_RESP_MSG
|
||||
{
|
||||
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
|
||||
UCHAR TransactionId;
|
||||
USHORT QMICTLType; // QMICTL_GET_CLIENT_ID_RESP
|
||||
USHORT Length;
|
||||
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
|
||||
USHORT TLVLength; // 0x0004
|
||||
USHORT QMIResult; // result code
|
||||
USHORT QMIError; // error code
|
||||
UCHAR TLV2Type; // QCTLV_TYPE_REQUIRED_PARAMETER
|
||||
USHORT TLV2Length; // 2
|
||||
UCHAR QMIType;
|
||||
UCHAR ClientId;
|
||||
} __attribute__ ((packed)) QMICTL_GET_CLIENT_ID_RESP_MSG, *PQMICTL_GET_CLIENT_ID_RESP_MSG;
|
||||
|
||||
typedef struct _QMICTL_RELEASE_CLIENT_ID_REQ_MSG
|
||||
{
|
||||
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
|
||||
UCHAR TransactionId;
|
||||
USHORT QMICTLType; // QMICTL_RELEASE_CLIENT_ID_REQ
|
||||
USHORT Length;
|
||||
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
|
||||
USHORT TLVLength; // 0x0002
|
||||
UCHAR QMIType;
|
||||
UCHAR ClientId;
|
||||
} __attribute__ ((packed)) QMICTL_RELEASE_CLIENT_ID_REQ_MSG, *PQMICTL_RELEASE_CLIENT_ID_REQ_MSG;
|
||||
|
||||
typedef struct _QMICTL_RELEASE_CLIENT_ID_RESP_MSG
|
||||
{
|
||||
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
|
||||
UCHAR TransactionId;
|
||||
USHORT QMICTLType; // QMICTL_RELEASE_CLIENT_ID_RESP
|
||||
USHORT Length;
|
||||
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
|
||||
USHORT TLVLength; // 0x0004
|
||||
USHORT QMIResult; // result code
|
||||
USHORT QMIError; // error code
|
||||
UCHAR TLV2Type; // QCTLV_TYPE_REQUIRED_PARAMETER
|
||||
USHORT TLV2Length; // 2
|
||||
UCHAR QMIType;
|
||||
UCHAR ClientId;
|
||||
} __attribute__ ((packed)) QMICTL_RELEASE_CLIENT_ID_RESP_MSG, *PQMICTL_RELEASE_CLIENT_ID_RESP_MSG;
|
||||
|
||||
typedef struct _QMICTL_REVOKE_CLIENT_ID_IND_MSG
|
||||
{
|
||||
UCHAR CtlFlags; // QMICTL_FLAG_INDICATION
|
||||
UCHAR TransactionId;
|
||||
USHORT QMICTLType; // QMICTL_REVOKE_CLIENT_ID_IND
|
||||
USHORT Length;
|
||||
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
|
||||
USHORT TLVLength; // 0x0002
|
||||
UCHAR QMIType;
|
||||
UCHAR ClientId;
|
||||
} __attribute__ ((packed)) QMICTL_REVOKE_CLIENT_ID_IND_MSG, *PQMICTL_REVOKE_CLIENT_ID_IND_MSG;
|
||||
|
||||
typedef struct _QMICTL_INVALID_CLIENT_ID_IND_MSG
|
||||
{
|
||||
UCHAR CtlFlags; // QMICTL_FLAG_INDICATION
|
||||
UCHAR TransactionId;
|
||||
USHORT QMICTLType; // QMICTL_REVOKE_CLIENT_ID_IND
|
||||
USHORT Length;
|
||||
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
|
||||
USHORT TLVLength; // 0x0002
|
||||
UCHAR QMIType;
|
||||
UCHAR ClientId;
|
||||
} __attribute__ ((packed)) QMICTL_INVALID_CLIENT_ID_IND_MSG, *PQMICTL_INVALID_CLIENT_ID_IND_MSG;
|
||||
|
||||
typedef struct _QMICTL_SET_DATA_FORMAT_REQ_MSG
|
||||
{
|
||||
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
|
||||
UCHAR TransactionId;
|
||||
USHORT QMICTLType; // QMICTL_SET_DATA_FORMAT_REQ
|
||||
USHORT Length;
|
||||
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
|
||||
USHORT TLVLength; // 1
|
||||
UCHAR DataFormat; // 0-default; 1-QoS hdr present
|
||||
} __attribute__ ((packed)) QMICTL_SET_DATA_FORMAT_REQ_MSG, *PQMICTL_SET_DATA_FORMAT_REQ_MSG;
|
||||
|
||||
#ifdef QC_IP_MODE
|
||||
#define SET_DATA_FORMAT_TLV_TYPE_LINK_PROTO 0x10
|
||||
#define SET_DATA_FORMAT_LINK_PROTO_ETH 0x0001
|
||||
#define SET_DATA_FORMAT_LINK_PROTO_IP 0x0002
|
||||
typedef struct _QMICTL_SET_DATA_FORMAT_TLV_LINK_PROT
|
||||
{
|
||||
UCHAR TLVType; // Link-Layer Protocol
|
||||
USHORT TLVLength; // 2
|
||||
USHORT LinkProt; // 0x1: ETH; 0x2: IP
|
||||
} QMICTL_SET_DATA_FORMAT_TLV_LINK_PROT, *PQMICTL_SET_DATA_FORMAT_TLV_LINK_PROT;
|
||||
|
||||
#ifdef QCMP_UL_TLP
|
||||
#define SET_DATA_FORMAT_TLV_TYPE_UL_TLP 0x11
|
||||
typedef struct _QMICTL_SET_DATA_FORMAT_TLV_UL_TLP
|
||||
{
|
||||
UCHAR TLVType; // 0x11, Uplink TLP Setting
|
||||
USHORT TLVLength; // 1
|
||||
UCHAR UlTlpSetting; // 0x0: Disable; 0x01: Enable
|
||||
} QMICTL_SET_DATA_FORMAT_TLV_UL_TLP, *PQMICTL_SET_DATA_FORMAT_TLV_UL_TLP;
|
||||
#endif // QCMP_UL_TLP
|
||||
|
||||
#ifdef QCMP_DL_TLP
|
||||
#define SET_DATA_FORMAT_TLV_TYPE_DL_TLP 0x13
|
||||
typedef struct _QMICTL_SET_DATA_FORMAT_TLV_DL_TLP
|
||||
{
|
||||
UCHAR TLVType; // 0x11, Uplink TLP Setting
|
||||
USHORT TLVLength; // 1
|
||||
UCHAR DlTlpSetting; // 0x0: Disable; 0x01: Enable
|
||||
} QMICTL_SET_DATA_FORMAT_TLV_DL_TLP, *PQMICTL_SET_DATA_FORMAT_TLV_DL_TLP;
|
||||
#endif // QCMP_DL_TLP
|
||||
|
||||
#endif // QC_IP_MODE
|
||||
|
||||
#ifdef MP_QCQOS_ENABLED
|
||||
#define SET_DATA_FORMAT_TLV_TYPE_QOS_SETTING 0x12
|
||||
typedef struct _QMICTL_SET_DATA_FORMAT_TLV_QOS_SETTING
|
||||
{
|
||||
UCHAR TLVType; // 0x12, QoS setting
|
||||
USHORT TLVLength; // 1
|
||||
UCHAR QosSetting; // 0x0: Disable; 0x01: Enable
|
||||
} QMICTL_SET_DATA_FORMAT_TLV_QOS_SETTING, *PQMICTL_SET_DATA_FORMAT_TLV_QOS_SETTING;
|
||||
#endif // MP_QCQOS_ENABLED
|
||||
|
||||
typedef struct _QMICTL_SET_DATA_FORMAT_RESP_MSG
|
||||
{
|
||||
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
|
||||
UCHAR TransactionId;
|
||||
USHORT QMICTLType; // QMICTL_SET_DATA_FORMAT_RESP
|
||||
USHORT Length;
|
||||
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
|
||||
USHORT TLVLength; // 0x0004
|
||||
USHORT QMIResult; // result code
|
||||
USHORT QMIError; // error code
|
||||
} __attribute__ ((packed)) QMICTL_SET_DATA_FORMAT_RESP_MSG, *PQMICTL_SET_DATA_FORMAT_RESP_MSG;
|
||||
|
||||
typedef struct _QMICTL_SYNC_REQ_MSG
|
||||
{
|
||||
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
|
||||
UCHAR TransactionId;
|
||||
USHORT QMICTLType; // QMICTL_CTL_SYNC_REQ
|
||||
USHORT Length; // 0
|
||||
} __attribute__ ((packed)) QMICTL_SYNC_REQ_MSG, *PQMICTL_SYNC_REQ_MSG;
|
||||
|
||||
typedef struct _QMICTL_SYNC_RESP_MSG
|
||||
{
|
||||
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
|
||||
UCHAR TransactionId;
|
||||
USHORT QMICTLType; // QMICTL_CTL_SYNC_RESP
|
||||
USHORT Length;
|
||||
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
|
||||
USHORT TLVLength; // 0x0004
|
||||
USHORT QMIResult;
|
||||
USHORT QMIError;
|
||||
} __attribute__ ((packed)) QMICTL_SYNC_RESP_MSG, *PQMICTL_SYNC_RESP_MSG;
|
||||
|
||||
typedef struct _QMICTL_SYNC_IND_MSG
|
||||
{
|
||||
UCHAR CtlFlags; // QMICTL_FLAG_INDICATION
|
||||
UCHAR TransactionId;
|
||||
USHORT QMICTLType; // QMICTL_REVOKE_CLIENT_ID_IND
|
||||
USHORT Length;
|
||||
} __attribute__ ((packed)) QMICTL_SYNC_IND_MSG, *PQMICTL_SYNC_IND_MSG;
|
||||
|
||||
typedef struct _QMICTL_LIBQMI_PROXY_OPEN_MSG
|
||||
{
|
||||
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
|
||||
UCHAR TransactionId;
|
||||
USHORT QMICTLType; // QMICTL_SET_DATA_FORMAT_RESP
|
||||
USHORT Length;
|
||||
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
|
||||
USHORT TLVLength; // 0x0004
|
||||
char device_path[0]; // result code
|
||||
} __attribute__ ((packed)) QMICTL_LIBQMI_PROXY_OPEN_MSG, *PQMICTL_LIBQMI_PROXY_OPEN_MSG;
|
||||
|
||||
typedef struct _QMICTL_MSG
|
||||
{
|
||||
union
|
||||
{
|
||||
// Message Header
|
||||
QCQMICTL_MSG_HDR QMICTLMsgHdr;
|
||||
QCQMICTL_MSG_HDR_RESP QMICTLMsgHdrRsp;
|
||||
|
||||
// QMICTL Message
|
||||
QMICTL_SET_INSTANCE_ID_REQ_MSG SetInstanceIdReq;
|
||||
QMICTL_SET_INSTANCE_ID_RESP_MSG SetInstanceIdRsp;
|
||||
QMICTL_GET_VERSION_REQ_MSG GetVersionReq;
|
||||
QMICTL_GET_VERSION_RESP_MSG GetVersionRsp;
|
||||
QMICTL_GET_CLIENT_ID_REQ_MSG GetClientIdReq;
|
||||
QMICTL_GET_CLIENT_ID_RESP_MSG GetClientIdRsp;
|
||||
QMICTL_RELEASE_CLIENT_ID_REQ_MSG ReleaseClientIdReq;
|
||||
QMICTL_RELEASE_CLIENT_ID_RESP_MSG ReleaseClientIdRsp;
|
||||
QMICTL_REVOKE_CLIENT_ID_IND_MSG RevokeClientIdInd;
|
||||
QMICTL_INVALID_CLIENT_ID_IND_MSG InvalidClientIdInd;
|
||||
QMICTL_SET_DATA_FORMAT_REQ_MSG SetDataFormatReq;
|
||||
QMICTL_SET_DATA_FORMAT_RESP_MSG SetDataFormatRsp;
|
||||
QMICTL_SYNC_REQ_MSG SyncReq;
|
||||
QMICTL_SYNC_RESP_MSG SyncRsp;
|
||||
QMICTL_SYNC_IND_MSG SyncInd;
|
||||
QMICTL_LIBQMI_PROXY_OPEN_MSG LibQmiProxyOpenReq;
|
||||
};
|
||||
} __attribute__ ((packed)) QMICTL_MSG, *PQMICTL_MSG;
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif //QCQCTL_H
|
||||
@ -1,320 +1,320 @@
|
||||
/******************************************************************************
|
||||
@file QCQMI.h
|
||||
|
||||
DESCRIPTION
|
||||
This module contains QMI module.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
None.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||
Quectel Wireless Solution Proprietary and Confidential.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#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
|
||||
/******************************************************************************
|
||||
@file QCQMI.h
|
||||
|
||||
DESCRIPTION
|
||||
This module contains QMI module.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
None.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||
Quectel Wireless Solution Proprietary and Confidential.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#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
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,423 +1,423 @@
|
||||
#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 *password;
|
||||
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_password[64];
|
||||
int old_auth;
|
||||
int old_iptype;
|
||||
|
||||
const struct qmi_device_ops *qmi_ops;
|
||||
const struct request_ops *request_ops;
|
||||
RMNET_INFO rmnet_info;
|
||||
} 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_create_vnd(char *devname, char *vndname, uint8_t muxid,
|
||||
uint32_t qmap_version, uint32_t ul_agg_cnt, uint32_t ul_agg_size);
|
||||
#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,
|
||||
};
|
||||
|
||||
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
|
||||
#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 *password;
|
||||
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_password[64];
|
||||
int old_auth;
|
||||
int old_iptype;
|
||||
|
||||
const struct qmi_device_ops *qmi_ops;
|
||||
const struct request_ops *request_ops;
|
||||
RMNET_INFO rmnet_info;
|
||||
} 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_create_vnd(char *devname, char *vndname, uint8_t muxid,
|
||||
uint32_t qmap_version, uint32_t ul_agg_cnt, uint32_t ul_agg_size);
|
||||
#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,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SIG_EVENT_START,
|
||||
SIG_EVENT_CHECK,
|
||||
SIG_EVENT_STOP,
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DMS_OP_MODE_ONLINE,
|
||||
DMS_OP_MODE_LOW_POWER,
|
||||
DMS_OP_MODE_FACTORY_TEST_MODE,
|
||||
DMS_OP_MODE_OFFLINE,
|
||||
DMS_OP_MODE_RESETTING,
|
||||
DMS_OP_MODE_SHUTTING_DOWN,
|
||||
DMS_OP_MODE_PERSISTENT_LOW_POWER,
|
||||
DMS_OP_MODE_MODE_ONLY_LOW_POWER,
|
||||
DMS_OP_MODE_NET_TEST_GW,
|
||||
}Device_operating_mode;
|
||||
|
||||
#ifdef CM_DEBUG
|
||||
#define dbg_time(fmt, args...) do { \
|
||||
fprintf(stdout, "[%15s-%04d: %s] " fmt "\n", __FILE__, __LINE__, get_time(), ##args); \
|
||||
fflush(stdout);\
|
||||
if (logfilefp) fprintf(logfilefp, "[%s-%04d: %s] " fmt "\n", __FILE__, __LINE__, get_time(), ##args); \
|
||||
} while(0)
|
||||
#else
|
||||
#define dbg_time(fmt, args...) do { \
|
||||
fprintf(stdout, "[%s] " fmt "\n", get_time(), ##args); \
|
||||
fflush(stdout);\
|
||||
if (logfilefp) fprintf(logfilefp, "[%s] " fmt "\n", get_time(), ##args); \
|
||||
} while(0)
|
||||
#endif
|
||||
#endif
|
||||
@ -1,459 +1,459 @@
|
||||
/******************************************************************************
|
||||
@file QmiWwanCM.c
|
||||
@brief QMI WWAN connectivity manager.
|
||||
|
||||
DESCRIPTION
|
||||
Connectivity Management Tool for USB network adapter of Quectel wireless cellular modules.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
None.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||
Quectel Wireless Solution Proprietary and Confidential.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
||||
|
||||
#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)
|
||||
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
|
||||
|
||||
/******************************************************************************
|
||||
@file QmiWwanCM.c
|
||||
@brief QMI WWAN connectivity manager.
|
||||
|
||||
DESCRIPTION
|
||||
Connectivity Management Tool for USB network adapter of Quectel wireless cellular modules.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
None.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||
Quectel Wireless Solution Proprietary and Confidential.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
||||
|
||||
#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)
|
||||
break;
|
||||
sleep(1);
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
QmiThreadSendQMI(ComposeQCTLMsg(QMICTL_GET_VERSION_REQ, CtlGetVersionReq, NULL), &pResponse);
|
||||
if (profile->qmap_mode) {
|
||||
if (pResponse) {
|
||||
if (pResponse->CTLMsg.QMICTLMsgHdrRsp.QMUXResult == 0 && pResponse->CTLMsg.QMICTLMsgHdrRsp.QMUXError == 0) {
|
||||
uint8_t NumElements = 0;
|
||||
|
||||
for (NumElements = 0; NumElements < pResponse->CTLMsg.GetVersionRsp.NumElements; NumElements++) {
|
||||
#if 0
|
||||
dbg_time("QMUXType = %02x Version = %d.%d",
|
||||
pResponse->CTLMsg.GetVersionRsp.TypeVersion[NumElements].QMUXType,
|
||||
pResponse->CTLMsg.GetVersionRsp.TypeVersion[NumElements].MajorVersion,
|
||||
pResponse->CTLMsg.GetVersionRsp.TypeVersion[NumElements].MinorVersion);
|
||||
#endif
|
||||
if (pResponse->CTLMsg.GetVersionRsp.TypeVersion[NumElements].QMUXType == QMUX_TYPE_WDS_ADMIN)
|
||||
profile->qmap_version = (pResponse->CTLMsg.GetVersionRsp.TypeVersion[NumElements].MinorVersion > 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pResponse) free(pResponse);
|
||||
qmiclientId[QMUX_TYPE_WDS] = QmiWwanGetClientID(QMUX_TYPE_WDS);
|
||||
if (profile->enable_ipv6)
|
||||
qmiclientId[QMUX_TYPE_WDS_IPV6] = QmiWwanGetClientID(QMUX_TYPE_WDS);
|
||||
qmiclientId[QMUX_TYPE_DMS] = QmiWwanGetClientID(QMUX_TYPE_DMS);
|
||||
qmiclientId[QMUX_TYPE_NAS] = QmiWwanGetClientID(QMUX_TYPE_NAS);
|
||||
qmiclientId[QMUX_TYPE_UIM] = QmiWwanGetClientID(QMUX_TYPE_UIM);
|
||||
qmiclientId[QMUX_TYPE_WDS_ADMIN] = QmiWwanGetClientID(QMUX_TYPE_WDS_ADMIN);
|
||||
#ifdef CONFIG_COEX_WWAN_STATE
|
||||
qmiclientId[QMUX_TYPE_COEX] = QmiWwanGetClientID(QMUX_TYPE_COEX);
|
||||
#endif
|
||||
#ifdef CONFIG_ENABLE_QOS
|
||||
qmiclientId[QMUX_TYPE_QOS] = QmiWwanGetClientID(QMUX_TYPE_QOS);
|
||||
#endif
|
||||
profile->wda_client = qmiclientId[QMUX_TYPE_WDS_ADMIN];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int QmiWwanDeInit(void) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < sizeof(qmiclientId)/sizeof(qmiclientId[0]); i++)
|
||||
{
|
||||
if (qmiclientId[i] != 0)
|
||||
{
|
||||
QmiWwanReleaseClientID((QMUX_TYPE_WDS_IPV6 == i ? QMUX_TYPE_WDS : i), qmiclientId[i]);
|
||||
qmiclientId[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t qmi_proxy_read (int fd, void *buf, size_t size) {
|
||||
ssize_t nreads;
|
||||
PQCQMI_HDR pHdr = (PQCQMI_HDR)buf;
|
||||
|
||||
nreads = read(fd, pHdr, sizeof(QCQMI_HDR));
|
||||
if (nreads == sizeof(QCQMI_HDR) && le16_to_cpu(pHdr->Length) < size) {
|
||||
nreads += read(fd, pHdr+1, le16_to_cpu(pHdr->Length) + 1 - sizeof(QCQMI_HDR));
|
||||
}
|
||||
|
||||
return nreads;
|
||||
}
|
||||
|
||||
#ifdef QUECTEL_QMI_MERGE
|
||||
static int QmiWwanMergeQmiRsp(void *buf, ssize_t *src_size) {
|
||||
static QMI_MSG_PACKET s_QMIPacket;
|
||||
QMI_MSG_HEADER *header = NULL;
|
||||
ssize_t size = *src_size;
|
||||
|
||||
if((uint16_t)size < sizeof(QMI_MSG_HEADER))
|
||||
return -1;
|
||||
|
||||
header = (QMI_MSG_HEADER *)buf;
|
||||
if(le16_to_cpu(header->idenity) != MERGE_PACKET_IDENTITY || le16_to_cpu(header->version) != MERGE_PACKET_VERSION || le16_to_cpu(header->cur_len) > le16_to_cpu(header->total_len))
|
||||
return -1;
|
||||
|
||||
if(le16_to_cpu(header->cur_len) == le16_to_cpu(header->total_len)) {
|
||||
*src_size = le16_to_cpu(header->total_len);
|
||||
memcpy(buf, buf + sizeof(QMI_MSG_HEADER), *src_size);
|
||||
s_QMIPacket.len = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(s_QMIPacket.buf + s_QMIPacket.len, buf + sizeof(QMI_MSG_HEADER), le16_to_cpu(header->cur_len));
|
||||
s_QMIPacket.len += le16_to_cpu(header->cur_len);
|
||||
|
||||
if (le16_to_cpu(header->cur_len) < MERGE_PACKET_MAX_PAYLOAD_SIZE || s_QMIPacket.len >= le16_to_cpu(header->total_len)) {
|
||||
memcpy(buf, s_QMIPacket.buf, s_QMIPacket.len);
|
||||
*src_size = s_QMIPacket.len;
|
||||
s_QMIPacket.len = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void * QmiWwanThread(void *pData) {
|
||||
PROFILE_T *profile = (PROFILE_T *)pData;
|
||||
const char *cdc_wdm = (const char *)profile->qmichannel;
|
||||
int wait_for_request_quit = 0;
|
||||
char num = cdc_wdm[strlen(cdc_wdm)-1];
|
||||
|
||||
if (profile->proxy[0]) {
|
||||
if (!strncmp(profile->proxy, QUECTEL_QMI_PROXY, strlen(QUECTEL_QMI_PROXY))) {
|
||||
snprintf(profile->proxy, sizeof(profile->proxy), "%s%c", QUECTEL_QMI_PROXY, num);
|
||||
}
|
||||
}
|
||||
else if (!strncmp(cdc_wdm, "/dev/mhi_IPCR", strlen("/dev/mhi_IPCR"))) {
|
||||
snprintf(profile->proxy, sizeof(profile->proxy), "%s%c", QUECTEL_QRTR_PROXY, num);
|
||||
}
|
||||
else if (profile->qmap_mode > 1) {
|
||||
snprintf(profile->proxy, sizeof(profile->proxy), "%s%c", QUECTEL_QMI_PROXY, num);
|
||||
}
|
||||
|
||||
if (profile->proxy[0])
|
||||
cdc_wdm_fd = cm_open_proxy(profile->proxy);
|
||||
else
|
||||
cdc_wdm_fd = cm_open_dev(cdc_wdm);
|
||||
|
||||
if (cdc_wdm_fd == -1) {
|
||||
dbg_time("%s Failed to open %s, errno: %d (%s)", __func__, cdc_wdm, errno, strerror(errno));
|
||||
qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_DISCONNECTED);
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dbg_time("cdc_wdm_fd = %d", cdc_wdm_fd);
|
||||
|
||||
qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_CONNECTED);
|
||||
while (1) {
|
||||
struct pollfd pollfds[] = {{qmidevice_control_fd[1], POLLIN, 0}, {cdc_wdm_fd, POLLIN, 0}};
|
||||
int ne, ret, nevents = sizeof(pollfds)/sizeof(pollfds[0]);
|
||||
|
||||
do {
|
||||
ret = poll(pollfds, nevents, wait_for_request_quit ? 1000 : -1);
|
||||
} while ((ret < 0) && (errno == EINTR));
|
||||
|
||||
if (ret == 0 && wait_for_request_quit) {
|
||||
QmiThreadRecvQMI(NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ret <= 0) {
|
||||
dbg_time("%s poll=%d, errno: %d (%s)", __func__, ret, errno, strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
for (ne = 0; ne < nevents; ne++) {
|
||||
int fd = pollfds[ne].fd;
|
||||
short revents = pollfds[ne].revents;
|
||||
|
||||
//dbg_time("{%d, %x, %x}", pollfds[ne].fd, pollfds[ne].events, pollfds[ne].revents);
|
||||
|
||||
if (revents & (POLLERR | POLLHUP | POLLNVAL)) {
|
||||
dbg_time("%s poll err/hup/inval", __func__);
|
||||
dbg_time("poll fd = %d, events = 0x%04x", fd, revents);
|
||||
if (fd == cdc_wdm_fd) {
|
||||
} else {
|
||||
}
|
||||
if (revents & (POLLHUP | POLLNVAL)) //EC20 bug, Can get POLLERR
|
||||
goto __QmiWwanThread_quit;
|
||||
}
|
||||
|
||||
if ((revents & POLLIN) == 0)
|
||||
continue;
|
||||
|
||||
if (fd == qmidevice_control_fd[1]) {
|
||||
int triger_event;
|
||||
if (read(fd, &triger_event, sizeof(triger_event)) == sizeof(triger_event)) {
|
||||
//DBG("triger_event = 0x%x", triger_event);
|
||||
switch (triger_event) {
|
||||
case RIL_REQUEST_QUIT:
|
||||
goto __QmiWwanThread_quit;
|
||||
break;
|
||||
case SIG_EVENT_STOP:
|
||||
wait_for_request_quit = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fd == cdc_wdm_fd) {
|
||||
ssize_t nreads;
|
||||
PQCQMIMSG pResponse = (PQCQMIMSG)cm_recv_buf;
|
||||
|
||||
if (!profile->proxy[0])
|
||||
nreads = read(fd, cm_recv_buf, sizeof(cm_recv_buf));
|
||||
else
|
||||
nreads = qmi_proxy_read(fd, cm_recv_buf, sizeof(cm_recv_buf));
|
||||
//dbg_time("%s read=%d errno: %d (%s)", __func__, (int)nreads, errno, strerror(errno));
|
||||
if (nreads <= 0) {
|
||||
dbg_time("%s read=%d errno: %d (%s)", __func__, (int)nreads, errno, strerror(errno));
|
||||
break;
|
||||
}
|
||||
#ifdef QUECTEL_QMI_MERGE
|
||||
if((profile->qmap_mode == 0 || profile->qmap_mode == 1) && QmiWwanMergeQmiRsp(cm_recv_buf, &nreads))
|
||||
continue;
|
||||
#endif
|
||||
if (nreads != (le16_to_cpu(pResponse->QMIHdr.Length) + 1)) {
|
||||
dbg_time("%s nreads=%d, pQCQMI->QMIHdr.Length = %d", __func__, (int)nreads, le16_to_cpu(pResponse->QMIHdr.Length));
|
||||
continue;
|
||||
}
|
||||
|
||||
QmiThreadRecvQMI(pResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__QmiWwanThread_quit:
|
||||
if (cdc_wdm_fd != -1) { close(cdc_wdm_fd); cdc_wdm_fd = -1; }
|
||||
qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_DISCONNECTED);
|
||||
QmiThreadRecvQMI(NULL); //main thread may pending on QmiThreadSendQMI()
|
||||
dbg_time("%s exit", __func__);
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct qmi_device_ops qmiwwan_qmidev_ops = {
|
||||
.init = QmiWwanInit,
|
||||
.deinit = QmiWwanDeInit,
|
||||
.send = QmiWwanSendQMI,
|
||||
.read = QmiWwanThread,
|
||||
};
|
||||
|
||||
uint8_t qmi_over_mbim_get_client_id(uint8_t QMIType) {
|
||||
return QmiWwanGetClientID(QMIType);
|
||||
}
|
||||
|
||||
uint8_t qmi_over_mbim_release_client_id(uint8_t QMIType, uint8_t ClientId) {
|
||||
return QmiWwanReleaseClientID(QMIType, ClientId);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1,339 +1,339 @@
|
||||
Release Notes
|
||||
|
||||
[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
|
||||
|
||||
Release Notes
|
||||
|
||||
[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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
71
wwan/app/quectel-cm/src/log/cdc_mbim.txt
Normal file
71
wwan/app/quectel-cm/src/log/cdc_mbim.txt
Normal file
@ -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
|
||||
168
wwan/app/quectel-cm/src/log/cdc_mbim_vlan.txt
Normal file
168
wwan/app/quectel-cm/src/log/cdc_mbim_vlan.txt
Normal file
@ -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
|
||||
129
wwan/app/quectel-cm/src/log/ecm_ncm_rndis.txt
Normal file
129
wwan/app/quectel-cm/src/log/ecm_ncm_rndis.txt
Normal file
@ -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
|
||||
62
wwan/app/quectel-cm/src/log/gobinet.txt
Normal file
62
wwan/app/quectel-cm/src/log/gobinet.txt
Normal file
@ -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
|
||||
60
wwan/app/quectel-cm/src/log/gobinet_bridge.txt
Normal file
60
wwan/app/quectel-cm/src/log/gobinet_bridge.txt
Normal file
@ -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
|
||||
45
wwan/app/quectel-cm/src/log/gobinet_qmap=1.txt
Normal file
45
wwan/app/quectel-cm/src/log/gobinet_qmap=1.txt
Normal file
@ -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
|
||||
62
wwan/app/quectel-cm/src/log/gobinet_qmap=1_bridge.txt
Normal file
62
wwan/app/quectel-cm/src/log/gobinet_qmap=1_bridge.txt
Normal file
@ -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
|
||||
146
wwan/app/quectel-cm/src/log/gobinet_qmap=4.txt
Normal file
146
wwan/app/quectel-cm/src/log/gobinet_qmap=4.txt
Normal file
@ -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)
|
||||
114
wwan/app/quectel-cm/src/log/gobinet_qmap=4_bridge.txt
Normal file
114
wwan/app/quectel-cm/src/log/gobinet_qmap=4_bridge.txt
Normal file
@ -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
|
||||
|
||||
80
wwan/app/quectel-cm/src/log/pcie_mhi_mbim.txt
Normal file
80
wwan/app/quectel-cm/src/log/pcie_mhi_mbim.txt
Normal file
@ -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
|
||||
170
wwan/app/quectel-cm/src/log/pcie_mhi_mbim_qmap=4.txt
Normal file
170
wwan/app/quectel-cm/src/log/pcie_mhi_mbim_qmap=4.txt
Normal file
@ -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
|
||||
127
wwan/app/quectel-cm/src/log/pcie_mhi_qmap=1.txt
Normal file
127
wwan/app/quectel-cm/src/log/pcie_mhi_qmap=1.txt
Normal file
@ -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)
|
||||
76
wwan/app/quectel-cm/src/log/pcie_mhi_qmap=1_bridge.txt
Normal file
76
wwan/app/quectel-cm/src/log/pcie_mhi_qmap=1_bridge.txt
Normal file
@ -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
|
||||
138
wwan/app/quectel-cm/src/log/pcie_mhi_qmap=4.txt
Normal file
138
wwan/app/quectel-cm/src/log/pcie_mhi_qmap=4.txt
Normal file
@ -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
|
||||
147
wwan/app/quectel-cm/src/log/pcie_mhi_qmap=4_bridge.txt
Normal file
147
wwan/app/quectel-cm/src/log/pcie_mhi_qmap=4_bridge.txt
Normal file
@ -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
|
||||
|
||||
65
wwan/app/quectel-cm/src/log/qmi_wwan_q.txt
Normal file
65
wwan/app/quectel-cm/src/log/qmi_wwan_q.txt
Normal file
@ -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
|
||||
57
wwan/app/quectel-cm/src/log/qmi_wwan_q_bridge.txt
Normal file
57
wwan/app/quectel-cm/src/log/qmi_wwan_q_bridge.txt
Normal file
@ -0,0 +1,57 @@
|
||||
root@ZhuoTK:/# insmod qmi_wwan_q.ko
|
||||
[ 116.910000] qmi_wwan_q 1-1.3:1.4: cdc-wdm0: USB WDM device
|
||||
[ 116.930000] qmi_wwan_q 1-1.3:1.4: Quectel Android work on RawIP mode
|
||||
[ 116.930000] qmi_wwan_q 1-1.3:1.4: rx_urb_size = 1520
|
||||
[ 116.940000] qmi_wwan_q 1-1.3:1.4 wwan0: register 'qmi_wwan_q' at usb-101c0000.ehci-1.3, WWAN/QMI device, 06:fb:51:a3:d6:c5
|
||||
[ 116.950000] usbcore: registered new interface driver qmi_wwan_q
|
||||
|
||||
root@ZhuoTK:/# brctl addbr br0
|
||||
root@ZhuoTK:/# brctl addif br0 eth0.1
|
||||
root@ZhuoTK:/# brctl addif br0 wwan0
|
||||
root@ZhuoTK:/# brctl show
|
||||
bridge name bridge id STP enabled interfaces
|
||||
br0 8000.00ca019197b9 no eth0.1
|
||||
wwan0
|
||||
|
||||
root@ZhuoTK:/# quectel-CM -s cmnet -b &
|
||||
root@ZhuoTK:/# [04-13_05:13:39:369] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-13_05:13:39:372] Find /sys/bus/usb/devices/1-1.3 idVendor=0x2c7c idProduct=0x125, bus=0x001, dev=0x003
|
||||
[ 143.340000] net wwan0: bridge_mode change to 0x1
|
||||
[04-13_05:13:39:373] Auto find qmichannel = /dev/cdc-wdm0
|
||||
[04-13_05:13:39:374] Auto find usbnet_adapter = wwan0
|
||||
[04-13_05:13:39:374] netcard driver = qmi_wwan_q, driver version = V1.2.0.23
|
||||
[04-13_05:13:39:380] Modem works in QMI mode
|
||||
[04-13_05:13:39:388] cdc_wdm_fd = 7
|
||||
[04-13_05:13:39:466] Get clientWDS = 5
|
||||
[04-13_05:13:39:496] Get clientDMS = 2
|
||||
[04-13_05:13:39:527] Get clientNAS = 4
|
||||
[04-13_05:13:39:559] Get clientUIM = 1
|
||||
[04-13_05:13:39:592] Get clientWDA = 1
|
||||
[04-13_05:13:39:626] requestBaseBandVersion EC25EFAR06A11M4G
|
||||
[04-13_05:13:39:752] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-13_05:13:39:752] requestSetProfile[1] cmnet///0
|
||||
[04-13_05:13:39:816] requestGetProfile[1] cmnet///0
|
||||
[04-13_05:13:39:848] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: LTE
|
||||
[04-13_05:13:39:879] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[04-13_05:13:39:880] ifconfig wwan0 0.0.0.0
|
||||
[04-13_05:13:39:893] ifconfig wwan0 down
|
||||
[04-13_05:13:39:943] requestSetupDataCall WdsConnectionIPv4Handle: 0x872627c0
|
||||
[04-13_05:13:40:073] ifconfig wwan0 up
|
||||
[04-13_05:13:40:085] echo '0xa8d9237' > /sys/class/net/wwan0/bridge_ipv4
|
||||
|
||||
root@ZhuoTK:/# ifconfig br0 up
|
||||
[ 165.730000] wwan0 PC Mac Address: 00:0e:c6:a6:6c:f1
|
||||
[ 165.750000] wwan0 PC Mac Address: 00:0e:c6:a6:6c:f1
|
||||
[ 165.860000] wwan0 sip = 10.141.146.55, tip=10.141.146.56, ipv4=10.141.146.55
|
||||
[ 165.870000] wwan0 sip = 10.141.146.55, tip=10.141.146.56, ipv4=10.141.146.55
|
||||
[ 165.990000] wwan0 sip = 10.141.146.55, tip=10.141.146.56, ipv4=10.141.146.55
|
||||
[ 166.010000] wwan0 sip = 0.0.0.0, tip=10.141.146.55, ipv4=10.141.146.55
|
||||
[ 166.070000] wwan0 sip = 10.141.146.55, tip=10.141.146.56, ipv4=10.141.146.55
|
||||
[ 167.010000] wwan0 sip = 0.0.0.0, tip=10.141.146.55, ipv4=10.141.146.55
|
||||
[ 167.480000] br0: port 2(wwan0) entered forwarding state
|
||||
[ 167.520000] br0: port 1(eth0.1) entered forwarding state
|
||||
[ 168.020000] wwan0 sip = 0.0.0.0, tip=10.141.146.55, ipv4=10.141.146.55
|
||||
[ 169.010000] wwan0 sip = 10.141.146.55, tip=10.141.146.55, ipv4=10.141.146.55
|
||||
[ 169.120000] wwan0 sip = 10.141.146.55, tip=10.141.146.56, ipv4=10.141.146.55
|
||||
[ 169.130000] wwan0 sip = 10.141.146.55, tip=10.141.146.56, ipv4=10.141.146.55
|
||||
[ 176.620000] wwan0 sip = 10.141.146.55, tip=10.141.146.56, ipv4=10.141.146.55
|
||||
54
wwan/app/quectel-cm/src/log/qmi_wwan_q_qmap=1.txt
Normal file
54
wwan/app/quectel-cm/src/log/qmi_wwan_q_qmap=1.txt
Normal file
@ -0,0 +1,54 @@
|
||||
root@ZhuoTK:/# insmod qmi_wwan_q.ko qmap_mode=1
|
||||
[ 1367.200000] usbcore: registered new interface driver qmi_wwan_q
|
||||
[ 1383.840000] usb 1-1.3: new high-speed USB device number 7 using ehci-platform
|
||||
[ 1384.080000] qmi_wwan_q 1-1.3:1.4: cdc-wdm0: USB WDM device
|
||||
[ 1384.080000] qmi_wwan_q 1-1.3:1.4: Quectel Android work on RawIP mode
|
||||
[ 1384.100000] qmi_wwan_q 1-1.3:1.4: rx_urb_size = 4096
|
||||
[ 1384.100000] 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 cmnet &
|
||||
[04-13_03:41:28:144] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-13_03:41:28:146] Find /sys/bus/usb/devices/1-1.3 idVendor=0x2c7c idProduct=0x125, bus=0x001, dev=0x007
|
||||
[04-13_03:41:28:148] Auto find qmichannel = /dev/cdc-wdm0
|
||||
[04-13_03:41:28:148] Auto find usbnet_adapter = wwan0
|
||||
[04-13_03:41:28:148] netcard driver = qmi_wwan_q, driver version = V1.2.0.23
|
||||
[04-13_03:41:28:149] qmap_mode = 1, qmap_version = 5, qmap_size = 4096, muxid = 0x81, qmap_netcard = wwan0
|
||||
[04-13_03:41:28:150] Modem works in QMI mode
|
||||
[04-13_03:41:28:158] cdc_wdm_fd = 7
|
||||
[04-13_03:41:28:238] Get clientWDS = 4
|
||||
[04-13_03:41:28:271] Get clientDMS = 1
|
||||
[04-13_03:41:28:302] Get clientNAS = 4
|
||||
[04-13_03:41:28:334] Get clientUIM = 1
|
||||
[04-13_03:41:28:365] Get clientWDA = 1
|
||||
[04-13_03:41:28:397] requestBaseBandVersion EC25EFAR06A11M4G
|
||||
[04-13_03:41:28:430] qmap_settings.rx_urb_size = 4096
|
||||
[ 1393.530000] net wwan0: ul_data_aggregation_max_datagrams=11, ul_data_aggregation_max_size=4096, dl_minimum_padding=0
|
||||
[04-13_03:41:28:431] qmap_settings.ul_data_aggregation_max_datagrams = 11
|
||||
[04-13_03:41:28:431] qmap_settings.ul_data_aggregation_max_size = 4096
|
||||
[04-13_03:41:28:431] qmap_settings.dl_minimum_padding = 0
|
||||
[04-13_03:41:28:557] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-13_03:41:28:558] requestSetProfile[1] cmnet///0
|
||||
[04-13_03:41:28:622] requestGetProfile[1] cmnet///0
|
||||
[04-13_03:41:28:654] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: LTE
|
||||
[04-13_03:41:28:685] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[ 1393.790000] net wwan0: link_state 0x1 -> 0x0
|
||||
[04-13_03:41:28:692] ifconfig wwan0 0.0.0.0
|
||||
[04-13_03:41:28:703] ifconfig wwan0 down
|
||||
[04-13_03:41:28:751] requestSetupDataCall WdsConnectionIPv4Handle: 0x8729a6b0
|
||||
[ 1393.980000] net wwan0: link_state 0x0 -> 0x1
|
||||
[04-13_03:41:28:882] ifconfig wwan0 up
|
||||
[04-13_03:41:28:895] you are use OpenWrt?
|
||||
[04-13_03:41:28:895] should not calling udhcpc manually?
|
||||
[04-13_03:41:28:895] should modify /etc/config/network as below?
|
||||
[04-13_03:41:28:896] config interface wan
|
||||
[04-13_03:41:28:896] option ifname wwan0
|
||||
[04-13_03:41:28:896] option proto dhcp
|
||||
[04-13_03:41:28:896] should use "/sbin/ifstaus wan" to check wwan0 's status?
|
||||
[04-13_03:41:28:896] busybox udhcpc -f -n -q -t 5 -i wwan0
|
||||
[04-13_03:41:28:907] udhcpc (v1.23.2) started
|
||||
[04-13_03:41:28:919] Sending discover...
|
||||
[04-13_03:41:28:925] Sending select for 10.129.198.20...
|
||||
[04-13_03:41:28:929] Lease of 10.129.198.20 obtained, lease time 7200
|
||||
[04-13_03:41:28:934] udhcpc: ifconfig wwan0 10.129.198.20 netmask 255.255.255.248 broadcast +
|
||||
[04-13_03:41:28:949] udhcpc: setting default routers: 10.129.198.21
|
||||
|
||||
86
wwan/app/quectel-cm/src/log/qmi_wwan_q_qmap=1_bridge.txt
Normal file
86
wwan/app/quectel-cm/src/log/qmi_wwan_q_qmap=1_bridge.txt
Normal file
@ -0,0 +1,86 @@
|
||||
root@ZhuoTK:/# insmod qmi_wwan_q.ko qmap_mode=1
|
||||
[ 49.000000] qmi_wwan_q 1-1.3:1.4: cdc-wdm0: USB WDM device
|
||||
[ 49.000000] qmi_wwan_q 1-1.3:1.4: Quectel Android work on RawIP mode
|
||||
[ 49.020000] qmi_wwan_q 1-1.3:1.4: rx_urb_size = 4096
|
||||
[ 49.020000] qmi_wwan_q 1-1.3:1.4 wwan0: register 'qmi_wwan_q' at usb-101c0000.ehci-1.3, WWAN/QMI device, de:ae:5c:82:b5:b2
|
||||
[ 49.030000] usbcore: registered new interface driver qmi_wwan_q
|
||||
|
||||
root@ZhuoTK:/# brctl addbr br0
|
||||
root@ZhuoTK:/# brctl addif br0 eth0.1
|
||||
root@ZhuoTK:/# brctl addif br0 wwan0
|
||||
root@ZhuoTK:/# brctl show
|
||||
bridge name bridge id STP enabled interfaces
|
||||
br0 8000.00ca019197b9 no eth0.1
|
||||
wwan0
|
||||
|
||||
root@ZhuoTK:/# quectel-CM -s cmnet -b &
|
||||
[04-13_05:11:46:442] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-13_05:11:46:444] Find /sys/bus/usb/devices/1-1.3 idVendor=0x2c7c idProduct=0x125, bus=0x001, dev=0x003
|
||||
[ 84.340000] net wwan0: bridge_mode change to 0x1
|
||||
[04-13_05:11:46:446] Auto find qmichannel = /dev/cdc-wdm0
|
||||
[04-13_05:11:46:446] Auto find usbnet_adapter = wwan0
|
||||
[04-13_05:11:46:446] netcard driver = qmi_wwan_q, driver version = V1.2.0.23
|
||||
[04-13_05:11:46:447] qmap_mode = 1, qmap_version = 5, qmap_size = 4096, muxid = 0x81, qmap_netcard = wwan0
|
||||
[04-13_05:11:46:454] Modem works in QMI mode
|
||||
[04-13_05:11:46:462] cdc_wdm_fd = 7
|
||||
[04-13_05:11:46:537] Get clientWDS = 5
|
||||
[04-13_05:11:46:569] Get clientDMS = 1
|
||||
[04-13_05:11:46:601] Get clientNAS = 4
|
||||
[04-13_05:11:46:633] Get clientUIM = 1
|
||||
[04-13_05:11:46:666] Get clientWDA = 1
|
||||
[04-13_05:11:46:697] requestBaseBandVersion EC25EFAR06A11M4G
|
||||
[04-13_05:11:46:730] qmap_settings.rx_urb_size = 4096
|
||||
[ 84.620000] net wwan0: ul_data_aggregation_max_datagrams=11, ul_data_aggregation_max_size=4096, dl_minimum_padding=0
|
||||
[04-13_05:11:46:730] qmap_settings.ul_data_aggregation_max_datagrams = 11
|
||||
[04-13_05:11:46:730] qmap_settings.ul_data_aggregation_max_size = 4096
|
||||
[04-13_05:11:46:730] qmap_settings.dl_minimum_padding = 0
|
||||
[04-13_05:11:46:859] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-13_05:11:46:859] requestSetProfile[1] cmnet///0
|
||||
[04-13_05:11:46:922] requestGetProfile[1] cmnet///0
|
||||
[04-13_05:11:46:954] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: LTE
|
||||
[04-13_05:11:46:986] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[ 84.880000] net wwan0: link_state 0x1 -> 0x0
|
||||
[04-13_05:11:46:992] ifconfig wwan0 0.0.0.0
|
||||
[04-13_05:11:47:005] ifconfig wwan0 down
|
||||
[04-13_05:11:47:050] requestSetupDataCall WdsConnectionIPv4Handle: 0x872a5830
|
||||
[ 85.070000] net wwan0: link_state 0x0 -> 0x1
|
||||
[04-13_05:11:47:183] ifconfig wwan0 up
|
||||
[04-13_05:11:47:195] echo '0xa54a78b' > /sys/class/net/wwan0/bridge_ipv4
|
||||
|
||||
root@ZhuoTK:/# ifconfig wwan0
|
||||
wwan0 Link encap:Ethernet HWaddr DE:AE:5C:82:B5:B2
|
||||
inet6 addr: fe80::dcae:5cff:fe82:b5b2/64 Scope:Link
|
||||
UP RUNNING NOARP MTU:1500 Metric:1
|
||||
RX packets:3792 errors:0 dropped:0 overruns:0 frame:0
|
||||
TX packets:3271 errors:0 dropped:36 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:2271762 (2.1 MiB) TX bytes:565184 (551.9 KiB)
|
||||
|
||||
root@ZhuoTK:/# ifconfig br0 up
|
||||
[ 89.530000] br0: port 2(wwan0) entered forwarding state
|
||||
[ 89.530000] br0: port 2(wwan0) entered forwarding state
|
||||
[ 89.540000] br0: port 1(eth0.1) entered forwarding state
|
||||
[ 89.540000] br0: port 1(eth0.1) entered forwarding state
|
||||
|
||||
root@ZhuoTK:/#
|
||||
[ 93.720000] wwan0 sip = 192.168.1.153, tip=10.84.167.140, ipv4=10.84.167.139
|
||||
[ 104.560000] br0: port 2(wwan0) entered forwarding state
|
||||
[ 104.560000] br0: port 1(eth0.1) entered forwarding state
|
||||
[ 111.750000] rt305x-esw 10110000.esw: link changed 0x00
|
||||
[ 116.440000] rt305x-esw 10110000.esw: link changed 0x01
|
||||
[ 116.620000] wwan0 PC Mac Address: 00:0e:c6:a6:6c:f1
|
||||
[ 116.680000] wwan0 PC Mac Address: 00:0e:c6:a6:6c:f1
|
||||
[ 116.690000] wwan0 PC Mac Address: 00:0e:c6:a6:6c:f1
|
||||
[ 116.760000] wwan0 sip = 10.84.167.139, tip=10.84.167.140, ipv4=10.84.167.139
|
||||
[ 117.050000] wwan0 sip = 10.84.167.139, tip=10.84.167.140, ipv4=10.84.167.139
|
||||
[ 117.220000] wwan0 sip = 0.0.0.0, tip=10.84.167.139, ipv4=10.84.167.139
|
||||
[ 117.820000] wwan0 sip = 10.84.167.139, tip=10.84.167.140, ipv4=10.84.167.139
|
||||
[ 118.220000] wwan0 sip = 0.0.0.0, tip=10.84.167.139, ipv4=10.84.167.139
|
||||
[ 118.300000] wwan0 sip = 10.84.167.139, tip=10.84.167.140, ipv4=10.84.167.139
|
||||
[ 119.220000] wwan0 sip = 0.0.0.0, tip=10.84.167.139, ipv4=10.84.167.139
|
||||
[ 120.220000] wwan0 sip = 10.84.167.139, tip=10.84.167.139, ipv4=10.84.167.139
|
||||
[ 120.300000] wwan0 sip = 10.84.167.139, tip=10.84.167.140, ipv4=10.84.167.139
|
||||
[ 121.430000] wwan0 sip = 10.84.167.139, tip=10.84.167.140, ipv4=10.84.167.139
|
||||
[ 141.730000] wwan0 sip = 10.84.167.139, tip=10.84.167.140, ipv4=10.84.167.139
|
||||
[ 144.390000] wwan0 sip = 10.84.167.139, tip=10.84.167.140, ipv4=10.84.167.139
|
||||
[ 144.510000] wwan0 sip = 10.84.167.139, tip=10.84.167.140, ipv4=10.84.167.139
|
||||
185
wwan/app/quectel-cm/src/log/qmi_wwan_q_qmap=4.txt
Normal file
185
wwan/app/quectel-cm/src/log/qmi_wwan_q_qmap=4.txt
Normal file
@ -0,0 +1,185 @@
|
||||
root@ZhuoTK:/# insmod qmi_wwan_q.ko qmap_mode=4
|
||||
[ 1515.180000] usbcore: registered new interface driver qmi_wwan_q
|
||||
[ 1530.260000] usb 1-1.3: new high-speed USB device number 8 using ehci-platform
|
||||
[ 1530.500000] qmi_wwan_q 1-1.3:1.4: cdc-wdm0: USB WDM device
|
||||
[ 1530.500000] qmi_wwan_q 1-1.3:1.4: Quectel Android work on RawIP mode
|
||||
[ 1530.520000] qmi_wwan_q 1-1.3:1.4: rx_urb_size = 4096
|
||||
[ 1530.520000] qmi_wwan_q 1-1.3:1.4 wwan0: register 'qmi_wwan_q' at usb-101c0000.ehci-1.3, RMNET/USB device, da:0b:ce:b2:db:21
|
||||
[ 1530.530000] net wwan0: qmap_register_device wwan0_1
|
||||
[ 1530.540000] net wwan0: qmap_register_device wwan0_2
|
||||
[ 1530.550000] net wwan0: qmap_register_device wwan0_3
|
||||
[ 1530.550000] net wwan0: qmap_register_device wwan0_4
|
||||
|
||||
root@ZhuoTK:~# quectel-qmi-proxy &
|
||||
[04-13_03:44:53:958] Will use cdc-wdm='/dev/cdc-wdm0', proxy='quectel-qmi-proxy0'
|
||||
[04-13_03:44:53:959] qmi_proxy_init enter
|
||||
[04-13_03:44:53:960] qmi_proxy_loop enter thread_id 0x77c07530
|
||||
[04-13_03:44:54:960] qmi_proxy_init succful
|
||||
[04-13_03:44:54:960] local server: quectel-qmi-proxy0 sockfd = 4
|
||||
[04-13_03:44:54:960] qmi_proxy_server_fd = 4
|
||||
[04-13_03:45:04:346] +++ ClientFd=5
|
||||
[04-13_03:45:04:410] +++ ClientFd=5 QMIType=1 ClientId=4
|
||||
[04-13_03:45:04:442] +++ ClientFd=5 QMIType=2 ClientId=1
|
||||
[04-13_03:45:04:474] +++ ClientFd=5 QMIType=3 ClientId=4
|
||||
[04-13_03:45:04:506] +++ ClientFd=5 QMIType=11 ClientId=1
|
||||
[04-13_03:45:04:539] +++ ClientFd=5 QMIType=26 ClientId=1
|
||||
[04-13_03:45:10:770] +++ ClientFd=6
|
||||
[04-13_03:45:10:811] +++ ClientFd=6 QMIType=1 ClientId=21
|
||||
[04-13_03:45:10:843] +++ ClientFd=6 QMIType=2 ClientId=2
|
||||
[04-13_03:45:10:875] +++ ClientFd=6 QMIType=3 ClientId=5
|
||||
[04-13_03:45:10:907] +++ ClientFd=6 QMIType=11 ClientId=2
|
||||
[04-13_03:46:31:419] --- ClientFd=6 QMIType=1 ClientId=21
|
||||
[04-13_03:46:31:451] --- ClientFd=6 QMIType=2 ClientId=2
|
||||
[04-13_03:46:31:484] --- ClientFd=6 QMIType=3 ClientId=5
|
||||
[04-13_03:46:31:517] --- ClientFd=6 QMIType=11 ClientId=2
|
||||
[04-13_03:46:31:518] qmi_proxy_loop poll fd = 6, revents = 0011
|
||||
[04-13_03:46:31:519] --- ClientFd=6
|
||||
|
||||
root@ZhuoTK:/# quectel-CM -n 1 -s cmnet &
|
||||
root@ZhuoTK:/# [04-13_03:45:04:340] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-13_03:45:04:343] Find /sys/bus/usb/devices/1-1.3 idVendor=0x2c7c idProduct=0x125, bus=0x001, dev=0x008
|
||||
[04-13_03:45:04:344] Auto find qmichannel = /dev/cdc-wdm0
|
||||
[04-13_03:45:04:344] Auto find usbnet_adapter = wwan0
|
||||
[04-13_03:45:04:345] netcard driver = qmi_wwan_q, driver version = V1.2.0.23
|
||||
[04-13_03:45:04:345] qmap_mode = 4, qmap_version = 5, qmap_size = 4096, muxid = 0x81, qmap_netcard = wwan0_1
|
||||
[04-13_03:45:04:345] Modem works in QMI mode
|
||||
[04-13_03:45:04:347] connect to quectel-qmi-proxy0 sockfd = 7
|
||||
[04-13_03:45:04:347] cdc_wdm_fd = 7
|
||||
[04-13_03:45:04:411] Get clientWDS = 4
|
||||
[04-13_03:45:04:443] Get clientDMS = 1
|
||||
[04-13_03:45:04:475] Get clientNAS = 4
|
||||
[04-13_03:45:04:507] Get clientUIM = 1
|
||||
[04-13_03:45:04:540] Get clientWDA = 1
|
||||
[04-13_03:45:04:571] requestBaseBandVersion EC25EFAR06A11M4G
|
||||
[04-13_03:45:04:602] qmap_settings.rx_urb_size = 4096
|
||||
[ 1609.700000] net wwan0: ul_data_aggregation_max_datagrams=11, ul_data_aggregation_max_size=4096, dl_minimum_padding=0
|
||||
[04-13_03:45:04:603] qmap_settings.ul_data_aggregation_max_datagrams = 11
|
||||
[04-13_03:45:04:603] qmap_settings.ul_data_aggregation_max_size = 4096
|
||||
[04-13_03:45:04:603] qmap_settings.dl_minimum_padding = 0
|
||||
[04-13_03:45:04:731] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-13_03:45:04:731] requestSetProfile[1] cmnet///0
|
||||
[04-13_03:45:04:795] requestGetProfile[1] cmnet///0
|
||||
[04-13_03:45:04:827] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: LTE
|
||||
[04-13_03:45:04:858] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[ 1609.960000] net wwan0: link_state 0x1 -> 0x0
|
||||
[04-13_03:45:04:865] ifconfig wwan0 down
|
||||
[04-13_03:45:04:879] ifconfig wwan0_1 0.0.0.0
|
||||
[04-13_03:45:04:889] ifconfig wwan0_1 down
|
||||
[04-13_03:45:04:955] requestSetupDataCall WdsConnectionIPv4Handle: 0x87253410
|
||||
[ 1610.180000] net wwan0: link_state 0x0 -> 0x1
|
||||
[04-13_03:45:05:087] ifconfig wwan0 up
|
||||
[ 1610.200000] IPv6: ADDRCONF(NETDEV_UP): wwan0: link is not ready
|
||||
[04-13_03:45:05:105] ifconfig wwan0_1 up
|
||||
[ 1610.220000] IPv6: ADDRCONF(NETDEV_CHANGE): wwan0: link becomes ready
|
||||
[04-13_03:45:05:125] you are use OpenWrt?
|
||||
[04-13_03:45:05:125] should not calling udhcpc manually?
|
||||
[04-13_03:45:05:125] should modify /etc/config/network as below?
|
||||
[04-13_03:45:05:125] config interface wan
|
||||
[04-13_03:45:05:125] option ifname wwan0_1
|
||||
[04-13_03:45:05:125] option proto dhcp
|
||||
[04-13_03:45:05:126] should use "/sbin/ifstaus wan" to check wwan0_1 's status?
|
||||
[04-13_03:45:05:126] busybox udhcpc -f -n -q -t 5 -i wwan0_1
|
||||
[04-13_03:45:05:136] udhcpc (v1.23.2) started
|
||||
[04-13_03:45:05:148] Sending discover...
|
||||
[04-13_03:45:05:155] Sending select for 10.244.10.206...
|
||||
[04-13_03:45:05:160] Lease of 10.244.10.206 obtained, lease time 7200
|
||||
[04-13_03:45:05:165] udhcpc: ifconfig wwan0_1 10.244.10.206 netmask 255.255.255.252 broadcast +
|
||||
[04-13_03:45:05:174] udhcpc: setting default routers: 10.244.10.205
|
||||
|
||||
root@ZhuoTK:/# quectel-CM -n 2 -s 4gnet &
|
||||
[04-13_03:45:10:764] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-13_03:45:10:767] Find /sys/bus/usb/devices/1-1.3 idVendor=0x2c7c idProduct=0x125, bus=0x001, dev=0x008
|
||||
[04-13_03:45:10:768] Auto find qmichannel = /dev/cdc-wdm0
|
||||
[04-13_03:45:10:768] Auto find usbnet_adapter = wwan0
|
||||
[04-13_03:45:10:768] netcard driver = qmi_wwan_q, driver version = V1.2.0.23
|
||||
[04-13_03:45:10:769] qmap_mode = 4, qmap_version = 5, qmap_size = 4096, muxid = 0x82, qmap_netcard = wwan0_2
|
||||
[04-13_03:45:10:769] Modem works in QMI mode
|
||||
[04-13_03:45:10:771] connect to quectel-qmi-proxy0 sockfd = 7
|
||||
[04-13_03:45:10:771] cdc_wdm_fd = 7
|
||||
[04-13_03:45:10:812] Get clientWDS = 21
|
||||
[04-13_03:45:10:844] Get clientDMS = 2
|
||||
[04-13_03:45:10:876] Get clientNAS = 5
|
||||
[04-13_03:45:10:908] Get clientUIM = 2
|
||||
[04-13_03:45:10:971] requestBaseBandVersion EC25EFAR06A11M4G
|
||||
[04-13_03:45:11:099] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-13_03:45:11:099] requestSetProfile[2] 4gnet///0
|
||||
[04-13_03:45:11:163] requestGetProfile[2] 4gnet///0
|
||||
[04-13_03:45:11:195] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: LTE
|
||||
[04-13_03:45:11:227] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[04-13_03:45:11:227] ifconfig wwan0_2 0.0.0.0
|
||||
[ 1616.340000] IPv6: ADDRCONF(NETDEV_UP): wwan0_2: link is not ready
|
||||
[04-13_03:45:11:246] ifconfig wwan0_2 down
|
||||
[04-13_03:45:11:642] requestSetupDataCall WdsConnectionIPv4Handle: 0x87254580
|
||||
[ 1616.870000] net wwan0: link_state 0x1 -> 0x3
|
||||
[04-13_03:45:11:775] ifconfig wwan0 up
|
||||
[04-13_03:45:11:785] ifconfig wwan0_2 up
|
||||
[04-13_03:45:11:798] you are use OpenWrt?
|
||||
[04-13_03:45:11:798] should not calling udhcpc manually?
|
||||
[04-13_03:45:11:798] should modify /etc/config/network as below?
|
||||
[04-13_03:45:11:798] config interface wan
|
||||
[04-13_03:45:11:798] option ifname wwan0_2
|
||||
[04-13_03:45:11:798] option proto dhcp
|
||||
[04-13_03:45:11:798] should use "/sbin/ifstaus wan" to check wwan0_2 's status?
|
||||
[04-13_03:45:11:799] busybox udhcpc -f -n -q -t 5 -i wwan0_2
|
||||
[04-13_03:45:11:809] udhcpc (v1.23.2) started
|
||||
[04-13_03:45:11:821] Sending discover...
|
||||
[04-13_03:45:11:830] Sending select for 10.245.78.212...
|
||||
[04-13_03:45:11:836] Lease of 10.245.78.212 obtained, lease time 7200
|
||||
[04-13_03:45:11:842] udhcpc: ifconfig wwan0_2 10.245.78.212 netmask 255.255.255.248 broadcast +
|
||||
[04-13_03:45:11:852] udhcpc: setting default routers: 10.245.78.213
|
||||
|
||||
root@ZhuoTK:/# ifconfig wwan0_1
|
||||
wwan0_1 Link encap:Ethernet HWaddr DA:0B:CE:B2:DB:21
|
||||
inet addr:10.244.10.206 Mask:255.255.255.252
|
||||
inet6 addr: fe80::d80b:ceff:feb2:db21/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:640 (640.0 B) TX bytes:1344 (1.3 KiB)
|
||||
|
||||
root@ZhuoTK:/# ifconfig wwan0_2
|
||||
wwan0_2 Link encap:Ethernet HWaddr DA:0B:CE:B2:DB:21
|
||||
inet addr:10.245.78.212 Mask:255.255.255.248
|
||||
inet6 addr: fe80::d80b:ceff:feb2:db21/64 Scope:Link
|
||||
UP RUNNING NOARP MTU:1500 Metric:1
|
||||
RX packets:8 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:1193 (1.1 KiB) TX bytes:1028 (1.0 KiB)
|
||||
|
||||
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=113.508 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=123.651 ms
|
||||
|
||||
root@ZhuoTK:/# quectel-CM -k 2
|
||||
[04-13_03:46:30:808] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-13_03:46:30:811] /proc/2834/cmdline: quectel-CM -n 2 -s 4gnet
|
||||
[04-13_03:46:30:811] send SIGINT to process 2834
|
||||
[04-13_03:46:30:811] requestDeactivateDefaultPDP WdsConnectionIPv4Handle
|
||||
[ 1696.460000] net wwan0: link_state 0x3 -> 0x1
|
||||
[04-13_03:46:31:361] ifconfig wwan0_2 0.0.0.0
|
||||
[04-13_03:46:31:373] ifconfig wwan0_2 down
|
||||
[04-13_03:46:31:516] QmiWwanThread exit
|
||||
[04-13_03:46:31:516] qmi_main exit
|
||||
|
||||
root@ZhuoTK:/# ifconfig wwan0_2
|
||||
wwan0_2 Link encap:Ethernet HWaddr DA:0B:CE:B2:DB:21
|
||||
NOARP MTU:1500 Metric:1
|
||||
RX packets:16 errors:0 dropped:0 overruns:0 frame:0
|
||||
TX packets:15 errors:0 dropped:0 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:1865 (1.8 KiB) TX bytes:1620 (1.5 KiB)
|
||||
132
wwan/app/quectel-cm/src/log/qmi_wwan_q_qmap=4_bridge.txt
Normal file
132
wwan/app/quectel-cm/src/log/qmi_wwan_q_qmap=4_bridge.txt
Normal file
@ -0,0 +1,132 @@
|
||||
root@ZhuoTK:/# brctl addbr br0
|
||||
brctl: bridge br0: File exists
|
||||
root@ZhuoTK:/# brctl delbr br0
|
||||
root@ZhuoTK:/# brctl addbr br0
|
||||
root@ZhuoTK:/# brctl addif br0 eth0.1
|
||||
|
||||
root@ZhuoTK:/# insmod qmi_wwan_q.ko qmap_mode=4
|
||||
[ 365.340000] usbcore: registered new interface driver qmi_wwan_q
|
||||
[ 380.860000] usb 1-1.3: new high-speed USB device number 4 using ehci-platform
|
||||
[ 381.100000] qmi_wwan_q 1-1.3:1.4: cdc-wdm0: USB WDM device
|
||||
[ 381.100000] qmi_wwan_q 1-1.3:1.4: Quectel Android work on RawIP mode
|
||||
[ 381.120000] qmi_wwan_q 1-1.3:1.4: rx_urb_size = 4096
|
||||
[ 381.120000] qmi_wwan_q 1-1.3:1.4 wwan0: register 'qmi_wwan_q' at usb-101c0000.ehci-1.3, RMNET/USB device, fa:24:73:b5:39:a8
|
||||
[ 381.130000] net wwan0: qmap_register_device wwan0_1
|
||||
[ 381.140000] net wwan0: qmap_register_device wwan0_2
|
||||
[ 381.150000] net wwan0: qmap_register_device wwan0_3
|
||||
[ 381.150000] net wwan0: qmap_register_device wwan0_4
|
||||
|
||||
root@ZhuoTK:/# brctl addbr br0
|
||||
root@ZhuoTK:/# brctl addif br0 eth0.1
|
||||
root@ZhuoTK:/# brctl addif br0 wwan0_2
|
||||
root@ZhuoTK:/# brctl show
|
||||
bridge name bridge id STP enabled interfaces
|
||||
br0 8000.00ca019197b9 no eth0.1
|
||||
wwan0_2
|
||||
|
||||
root@ZhuoTK:/# quectel-qmi-proxy &
|
||||
[04-13_05:18:10:832] Will use cdc-wdm='/dev/cdc-wdm0', proxy='quectel-qmi-proxy0'
|
||||
[04-13_05:18:10:833] qmi_proxy_init enter
|
||||
[04-13_05:18:10:833] qmi_proxy_loop enter thread_id 0x77995530
|
||||
[04-13_05:18:11:833] qmi_proxy_init succful
|
||||
[04-13_05:18:11:833] local server: quectel-qmi-proxy0 sockfd = 4
|
||||
[04-13_05:18:11:833] qmi_proxy_server_fd = 4
|
||||
|
||||
root@ZhuoTK:/# quectel-CM -n 2 -s 4gnet -b &
|
||||
[04-13_05:18:20:144] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-13_05:18:20:146] Find /sys/bus/usb/devices/1-1.3 idVendor=0x2c7c idProduct=0x125, bus=0x001, dev=0x004
|
||||
[04-13_05:18:20:147] Auto find qmichannel = /dev/cdc-wdm0
|
||||
[04-13_05:18:20:148] Auto find usbnet_adapter = wwan0
|
||||
[04-13_05:18:20:148] netcard driver = qmi_wwan_q, driver version = V1.2.0.23
|
||||
[04-13_05:18:20:148] qmap_mode = 4, qmap_version = 5, qmap_size = 4096, muxid = 0x82, qmap_netcard = wwan0_2
|
||||
[04-13_05:18:20:149] Modem works in QMI mode
|
||||
[04-13_05:18:20:150] connect to quectel-qmi-proxy0 sockfd = 7
|
||||
[04-13_05:18:20:150] cdc_wdm_fd = 7
|
||||
[04-13_05:18:20:370] requestBaseBandVersion EC25EFAR06A11M4G
|
||||
[04-13_05:18:20:403] qmap_settings.rx_urb_size = 4096
|
||||
[04-13_05:18:20:404] qmap_settings.ul_data_aggregation_max_datagrams = 11
|
||||
[04-13_05:18:20:404] qmap_settings.ul_data_aggregation_max_size = 4096
|
||||
[04-13_05:18:20:404] qmap_settings.dl_minimum_padding = 0
|
||||
[04-13_05:18:20:530] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-13_05:18:20:530] requestSetProfile[2] 4gnet///0
|
||||
[04-13_05:18:20:594] requestGetProfile[2] 4gnet///0
|
||||
[04-13_05:18:20:626] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: LTE
|
||||
[04-13_05:18:20:657] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[04-13_05:18:20:658] ifconfig wwan0_2 0.0.0.0
|
||||
[04-13_05:18:20:669] ifconfig wwan0_2 down
|
||||
[04-13_05:18:21:010] requestSetupDataCall WdsConnectionIPv4Handle: 0x87249650
|
||||
[ 425.100000] net wwan0: link_state 0x1 -> 0x3
|
||||
[04-13_05:18:21:143] ifconfig wwan0 up
|
||||
[04-13_05:18:21:156] ifconfig wwan0_2 up
|
||||
[04-13_05:18:21:168] echo '0xa8ceec7' > /sys/class/net/wwan0_2/bridge_ipv4
|
||||
|
||||
root@ZhuoTK:/# ifconfig br0 up
|
||||
|
||||
[ 450.520000] br0: port 2(wwan0_2) entered forwarding state
|
||||
[ 450.520000] br0: port 1(eth0.1) entered forwarding state
|
||||
[ 450.770000] wwan0_2 PC Mac Address: 00:0e:c6:a6:6c:f1
|
||||
[ 450.790000] wwan0_2 PC Mac Address: 00:0e:c6:a6:6c:f1
|
||||
[ 450.840000] wwan0_2 sip = 10.140.238.199, tip=10.140.238.200, ipv4=10.140.238.199
|
||||
[ 450.950000] wwan0_2 sip = 10.140.238.199, tip=10.140.238.200, ipv4=10.140.238.199
|
||||
[ 450.950000] wwan0_2 sip = 10.140.238.199, tip=10.140.238.200, ipv4=10.140.238.199
|
||||
[ 451.120000] wwan0_2 sip = 0.0.0.0, tip=10.140.238.199, ipv4=10.140.238.199
|
||||
[ 451.180000] wwan0_2 sip = 10.140.238.199, tip=10.140.238.200, ipv4=10.140.238.199
|
||||
[ 452.120000] wwan0_2 sip = 0.0.0.0, tip=10.140.238.199, ipv4=10.140.238.199
|
||||
[ 453.080000] wwan0_2 sip = 10.140.238.199, tip=10.140.238.200, ipv4=10.140.238.199
|
||||
[ 453.120000] wwan0_2 sip = 0.0.0.0, tip=10.140.238.199, ipv4=10.140.238.199
|
||||
[ 454.120000] wwan0_2 sip = 10.140.238.199, tip=10.140.238.199, ipv4=10.140.238.199
|
||||
[ 454.220000] wwan0_2 sip = 10.140.238.199, tip=10.140.238.200, ipv4=10.140.238.199
|
||||
[ 456.200000] wwan0_2 sip = 10.140.238.199, tip=10.140.238.200, ipv4=10.140.238.199
|
||||
[ 458.120000] wwan0_2 sip = 10.140.238.199, tip=10.140.238.200, ipv4=10.140.238.199
|
||||
[ 459.240000] wwan0_2 sip = 10.140.238.199, tip=10.140.238.200, ipv4=10.140.238.199
|
||||
|
||||
root@ZhuoTK:/# quectel-CM -n 1 -s cmnet &
|
||||
[04-13_05:19:21:122] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-13_05:19:21:125] Find /sys/bus/usb/devices/1-1.3 idVendor=0x2c7c idProduct=0x125, bus=0x001, dev=0x004
|
||||
[04-13_05:19:21:126] Auto find qmichannel = /dev/cdc-wdm0
|
||||
[04-13_05:19:21:126] Auto find usbnet_adapter = wwan0
|
||||
[04-13_05:19:21:127] netcard driver = qmi_wwan_q, driver version = V1.2.0.23
|
||||
[04-13_05:19:21:127] qmap_mode = 4, qmap_version = 5, qmap_size = 4096, muxid = 0x81, qmap_netcard = wwan0_1
|
||||
[04-13_05:19:21:127] Modem works in QMI mode
|
||||
[04-13_05:19:21:128] connect to quectel-qmi-proxy0 sockfd = 7
|
||||
[04-13_05:19:21:129] cdc_wdm_fd = 7
|
||||
[04-13_05:19:21:331] requestBaseBandVersion EC25EFAR06A11M4G
|
||||
[04-13_05:19:21:459] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-13_05:19:21:459] requestSetProfile[1] cmnet///0
|
||||
[04-13_05:19:21:522] requestGetProfile[1] cmnet///0
|
||||
[04-13_05:19:21:554] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: LTE
|
||||
[04-13_05:19:21:585] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[ 485.550000] net wwan0: link_state 0x3 -> 0x2
|
||||
[04-13_05:19:21:592] ifconfig wwan0_1 0.0.0.0
|
||||
[ 485.570000] IPv6: ADDRCONF(NETDEV_UP): wwan0_1: link is not ready
|
||||
[04-13_05:19:21:610] ifconfig wwan0_1 down
|
||||
[04-13_05:19:21:682] requestSetupDataCall WdsConnectionIPv4Handle: 0x8725ed70
|
||||
[ 485.780000] net wwan0: link_state 0x2 -> 0x3
|
||||
[04-13_05:19:21:815] ifconfig wwan0 up
|
||||
[04-13_05:19:21:826] ifconfig wwan0_1 up
|
||||
[04-13_05:19:21:845] you are use OpenWrt?
|
||||
[04-13_05:19:21:845] should not calling udhcpc manually?
|
||||
[04-13_05:19:21:845] should modify /etc/config/network as below?
|
||||
[04-13_05:19:21:845] config interface wan
|
||||
[04-13_05:19:21:845] option ifname wwan0_1
|
||||
[04-13_05:19:21:845] option proto dhcp
|
||||
[04-13_05:19:21:845] should use "/sbin/ifstaus wan" to check wwan0_1 's status?
|
||||
[04-13_05:19:21:846] busybox udhcpc -f -n -q -t 5 -i wwan0_1
|
||||
[04-13_05:19:21:863] udhcpc (v1.23.2) started
|
||||
[04-13_05:19:21:923] Sending discover...
|
||||
[04-13_05:19:21:927] Sending select for 10.141.146.55...
|
||||
[04-13_05:19:21:932] Lease of 10.141.146.55 obtained, lease time 7200
|
||||
[04-13_05:19:21:938] udhcpc: ifconfig wwan0_1 10.141.146.55 netmask 255.255.255.240 broadcast +
|
||||
[04-13_05:19:21:949] udhcpc: setting default routers: 10.141.146.56
|
||||
|
||||
root@ZhuoTK:/# ip ro show
|
||||
default via 10.141.146.56 dev wwan0_1
|
||||
10.141.146.48/28 dev wwan0_1 proto kernel scope link src 10.141.146.55
|
||||
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=111 time=86.006 ms
|
||||
64 bytes from 8.8.8.8: seq=1 ttl=111 time=74.763 ms
|
||||
64 bytes from 8.8.8.8: seq=2 ttl=111 time=85.501 ms
|
||||
64 bytes from 8.8.8.8: seq=3 ttl=111 time=74.231 ms
|
||||
55
wwan/app/quectel-cm/src/log/qmi_wwan_qmap=4.txt
Normal file
55
wwan/app/quectel-cm/src/log/qmi_wwan_qmap=4.txt
Normal file
@ -0,0 +1,55 @@
|
||||
# dmesg
|
||||
[ 1737.738025] usb 1-1.2: new high-speed USB device number 5 using xhci-hcd
|
||||
[ 1737.838917] usb 1-1.2: New USB device found, idVendor=2c7c, idProduct=0512, bcdDevice= 3.18
|
||||
[ 1737.838948] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
|
||||
[ 1737.838963] usb 1-1.2: Product: EG12-EA
|
||||
[ 1737.838975] usb 1-1.2: Manufacturer: Quectel
|
||||
[ 1737.838986] usb 1-1.2: SerialNumber: 0123456789ABCDE
|
||||
[ 1737.994955] option 1-1.2:1.0: GSM modem (1-port) converter detected
|
||||
[ 1737.995430] usb 1-1.2: GSM modem (1-port) converter now attached to ttyUSB0
|
||||
[ 1737.995978] option 1-1.2:1.1: GSM modem (1-port) converter detected
|
||||
[ 1737.996409] usb 1-1.2: GSM modem (1-port) converter now attached to ttyUSB1
|
||||
[ 1737.996963] option 1-1.2:1.2: GSM modem (1-port) converter detected
|
||||
[ 1737.997351] usb 1-1.2: GSM modem (1-port) converter now attached to ttyUSB2
|
||||
[ 1737.997909] option 1-1.2:1.3: GSM modem (1-port) converter detected
|
||||
[ 1737.998976] usb 1-1.2: GSM modem (1-port) converter now attached to ttyUSB3
|
||||
[ 1825.835796] qmi_wwan 1-1.2:1.4: cdc-wdm0: USB WDM device
|
||||
[ 1825.839685] qmi_wwan 1-1.2:1.4 wwan0: register 'qmi_wwan' at usb-fe9c0000.xhci-1.2, WWAN/QMI device, 0e:80:14:b1:f6:b9
|
||||
[ 1825.840062] usbcore: registered new interface driver qmi_wwan
|
||||
|
||||
# ifconfig wwan0 down
|
||||
# echo Y > /sys/class/net/wwan0/qmi/raw_ip
|
||||
|
||||
# echo 1 > /sys/class/net/wwan0/qmi/add_mux
|
||||
# ifconfig qmimux0
|
||||
qmimux0: flags=4240<POINTOPOINT,NOARP,MULTICAST> mtu 1500
|
||||
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 1000 (UNSPEC)
|
||||
RX packets 0 bytes 0 (0.0 B)
|
||||
RX errors 0 dropped 0 overruns 0 frame 0
|
||||
TX packets 0 bytes 0 (0.0 B)
|
||||
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
|
||||
|
||||
# echo 2 > /sys/class/net/wwan0/qmi/add_mux
|
||||
# echo 3 > /sys/class/net/wwan0/qmi/add_mux
|
||||
# echo 4 > /sys/class/net/wwan0/qmi/add_mux
|
||||
# ifconfig qmimux3
|
||||
qmimux3: flags=4240<POINTOPOINT,NOARP,MULTICAST> mtu 1500
|
||||
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 1000 (UNSPEC)
|
||||
RX packets 0 bytes 0 (0.0 B)
|
||||
RX errors 0 dropped 0 overruns 0 frame 0
|
||||
TX packets 0 bytes 0 (0.0 B)
|
||||
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
|
||||
|
||||
set wwan0's mtu to max qmap packet size, for usbnet.c:usbnet_change_mtu() do not accept
|
||||
# ifconfig wwan0 mtu 16385
|
||||
|
||||
run qmi proxy programm,
|
||||
# quectel-CM/quectel-qmi-proxy -d /dev/cdc-wdm0
|
||||
or libqmi's qmi-proxy, if use libqmi's qmi-proxy, you can use qmicli to setup data call.
|
||||
# /usr/libexec/qmi-proxy --verbose --no-exit
|
||||
|
||||
use quectel-CM to setup data call, if use libqmi's qmi-proxy, use '-p qmi-proxy' instead of '-p quectel-qmi-proxy'
|
||||
# quectel-CM -p quectel-qmi-proxy -n 4 -s cmnet4
|
||||
# quectel-CM -p quectel-qmi-proxy -n 1 -s cmnet
|
||||
|
||||
for how to use libqmi to setup data call, please refer to https://knowledge.quectel.com/display/SWSYSTLinuxAndroid/libqmi_How+to+using+QMAP+multiplexing
|
||||
68
wwan/app/quectel-cm/src/log/usage_of_argument/6.txt
Normal file
68
wwan/app/quectel-cm/src/log/usage_of_argument/6.txt
Normal file
@ -0,0 +1,68 @@
|
||||
root@OpenWrt:~# quectel-CM -s cmnet -4 -6
|
||||
[04-14_06:56:51:778] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-14_06:56:51:779] network interface '' or qmidev '' is not exist
|
||||
[04-14_06:56:51:780] netcard driver = pcie_mhi, driver version = V1.3.0.17
|
||||
[04-14_06:56:51:781] qmap_mode = 4, qmap_version = 9, qmap_size = 16384, muxid = 0x81, qmap_netcard = rmnet_mhi0.1
|
||||
[04-14_06:56:51:782] Modem works in QMI mode
|
||||
[04-14_06:56:51:783] connect to quectel-qmi-proxy0 sockfd = 7
|
||||
[04-14_06:56:51:783] cdc_wdm_fd = 7
|
||||
[04-14_06:56:51:789] Get clientWDS = 15
|
||||
[04-14_06:56:51:792] Get clientWDS = 16
|
||||
[04-14_06:56:51:794] Get clientDMS = 3
|
||||
[04-14_06:56:51:798] Get clientNAS = 4
|
||||
[04-14_06:56:51:801] Get clientUIM = 1
|
||||
[04-14_06:56:51:805] Get clientWDA = 1
|
||||
[04-14_06:56:51:809] requestBaseBandVersion RM500QGLABR10A03M4G
|
||||
[04-14_06:56:51:813] qmap_settings.rx_urb_size = 16384
|
||||
[04-14_06:56:51:813] qmap_settings.ul_data_aggregation_max_datagrams = 11
|
||||
[04-14_06:56:51:814] qmap_settings.ul_data_aggregation_max_size = 8192
|
||||
[04-14_06:56:51:814] qmap_settings.dl_minimum_padding = 0
|
||||
[04-14_06:56:51:835] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-14_06:56:51:836] requestSetProfile[1] cmnet///0
|
||||
[04-14_06:56:51:848] requestGetProfile[1] cmnet///0
|
||||
[04-14_06:56:51:852] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: 5G_NSA
|
||||
[04-14_06:56:51:857] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[04-14_06:56:51:860] requestQueryDataCall IPv6ConnectionStatus: DISCONNECTED
|
||||
[04-14_06:56:51:861] ifconfig rmnet_mhi0 down
|
||||
[04-14_06:56:51:885] ifconfig rmnet_mhi0.1 0.0.0.0
|
||||
ifconfig: SIOCSIFFLAGS: Network is down
|
||||
[04-14_06:56:51:909] ifconfig rmnet_mhi0.1 down
|
||||
[04-14_06:56:51:943] requestSetupDataCall WdsConnectionIPv4Handle: 0x341450a0
|
||||
[04-14_06:56:52:423] requestSetupDataCall WdsConnectionIPv6Handle: 0x341439f0
|
||||
[ 1001.561353] net rmnet_mhi0: link_state 0x0 -> 0x1
|
||||
[04-14_06:56:52:441] ifconfig rmnet_mhi0 up
|
||||
[ 1001.584623] [I][mhi_netdev_open] Opened net dev interface
|
||||
[04-14_06:56:52:467] ifconfig rmnet_mhi0.1 up
|
||||
[04-14_06:56:52:495] you are use OpenWrt?
|
||||
[04-14_06:56:52:496] should not calling udhcpc manually?
|
||||
[04-14_06:56:52:496] should modify /etc/config/network as below?
|
||||
[04-14_06:56:52:497] config interface wan
|
||||
[04-14_06:56:52:497] option ifname rmnet_mhi0.1
|
||||
[04-14_06:56:52:497] option proto dhcp
|
||||
[04-14_06:56:52:498] should use "/sbin/ifstaus wan" to check rmnet_mhi0.1 's status?
|
||||
[04-14_06:56:52:498] busybox udhcpc -f -n -q -t 5 -i rmnet_mhi0.1
|
||||
udhcpc: started, v1.28.3
|
||||
udhcpc: sending discover
|
||||
udhcpc: sending select for 10.245.22.3
|
||||
udhcpc: lease of 10.245.22.3 obtained, lease time 7200
|
||||
[04-14_06:56:52:713] udhcpc: ifconfig rmnet_mhi0.1 10.245.22.3 netmask 255.255.255.248 broadcast +
|
||||
[04-14_06:56:52:754] udhcpc: setting default routers: 10.245.22.4
|
||||
[04-14_06:56:52:838] ip -6 address flush dev rmnet_mhi0.1
|
||||
[04-14_06:56:52:861] ip -6 address add 2409:8930:463:3daa:7c8e:429a:c902:c6cc/64 dev rmnet_mhi0.1
|
||||
[04-14_06:56:52:884] ip -6 route add default dev rmnet_mhi0.1
|
||||
|
||||
root@OpenWrt:~# cat /etc/resolv.conf
|
||||
nameserver 2409:8030:2000:0:0:0:0:1 # IPV6 rmnet_mhi0.1
|
||||
nameserver 2409:8030:2000:0:0:0:0:2 # IPV6 rmnet_mhi0.1
|
||||
search lan
|
||||
nameserver 127.0.0.1
|
||||
|
||||
root@OpenWrt:~# ip -6 ro show
|
||||
2409:8930:463:96df::/64 dev rmnet_mhi0.1 proto kernel metric 256
|
||||
fe80::/64 dev br-lan proto kernel metric 256
|
||||
fe80::/64 dev br0 proto kernel metric 256
|
||||
default dev rmnet_mhi0.1 metric 1024
|
||||
|
||||
root@OpenWrt:~# ping6 www.qq.com
|
||||
PING www.qq.com (2402:4e00:1430:1301::9227:79cc:76f2): 56 data bytes
|
||||
64 bytes from 2402:4e00:1430:1301::9227:79cc:76f2: seq=0 ttl=51 time=97.230 ms
|
||||
58
wwan/app/quectel-cm/src/log/usage_of_argument/m.txt
Normal file
58
wwan/app/quectel-cm/src/log/usage_of_argument/m.txt
Normal file
@ -0,0 +1,58 @@
|
||||
root@ZhuoTK:/# quectel-CM -n 1 -m 4 -s cmnet &
|
||||
[04-13_05:12:07:455] Quectel_QConnectManager_Linux_V1.6.0.25
|
||||
[04-13_05:12:07:458] Find /sys/bus/usb/devices/1-1.3 idVendor=0x2c7c idProduct=0x125, bus=0x001, dev=0x003
|
||||
[04-13_05:12:07:459] Auto find qmichannel = /dev/qcqmi0
|
||||
[04-13_05:12:07:459] Auto find usbnet_adapter = usb0
|
||||
[04-13_05:12:07:467] netcard driver = GobiNet, driver version = V1.6.2.13
|
||||
[04-13_05:12:07:467] qmap_mode = 4, qmap_version = 5, qmap_size = 4096, muxid = 0x84, qmap_netcard = usb0.4
|
||||
[04-13_05:12:07:467] Modem works in QMI mode
|
||||
[04-13_05:12:07:495] Get clientWDS = 7
|
||||
[04-13_05:12:07:529] Get clientDMS = 8
|
||||
[04-13_05:12:07:561] Get clientNAS = 9
|
||||
[04-13_05:12:07:591] Get clientUIM = 10
|
||||
[04-13_05:12:07:623] requestBaseBandVersion EC25EFAR06A11M4G
|
||||
[04-13_05:12:07:752] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[04-13_05:12:07:752] requestSetProfile[1] cmnet///0
|
||||
[04-13_05:12:07:817] requestGetProfile[1] cmnet///0
|
||||
[04-13_05:12:07:849] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: LTE
|
||||
[04-13_05:12:07:881] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[04-13_05:12:07:881] ifconfig usb0 down
|
||||
[04-13_05:12:07:892] ifconfig usb0.4 0.0.0.0
|
||||
[04-13_05:12:07:903] ifconfig usb0.4 down
|
||||
[04-13_05:12:07:944] requestSetupDataCall WdsConnectionIPv4Handle: 0x87265c40
|
||||
[ 52.020000] net usb0: link_state 0x0 -> 0x8
|
||||
[04-13_05:12:08:077] ifconfig usb0 up
|
||||
[04-13_05:12:08:096] ifconfig usb0.4 up
|
||||
[04-13_05:12:08:116] you are use OpenWrt?
|
||||
[04-13_05:12:08:116] should not calling udhcpc manually?
|
||||
[04-13_05:12:08:116] should modify /etc/config/network as below?
|
||||
[04-13_05:12:08:116] config interface wan
|
||||
[04-13_05:12:08:116] option ifname usb0.4
|
||||
[04-13_05:12:08:116] option proto dhcp
|
||||
[04-13_05:12:08:116] should use "/sbin/ifstaus wan" to check usb0.4 's status?
|
||||
[04-13_05:12:08:117] busybox udhcpc -f -n -q -t 5 -i usb0.4
|
||||
[04-13_05:12:08:134] udhcpc (v1.23.2) started
|
||||
[04-13_05:12:08:193] Sending discover...
|
||||
[04-13_05:12:08:197] Sending select for 10.84.241.180...
|
||||
[04-13_05:12:08:203] Lease of 10.84.241.180 obtained, lease time 7200
|
||||
[04-13_05:12:08:208] udhcpc: ifconfig usb0.4 10.84.241.180 netmask 255.255.255.248 broadcast +
|
||||
[04-13_05:12:08:221] udhcpc: setting default routers: 10.84.241.181
|
||||
|
||||
root@ZhuoTK:/# ifconfig usb0.4
|
||||
usb0.4 Link encap:Ethernet HWaddr 02:50:F4:00:00:00
|
||||
inet addr:10.84.241.180 Mask:255.255.255.248
|
||||
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:6 errors:0 dropped:0 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:612 (612.0 B) TX bytes:984 (984.0 B)
|
||||
|
||||
root@ZhuoTK:/# ip ro show
|
||||
default via 10.84.241.181 dev usb0.4
|
||||
10.84.241.176/29 dev usb0.4 proto kernel scope link src 10.84.241.180
|
||||
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=99.431 ms
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
#ifndef __QUECTEL_ENDIAN_H__
|
||||
#define __QUECTEL_ENDIAN_H__
|
||||
#include <endian.h>
|
||||
|
||||
#ifndef __QUECTEL_ENDIAN_H__
|
||||
#define __QUECTEL_ENDIAN_H__
|
||||
#include <endian.h>
|
||||
|
||||
#ifndef htole32
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define htole16(x) (uint16_t)(x)
|
||||
@ -36,17 +36,17 @@ static __inline uint64_t __bswap64(uint64_t __x) {
|
||||
#define le64toh(x) __bswap64(x)
|
||||
#define letoh64(x) __bswap64(x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define le16_to_cpu(x) le16toh((uint16_t)(x))
|
||||
#define le32_to_cpu(x) le32toh((uint32_t)(x))
|
||||
#define le64_to_cpu(x) le64toh((uint64_t)(x))
|
||||
#define cpu_to_le16(x) htole16((uint16_t)(x))
|
||||
#define cpu_to_le32(x) htole32((uint32_t)(x))
|
||||
#define cpu_to_le64(x) htole64((uint64_t)(x))
|
||||
|
||||
static __inline uint32_t ql_swap32(uint32_t __x) {
|
||||
#endif
|
||||
|
||||
#define le16_to_cpu(x) le16toh((uint16_t)(x))
|
||||
#define le32_to_cpu(x) le32toh((uint32_t)(x))
|
||||
#define le64_to_cpu(x) le64toh((uint64_t)(x))
|
||||
#define cpu_to_le16(x) htole16((uint16_t)(x))
|
||||
#define cpu_to_le32(x) htole32((uint32_t)(x))
|
||||
#define cpu_to_le64(x) htole64((uint64_t)(x))
|
||||
|
||||
static __inline uint32_t ql_swap32(uint32_t __x) {
|
||||
return (__x>>24) | (__x>>8&0xff00) | (__x<<8&0xff0000) | (__x<<24);
|
||||
}
|
||||
#endif //__QUECTEL_ENDIAN_H__
|
||||
|
||||
}
|
||||
#endif //__QUECTEL_ENDIAN_H__
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#ifndef __QUECTEL_LIST_H__
|
||||
#define __QUECTEL_LIST_H__
|
||||
struct qlistnode
|
||||
#ifndef __QUECTEL_LIST_H__
|
||||
#define __QUECTEL_LIST_H__
|
||||
struct qlistnode
|
||||
{
|
||||
struct qlistnode *next;
|
||||
struct qlistnode *prev;
|
||||
@ -14,8 +14,8 @@ struct qlistnode
|
||||
|
||||
#define qlist_empty(list) ((list) == (list)->next)
|
||||
#define qlist_head(list) ((list)->next)
|
||||
#define qlist_tail(list) ((list)->prev)
|
||||
|
||||
#define qlist_tail(list) ((list)->prev)
|
||||
|
||||
static void qlist_init(struct qlistnode *node)
|
||||
{
|
||||
node->next = node;
|
||||
@ -34,5 +34,5 @@ static void qlist_remove(struct qlistnode *item)
|
||||
{
|
||||
item->next->prev = item->prev;
|
||||
item->prev->next = item->next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -1,402 +1,402 @@
|
||||
/******************************************************************************
|
||||
@file qmap_bridge_mode.c
|
||||
@brief Connectivity bridge manager.
|
||||
|
||||
DESCRIPTION
|
||||
Connectivity Management Tool for USB network adapter of Quectel wireless cellular modules.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
None.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||
Quectel Wireless Solution Proprietary and Confidential.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
||||
#include "QMIThread.h"
|
||||
|
||||
static size_t ql_fread(const char *filename, void *buf, size_t size) {
|
||||
FILE *fp = fopen(filename , "r");
|
||||
size_t n = 0;
|
||||
|
||||
memset(buf, 0x00, size);
|
||||
|
||||
if (fp) {
|
||||
n = fread(buf, 1, size, fp);
|
||||
if (n <= 0 || n == size) {
|
||||
dbg_time("warnning: fail to fread(%s), fread=%zu, buf_size=%zu: (%s)", filename, n, size, strerror(errno));
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return n > 0 ? n : 0;
|
||||
}
|
||||
|
||||
static size_t ql_fwrite(const char *filename, const void *buf, size_t size) {
|
||||
FILE *fp = fopen(filename , "w");
|
||||
size_t n = 0;
|
||||
|
||||
if (fp) {
|
||||
n = fwrite(buf, 1, size, fp);
|
||||
if (n != size) {
|
||||
dbg_time("warnning: fail to fwrite(%s), fwrite=%zu, buf_size=%zu: (%s)", filename, n, size, strerror(errno));
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return n > 0 ? n : 0;
|
||||
}
|
||||
|
||||
int ql_bridge_mode_detect(PROFILE_T *profile) {
|
||||
const char *ifname = profile->qmapnet_adapter[0] ? profile->qmapnet_adapter : profile->usbnet_adapter;
|
||||
const char *driver;
|
||||
char bridge_mode[128];
|
||||
char bridge_ipv4[128];
|
||||
char ipv4[128];
|
||||
char buf[64];
|
||||
size_t n;
|
||||
int in_bridge = 0;
|
||||
|
||||
driver = profile->driver_name;
|
||||
snprintf(bridge_mode, sizeof(bridge_mode), "/sys/class/net/%s/bridge_mode", ifname);
|
||||
snprintf(bridge_ipv4, sizeof(bridge_ipv4), "/sys/class/net/%s/bridge_ipv4", ifname);
|
||||
|
||||
if (access(bridge_ipv4, R_OK)) {
|
||||
if (errno != ENOENT) {
|
||||
dbg_time("fail to access %s, errno: %d (%s)", bridge_mode, errno, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
snprintf(bridge_mode, sizeof(bridge_mode), "/sys/module/%s/parameters/bridge_mode", driver);
|
||||
snprintf(bridge_ipv4, sizeof(bridge_ipv4), "/sys/module/%s/parameters/bridge_ipv4", driver);
|
||||
|
||||
if (access(bridge_mode, R_OK)) {
|
||||
if (errno != ENOENT) {
|
||||
dbg_time("fail to access %s, errno: %d (%s)", bridge_mode, errno, strerror(errno));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
n = ql_fread(bridge_mode, buf, sizeof(buf));
|
||||
if (n > 0) {
|
||||
in_bridge = (buf[0] != '0');
|
||||
}
|
||||
if (!in_bridge)
|
||||
return 0;
|
||||
|
||||
memset(ipv4, 0, sizeof(ipv4));
|
||||
|
||||
if (strstr(bridge_ipv4, "/sys/class/net/") || profile->qmap_mode == 0 || profile->qmap_mode == 1) {
|
||||
snprintf(ipv4, sizeof(ipv4), "0x%x", profile->ipv4.Address);
|
||||
dbg_time("echo '%s' > %s", ipv4, bridge_ipv4);
|
||||
ql_fwrite(bridge_ipv4, ipv4, strlen(ipv4));
|
||||
}
|
||||
else {
|
||||
snprintf(ipv4, sizeof(ipv4), "0x%x:%d", profile->ipv4.Address, profile->muxid);
|
||||
dbg_time("echo '%s' > %s", ipv4, bridge_ipv4);
|
||||
ql_fwrite(bridge_ipv4, ipv4, strlen(ipv4));
|
||||
}
|
||||
|
||||
return in_bridge;
|
||||
}
|
||||
|
||||
int ql_enable_qmi_wwan_rawip_mode(PROFILE_T *profile) {
|
||||
char filename[256];
|
||||
char buf[4];
|
||||
size_t n;
|
||||
FILE *fp;
|
||||
|
||||
if (!qmidev_is_qmiwwan(profile->qmichannel))
|
||||
return 0;
|
||||
|
||||
snprintf(filename, sizeof(filename), "/sys/class/net/%s/qmi/rawip", profile->usbnet_adapter);
|
||||
n = ql_fread(filename, buf, sizeof(buf));
|
||||
|
||||
if (n == 0)
|
||||
return 0;
|
||||
|
||||
if (buf[0] == '1' || buf[0] == 'Y')
|
||||
return 0;
|
||||
|
||||
fp = fopen(filename , "w");
|
||||
if (fp == NULL) {
|
||||
dbg_time("Fail to fopen(%s, \"w\"), errno: %d (%s)", filename, errno, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
buf[0] = 'Y';
|
||||
n = fwrite(buf, 1, 1, fp);
|
||||
if (n != 1) {
|
||||
dbg_time("Fail to fwrite(%s), errno: %d (%s)", filename, errno, strerror(errno));
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ql_driver_type_detect(PROFILE_T *profile) {
|
||||
if (qmidev_is_gobinet(profile->qmichannel)) {
|
||||
profile->qmi_ops = &gobi_qmidev_ops;
|
||||
}
|
||||
else {
|
||||
profile->qmi_ops = &qmiwwan_qmidev_ops;
|
||||
}
|
||||
qmidev_send = profile->qmi_ops->send;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ql_set_driver_bridge_mode(PROFILE_T *profile) {
|
||||
char enable[16];
|
||||
char filename[256];
|
||||
|
||||
if(profile->qmap_mode)
|
||||
snprintf(filename, sizeof(filename), "/sys/class/net/%s/bridge_mode", profile->qmapnet_adapter);
|
||||
else
|
||||
snprintf(filename, sizeof(filename), "/sys/class/net/%s/bridge_mode", profile->usbnet_adapter);
|
||||
snprintf(enable, sizeof(enable), "%02d\n", profile->enable_bridge);
|
||||
ql_fwrite(filename, enable, sizeof(enable));
|
||||
}
|
||||
|
||||
static int ql_qmi_qmap_mode_detect(PROFILE_T *profile) {
|
||||
char buf[128];
|
||||
int n;
|
||||
struct {
|
||||
char filename[255 * 2];
|
||||
char linkname[255 * 2];
|
||||
} *pl;
|
||||
|
||||
pl = (typeof(pl)) malloc(sizeof(*pl));
|
||||
|
||||
snprintf(pl->linkname, sizeof(pl->linkname), "/sys/class/net/%s/device/driver", profile->usbnet_adapter);
|
||||
n = readlink(pl->linkname, pl->filename, sizeof(pl->filename));
|
||||
pl->filename[n] = '\0';
|
||||
while (pl->filename[n] != '/')
|
||||
n--;
|
||||
strncpy(profile->driver_name, &pl->filename[n+1], sizeof(profile->driver_name) - 1);
|
||||
|
||||
ql_get_driver_rmnet_info(profile, &profile->rmnet_info);
|
||||
if (profile->rmnet_info.size) {
|
||||
profile->qmap_mode = profile->rmnet_info.qmap_mode;
|
||||
if (profile->qmap_mode) {
|
||||
int offset_id = (profile->muxid == 0)? profile->pdp - 1 : profile->muxid - 0x81;
|
||||
|
||||
if (profile->qmap_mode == 1)
|
||||
offset_id = 0;
|
||||
profile->muxid = profile->rmnet_info.mux_id[offset_id];
|
||||
strncpy(profile->qmapnet_adapter, profile->rmnet_info.ifname[offset_id], sizeof(profile->qmapnet_adapter) - 1);
|
||||
profile->qmap_size = profile->rmnet_info.rx_urb_size;
|
||||
profile->qmap_version = profile->rmnet_info.qmap_version;
|
||||
}
|
||||
|
||||
goto _out;
|
||||
}
|
||||
|
||||
snprintf(pl->filename, sizeof(pl->filename), "/sys/class/net/%s/qmap_mode", profile->usbnet_adapter);
|
||||
if (access(pl->filename, R_OK)) {
|
||||
if (errno != ENOENT) {
|
||||
dbg_time("fail to access %s, errno: %d (%s)", pl->filename, errno, strerror(errno));
|
||||
goto _out;
|
||||
}
|
||||
|
||||
snprintf(pl->filename, sizeof(pl->filename), "/sys/module/%s/parameters/qmap_mode", profile->driver_name);
|
||||
if (access(pl->filename, R_OK)) {
|
||||
if (errno != ENOENT) {
|
||||
dbg_time("fail to access %s, errno: %d (%s)", pl->filename, errno, strerror(errno));
|
||||
goto _out;
|
||||
}
|
||||
|
||||
snprintf(pl->filename, sizeof(pl->filename), "/sys/class/net/%s/device/driver/module/parameters/qmap_mode", profile->usbnet_adapter);
|
||||
if (access(pl->filename, R_OK)) {
|
||||
if (errno != ENOENT) {
|
||||
dbg_time("fail to access %s, errno: %d (%s)", pl->filename, errno, strerror(errno));
|
||||
goto _out;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!access(pl->filename, R_OK)) {
|
||||
n = ql_fread(pl->filename, buf, sizeof(buf));
|
||||
if (n > 0) {
|
||||
profile->qmap_mode = atoi(buf);
|
||||
|
||||
if (profile->qmap_mode > 1) {
|
||||
if(!profile->muxid)
|
||||
profile->muxid = profile->pdp + 0x80; //muxis is 0x8X for PDN-X
|
||||
snprintf(profile->qmapnet_adapter, sizeof(profile->qmapnet_adapter),
|
||||
"%.16s.%d", profile->usbnet_adapter, profile->muxid - 0x80);
|
||||
} if (profile->qmap_mode == 1) {
|
||||
profile->muxid = 0x81;
|
||||
strncpy(profile->qmapnet_adapter, profile->usbnet_adapter, sizeof(profile->qmapnet_adapter));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (qmidev_is_qmiwwan(profile->qmichannel)) {
|
||||
snprintf(pl->filename, sizeof(pl->filename), "/sys/class/net/qmimux%d", profile->pdp - 1);
|
||||
if (access(pl->filename, R_OK)) {
|
||||
if (errno != ENOENT) {
|
||||
dbg_time("fail to access %s, errno: %d (%s)", pl->filename, errno, strerror(errno));
|
||||
}
|
||||
goto _out;
|
||||
}
|
||||
|
||||
//upstream Kernel Style QMAP qmi_wwan.c
|
||||
snprintf(pl->filename, sizeof(pl->filename), "/sys/class/net/%s/qmi/add_mux", profile->usbnet_adapter);
|
||||
n = ql_fread(pl->filename, buf, sizeof(buf));
|
||||
if (n >= 5) {
|
||||
dbg_time("If use QMAP by /sys/class/net/%s/qmi/add_mux", profile->usbnet_adapter);
|
||||
#if 1
|
||||
dbg_time("Please set mtu of wwan0 >= max dl qmap packet size");
|
||||
#else
|
||||
dbg_time("File:%s Line:%d Please make sure add next patch to qmi_wwan.c", __func__, __LINE__);
|
||||
/*
|
||||
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
|
||||
index 74bebbd..db8a777 100644
|
||||
--- a/drivers/net/usb/qmi_wwan.c
|
||||
+++ b/drivers/net/usb/qmi_wwan.c
|
||||
@@ -379,6 +379,24 @@ static ssize_t add_mux_store(struct device *d, struct device_attribute *attr, c
|
||||
if (!ret) {
|
||||
info->flags |= QMI_WWAN_FLAG_MUX;
|
||||
ret = len;
|
||||
+#if 1 //Add by Quectel
|
||||
+ if (le16_to_cpu(dev->udev->descriptor.idVendor) == 0x2c7c) {
|
||||
+ int idProduct = le16_to_cpu(dev->udev->descriptor.idProduct);
|
||||
+
|
||||
+ if (idProduct == 0x0121 || idProduct == 0x0125 || idProduct == 0x0435) //MDM9x07
|
||||
+ dev->rx_urb_size = 4*1024;
|
||||
+ else if (idProduct == 0x0306) //MDM9x40
|
||||
+ dev->rx_urb_size = 16*1024;
|
||||
+ else if (idProduct == 0x0512) //SDX20
|
||||
+ dev->rx_urb_size = 32*1024;
|
||||
+ else if (idProduct == 0x0620) //SDX24
|
||||
+ dev->rx_urb_size = 32*1024;
|
||||
+ else if (idProduct == 0x0800) //SDX55
|
||||
+ dev->rx_urb_size = 32*1024;
|
||||
+ else
|
||||
+ dev->rx_urb_size = 32*1024;
|
||||
+ }
|
||||
+#endif
|
||||
}
|
||||
err:
|
||||
rtnl_unlock();
|
||||
*/
|
||||
#endif
|
||||
profile->qmap_mode = n/5; //0x11\n0x22\n0x33\n
|
||||
if (profile->qmap_mode > 1) {
|
||||
//PDN-X map to qmimux-X
|
||||
if(!profile->muxid) {
|
||||
profile->muxid = (buf[5*(profile->pdp - 1) + 2] - '0')*16 + (buf[5*(profile->pdp - 1) + 3] - '0');
|
||||
snprintf(profile->qmapnet_adapter, sizeof(profile->qmapnet_adapter), "qmimux%d", profile->pdp - 1);
|
||||
} else {
|
||||
profile->muxid = (buf[5*(profile->muxid - 0x81) + 2] - '0')*16 + (buf[5*(profile->muxid - 0x81) + 3] - '0');
|
||||
snprintf(profile->qmapnet_adapter, sizeof(profile->qmapnet_adapter), "qmimux%d", profile->muxid - 0x81);
|
||||
}
|
||||
} else if (profile->qmap_mode == 1) {
|
||||
profile->muxid = (buf[5*0 + 2] - '0')*16 + (buf[5*0 + 3] - '0');
|
||||
snprintf(profile->qmapnet_adapter, sizeof(profile->qmapnet_adapter),
|
||||
"qmimux%d", 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_out:
|
||||
if (profile->qmap_mode) {
|
||||
if (profile->qmap_size == 0) {
|
||||
profile->qmap_size = 16*1024;
|
||||
snprintf(pl->filename, sizeof(pl->filename), "/sys/class/net/%s/qmap_size", profile->usbnet_adapter);
|
||||
if (!access(pl->filename, R_OK)) {
|
||||
size_t n;
|
||||
char buf[32];
|
||||
n = ql_fread(pl->filename, buf, sizeof(buf));
|
||||
if (n > 0) {
|
||||
profile->qmap_size = atoi(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (profile->qmap_version == 0) {
|
||||
profile->qmap_version = WDA_DL_DATA_AGG_QMAP_ENABLED;
|
||||
}
|
||||
|
||||
dbg_time("qmap_mode = %d, qmap_version = %d, qmap_size = %d, muxid = 0x%02x, qmap_netcard = %s",
|
||||
profile->qmap_mode, profile->qmap_version, profile->qmap_size, profile->muxid, profile->qmapnet_adapter);
|
||||
}
|
||||
ql_set_driver_bridge_mode(profile);
|
||||
free(pl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ql_mbim_usb_vlan_mode_detect(PROFILE_T *profile) {
|
||||
char tmp[128];
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "/sys/class/net/%s.%d", profile->usbnet_adapter, profile->pdp);
|
||||
if (!access(tmp, F_OK)) {
|
||||
profile->qmap_mode = 4;
|
||||
profile->muxid = profile->pdp;
|
||||
no_trunc_strncpy(profile->qmapnet_adapter, tmp + strlen("/sys/class/net/"), sizeof(profile->qmapnet_adapter) - 1);
|
||||
|
||||
dbg_time("mbim_qmap_mode = %d, vlan_id = 0x%02x, qmap_netcard = %s",
|
||||
profile->qmap_mode, profile->muxid, profile->qmapnet_adapter);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ql_mbim_mhi_qmap_mode_detect(PROFILE_T *profile) {
|
||||
ql_get_driver_rmnet_info(profile, &profile->rmnet_info);
|
||||
if (profile->rmnet_info.size) {
|
||||
profile->qmap_mode = profile->rmnet_info.qmap_mode;
|
||||
if (profile->qmap_mode) {
|
||||
int offset_id = profile->pdp - 1;
|
||||
|
||||
if (profile->qmap_mode == 1)
|
||||
offset_id = 0;
|
||||
profile->muxid = profile->pdp;
|
||||
strcpy(profile->qmapnet_adapter, profile->rmnet_info.ifname[offset_id]);
|
||||
profile->qmap_size = profile->rmnet_info.rx_urb_size;
|
||||
profile->qmap_version = profile->rmnet_info.qmap_version;
|
||||
|
||||
dbg_time("mbim_qmap_mode = %d, vlan_id = 0x%02x, qmap_netcard = %s",
|
||||
profile->qmap_mode, profile->muxid, profile->qmapnet_adapter);
|
||||
}
|
||||
|
||||
goto _out;
|
||||
}
|
||||
|
||||
_out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ql_qmap_mode_detect(PROFILE_T *profile) {
|
||||
if (profile->software_interface == SOFTWARE_MBIM) {
|
||||
if (profile->hardware_interface == HARDWARE_USB)
|
||||
return ql_mbim_usb_vlan_mode_detect(profile);
|
||||
else if (profile->hardware_interface == HARDWARE_PCIE)
|
||||
return ql_mbim_mhi_qmap_mode_detect(profile);
|
||||
} else if (profile->software_interface == SOFTWARE_QMI) {
|
||||
return ql_qmi_qmap_mode_detect(profile);
|
||||
}
|
||||
#ifdef CONFIG_QRTR
|
||||
else if(profile->software_interface == SOFTWARE_QRTR) {
|
||||
char tmp[128];
|
||||
|
||||
profile->qmap_mode = 4;
|
||||
profile->qmap_version = WDA_DL_DATA_AGG_QMAP_V5_ENABLED;
|
||||
profile->qmap_size = 31*1024;
|
||||
profile->muxid = 0x80 | profile->pdp;
|
||||
snprintf(profile->qmapnet_adapter, sizeof(profile->qmapnet_adapter), "rmnet_data%d", profile->muxid&0xF);
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "/sys/class/net/%s", profile->qmapnet_adapter);
|
||||
if (access(tmp, F_OK)) {
|
||||
rtrmnet_ctl_create_vnd(profile->usbnet_adapter, profile->qmapnet_adapter,
|
||||
profile->muxid, profile->qmap_version, 11, 4096);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
/******************************************************************************
|
||||
@file qmap_bridge_mode.c
|
||||
@brief Connectivity bridge manager.
|
||||
|
||||
DESCRIPTION
|
||||
Connectivity Management Tool for USB network adapter of Quectel wireless cellular modules.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
None.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||
Quectel Wireless Solution Proprietary and Confidential.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
||||
#include "QMIThread.h"
|
||||
|
||||
static size_t ql_fread(const char *filename, void *buf, size_t size) {
|
||||
FILE *fp = fopen(filename , "r");
|
||||
size_t n = 0;
|
||||
|
||||
memset(buf, 0x00, size);
|
||||
|
||||
if (fp) {
|
||||
n = fread(buf, 1, size, fp);
|
||||
if (n <= 0 || n == size) {
|
||||
dbg_time("warnning: fail to fread(%s), fread=%zu, buf_size=%zu: (%s)", filename, n, size, strerror(errno));
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return n > 0 ? n : 0;
|
||||
}
|
||||
|
||||
static size_t ql_fwrite(const char *filename, const void *buf, size_t size) {
|
||||
FILE *fp = fopen(filename , "w");
|
||||
size_t n = 0;
|
||||
|
||||
if (fp) {
|
||||
n = fwrite(buf, 1, size, fp);
|
||||
if (n != size) {
|
||||
dbg_time("warnning: fail to fwrite(%s), fwrite=%zu, buf_size=%zu: (%s)", filename, n, size, strerror(errno));
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return n > 0 ? n : 0;
|
||||
}
|
||||
|
||||
int ql_bridge_mode_detect(PROFILE_T *profile) {
|
||||
const char *ifname = profile->qmapnet_adapter[0] ? profile->qmapnet_adapter : profile->usbnet_adapter;
|
||||
const char *driver;
|
||||
char bridge_mode[128];
|
||||
char bridge_ipv4[128];
|
||||
char ipv4[128];
|
||||
char buf[64];
|
||||
size_t n;
|
||||
int in_bridge = 0;
|
||||
|
||||
driver = profile->driver_name;
|
||||
snprintf(bridge_mode, sizeof(bridge_mode), "/sys/class/net/%s/bridge_mode", ifname);
|
||||
snprintf(bridge_ipv4, sizeof(bridge_ipv4), "/sys/class/net/%s/bridge_ipv4", ifname);
|
||||
|
||||
if (access(bridge_ipv4, R_OK)) {
|
||||
if (errno != ENOENT) {
|
||||
dbg_time("fail to access %s, errno: %d (%s)", bridge_mode, errno, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
snprintf(bridge_mode, sizeof(bridge_mode), "/sys/module/%s/parameters/bridge_mode", driver);
|
||||
snprintf(bridge_ipv4, sizeof(bridge_ipv4), "/sys/module/%s/parameters/bridge_ipv4", driver);
|
||||
|
||||
if (access(bridge_mode, R_OK)) {
|
||||
if (errno != ENOENT) {
|
||||
dbg_time("fail to access %s, errno: %d (%s)", bridge_mode, errno, strerror(errno));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
n = ql_fread(bridge_mode, buf, sizeof(buf));
|
||||
if (n > 0) {
|
||||
in_bridge = (buf[0] != '0');
|
||||
}
|
||||
if (!in_bridge)
|
||||
return 0;
|
||||
|
||||
memset(ipv4, 0, sizeof(ipv4));
|
||||
|
||||
if (strstr(bridge_ipv4, "/sys/class/net/") || profile->qmap_mode == 0 || profile->qmap_mode == 1) {
|
||||
snprintf(ipv4, sizeof(ipv4), "0x%x", profile->ipv4.Address);
|
||||
dbg_time("echo '%s' > %s", ipv4, bridge_ipv4);
|
||||
ql_fwrite(bridge_ipv4, ipv4, strlen(ipv4));
|
||||
}
|
||||
else {
|
||||
snprintf(ipv4, sizeof(ipv4), "0x%x:%d", profile->ipv4.Address, profile->muxid);
|
||||
dbg_time("echo '%s' > %s", ipv4, bridge_ipv4);
|
||||
ql_fwrite(bridge_ipv4, ipv4, strlen(ipv4));
|
||||
}
|
||||
|
||||
return in_bridge;
|
||||
}
|
||||
|
||||
int ql_enable_qmi_wwan_rawip_mode(PROFILE_T *profile) {
|
||||
char filename[256];
|
||||
char buf[4];
|
||||
size_t n;
|
||||
FILE *fp;
|
||||
|
||||
if (!qmidev_is_qmiwwan(profile->qmichannel))
|
||||
return 0;
|
||||
|
||||
snprintf(filename, sizeof(filename), "/sys/class/net/%s/qmi/rawip", profile->usbnet_adapter);
|
||||
n = ql_fread(filename, buf, sizeof(buf));
|
||||
|
||||
if (n == 0)
|
||||
return 0;
|
||||
|
||||
if (buf[0] == '1' || buf[0] == 'Y')
|
||||
return 0;
|
||||
|
||||
fp = fopen(filename , "w");
|
||||
if (fp == NULL) {
|
||||
dbg_time("Fail to fopen(%s, \"w\"), errno: %d (%s)", filename, errno, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
buf[0] = 'Y';
|
||||
n = fwrite(buf, 1, 1, fp);
|
||||
if (n != 1) {
|
||||
dbg_time("Fail to fwrite(%s), errno: %d (%s)", filename, errno, strerror(errno));
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ql_driver_type_detect(PROFILE_T *profile) {
|
||||
if (qmidev_is_gobinet(profile->qmichannel)) {
|
||||
profile->qmi_ops = &gobi_qmidev_ops;
|
||||
}
|
||||
else {
|
||||
profile->qmi_ops = &qmiwwan_qmidev_ops;
|
||||
}
|
||||
qmidev_send = profile->qmi_ops->send;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ql_set_driver_bridge_mode(PROFILE_T *profile) {
|
||||
char enable[16];
|
||||
char filename[256];
|
||||
|
||||
if(profile->qmap_mode)
|
||||
snprintf(filename, sizeof(filename), "/sys/class/net/%s/bridge_mode", profile->qmapnet_adapter);
|
||||
else
|
||||
snprintf(filename, sizeof(filename), "/sys/class/net/%s/bridge_mode", profile->usbnet_adapter);
|
||||
snprintf(enable, sizeof(enable), "%02d\n", profile->enable_bridge);
|
||||
ql_fwrite(filename, enable, sizeof(enable));
|
||||
}
|
||||
|
||||
static int ql_qmi_qmap_mode_detect(PROFILE_T *profile) {
|
||||
char buf[128];
|
||||
int n;
|
||||
struct {
|
||||
char filename[255 * 2];
|
||||
char linkname[255 * 2];
|
||||
} *pl;
|
||||
|
||||
pl = (typeof(pl)) malloc(sizeof(*pl));
|
||||
|
||||
snprintf(pl->linkname, sizeof(pl->linkname), "/sys/class/net/%s/device/driver", profile->usbnet_adapter);
|
||||
n = readlink(pl->linkname, pl->filename, sizeof(pl->filename));
|
||||
pl->filename[n] = '\0';
|
||||
while (pl->filename[n] != '/')
|
||||
n--;
|
||||
strncpy(profile->driver_name, &pl->filename[n+1], sizeof(profile->driver_name) - 1);
|
||||
|
||||
ql_get_driver_rmnet_info(profile, &profile->rmnet_info);
|
||||
if (profile->rmnet_info.size) {
|
||||
profile->qmap_mode = profile->rmnet_info.qmap_mode;
|
||||
if (profile->qmap_mode) {
|
||||
int offset_id = (profile->muxid == 0)? profile->pdp - 1 : profile->muxid - 0x81;
|
||||
|
||||
if (profile->qmap_mode == 1)
|
||||
offset_id = 0;
|
||||
profile->muxid = profile->rmnet_info.mux_id[offset_id];
|
||||
strncpy(profile->qmapnet_adapter, profile->rmnet_info.ifname[offset_id], sizeof(profile->qmapnet_adapter) - 1);
|
||||
profile->qmap_size = profile->rmnet_info.rx_urb_size;
|
||||
profile->qmap_version = profile->rmnet_info.qmap_version;
|
||||
}
|
||||
|
||||
goto _out;
|
||||
}
|
||||
|
||||
snprintf(pl->filename, sizeof(pl->filename), "/sys/class/net/%s/qmap_mode", profile->usbnet_adapter);
|
||||
if (access(pl->filename, R_OK)) {
|
||||
if (errno != ENOENT) {
|
||||
dbg_time("fail to access %s, errno: %d (%s)", pl->filename, errno, strerror(errno));
|
||||
goto _out;
|
||||
}
|
||||
|
||||
snprintf(pl->filename, sizeof(pl->filename), "/sys/module/%s/parameters/qmap_mode", profile->driver_name);
|
||||
if (access(pl->filename, R_OK)) {
|
||||
if (errno != ENOENT) {
|
||||
dbg_time("fail to access %s, errno: %d (%s)", pl->filename, errno, strerror(errno));
|
||||
goto _out;
|
||||
}
|
||||
|
||||
snprintf(pl->filename, sizeof(pl->filename), "/sys/class/net/%s/device/driver/module/parameters/qmap_mode", profile->usbnet_adapter);
|
||||
if (access(pl->filename, R_OK)) {
|
||||
if (errno != ENOENT) {
|
||||
dbg_time("fail to access %s, errno: %d (%s)", pl->filename, errno, strerror(errno));
|
||||
goto _out;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!access(pl->filename, R_OK)) {
|
||||
n = ql_fread(pl->filename, buf, sizeof(buf));
|
||||
if (n > 0) {
|
||||
profile->qmap_mode = atoi(buf);
|
||||
|
||||
if (profile->qmap_mode > 1) {
|
||||
if(!profile->muxid)
|
||||
profile->muxid = profile->pdp + 0x80; //muxis is 0x8X for PDN-X
|
||||
snprintf(profile->qmapnet_adapter, sizeof(profile->qmapnet_adapter),
|
||||
"%.16s.%d", profile->usbnet_adapter, profile->muxid - 0x80);
|
||||
} if (profile->qmap_mode == 1) {
|
||||
profile->muxid = 0x81;
|
||||
strncpy(profile->qmapnet_adapter, profile->usbnet_adapter, sizeof(profile->qmapnet_adapter));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (qmidev_is_qmiwwan(profile->qmichannel)) {
|
||||
snprintf(pl->filename, sizeof(pl->filename), "/sys/class/net/qmimux%d", profile->pdp - 1);
|
||||
if (access(pl->filename, R_OK)) {
|
||||
if (errno != ENOENT) {
|
||||
dbg_time("fail to access %s, errno: %d (%s)", pl->filename, errno, strerror(errno));
|
||||
}
|
||||
goto _out;
|
||||
}
|
||||
|
||||
//upstream Kernel Style QMAP qmi_wwan.c
|
||||
snprintf(pl->filename, sizeof(pl->filename), "/sys/class/net/%s/qmi/add_mux", profile->usbnet_adapter);
|
||||
n = ql_fread(pl->filename, buf, sizeof(buf));
|
||||
if (n >= 5) {
|
||||
dbg_time("If use QMAP by /sys/class/net/%s/qmi/add_mux", profile->usbnet_adapter);
|
||||
#if 1
|
||||
dbg_time("Please set mtu of wwan0 >= max dl qmap packet size");
|
||||
#else
|
||||
dbg_time("File:%s Line:%d Please make sure add next patch to qmi_wwan.c", __func__, __LINE__);
|
||||
/*
|
||||
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
|
||||
index 74bebbd..db8a777 100644
|
||||
--- a/drivers/net/usb/qmi_wwan.c
|
||||
+++ b/drivers/net/usb/qmi_wwan.c
|
||||
@@ -379,6 +379,24 @@ static ssize_t add_mux_store(struct device *d, struct device_attribute *attr, c
|
||||
if (!ret) {
|
||||
info->flags |= QMI_WWAN_FLAG_MUX;
|
||||
ret = len;
|
||||
+#if 1 //Add by Quectel
|
||||
+ if (le16_to_cpu(dev->udev->descriptor.idVendor) == 0x2c7c) {
|
||||
+ int idProduct = le16_to_cpu(dev->udev->descriptor.idProduct);
|
||||
+
|
||||
+ if (idProduct == 0x0121 || idProduct == 0x0125 || idProduct == 0x0435) //MDM9x07
|
||||
+ dev->rx_urb_size = 4*1024;
|
||||
+ else if (idProduct == 0x0306) //MDM9x40
|
||||
+ dev->rx_urb_size = 16*1024;
|
||||
+ else if (idProduct == 0x0512) //SDX20
|
||||
+ dev->rx_urb_size = 32*1024;
|
||||
+ else if (idProduct == 0x0620) //SDX24
|
||||
+ dev->rx_urb_size = 32*1024;
|
||||
+ else if (idProduct == 0x0800) //SDX55
|
||||
+ dev->rx_urb_size = 32*1024;
|
||||
+ else
|
||||
+ dev->rx_urb_size = 32*1024;
|
||||
+ }
|
||||
+#endif
|
||||
}
|
||||
err:
|
||||
rtnl_unlock();
|
||||
*/
|
||||
#endif
|
||||
profile->qmap_mode = n/5; //0x11\n0x22\n0x33\n
|
||||
if (profile->qmap_mode > 1) {
|
||||
//PDN-X map to qmimux-X
|
||||
if(!profile->muxid) {
|
||||
profile->muxid = (buf[5*(profile->pdp - 1) + 2] - '0')*16 + (buf[5*(profile->pdp - 1) + 3] - '0');
|
||||
snprintf(profile->qmapnet_adapter, sizeof(profile->qmapnet_adapter), "qmimux%d", profile->pdp - 1);
|
||||
} else {
|
||||
profile->muxid = (buf[5*(profile->muxid - 0x81) + 2] - '0')*16 + (buf[5*(profile->muxid - 0x81) + 3] - '0');
|
||||
snprintf(profile->qmapnet_adapter, sizeof(profile->qmapnet_adapter), "qmimux%d", profile->muxid - 0x81);
|
||||
}
|
||||
} else if (profile->qmap_mode == 1) {
|
||||
profile->muxid = (buf[5*0 + 2] - '0')*16 + (buf[5*0 + 3] - '0');
|
||||
snprintf(profile->qmapnet_adapter, sizeof(profile->qmapnet_adapter),
|
||||
"qmimux%d", 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_out:
|
||||
if (profile->qmap_mode) {
|
||||
if (profile->qmap_size == 0) {
|
||||
profile->qmap_size = 16*1024;
|
||||
snprintf(pl->filename, sizeof(pl->filename), "/sys/class/net/%s/qmap_size", profile->usbnet_adapter);
|
||||
if (!access(pl->filename, R_OK)) {
|
||||
size_t n;
|
||||
char buf[32];
|
||||
n = ql_fread(pl->filename, buf, sizeof(buf));
|
||||
if (n > 0) {
|
||||
profile->qmap_size = atoi(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (profile->qmap_version == 0) {
|
||||
profile->qmap_version = WDA_DL_DATA_AGG_QMAP_ENABLED;
|
||||
}
|
||||
|
||||
dbg_time("qmap_mode = %d, qmap_version = %d, qmap_size = %d, muxid = 0x%02x, qmap_netcard = %s",
|
||||
profile->qmap_mode, profile->qmap_version, profile->qmap_size, profile->muxid, profile->qmapnet_adapter);
|
||||
}
|
||||
ql_set_driver_bridge_mode(profile);
|
||||
free(pl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ql_mbim_usb_vlan_mode_detect(PROFILE_T *profile) {
|
||||
char tmp[128];
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "/sys/class/net/%s.%d", profile->usbnet_adapter, profile->pdp);
|
||||
if (!access(tmp, F_OK)) {
|
||||
profile->qmap_mode = 4;
|
||||
profile->muxid = profile->pdp;
|
||||
no_trunc_strncpy(profile->qmapnet_adapter, tmp + strlen("/sys/class/net/"), sizeof(profile->qmapnet_adapter) - 1);
|
||||
|
||||
dbg_time("mbim_qmap_mode = %d, vlan_id = 0x%02x, qmap_netcard = %s",
|
||||
profile->qmap_mode, profile->muxid, profile->qmapnet_adapter);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ql_mbim_mhi_qmap_mode_detect(PROFILE_T *profile) {
|
||||
ql_get_driver_rmnet_info(profile, &profile->rmnet_info);
|
||||
if (profile->rmnet_info.size) {
|
||||
profile->qmap_mode = profile->rmnet_info.qmap_mode;
|
||||
if (profile->qmap_mode) {
|
||||
int offset_id = profile->pdp - 1;
|
||||
|
||||
if (profile->qmap_mode == 1)
|
||||
offset_id = 0;
|
||||
profile->muxid = profile->pdp;
|
||||
strcpy(profile->qmapnet_adapter, profile->rmnet_info.ifname[offset_id]);
|
||||
profile->qmap_size = profile->rmnet_info.rx_urb_size;
|
||||
profile->qmap_version = profile->rmnet_info.qmap_version;
|
||||
|
||||
dbg_time("mbim_qmap_mode = %d, vlan_id = 0x%02x, qmap_netcard = %s",
|
||||
profile->qmap_mode, profile->muxid, profile->qmapnet_adapter);
|
||||
}
|
||||
|
||||
goto _out;
|
||||
}
|
||||
|
||||
_out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ql_qmap_mode_detect(PROFILE_T *profile) {
|
||||
if (profile->software_interface == SOFTWARE_MBIM) {
|
||||
if (profile->hardware_interface == HARDWARE_USB)
|
||||
return ql_mbim_usb_vlan_mode_detect(profile);
|
||||
else if (profile->hardware_interface == HARDWARE_PCIE)
|
||||
return ql_mbim_mhi_qmap_mode_detect(profile);
|
||||
} else if (profile->software_interface == SOFTWARE_QMI) {
|
||||
return ql_qmi_qmap_mode_detect(profile);
|
||||
}
|
||||
#ifdef CONFIG_QRTR
|
||||
else if(profile->software_interface == SOFTWARE_QRTR) {
|
||||
char tmp[128];
|
||||
|
||||
profile->qmap_mode = 4;
|
||||
profile->qmap_version = WDA_DL_DATA_AGG_QMAP_V5_ENABLED;
|
||||
profile->qmap_size = 31*1024;
|
||||
profile->muxid = 0x80 | profile->pdp;
|
||||
snprintf(profile->qmapnet_adapter, sizeof(profile->qmapnet_adapter), "rmnet_data%d", profile->muxid&0xF);
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "/sys/class/net/%s", profile->qmapnet_adapter);
|
||||
if (access(tmp, F_OK)) {
|
||||
rtrmnet_ctl_create_vnd(profile->usbnet_adapter, profile->qmapnet_adapter,
|
||||
profile->muxid, profile->qmap_version, 11, 4096);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,342 +1,342 @@
|
||||
//https://source.codeaurora.org/quic/la/platform/vendor/qcom-opensource/dataservices/tree/rmnetctl
|
||||
#include <sys/socket.h>
|
||||
#include <stdint.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/gen_stats.h>
|
||||
#include <net/if.h>
|
||||
#include <asm/types.h>
|
||||
#include <linux/rmnet_data.h>
|
||||
|
||||
#define RMNETCTL_SUCCESS 0
|
||||
#define RMNETCTL_LIB_ERR 1
|
||||
#define RMNETCTL_KERNEL_ERR 2
|
||||
#define RMNETCTL_INVALID_ARG 3
|
||||
|
||||
enum rmnetctl_error_codes_e {
|
||||
RMNETCTL_API_SUCCESS = 0,
|
||||
|
||||
RMNETCTL_API_FIRST_ERR = 1,
|
||||
RMNETCTL_API_ERR_MESSAGE_SEND = 3,
|
||||
RMNETCTL_API_ERR_MESSAGE_RECEIVE = 4,
|
||||
|
||||
RMNETCTL_INIT_FIRST_ERR = 5,
|
||||
RMNETCTL_INIT_ERR_PROCESS_ID = RMNETCTL_INIT_FIRST_ERR,
|
||||
RMNETCTL_INIT_ERR_NETLINK_FD = 6,
|
||||
RMNETCTL_INIT_ERR_BIND = 7,
|
||||
|
||||
RMNETCTL_API_SECOND_ERR = 9,
|
||||
RMNETCTL_API_ERR_HNDL_INVALID = RMNETCTL_API_SECOND_ERR,
|
||||
RMNETCTL_API_ERR_RETURN_TYPE = 13,
|
||||
};
|
||||
|
||||
struct rmnetctl_hndl_s {
|
||||
uint32_t pid;
|
||||
uint32_t transaction_id;
|
||||
int netlink_fd;
|
||||
struct sockaddr_nl src_addr, dest_addr;
|
||||
};
|
||||
typedef struct rmnetctl_hndl_s rmnetctl_hndl_t;
|
||||
|
||||
#define NLMSG_TAIL(nmsg) \
|
||||
((struct rtattr *) (((char *)(nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
|
||||
|
||||
struct nlmsg {
|
||||
struct nlmsghdr nl_addr;
|
||||
struct ifinfomsg ifmsg;
|
||||
char data[500];
|
||||
};
|
||||
|
||||
#define MIN_VALID_PROCESS_ID 0
|
||||
#define MIN_VALID_SOCKET_FD 0
|
||||
#define KERNEL_PROCESS_ID 0
|
||||
#define UNICAST 0
|
||||
|
||||
enum {
|
||||
IFLA_RMNET_UL_AGG_PARAMS = __IFLA_RMNET_MAX,
|
||||
__IFLA_RMNET_EXT_MAX,
|
||||
};
|
||||
|
||||
struct rmnet_egress_agg_params {
|
||||
uint16_t agg_size;
|
||||
uint16_t agg_count;
|
||||
uint32_t agg_time;
|
||||
};
|
||||
|
||||
static int rmnet_get_ack(rmnetctl_hndl_t *hndl, uint16_t *error_code)
|
||||
{
|
||||
struct nlack {
|
||||
struct nlmsghdr ackheader;
|
||||
struct nlmsgerr ackdata;
|
||||
char data[256];
|
||||
|
||||
} ack;
|
||||
int i;
|
||||
|
||||
if (!hndl || !error_code)
|
||||
return RMNETCTL_INVALID_ARG;
|
||||
|
||||
if ((i = recv(hndl->netlink_fd, &ack, sizeof(ack), 0)) < 0) {
|
||||
*error_code = errno;
|
||||
return RMNETCTL_API_ERR_MESSAGE_RECEIVE;
|
||||
}
|
||||
|
||||
/*Ack should always be NLMSG_ERROR type*/
|
||||
if (ack.ackheader.nlmsg_type == NLMSG_ERROR) {
|
||||
if (ack.ackdata.error == 0) {
|
||||
*error_code = RMNETCTL_API_SUCCESS;
|
||||
return RMNETCTL_SUCCESS;
|
||||
} else {
|
||||
*error_code = -ack.ackdata.error;
|
||||
return RMNETCTL_KERNEL_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
*error_code = RMNETCTL_API_ERR_RETURN_TYPE;
|
||||
return RMNETCTL_API_FIRST_ERR;
|
||||
}
|
||||
|
||||
static int rtrmnet_ctl_init(rmnetctl_hndl_t **hndl, uint16_t *error_code)
|
||||
{
|
||||
struct sockaddr_nl __attribute__((__may_alias__)) *saddr_ptr;
|
||||
int netlink_fd = -1;
|
||||
pid_t pid = 0;
|
||||
|
||||
if (!hndl || !error_code)
|
||||
return RMNETCTL_INVALID_ARG;
|
||||
|
||||
*hndl = (rmnetctl_hndl_t *)malloc(sizeof(rmnetctl_hndl_t));
|
||||
if (!*hndl) {
|
||||
*error_code = RMNETCTL_API_ERR_HNDL_INVALID;
|
||||
return RMNETCTL_LIB_ERR;
|
||||
}
|
||||
|
||||
memset(*hndl, 0, sizeof(rmnetctl_hndl_t));
|
||||
|
||||
pid = getpid();
|
||||
if (pid < MIN_VALID_PROCESS_ID) {
|
||||
free(*hndl);
|
||||
*error_code = RMNETCTL_INIT_ERR_PROCESS_ID;
|
||||
return RMNETCTL_LIB_ERR;
|
||||
}
|
||||
(*hndl)->pid = KERNEL_PROCESS_ID;
|
||||
netlink_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||||
if (netlink_fd < MIN_VALID_SOCKET_FD) {
|
||||
free(*hndl);
|
||||
*error_code = RMNETCTL_INIT_ERR_NETLINK_FD;
|
||||
return RMNETCTL_LIB_ERR;
|
||||
}
|
||||
|
||||
(*hndl)->netlink_fd = netlink_fd;
|
||||
|
||||
memset(&(*hndl)->src_addr, 0, sizeof(struct sockaddr_nl));
|
||||
|
||||
(*hndl)->src_addr.nl_family = AF_NETLINK;
|
||||
(*hndl)->src_addr.nl_pid = (*hndl)->pid;
|
||||
|
||||
saddr_ptr = &(*hndl)->src_addr;
|
||||
if (bind((*hndl)->netlink_fd,
|
||||
(struct sockaddr *)saddr_ptr,
|
||||
sizeof(struct sockaddr_nl)) < 0) {
|
||||
close((*hndl)->netlink_fd);
|
||||
free(*hndl);
|
||||
*error_code = RMNETCTL_INIT_ERR_BIND;
|
||||
return RMNETCTL_LIB_ERR;
|
||||
}
|
||||
|
||||
memset(&(*hndl)->dest_addr, 0, sizeof(struct sockaddr_nl));
|
||||
|
||||
(*hndl)->dest_addr.nl_family = AF_NETLINK;
|
||||
(*hndl)->dest_addr.nl_pid = KERNEL_PROCESS_ID;
|
||||
(*hndl)->dest_addr.nl_groups = UNICAST;
|
||||
|
||||
return RMNETCTL_SUCCESS;
|
||||
}
|
||||
|
||||
static int rtrmnet_ctl_deinit(rmnetctl_hndl_t *hndl)
|
||||
{
|
||||
if (!hndl)
|
||||
return RMNETCTL_SUCCESS;
|
||||
|
||||
close(hndl->netlink_fd);
|
||||
free(hndl);
|
||||
|
||||
return RMNETCTL_SUCCESS;
|
||||
}
|
||||
|
||||
static int rtrmnet_ctl_newvnd(rmnetctl_hndl_t *hndl, char *devname, char *vndname,
|
||||
uint16_t *error_code, uint8_t index,
|
||||
uint32_t flagconfig, uint32_t ul_agg_cnt, uint32_t ul_agg_size)
|
||||
{
|
||||
struct rtattr *attrinfo, *datainfo, *linkinfo;
|
||||
struct ifla_vlan_flags flags;
|
||||
int devindex = 0, val = 0;
|
||||
char *kind = "rmnet";
|
||||
struct nlmsg req;
|
||||
short id;
|
||||
|
||||
if (!hndl || !devname || !vndname || !error_code)
|
||||
return RMNETCTL_INVALID_ARG;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.nl_addr.nlmsg_type = RTM_NEWLINK;
|
||||
req.nl_addr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
|
||||
req.nl_addr.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL |
|
||||
NLM_F_ACK;
|
||||
req.nl_addr.nlmsg_seq = hndl->transaction_id;
|
||||
hndl->transaction_id++;
|
||||
|
||||
/* Get index of devname*/
|
||||
devindex = if_nametoindex(devname);
|
||||
if (devindex < 0) {
|
||||
*error_code = errno;
|
||||
return RMNETCTL_KERNEL_ERR;
|
||||
}
|
||||
|
||||
/* Setup link attr with devindex as data */
|
||||
val = devindex;
|
||||
attrinfo = (struct rtattr *)(((char *)&req) +
|
||||
NLMSG_ALIGN(req.nl_addr.nlmsg_len));
|
||||
attrinfo->rta_type = IFLA_LINK;
|
||||
attrinfo->rta_len = RTA_ALIGN(RTA_LENGTH(sizeof(val)));
|
||||
memcpy(RTA_DATA(attrinfo), &val, sizeof(val));
|
||||
req.nl_addr.nlmsg_len = NLMSG_ALIGN(req.nl_addr.nlmsg_len) +
|
||||
RTA_ALIGN(RTA_LENGTH(sizeof(val)));
|
||||
|
||||
/* Set up IFLA info kind RMNET that has linkinfo and type */
|
||||
attrinfo = (struct rtattr *)(((char *)&req) +
|
||||
NLMSG_ALIGN(req.nl_addr.nlmsg_len));
|
||||
attrinfo->rta_type = IFLA_IFNAME;
|
||||
attrinfo->rta_len = RTA_ALIGN(RTA_LENGTH(strlen(vndname) + 1));
|
||||
memcpy(RTA_DATA(attrinfo), vndname, strlen(vndname) + 1);
|
||||
req.nl_addr.nlmsg_len = NLMSG_ALIGN(req.nl_addr.nlmsg_len) +
|
||||
RTA_ALIGN(RTA_LENGTH(strlen(vndname) + 1));
|
||||
|
||||
linkinfo = (struct rtattr *)(((char *)&req) +
|
||||
NLMSG_ALIGN(req.nl_addr.nlmsg_len));
|
||||
linkinfo->rta_type = IFLA_LINKINFO;
|
||||
linkinfo->rta_len = RTA_ALIGN(RTA_LENGTH(0));
|
||||
req.nl_addr.nlmsg_len = NLMSG_ALIGN(req.nl_addr.nlmsg_len) +
|
||||
RTA_ALIGN(RTA_LENGTH(0));
|
||||
|
||||
attrinfo = (struct rtattr *)(((char *)&req) +
|
||||
NLMSG_ALIGN(req.nl_addr.nlmsg_len));
|
||||
attrinfo->rta_type = IFLA_INFO_KIND;
|
||||
attrinfo->rta_len = RTA_ALIGN(RTA_LENGTH(strlen(kind)));
|
||||
memcpy(RTA_DATA(attrinfo), kind, strlen(kind));
|
||||
req.nl_addr.nlmsg_len = NLMSG_ALIGN(req.nl_addr.nlmsg_len) +
|
||||
RTA_ALIGN(RTA_LENGTH(strlen(kind)));
|
||||
|
||||
datainfo = (struct rtattr *)(((char *)&req) +
|
||||
NLMSG_ALIGN(req.nl_addr.nlmsg_len));
|
||||
datainfo->rta_type = IFLA_INFO_DATA;
|
||||
datainfo->rta_len = RTA_ALIGN(RTA_LENGTH(0));
|
||||
req.nl_addr.nlmsg_len = NLMSG_ALIGN(req.nl_addr.nlmsg_len) +
|
||||
RTA_ALIGN(RTA_LENGTH(0));
|
||||
|
||||
id = index;
|
||||
attrinfo = (struct rtattr *)(((char *)&req) +
|
||||
NLMSG_ALIGN(req.nl_addr.nlmsg_len));
|
||||
attrinfo->rta_type = IFLA_VLAN_ID;
|
||||
attrinfo->rta_len = RTA_LENGTH(sizeof(id));
|
||||
memcpy(RTA_DATA(attrinfo), &id, sizeof(id));
|
||||
req.nl_addr.nlmsg_len = NLMSG_ALIGN(req.nl_addr.nlmsg_len) +
|
||||
RTA_ALIGN(RTA_LENGTH(sizeof(id)));
|
||||
|
||||
if (flagconfig != 0) {
|
||||
flags.mask = flagconfig;
|
||||
flags.flags = flagconfig;
|
||||
|
||||
attrinfo = (struct rtattr *)(((char *)&req) +
|
||||
NLMSG_ALIGN(req.nl_addr.nlmsg_len));
|
||||
attrinfo->rta_type = IFLA_VLAN_FLAGS;
|
||||
attrinfo->rta_len = RTA_LENGTH(sizeof(flags));
|
||||
memcpy(RTA_DATA(attrinfo), &flags, sizeof(flags));
|
||||
req.nl_addr.nlmsg_len = NLMSG_ALIGN(req.nl_addr.nlmsg_len) +
|
||||
RTA_ALIGN(RTA_LENGTH(sizeof(flags)));
|
||||
}
|
||||
|
||||
if (ul_agg_cnt > 1) {
|
||||
struct rmnet_egress_agg_params agg_params;
|
||||
|
||||
agg_params.agg_size = ul_agg_size;
|
||||
agg_params.agg_count = ul_agg_cnt;
|
||||
agg_params.agg_time = 3000000;
|
||||
|
||||
attrinfo = (struct rtattr *)(((char *)&req) +
|
||||
NLMSG_ALIGN(req.nl_addr.nlmsg_len));
|
||||
attrinfo->rta_type = IFLA_RMNET_UL_AGG_PARAMS;
|
||||
attrinfo->rta_len = RTA_LENGTH(sizeof(agg_params));
|
||||
memcpy(RTA_DATA(attrinfo), &agg_params, sizeof(agg_params));
|
||||
req.nl_addr.nlmsg_len = NLMSG_ALIGN(req.nl_addr.nlmsg_len) +
|
||||
RTA_ALIGN(RTA_LENGTH(sizeof(agg_params)));
|
||||
}
|
||||
|
||||
datainfo->rta_len = (char *)NLMSG_TAIL(&req.nl_addr) - (char *)datainfo;
|
||||
|
||||
linkinfo->rta_len = (char *)NLMSG_TAIL(&req.nl_addr) - (char *)linkinfo;
|
||||
|
||||
if (send(hndl->netlink_fd, &req, req.nl_addr.nlmsg_len, 0) < 0) {
|
||||
*error_code = RMNETCTL_API_ERR_MESSAGE_SEND;
|
||||
return RMNETCTL_LIB_ERR;
|
||||
}
|
||||
|
||||
return rmnet_get_ack(hndl, error_code);
|
||||
}
|
||||
|
||||
int rtrmnet_ctl_create_vnd(char *devname, char *vndname, uint8_t muxid,
|
||||
uint32_t qmap_version, uint32_t ul_agg_cnt, uint32_t ul_agg_size)
|
||||
{
|
||||
struct rmnetctl_hndl_s *handle;
|
||||
uint16_t error_code;
|
||||
int return_code;
|
||||
uint32_t flagconfig = RMNET_FLAGS_INGRESS_DEAGGREGATION;
|
||||
|
||||
printf("%s devname: %s, vndname: %s, muxid: %d, qmap_version: %d\n",
|
||||
__func__, devname, vndname, muxid, qmap_version);
|
||||
|
||||
ul_agg_cnt = 0; //TODO
|
||||
|
||||
if (ul_agg_cnt > 1)
|
||||
flagconfig |= RMNET_EGRESS_FORMAT_AGGREGATION;
|
||||
|
||||
if (qmap_version == 9) { //QMAPV5
|
||||
#ifdef RMNET_FLAGS_INGRESS_MAP_CKSUMV5
|
||||
flagconfig |= RMNET_FLAGS_INGRESS_MAP_CKSUMV5;
|
||||
flagconfig |= RMNET_FLAGS_EGRESS_MAP_CKSUMV5;
|
||||
#else
|
||||
return -1001;
|
||||
#endif
|
||||
}
|
||||
else if (qmap_version == 8) { //QMAPV4
|
||||
flagconfig |= RMNET_FLAGS_INGRESS_MAP_CKSUMV4;
|
||||
flagconfig |= RMNET_FLAGS_EGRESS_MAP_CKSUMV4;
|
||||
}
|
||||
else if (qmap_version == 5) { //QMAPV1
|
||||
}
|
||||
else {
|
||||
flagconfig = 0;
|
||||
}
|
||||
|
||||
return_code = rtrmnet_ctl_init(&handle, &error_code);
|
||||
if (return_code) {
|
||||
printf("rtrmnet_ctl_init error_code: %d, return_code: %d, errno: %d (%s)\n",
|
||||
error_code, return_code, errno, strerror(errno));
|
||||
}
|
||||
if (return_code == RMNETCTL_SUCCESS) {
|
||||
return_code = rtrmnet_ctl_newvnd(handle, devname, vndname, &error_code,
|
||||
muxid, flagconfig, ul_agg_cnt, ul_agg_size);
|
||||
if (return_code) {
|
||||
printf("rtrmnet_ctl_newvnd error_code: %d, return_code: %d, errno: %d (%s)\n",
|
||||
error_code, return_code, errno, strerror(errno));
|
||||
}
|
||||
rtrmnet_ctl_deinit(handle);
|
||||
}
|
||||
|
||||
return return_code;
|
||||
}
|
||||
//https://source.codeaurora.org/quic/la/platform/vendor/qcom-opensource/dataservices/tree/rmnetctl
|
||||
#include <sys/socket.h>
|
||||
#include <stdint.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/gen_stats.h>
|
||||
#include <net/if.h>
|
||||
#include <asm/types.h>
|
||||
#include <linux/rmnet_data.h>
|
||||
|
||||
#define RMNETCTL_SUCCESS 0
|
||||
#define RMNETCTL_LIB_ERR 1
|
||||
#define RMNETCTL_KERNEL_ERR 2
|
||||
#define RMNETCTL_INVALID_ARG 3
|
||||
|
||||
enum rmnetctl_error_codes_e {
|
||||
RMNETCTL_API_SUCCESS = 0,
|
||||
|
||||
RMNETCTL_API_FIRST_ERR = 1,
|
||||
RMNETCTL_API_ERR_MESSAGE_SEND = 3,
|
||||
RMNETCTL_API_ERR_MESSAGE_RECEIVE = 4,
|
||||
|
||||
RMNETCTL_INIT_FIRST_ERR = 5,
|
||||
RMNETCTL_INIT_ERR_PROCESS_ID = RMNETCTL_INIT_FIRST_ERR,
|
||||
RMNETCTL_INIT_ERR_NETLINK_FD = 6,
|
||||
RMNETCTL_INIT_ERR_BIND = 7,
|
||||
|
||||
RMNETCTL_API_SECOND_ERR = 9,
|
||||
RMNETCTL_API_ERR_HNDL_INVALID = RMNETCTL_API_SECOND_ERR,
|
||||
RMNETCTL_API_ERR_RETURN_TYPE = 13,
|
||||
};
|
||||
|
||||
struct rmnetctl_hndl_s {
|
||||
uint32_t pid;
|
||||
uint32_t transaction_id;
|
||||
int netlink_fd;
|
||||
struct sockaddr_nl src_addr, dest_addr;
|
||||
};
|
||||
typedef struct rmnetctl_hndl_s rmnetctl_hndl_t;
|
||||
|
||||
#define NLMSG_TAIL(nmsg) \
|
||||
((struct rtattr *) (((char *)(nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
|
||||
|
||||
struct nlmsg {
|
||||
struct nlmsghdr nl_addr;
|
||||
struct ifinfomsg ifmsg;
|
||||
char data[500];
|
||||
};
|
||||
|
||||
#define MIN_VALID_PROCESS_ID 0
|
||||
#define MIN_VALID_SOCKET_FD 0
|
||||
#define KERNEL_PROCESS_ID 0
|
||||
#define UNICAST 0
|
||||
|
||||
enum {
|
||||
IFLA_RMNET_UL_AGG_PARAMS = __IFLA_RMNET_MAX,
|
||||
__IFLA_RMNET_EXT_MAX,
|
||||
};
|
||||
|
||||
struct rmnet_egress_agg_params {
|
||||
uint16_t agg_size;
|
||||
uint16_t agg_count;
|
||||
uint32_t agg_time;
|
||||
};
|
||||
|
||||
static int rmnet_get_ack(rmnetctl_hndl_t *hndl, uint16_t *error_code)
|
||||
{
|
||||
struct nlack {
|
||||
struct nlmsghdr ackheader;
|
||||
struct nlmsgerr ackdata;
|
||||
char data[256];
|
||||
|
||||
} ack;
|
||||
int i;
|
||||
|
||||
if (!hndl || !error_code)
|
||||
return RMNETCTL_INVALID_ARG;
|
||||
|
||||
if ((i = recv(hndl->netlink_fd, &ack, sizeof(ack), 0)) < 0) {
|
||||
*error_code = errno;
|
||||
return RMNETCTL_API_ERR_MESSAGE_RECEIVE;
|
||||
}
|
||||
|
||||
/*Ack should always be NLMSG_ERROR type*/
|
||||
if (ack.ackheader.nlmsg_type == NLMSG_ERROR) {
|
||||
if (ack.ackdata.error == 0) {
|
||||
*error_code = RMNETCTL_API_SUCCESS;
|
||||
return RMNETCTL_SUCCESS;
|
||||
} else {
|
||||
*error_code = -ack.ackdata.error;
|
||||
return RMNETCTL_KERNEL_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
*error_code = RMNETCTL_API_ERR_RETURN_TYPE;
|
||||
return RMNETCTL_API_FIRST_ERR;
|
||||
}
|
||||
|
||||
static int rtrmnet_ctl_init(rmnetctl_hndl_t **hndl, uint16_t *error_code)
|
||||
{
|
||||
struct sockaddr_nl __attribute__((__may_alias__)) *saddr_ptr;
|
||||
int netlink_fd = -1;
|
||||
pid_t pid = 0;
|
||||
|
||||
if (!hndl || !error_code)
|
||||
return RMNETCTL_INVALID_ARG;
|
||||
|
||||
*hndl = (rmnetctl_hndl_t *)malloc(sizeof(rmnetctl_hndl_t));
|
||||
if (!*hndl) {
|
||||
*error_code = RMNETCTL_API_ERR_HNDL_INVALID;
|
||||
return RMNETCTL_LIB_ERR;
|
||||
}
|
||||
|
||||
memset(*hndl, 0, sizeof(rmnetctl_hndl_t));
|
||||
|
||||
pid = getpid();
|
||||
if (pid < MIN_VALID_PROCESS_ID) {
|
||||
free(*hndl);
|
||||
*error_code = RMNETCTL_INIT_ERR_PROCESS_ID;
|
||||
return RMNETCTL_LIB_ERR;
|
||||
}
|
||||
(*hndl)->pid = KERNEL_PROCESS_ID;
|
||||
netlink_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||||
if (netlink_fd < MIN_VALID_SOCKET_FD) {
|
||||
free(*hndl);
|
||||
*error_code = RMNETCTL_INIT_ERR_NETLINK_FD;
|
||||
return RMNETCTL_LIB_ERR;
|
||||
}
|
||||
|
||||
(*hndl)->netlink_fd = netlink_fd;
|
||||
|
||||
memset(&(*hndl)->src_addr, 0, sizeof(struct sockaddr_nl));
|
||||
|
||||
(*hndl)->src_addr.nl_family = AF_NETLINK;
|
||||
(*hndl)->src_addr.nl_pid = (*hndl)->pid;
|
||||
|
||||
saddr_ptr = &(*hndl)->src_addr;
|
||||
if (bind((*hndl)->netlink_fd,
|
||||
(struct sockaddr *)saddr_ptr,
|
||||
sizeof(struct sockaddr_nl)) < 0) {
|
||||
close((*hndl)->netlink_fd);
|
||||
free(*hndl);
|
||||
*error_code = RMNETCTL_INIT_ERR_BIND;
|
||||
return RMNETCTL_LIB_ERR;
|
||||
}
|
||||
|
||||
memset(&(*hndl)->dest_addr, 0, sizeof(struct sockaddr_nl));
|
||||
|
||||
(*hndl)->dest_addr.nl_family = AF_NETLINK;
|
||||
(*hndl)->dest_addr.nl_pid = KERNEL_PROCESS_ID;
|
||||
(*hndl)->dest_addr.nl_groups = UNICAST;
|
||||
|
||||
return RMNETCTL_SUCCESS;
|
||||
}
|
||||
|
||||
static int rtrmnet_ctl_deinit(rmnetctl_hndl_t *hndl)
|
||||
{
|
||||
if (!hndl)
|
||||
return RMNETCTL_SUCCESS;
|
||||
|
||||
close(hndl->netlink_fd);
|
||||
free(hndl);
|
||||
|
||||
return RMNETCTL_SUCCESS;
|
||||
}
|
||||
|
||||
static int rtrmnet_ctl_newvnd(rmnetctl_hndl_t *hndl, char *devname, char *vndname,
|
||||
uint16_t *error_code, uint8_t index,
|
||||
uint32_t flagconfig, uint32_t ul_agg_cnt, uint32_t ul_agg_size)
|
||||
{
|
||||
struct rtattr *attrinfo, *datainfo, *linkinfo;
|
||||
struct ifla_vlan_flags flags;
|
||||
int devindex = 0, val = 0;
|
||||
char *kind = "rmnet";
|
||||
struct nlmsg req;
|
||||
short id;
|
||||
|
||||
if (!hndl || !devname || !vndname || !error_code)
|
||||
return RMNETCTL_INVALID_ARG;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.nl_addr.nlmsg_type = RTM_NEWLINK;
|
||||
req.nl_addr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
|
||||
req.nl_addr.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL |
|
||||
NLM_F_ACK;
|
||||
req.nl_addr.nlmsg_seq = hndl->transaction_id;
|
||||
hndl->transaction_id++;
|
||||
|
||||
/* Get index of devname*/
|
||||
devindex = if_nametoindex(devname);
|
||||
if (devindex < 0) {
|
||||
*error_code = errno;
|
||||
return RMNETCTL_KERNEL_ERR;
|
||||
}
|
||||
|
||||
/* Setup link attr with devindex as data */
|
||||
val = devindex;
|
||||
attrinfo = (struct rtattr *)(((char *)&req) +
|
||||
NLMSG_ALIGN(req.nl_addr.nlmsg_len));
|
||||
attrinfo->rta_type = IFLA_LINK;
|
||||
attrinfo->rta_len = RTA_ALIGN(RTA_LENGTH(sizeof(val)));
|
||||
memcpy(RTA_DATA(attrinfo), &val, sizeof(val));
|
||||
req.nl_addr.nlmsg_len = NLMSG_ALIGN(req.nl_addr.nlmsg_len) +
|
||||
RTA_ALIGN(RTA_LENGTH(sizeof(val)));
|
||||
|
||||
/* Set up IFLA info kind RMNET that has linkinfo and type */
|
||||
attrinfo = (struct rtattr *)(((char *)&req) +
|
||||
NLMSG_ALIGN(req.nl_addr.nlmsg_len));
|
||||
attrinfo->rta_type = IFLA_IFNAME;
|
||||
attrinfo->rta_len = RTA_ALIGN(RTA_LENGTH(strlen(vndname) + 1));
|
||||
memcpy(RTA_DATA(attrinfo), vndname, strlen(vndname) + 1);
|
||||
req.nl_addr.nlmsg_len = NLMSG_ALIGN(req.nl_addr.nlmsg_len) +
|
||||
RTA_ALIGN(RTA_LENGTH(strlen(vndname) + 1));
|
||||
|
||||
linkinfo = (struct rtattr *)(((char *)&req) +
|
||||
NLMSG_ALIGN(req.nl_addr.nlmsg_len));
|
||||
linkinfo->rta_type = IFLA_LINKINFO;
|
||||
linkinfo->rta_len = RTA_ALIGN(RTA_LENGTH(0));
|
||||
req.nl_addr.nlmsg_len = NLMSG_ALIGN(req.nl_addr.nlmsg_len) +
|
||||
RTA_ALIGN(RTA_LENGTH(0));
|
||||
|
||||
attrinfo = (struct rtattr *)(((char *)&req) +
|
||||
NLMSG_ALIGN(req.nl_addr.nlmsg_len));
|
||||
attrinfo->rta_type = IFLA_INFO_KIND;
|
||||
attrinfo->rta_len = RTA_ALIGN(RTA_LENGTH(strlen(kind)));
|
||||
memcpy(RTA_DATA(attrinfo), kind, strlen(kind));
|
||||
req.nl_addr.nlmsg_len = NLMSG_ALIGN(req.nl_addr.nlmsg_len) +
|
||||
RTA_ALIGN(RTA_LENGTH(strlen(kind)));
|
||||
|
||||
datainfo = (struct rtattr *)(((char *)&req) +
|
||||
NLMSG_ALIGN(req.nl_addr.nlmsg_len));
|
||||
datainfo->rta_type = IFLA_INFO_DATA;
|
||||
datainfo->rta_len = RTA_ALIGN(RTA_LENGTH(0));
|
||||
req.nl_addr.nlmsg_len = NLMSG_ALIGN(req.nl_addr.nlmsg_len) +
|
||||
RTA_ALIGN(RTA_LENGTH(0));
|
||||
|
||||
id = index;
|
||||
attrinfo = (struct rtattr *)(((char *)&req) +
|
||||
NLMSG_ALIGN(req.nl_addr.nlmsg_len));
|
||||
attrinfo->rta_type = IFLA_VLAN_ID;
|
||||
attrinfo->rta_len = RTA_LENGTH(sizeof(id));
|
||||
memcpy(RTA_DATA(attrinfo), &id, sizeof(id));
|
||||
req.nl_addr.nlmsg_len = NLMSG_ALIGN(req.nl_addr.nlmsg_len) +
|
||||
RTA_ALIGN(RTA_LENGTH(sizeof(id)));
|
||||
|
||||
if (flagconfig != 0) {
|
||||
flags.mask = flagconfig;
|
||||
flags.flags = flagconfig;
|
||||
|
||||
attrinfo = (struct rtattr *)(((char *)&req) +
|
||||
NLMSG_ALIGN(req.nl_addr.nlmsg_len));
|
||||
attrinfo->rta_type = IFLA_VLAN_FLAGS;
|
||||
attrinfo->rta_len = RTA_LENGTH(sizeof(flags));
|
||||
memcpy(RTA_DATA(attrinfo), &flags, sizeof(flags));
|
||||
req.nl_addr.nlmsg_len = NLMSG_ALIGN(req.nl_addr.nlmsg_len) +
|
||||
RTA_ALIGN(RTA_LENGTH(sizeof(flags)));
|
||||
}
|
||||
|
||||
if (ul_agg_cnt > 1) {
|
||||
struct rmnet_egress_agg_params agg_params;
|
||||
|
||||
agg_params.agg_size = ul_agg_size;
|
||||
agg_params.agg_count = ul_agg_cnt;
|
||||
agg_params.agg_time = 3000000;
|
||||
|
||||
attrinfo = (struct rtattr *)(((char *)&req) +
|
||||
NLMSG_ALIGN(req.nl_addr.nlmsg_len));
|
||||
attrinfo->rta_type = IFLA_RMNET_UL_AGG_PARAMS;
|
||||
attrinfo->rta_len = RTA_LENGTH(sizeof(agg_params));
|
||||
memcpy(RTA_DATA(attrinfo), &agg_params, sizeof(agg_params));
|
||||
req.nl_addr.nlmsg_len = NLMSG_ALIGN(req.nl_addr.nlmsg_len) +
|
||||
RTA_ALIGN(RTA_LENGTH(sizeof(agg_params)));
|
||||
}
|
||||
|
||||
datainfo->rta_len = (char *)NLMSG_TAIL(&req.nl_addr) - (char *)datainfo;
|
||||
|
||||
linkinfo->rta_len = (char *)NLMSG_TAIL(&req.nl_addr) - (char *)linkinfo;
|
||||
|
||||
if (send(hndl->netlink_fd, &req, req.nl_addr.nlmsg_len, 0) < 0) {
|
||||
*error_code = RMNETCTL_API_ERR_MESSAGE_SEND;
|
||||
return RMNETCTL_LIB_ERR;
|
||||
}
|
||||
|
||||
return rmnet_get_ack(hndl, error_code);
|
||||
}
|
||||
|
||||
int rtrmnet_ctl_create_vnd(char *devname, char *vndname, uint8_t muxid,
|
||||
uint32_t qmap_version, uint32_t ul_agg_cnt, uint32_t ul_agg_size)
|
||||
{
|
||||
struct rmnetctl_hndl_s *handle;
|
||||
uint16_t error_code;
|
||||
int return_code;
|
||||
uint32_t flagconfig = RMNET_FLAGS_INGRESS_DEAGGREGATION;
|
||||
|
||||
printf("%s devname: %s, vndname: %s, muxid: %d, qmap_version: %d\n",
|
||||
__func__, devname, vndname, muxid, qmap_version);
|
||||
|
||||
ul_agg_cnt = 0; //TODO
|
||||
|
||||
if (ul_agg_cnt > 1)
|
||||
flagconfig |= RMNET_EGRESS_FORMAT_AGGREGATION;
|
||||
|
||||
if (qmap_version == 9) { //QMAPV5
|
||||
#ifdef RMNET_FLAGS_INGRESS_MAP_CKSUMV5
|
||||
flagconfig |= RMNET_FLAGS_INGRESS_MAP_CKSUMV5;
|
||||
flagconfig |= RMNET_FLAGS_EGRESS_MAP_CKSUMV5;
|
||||
#else
|
||||
return -1001;
|
||||
#endif
|
||||
}
|
||||
else if (qmap_version == 8) { //QMAPV4
|
||||
flagconfig |= RMNET_FLAGS_INGRESS_MAP_CKSUMV4;
|
||||
flagconfig |= RMNET_FLAGS_EGRESS_MAP_CKSUMV4;
|
||||
}
|
||||
else if (qmap_version == 5) { //QMAPV1
|
||||
}
|
||||
else {
|
||||
flagconfig = 0;
|
||||
}
|
||||
|
||||
return_code = rtrmnet_ctl_init(&handle, &error_code);
|
||||
if (return_code) {
|
||||
printf("rtrmnet_ctl_init error_code: %d, return_code: %d, errno: %d (%s)\n",
|
||||
error_code, return_code, errno, strerror(errno));
|
||||
}
|
||||
if (return_code == RMNETCTL_SUCCESS) {
|
||||
return_code = rtrmnet_ctl_newvnd(handle, devname, vndname, &error_code,
|
||||
muxid, flagconfig, ul_agg_cnt, ul_agg_size);
|
||||
if (return_code) {
|
||||
printf("rtrmnet_ctl_newvnd error_code: %d, return_code: %d, errno: %d (%s)\n",
|
||||
error_code, return_code, errno, strerror(errno));
|
||||
}
|
||||
rtrmnet_ctl_deinit(handle);
|
||||
}
|
||||
|
||||
return return_code;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,179 +1,179 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/types.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <endian.h>
|
||||
|
||||
#include "libmnl/ifutils.h"
|
||||
#include "libmnl/dhcp/dhcp.h"
|
||||
#include "util.h"
|
||||
#include "QMIThread.h"
|
||||
|
||||
static int ql_raw_ip_mode_check(const char *ifname)
|
||||
{
|
||||
int fd;
|
||||
char raw_ip[128];
|
||||
char mode[2] = "X";
|
||||
int mode_change = 0;
|
||||
|
||||
snprintf(raw_ip, sizeof(raw_ip), "/sys/class/net/%s/qmi/raw_ip", ifname);
|
||||
if (access(raw_ip, F_OK))
|
||||
return 0;
|
||||
|
||||
fd = open(raw_ip, O_RDWR | O_NONBLOCK | O_NOCTTY);
|
||||
if (fd < 0)
|
||||
{
|
||||
dbg_time("%s %d fail to open(%s), errno:%d (%s)", __FILE__, __LINE__, raw_ip, errno, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
read(fd, mode, 2);
|
||||
if (mode[0] == '0' || mode[0] == 'N')
|
||||
{
|
||||
if_link_down(ifname);
|
||||
dbg_time("echo Y > /sys/class/net/%s/qmi/raw_ip", ifname);
|
||||
mode[0] = 'Y';
|
||||
write(fd, mode, 2);
|
||||
mode_change = 1;
|
||||
if_link_up(ifname);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return mode_change;
|
||||
}
|
||||
|
||||
void ql_set_driver_link_state(PROFILE_T *profile, int link_state)
|
||||
{
|
||||
char link_file[128];
|
||||
int fd;
|
||||
int new_state = 0;
|
||||
|
||||
snprintf(link_file, sizeof(link_file), "/sys/class/net/%s/link_state", profile->usbnet_adapter);
|
||||
fd = open(link_file, O_RDWR | O_NONBLOCK | O_NOCTTY);
|
||||
if (fd == -1)
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
dbg_time("Fail to access %s, errno: %d (%s)", link_file, errno, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
if (profile->qmap_mode <= 1)
|
||||
new_state = !!link_state;
|
||||
else
|
||||
{
|
||||
//0x80 means link off this pdp
|
||||
new_state = (link_state ? 0x00 : 0x80) + profile->pdp;
|
||||
}
|
||||
|
||||
snprintf(link_file, sizeof(link_file), "%d\n", new_state);
|
||||
write(fd, link_file, sizeof(link_file));
|
||||
|
||||
if (link_state == 0 && profile->qmap_mode > 1)
|
||||
{
|
||||
size_t rc;
|
||||
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
rc = read(fd, link_file, sizeof(link_file));
|
||||
if (rc > 1 && (!strcasecmp(link_file, "0\n") || !strcasecmp(link_file, "0x0\n")))
|
||||
{
|
||||
if_link_down(profile->usbnet_adapter);
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void udhcpc_start(PROFILE_T *profile)
|
||||
{
|
||||
char *ifname = profile->usbnet_adapter;
|
||||
|
||||
ql_set_driver_link_state(profile, 1);
|
||||
ql_raw_ip_mode_check(ifname);
|
||||
|
||||
if (profile->qmapnet_adapter)
|
||||
{
|
||||
ifname = profile->qmapnet_adapter;
|
||||
}
|
||||
if (profile->rawIP && profile->ipv4.Address && profile->ipv4.Mtu)
|
||||
{
|
||||
if_set_mtu(ifname, (profile->ipv4.Mtu));
|
||||
}
|
||||
|
||||
if (strcmp(ifname, profile->usbnet_adapter))
|
||||
{
|
||||
if_link_up(profile->usbnet_adapter);
|
||||
}
|
||||
|
||||
if_link_up(ifname);
|
||||
|
||||
#if 1 //for bridge mode, only one public IP, so do udhcpc manually
|
||||
if (ql_bridge_mode_detect(profile))
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
// if use DHCP(should make with ${DHCP} src files)
|
||||
// do_dhcp(ifname);
|
||||
// return 0;
|
||||
/* IPv4 Addr Info */
|
||||
if (profile->ipv4.Address)
|
||||
{
|
||||
dbg_time("IPv4 MTU: %d", profile->ipv4.Mtu);
|
||||
dbg_time("IPv4 Address: %s", ipaddr_to_string_v4(ntohl(profile->ipv4.Address)));
|
||||
dbg_time("IPv4 Netmask: %d", mask_to_prefix_v4(ntohl(profile->ipv4.SubnetMask)));
|
||||
dbg_time("IPv4 Gateway: %s", ipaddr_to_string_v4(ntohl(profile->ipv4.Gateway)));
|
||||
dbg_time("IPv4 DNS1: %s", ipaddr_to_string_v4(ntohl(profile->ipv4.DnsPrimary)));
|
||||
dbg_time("IPv4 DNS2: %s", ipaddr_to_string_v4(ntohl(profile->ipv4.DnsSecondary)));
|
||||
if_set_network_v4(ifname, ntohl(profile->ipv4.Address),
|
||||
mask_to_prefix_v4(profile->ipv4.SubnetMask),
|
||||
ntohl(profile->ipv4.Gateway),
|
||||
ntohl(profile->ipv4.DnsPrimary),
|
||||
ntohl(profile->ipv4.DnsSecondary));
|
||||
}
|
||||
|
||||
if (profile->ipv6.Address[0] && profile->ipv6.PrefixLengthIPAddr)
|
||||
{
|
||||
//module do not support DHCPv6, only support 'Router Solicit'
|
||||
//and it seem if enable /proc/sys/net/ipv6/conf/all/forwarding, Kernel do not send RS
|
||||
const char *forward_file = "/proc/sys/net/ipv6/conf/all/forwarding";
|
||||
int forward_fd = open(forward_file, O_RDONLY);
|
||||
if (forward_fd > 0)
|
||||
{
|
||||
char forward_state[2];
|
||||
read(forward_fd, forward_state, 2);
|
||||
if (forward_state[0] == '1')
|
||||
{
|
||||
dbg_time("%s enabled, kernel maybe donot send 'Router Solicit'", forward_file);
|
||||
}
|
||||
close(forward_fd);
|
||||
}
|
||||
|
||||
dbg_time("IPv6 MTU: %d", profile->ipv6.Mtu);
|
||||
dbg_time("IPv6 Address: %s", ipaddr_to_string_v6(profile->ipv6.Address));
|
||||
dbg_time("IPv6 Netmask: %d", profile->ipv6.PrefixLengthIPAddr);
|
||||
dbg_time("IPv6 Gateway: %s", ipaddr_to_string_v6(profile->ipv6.Gateway));
|
||||
dbg_time("IPv6 DNS1: %s", ipaddr_to_string_v6(profile->ipv6.DnsPrimary));
|
||||
dbg_time("IPv6 DNS2: %s", ipaddr_to_string_v6(profile->ipv6.DnsSecondary));
|
||||
if_set_network_v6(ifname, profile->ipv6.Address, profile->ipv6.PrefixLengthIPAddr,
|
||||
profile->ipv6.Gateway, profile->ipv6.DnsPrimary, profile->ipv6.DnsSecondary);
|
||||
}
|
||||
}
|
||||
|
||||
void udhcpc_stop(PROFILE_T *profile)
|
||||
{
|
||||
char *ifname = profile->usbnet_adapter;
|
||||
|
||||
ql_set_driver_link_state(profile, 0);
|
||||
|
||||
if (profile->qmapnet_adapter)
|
||||
{
|
||||
ifname = profile->qmapnet_adapter;
|
||||
}
|
||||
|
||||
if_link_down(ifname);
|
||||
if_flush_v4_addr(ifname);
|
||||
if_flush_v6_addr(ifname);
|
||||
}
|
||||
#include <sys/socket.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/types.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <endian.h>
|
||||
|
||||
#include "libmnl/ifutils.h"
|
||||
#include "libmnl/dhcp/dhcp.h"
|
||||
#include "util.h"
|
||||
#include "QMIThread.h"
|
||||
|
||||
static int ql_raw_ip_mode_check(const char *ifname)
|
||||
{
|
||||
int fd;
|
||||
char raw_ip[128];
|
||||
char mode[2] = "X";
|
||||
int mode_change = 0;
|
||||
|
||||
snprintf(raw_ip, sizeof(raw_ip), "/sys/class/net/%s/qmi/raw_ip", ifname);
|
||||
if (access(raw_ip, F_OK))
|
||||
return 0;
|
||||
|
||||
fd = open(raw_ip, O_RDWR | O_NONBLOCK | O_NOCTTY);
|
||||
if (fd < 0)
|
||||
{
|
||||
dbg_time("%s %d fail to open(%s), errno:%d (%s)", __FILE__, __LINE__, raw_ip, errno, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
read(fd, mode, 2);
|
||||
if (mode[0] == '0' || mode[0] == 'N')
|
||||
{
|
||||
if_link_down(ifname);
|
||||
dbg_time("echo Y > /sys/class/net/%s/qmi/raw_ip", ifname);
|
||||
mode[0] = 'Y';
|
||||
write(fd, mode, 2);
|
||||
mode_change = 1;
|
||||
if_link_up(ifname);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return mode_change;
|
||||
}
|
||||
|
||||
void ql_set_driver_link_state(PROFILE_T *profile, int link_state)
|
||||
{
|
||||
char link_file[128];
|
||||
int fd;
|
||||
int new_state = 0;
|
||||
|
||||
snprintf(link_file, sizeof(link_file), "/sys/class/net/%s/link_state", profile->usbnet_adapter);
|
||||
fd = open(link_file, O_RDWR | O_NONBLOCK | O_NOCTTY);
|
||||
if (fd == -1)
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
dbg_time("Fail to access %s, errno: %d (%s)", link_file, errno, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
if (profile->qmap_mode <= 1)
|
||||
new_state = !!link_state;
|
||||
else
|
||||
{
|
||||
//0x80 means link off this pdp
|
||||
new_state = (link_state ? 0x00 : 0x80) + profile->pdp;
|
||||
}
|
||||
|
||||
snprintf(link_file, sizeof(link_file), "%d\n", new_state);
|
||||
write(fd, link_file, sizeof(link_file));
|
||||
|
||||
if (link_state == 0 && profile->qmap_mode > 1)
|
||||
{
|
||||
size_t rc;
|
||||
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
rc = read(fd, link_file, sizeof(link_file));
|
||||
if (rc > 1 && (!strcasecmp(link_file, "0\n") || !strcasecmp(link_file, "0x0\n")))
|
||||
{
|
||||
if_link_down(profile->usbnet_adapter);
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void udhcpc_start(PROFILE_T *profile)
|
||||
{
|
||||
char *ifname = profile->usbnet_adapter;
|
||||
|
||||
ql_set_driver_link_state(profile, 1);
|
||||
ql_raw_ip_mode_check(ifname);
|
||||
|
||||
if (profile->qmapnet_adapter)
|
||||
{
|
||||
ifname = profile->qmapnet_adapter;
|
||||
}
|
||||
if (profile->rawIP && profile->ipv4.Address && profile->ipv4.Mtu)
|
||||
{
|
||||
if_set_mtu(ifname, (profile->ipv4.Mtu));
|
||||
}
|
||||
|
||||
if (strcmp(ifname, profile->usbnet_adapter))
|
||||
{
|
||||
if_link_up(profile->usbnet_adapter);
|
||||
}
|
||||
|
||||
if_link_up(ifname);
|
||||
|
||||
#if 1 //for bridge mode, only one public IP, so do udhcpc manually
|
||||
if (ql_bridge_mode_detect(profile))
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
// if use DHCP(should make with ${DHCP} src files)
|
||||
// do_dhcp(ifname);
|
||||
// return 0;
|
||||
/* IPv4 Addr Info */
|
||||
if (profile->ipv4.Address)
|
||||
{
|
||||
dbg_time("IPv4 MTU: %d", profile->ipv4.Mtu);
|
||||
dbg_time("IPv4 Address: %s", ipaddr_to_string_v4(ntohl(profile->ipv4.Address)));
|
||||
dbg_time("IPv4 Netmask: %d", mask_to_prefix_v4(ntohl(profile->ipv4.SubnetMask)));
|
||||
dbg_time("IPv4 Gateway: %s", ipaddr_to_string_v4(ntohl(profile->ipv4.Gateway)));
|
||||
dbg_time("IPv4 DNS1: %s", ipaddr_to_string_v4(ntohl(profile->ipv4.DnsPrimary)));
|
||||
dbg_time("IPv4 DNS2: %s", ipaddr_to_string_v4(ntohl(profile->ipv4.DnsSecondary)));
|
||||
if_set_network_v4(ifname, ntohl(profile->ipv4.Address),
|
||||
mask_to_prefix_v4(profile->ipv4.SubnetMask),
|
||||
ntohl(profile->ipv4.Gateway),
|
||||
ntohl(profile->ipv4.DnsPrimary),
|
||||
ntohl(profile->ipv4.DnsSecondary));
|
||||
}
|
||||
|
||||
if (profile->ipv6.Address[0] && profile->ipv6.PrefixLengthIPAddr)
|
||||
{
|
||||
//module do not support DHCPv6, only support 'Router Solicit'
|
||||
//and it seem if enable /proc/sys/net/ipv6/conf/all/forwarding, Kernel do not send RS
|
||||
const char *forward_file = "/proc/sys/net/ipv6/conf/all/forwarding";
|
||||
int forward_fd = open(forward_file, O_RDONLY);
|
||||
if (forward_fd > 0)
|
||||
{
|
||||
char forward_state[2];
|
||||
read(forward_fd, forward_state, 2);
|
||||
if (forward_state[0] == '1')
|
||||
{
|
||||
dbg_time("%s enabled, kernel maybe donot send 'Router Solicit'", forward_file);
|
||||
}
|
||||
close(forward_fd);
|
||||
}
|
||||
|
||||
dbg_time("IPv6 MTU: %d", profile->ipv6.Mtu);
|
||||
dbg_time("IPv6 Address: %s", ipaddr_to_string_v6(profile->ipv6.Address));
|
||||
dbg_time("IPv6 Netmask: %d", profile->ipv6.PrefixLengthIPAddr);
|
||||
dbg_time("IPv6 Gateway: %s", ipaddr_to_string_v6(profile->ipv6.Gateway));
|
||||
dbg_time("IPv6 DNS1: %s", ipaddr_to_string_v6(profile->ipv6.DnsPrimary));
|
||||
dbg_time("IPv6 DNS2: %s", ipaddr_to_string_v6(profile->ipv6.DnsSecondary));
|
||||
if_set_network_v6(ifname, profile->ipv6.Address, profile->ipv6.PrefixLengthIPAddr,
|
||||
profile->ipv6.Gateway, profile->ipv6.DnsPrimary, profile->ipv6.DnsSecondary);
|
||||
}
|
||||
}
|
||||
|
||||
void udhcpc_stop(PROFILE_T *profile)
|
||||
{
|
||||
char *ifname = profile->usbnet_adapter;
|
||||
|
||||
ql_set_driver_link_state(profile, 0);
|
||||
|
||||
if (profile->qmapnet_adapter)
|
||||
{
|
||||
ifname = profile->qmapnet_adapter;
|
||||
}
|
||||
|
||||
if_link_down(ifname);
|
||||
if_flush_v4_addr(ifname);
|
||||
if_flush_v6_addr(ifname);
|
||||
}
|
||||
@ -1,132 +1,132 @@
|
||||
/******************************************************************************
|
||||
@file udhcpc.c
|
||||
@brief call DHCP tools to obtain IP address.
|
||||
|
||||
DESCRIPTION
|
||||
Connectivity Management Tool for USB network adapter of Quectel wireless cellular modules.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
None.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||
Quectel Wireless Solution Proprietary and Confidential.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
||||
#include <sys/socket.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/types.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <endian.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "QMIThread.h"
|
||||
|
||||
#define IFDOWN_SCRIPT "/etc/quectel/ifdown.sh"
|
||||
#define IFUP_SCRIPT "/etc/quectel/ifup.sh"
|
||||
|
||||
static int ql_system(const char *shell_cmd)
|
||||
{
|
||||
dbg_time("%s", shell_cmd);
|
||||
return system(shell_cmd);
|
||||
}
|
||||
|
||||
uint32_t mask_to_prefix_v4(uint32_t mask)
|
||||
{
|
||||
uint32_t prefix = 0;
|
||||
while (mask)
|
||||
{
|
||||
mask = mask & (mask - 1);
|
||||
prefix++;
|
||||
}
|
||||
return prefix;
|
||||
}
|
||||
|
||||
uint32_t mask_from_prefix_v4(uint32_t prefix)
|
||||
{
|
||||
return ~((1 << (32 - prefix)) - 1);
|
||||
}
|
||||
|
||||
/* mask in int */
|
||||
uint32_t broadcast_from_mask(uint32_t ip, uint32_t mask)
|
||||
{
|
||||
return (ip & mask) | (~mask);
|
||||
}
|
||||
|
||||
const char *ipaddr_to_string_v4(in_addr_t ipaddr, char *buf, size_t size)
|
||||
{
|
||||
// static char buf[INET6_ADDRSTRLEN] = {'\0'};
|
||||
buf[0] = '\0';
|
||||
uint32_t addr = ipaddr;
|
||||
return inet_ntop(AF_INET, &addr, buf, size);
|
||||
}
|
||||
|
||||
const char *ipaddr_to_string_v6(uint8_t *ipaddr, char *buf, size_t size)
|
||||
{
|
||||
buf[0] = '\0';
|
||||
return inet_ntop(AF_INET6, ipaddr, buf, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* For more details see default.script
|
||||
*
|
||||
* The main aim of this function is offload ip management to script, CM has not interest in manage IP address.
|
||||
* just tell script all the info about ip, mask, router, dns...
|
||||
*/
|
||||
void udhcpc_start(PROFILE_T *profile)
|
||||
{
|
||||
char shell_cmd[1024];
|
||||
char ip[128];
|
||||
char subnet[128];
|
||||
char broadcast[128];
|
||||
char router[128];
|
||||
char domain1[128];
|
||||
char domain2[128];
|
||||
|
||||
if (NULL == getenv(IFUP_SCRIPT))
|
||||
return;
|
||||
|
||||
// manage IPv4???
|
||||
// check rawip ???
|
||||
snprintf(shell_cmd, sizeof(shell_cmd),
|
||||
" netiface=%s interface=%s mtu=%u ip=%s subnet=%s broadcast=%s router=%s"
|
||||
" domain=\"%s %s\" %s",
|
||||
profile->usbnet_adapter,
|
||||
profile->qmapnet_adapter ? profile->qmapnet_adapter : profile->usbnet_adapter,
|
||||
profile->ipv4.Mtu,
|
||||
ipaddr_to_string_v4(ntohl(profile->ipv4.Address), ip, sizeof(ip)),
|
||||
ipaddr_to_string_v4(ntohl(profile->ipv4.SubnetMask), subnet, sizeof(subnet)),
|
||||
ipaddr_to_string_v4(ntohl(broadcast_from_mask(profile->ipv4.Address, profile->ipv4.SubnetMask)),
|
||||
broadcast, sizeof(broadcast)),
|
||||
ipaddr_to_string_v4(ntohl(profile->ipv4.Gateway), router, sizeof(router)),
|
||||
ipaddr_to_string_v4(ntohl(profile->ipv4.DnsPrimary), domain1, sizeof(domain1)),
|
||||
ipaddr_to_string_v4(ntohl(profile->ipv4.DnsSecondary), domain2, sizeof(domain2)),
|
||||
getenv(IFUP_SCRIPT));
|
||||
ql_system(shell_cmd);
|
||||
|
||||
// manage IPv6???
|
||||
}
|
||||
|
||||
/**
|
||||
* For more details see default.script
|
||||
*
|
||||
* The main aim of this function is offload ip management to script, CM has not interest in manage IP address.
|
||||
* just tell script all the info about ip, mask, router, dns...
|
||||
*/
|
||||
void udhcpc_stop(PROFILE_T *profile)
|
||||
{
|
||||
char shell_cmd[1024];
|
||||
|
||||
if (NULL == getenv(IFDOWN_SCRIPT))
|
||||
return;
|
||||
|
||||
snprintf(shell_cmd, sizeof(shell_cmd),
|
||||
"netiface=%s interface=%s %s",
|
||||
profile->usbnet_adapter,
|
||||
profile->qmapnet_adapter ? profile->qmapnet_adapter : profile->usbnet_adapter,
|
||||
getenv(IFDOWN_SCRIPT));
|
||||
ql_system(shell_cmd);
|
||||
}
|
||||
/******************************************************************************
|
||||
@file udhcpc.c
|
||||
@brief call DHCP tools to obtain IP address.
|
||||
|
||||
DESCRIPTION
|
||||
Connectivity Management Tool for USB network adapter of Quectel wireless cellular modules.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
None.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||
Quectel Wireless Solution Proprietary and Confidential.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
||||
#include <sys/socket.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/types.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <endian.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "QMIThread.h"
|
||||
|
||||
#define IFDOWN_SCRIPT "/etc/quectel/ifdown.sh"
|
||||
#define IFUP_SCRIPT "/etc/quectel/ifup.sh"
|
||||
|
||||
static int ql_system(const char *shell_cmd)
|
||||
{
|
||||
dbg_time("%s", shell_cmd);
|
||||
return system(shell_cmd);
|
||||
}
|
||||
|
||||
uint32_t mask_to_prefix_v4(uint32_t mask)
|
||||
{
|
||||
uint32_t prefix = 0;
|
||||
while (mask)
|
||||
{
|
||||
mask = mask & (mask - 1);
|
||||
prefix++;
|
||||
}
|
||||
return prefix;
|
||||
}
|
||||
|
||||
uint32_t mask_from_prefix_v4(uint32_t prefix)
|
||||
{
|
||||
return ~((1 << (32 - prefix)) - 1);
|
||||
}
|
||||
|
||||
/* mask in int */
|
||||
uint32_t broadcast_from_mask(uint32_t ip, uint32_t mask)
|
||||
{
|
||||
return (ip & mask) | (~mask);
|
||||
}
|
||||
|
||||
const char *ipaddr_to_string_v4(in_addr_t ipaddr, char *buf, size_t size)
|
||||
{
|
||||
// static char buf[INET6_ADDRSTRLEN] = {'\0'};
|
||||
buf[0] = '\0';
|
||||
uint32_t addr = ipaddr;
|
||||
return inet_ntop(AF_INET, &addr, buf, size);
|
||||
}
|
||||
|
||||
const char *ipaddr_to_string_v6(uint8_t *ipaddr, char *buf, size_t size)
|
||||
{
|
||||
buf[0] = '\0';
|
||||
return inet_ntop(AF_INET6, ipaddr, buf, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* For more details see default.script
|
||||
*
|
||||
* The main aim of this function is offload ip management to script, CM has not interest in manage IP address.
|
||||
* just tell script all the info about ip, mask, router, dns...
|
||||
*/
|
||||
void udhcpc_start(PROFILE_T *profile)
|
||||
{
|
||||
char shell_cmd[1024];
|
||||
char ip[128];
|
||||
char subnet[128];
|
||||
char broadcast[128];
|
||||
char router[128];
|
||||
char domain1[128];
|
||||
char domain2[128];
|
||||
|
||||
if (NULL == getenv(IFUP_SCRIPT))
|
||||
return;
|
||||
|
||||
// manage IPv4???
|
||||
// check rawip ???
|
||||
snprintf(shell_cmd, sizeof(shell_cmd),
|
||||
" netiface=%s interface=%s mtu=%u ip=%s subnet=%s broadcast=%s router=%s"
|
||||
" domain=\"%s %s\" %s",
|
||||
profile->usbnet_adapter,
|
||||
profile->qmapnet_adapter ? profile->qmapnet_adapter : profile->usbnet_adapter,
|
||||
profile->ipv4.Mtu,
|
||||
ipaddr_to_string_v4(ntohl(profile->ipv4.Address), ip, sizeof(ip)),
|
||||
ipaddr_to_string_v4(ntohl(profile->ipv4.SubnetMask), subnet, sizeof(subnet)),
|
||||
ipaddr_to_string_v4(ntohl(broadcast_from_mask(profile->ipv4.Address, profile->ipv4.SubnetMask)),
|
||||
broadcast, sizeof(broadcast)),
|
||||
ipaddr_to_string_v4(ntohl(profile->ipv4.Gateway), router, sizeof(router)),
|
||||
ipaddr_to_string_v4(ntohl(profile->ipv4.DnsPrimary), domain1, sizeof(domain1)),
|
||||
ipaddr_to_string_v4(ntohl(profile->ipv4.DnsSecondary), domain2, sizeof(domain2)),
|
||||
getenv(IFUP_SCRIPT));
|
||||
ql_system(shell_cmd);
|
||||
|
||||
// manage IPv6???
|
||||
}
|
||||
|
||||
/**
|
||||
* For more details see default.script
|
||||
*
|
||||
* The main aim of this function is offload ip management to script, CM has not interest in manage IP address.
|
||||
* just tell script all the info about ip, mask, router, dns...
|
||||
*/
|
||||
void udhcpc_stop(PROFILE_T *profile)
|
||||
{
|
||||
char shell_cmd[1024];
|
||||
|
||||
if (NULL == getenv(IFDOWN_SCRIPT))
|
||||
return;
|
||||
|
||||
snprintf(shell_cmd, sizeof(shell_cmd),
|
||||
"netiface=%s interface=%s %s",
|
||||
profile->usbnet_adapter,
|
||||
profile->qmapnet_adapter ? profile->qmapnet_adapter : profile->usbnet_adapter,
|
||||
getenv(IFDOWN_SCRIPT));
|
||||
ql_system(shell_cmd);
|
||||
}
|
||||
@ -1,361 +1,361 @@
|
||||
/******************************************************************************
|
||||
@file util.c
|
||||
@brief some utils for this QCM tool.
|
||||
|
||||
DESCRIPTION
|
||||
Connectivity Management Tool for USB network adapter of Quectel wireless cellular modules.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
None.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||
Quectel Wireless Solution Proprietary and Confidential.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <net/if.h>
|
||||
typedef unsigned short sa_family_t;
|
||||
#include <linux/un.h>
|
||||
|
||||
#if defined(__STDC__)
|
||||
#include <stdarg.h>
|
||||
#define __V(x) x
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#define __V(x) (va_alist) va_dcl
|
||||
#define const
|
||||
#define volatile
|
||||
#endif
|
||||
|
||||
#include <syslog.h>
|
||||
|
||||
#include "QMIThread.h"
|
||||
|
||||
pthread_mutex_t cm_command_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_cond_t cm_command_cond = PTHREAD_COND_INITIALIZER;
|
||||
unsigned int cm_recv_buf[1024];
|
||||
|
||||
int cm_open_dev(const char *dev) {
|
||||
int fd;
|
||||
|
||||
fd = open(dev, O_RDWR | O_NONBLOCK | O_NOCTTY);
|
||||
if (fd != -1) {
|
||||
fcntl(fd, F_SETFL, fcntl(fd,F_GETFL) | O_NONBLOCK);
|
||||
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
if (!strncmp(dev, "/dev/tty", strlen("/dev/tty")))
|
||||
{
|
||||
//disable echo on serial ports
|
||||
struct termios ios;
|
||||
|
||||
memset(&ios, 0, sizeof(ios));
|
||||
tcgetattr( fd, &ios );
|
||||
cfmakeraw(&ios);
|
||||
cfsetispeed(&ios, B115200);
|
||||
cfsetospeed(&ios, B115200);
|
||||
tcsetattr( fd, TCSANOW, &ios );
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
}
|
||||
} else {
|
||||
dbg_time("Failed to open %s, errno: %d (%s)", dev, errno, strerror(errno));
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
int cm_open_proxy(const char *name) {
|
||||
int sockfd = -1;
|
||||
int reuse_addr = 1;
|
||||
struct sockaddr_un sockaddr;
|
||||
socklen_t alen;
|
||||
|
||||
/*Create server socket*/
|
||||
sockfd = socket(AF_LOCAL, SOCK_STREAM, 0);
|
||||
if (sockfd < 0)
|
||||
return sockfd;
|
||||
|
||||
memset(&sockaddr, 0, sizeof(sockaddr));
|
||||
sockaddr.sun_family = AF_LOCAL;
|
||||
sockaddr.sun_path[0] = 0;
|
||||
memcpy(sockaddr.sun_path + 1, name, strlen(name) );
|
||||
|
||||
alen = strlen(name) + offsetof(struct sockaddr_un, sun_path) + 1;
|
||||
if(connect(sockfd, (struct sockaddr *)&sockaddr, alen) < 0) {
|
||||
close(sockfd);
|
||||
dbg_time("connect %s errno: %d (%s)", name, errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse_addr,sizeof(reuse_addr));
|
||||
fcntl(sockfd, F_SETFL, fcntl(sockfd,F_GETFL) | O_NONBLOCK);
|
||||
fcntl(sockfd, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
dbg_time("connect to %s sockfd = %d", name, sockfd);
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
static void setTimespecRelative(struct timespec *p_ts, long long msec)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, (struct timezone *) NULL);
|
||||
|
||||
/* what's really funny about this is that I know
|
||||
pthread_cond_timedwait just turns around and makes this
|
||||
a relative time again */
|
||||
p_ts->tv_sec = tv.tv_sec + (msec / 1000);
|
||||
p_ts->tv_nsec = (tv.tv_usec + (msec % 1000) * 1000L ) * 1000L;
|
||||
if ((unsigned long)p_ts->tv_nsec >= 1000000000UL) {
|
||||
p_ts->tv_sec += 1;
|
||||
p_ts->tv_nsec -= 1000000000UL;
|
||||
}
|
||||
}
|
||||
|
||||
int pthread_cond_timeout_np(pthread_cond_t *cond, pthread_mutex_t * mutex, unsigned msecs) {
|
||||
if (msecs != 0) {
|
||||
unsigned i;
|
||||
unsigned t = msecs/4;
|
||||
int ret = 0;
|
||||
|
||||
if (t == 0)
|
||||
t = 1;
|
||||
|
||||
for (i = 0; i < msecs; i += t) {
|
||||
struct timespec ts;
|
||||
setTimespecRelative(&ts, t);
|
||||
//very old uclibc do not support pthread_condattr_setclock(CLOCK_MONOTONIC)
|
||||
ret = pthread_cond_timedwait(cond, mutex, &ts); //to advoid system time change
|
||||
if (ret != ETIMEDOUT) {
|
||||
if(ret) dbg_time("ret=%d, msecs=%u, t=%u", ret, msecs, t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
} else {
|
||||
return pthread_cond_wait(cond, mutex);
|
||||
}
|
||||
}
|
||||
|
||||
const char * get_time(void) {
|
||||
static char time_buf[128];
|
||||
struct timeval tv;
|
||||
time_t time;
|
||||
suseconds_t millitm;
|
||||
struct tm *ti;
|
||||
|
||||
gettimeofday (&tv, NULL);
|
||||
|
||||
time= tv.tv_sec;
|
||||
millitm = (tv.tv_usec + 500) / 1000;
|
||||
|
||||
if (millitm == 1000) {
|
||||
++time;
|
||||
millitm = 0;
|
||||
}
|
||||
|
||||
ti = localtime(&time);
|
||||
sprintf(time_buf, "%02d-%02d_%02d:%02d:%02d:%03d", ti->tm_mon+1, ti->tm_mday, ti->tm_hour, ti->tm_min, ti->tm_sec, (int)millitm);
|
||||
return time_buf;
|
||||
}
|
||||
|
||||
unsigned long clock_msec(void)
|
||||
{
|
||||
struct timespec tm;
|
||||
clock_gettime( CLOCK_MONOTONIC, &tm);
|
||||
return (unsigned long)(tm.tv_sec*1000 + (tm.tv_nsec/1000000));
|
||||
}
|
||||
|
||||
FILE *logfilefp = NULL;
|
||||
|
||||
void update_resolv_conf(int iptype, const char *ifname, const char *dns1, const char *dns2) {
|
||||
const char *dns_file = "/etc/resolv.conf";
|
||||
FILE *dns_fp;
|
||||
char dns_line[256];
|
||||
#define MAX_DNS 16
|
||||
char *dns_info[MAX_DNS];
|
||||
char dns_tag[64];
|
||||
int dns_match = 0;
|
||||
int i;
|
||||
|
||||
snprintf(dns_tag, sizeof(dns_tag), "# IPV%d %s", iptype, ifname);
|
||||
|
||||
for (i = 0; i < MAX_DNS; i++)
|
||||
dns_info[i] = NULL;
|
||||
|
||||
dns_fp = fopen(dns_file, "r");
|
||||
if (dns_fp) {
|
||||
i = 0;
|
||||
dns_line[sizeof(dns_line)-1] = '\0';
|
||||
|
||||
while((fgets(dns_line, sizeof(dns_line)-1, dns_fp)) != NULL) {
|
||||
if ((strlen(dns_line) > 1) && (dns_line[strlen(dns_line) - 1] == '\n'))
|
||||
dns_line[strlen(dns_line) - 1] = '\0';
|
||||
//dbg_time("%s", dns_line);
|
||||
if (strstr(dns_line, dns_tag)) {
|
||||
dns_match++;
|
||||
continue;
|
||||
}
|
||||
dns_info[i++] = strdup(dns_line);
|
||||
if (i == MAX_DNS)
|
||||
break;
|
||||
}
|
||||
|
||||
fclose(dns_fp);
|
||||
}
|
||||
else if (errno != ENOENT) {
|
||||
dbg_time("fopen %s fail, errno:%d (%s)", dns_file, errno, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
if (dns1 == NULL && dns_match == 0)
|
||||
return;
|
||||
|
||||
dns_fp = fopen(dns_file, "w");
|
||||
if (dns_fp) {
|
||||
if (dns1)
|
||||
fprintf(dns_fp, "nameserver %s %s\n", dns1, dns_tag);
|
||||
if (dns2)
|
||||
fprintf(dns_fp, "nameserver %s %s\n", dns2, dns_tag);
|
||||
|
||||
for (i = 0; i < MAX_DNS && dns_info[i]; i++)
|
||||
fprintf(dns_fp, "%s\n", dns_info[i]);
|
||||
fclose(dns_fp);
|
||||
}
|
||||
else {
|
||||
dbg_time("fopen %s fail, errno:%d (%s)", dns_file, errno, strerror(errno));
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_DNS && dns_info[i]; i++)
|
||||
free(dns_info[i]);
|
||||
}
|
||||
|
||||
pid_t getpid_by_pdp(int pdp, const char* program_name)
|
||||
{
|
||||
glob_t gt;
|
||||
int ret;
|
||||
char filter[16];
|
||||
pid_t pid;
|
||||
|
||||
snprintf(filter, sizeof(filter), "-n %d", pdp);
|
||||
ret = glob("/proc/*/cmdline", GLOB_NOSORT, NULL, >);
|
||||
if (ret != 0) {
|
||||
dbg_time("glob error, errno = %d(%s)", errno, strerror(errno));
|
||||
return -1;
|
||||
} else {
|
||||
int i = 0, fd = -1;
|
||||
ssize_t nreads;
|
||||
char cmdline[512] = {0};
|
||||
|
||||
for (i = 0; i < (int)gt.gl_pathc; i++) {
|
||||
fd = open(gt.gl_pathv[i], O_RDONLY);
|
||||
if (fd == -1) {
|
||||
dbg_time("open %s failed, errno = %d(%s)", gt.gl_pathv[i], errno, strerror(errno));
|
||||
globfree(>);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nreads = read(fd, cmdline, sizeof(cmdline));
|
||||
if (nreads > 0) {
|
||||
int pos = 0;
|
||||
while (pos < nreads-1) {
|
||||
if (cmdline[pos] == '\0')
|
||||
cmdline[pos] = ' '; // space
|
||||
pos++;
|
||||
}
|
||||
// printf("%s\n", cmdline);
|
||||
}
|
||||
|
||||
if (strstr(cmdline, program_name) && strstr(cmdline, filter)) {
|
||||
char path[64] = {0};
|
||||
char pidstr[64] = {0};
|
||||
char *p;
|
||||
|
||||
dbg_time("%s: %s", gt.gl_pathv[i], cmdline);
|
||||
strcpy(path, gt.gl_pathv[i]);
|
||||
p = strstr(gt.gl_pathv[i], "/cmdline");
|
||||
*p = '\0';
|
||||
while (*(--p) != '/') ;
|
||||
|
||||
strcpy(pidstr, p+1);
|
||||
pid = atoi(pidstr);
|
||||
globfree(>);
|
||||
|
||||
return pid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
globfree(>);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ql_get_driver_rmnet_info(PROFILE_T *profile, RMNET_INFO *rmnet_info) {
|
||||
int ifc_ctl_sock;
|
||||
struct ifreq ifr;
|
||||
int rc;
|
||||
int request = 0x89F3;
|
||||
unsigned char data[512];
|
||||
|
||||
memset(rmnet_info, 0x00, sizeof(*rmnet_info));
|
||||
|
||||
ifc_ctl_sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (ifc_ctl_sock <= 0) {
|
||||
dbg_time("socket() failed: %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&ifr, 0, sizeof(struct ifreq));
|
||||
strncpy(ifr.ifr_name, profile->usbnet_adapter, IFNAMSIZ);
|
||||
ifr.ifr_name[IFNAMSIZ - 1] = 0;
|
||||
ifr.ifr_ifru.ifru_data = (void *)data;
|
||||
|
||||
rc = ioctl(ifc_ctl_sock, request, &ifr);
|
||||
if (rc < 0) {
|
||||
if (errno != ENOTSUP)
|
||||
dbg_time("ioctl(0x%x, qmap_settings) errno:%d (%s), rc=%d", request, errno, strerror(errno), rc);
|
||||
}
|
||||
else {
|
||||
memcpy(rmnet_info, data, sizeof(*rmnet_info));
|
||||
}
|
||||
|
||||
close(ifc_ctl_sock);
|
||||
}
|
||||
|
||||
void ql_set_driver_qmap_setting(PROFILE_T *profile, QMAP_SETTING *qmap_settings) {
|
||||
int ifc_ctl_sock;
|
||||
struct ifreq ifr;
|
||||
int rc;
|
||||
int request = 0x89F2;
|
||||
|
||||
ifc_ctl_sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (ifc_ctl_sock <= 0) {
|
||||
dbg_time("socket() failed: %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&ifr, 0, sizeof(struct ifreq));
|
||||
strncpy(ifr.ifr_name, profile->usbnet_adapter, IFNAMSIZ);
|
||||
ifr.ifr_name[IFNAMSIZ - 1] = 0;
|
||||
ifr.ifr_ifru.ifru_data = (void *)qmap_settings;
|
||||
|
||||
rc = ioctl(ifc_ctl_sock, request, &ifr);
|
||||
if (rc < 0) {
|
||||
dbg_time("ioctl(0x%x, qmap_settings) failed: %s, rc=%d", request, strerror(errno), rc);
|
||||
}
|
||||
|
||||
close(ifc_ctl_sock);
|
||||
}
|
||||
|
||||
void no_trunc_strncpy(char *dest, const char *src, size_t dest_size)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
for (i = 0; i < dest_size && *src; i++) {
|
||||
*dest++ = *src++;
|
||||
}
|
||||
|
||||
*dest = 0;
|
||||
}
|
||||
/******************************************************************************
|
||||
@file util.c
|
||||
@brief some utils for this QCM tool.
|
||||
|
||||
DESCRIPTION
|
||||
Connectivity Management Tool for USB network adapter of Quectel wireless cellular modules.
|
||||
|
||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
||||
None.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||
Quectel Wireless Solution Proprietary and Confidential.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <net/if.h>
|
||||
typedef unsigned short sa_family_t;
|
||||
#include <linux/un.h>
|
||||
|
||||
#if defined(__STDC__)
|
||||
#include <stdarg.h>
|
||||
#define __V(x) x
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#define __V(x) (va_alist) va_dcl
|
||||
#define const
|
||||
#define volatile
|
||||
#endif
|
||||
|
||||
#include <syslog.h>
|
||||
|
||||
#include "QMIThread.h"
|
||||
|
||||
pthread_mutex_t cm_command_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_cond_t cm_command_cond = PTHREAD_COND_INITIALIZER;
|
||||
unsigned int cm_recv_buf[1024];
|
||||
|
||||
int cm_open_dev(const char *dev) {
|
||||
int fd;
|
||||
|
||||
fd = open(dev, O_RDWR | O_NONBLOCK | O_NOCTTY);
|
||||
if (fd != -1) {
|
||||
fcntl(fd, F_SETFL, fcntl(fd,F_GETFL) | O_NONBLOCK);
|
||||
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
if (!strncmp(dev, "/dev/tty", strlen("/dev/tty")))
|
||||
{
|
||||
//disable echo on serial ports
|
||||
struct termios ios;
|
||||
|
||||
memset(&ios, 0, sizeof(ios));
|
||||
tcgetattr( fd, &ios );
|
||||
cfmakeraw(&ios);
|
||||
cfsetispeed(&ios, B115200);
|
||||
cfsetospeed(&ios, B115200);
|
||||
tcsetattr( fd, TCSANOW, &ios );
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
}
|
||||
} else {
|
||||
dbg_time("Failed to open %s, errno: %d (%s)", dev, errno, strerror(errno));
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
int cm_open_proxy(const char *name) {
|
||||
int sockfd = -1;
|
||||
int reuse_addr = 1;
|
||||
struct sockaddr_un sockaddr;
|
||||
socklen_t alen;
|
||||
|
||||
/*Create server socket*/
|
||||
sockfd = socket(AF_LOCAL, SOCK_STREAM, 0);
|
||||
if (sockfd < 0)
|
||||
return sockfd;
|
||||
|
||||
memset(&sockaddr, 0, sizeof(sockaddr));
|
||||
sockaddr.sun_family = AF_LOCAL;
|
||||
sockaddr.sun_path[0] = 0;
|
||||
memcpy(sockaddr.sun_path + 1, name, strlen(name) );
|
||||
|
||||
alen = strlen(name) + offsetof(struct sockaddr_un, sun_path) + 1;
|
||||
if(connect(sockfd, (struct sockaddr *)&sockaddr, alen) < 0) {
|
||||
close(sockfd);
|
||||
dbg_time("connect %s errno: %d (%s)", name, errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse_addr,sizeof(reuse_addr));
|
||||
fcntl(sockfd, F_SETFL, fcntl(sockfd,F_GETFL) | O_NONBLOCK);
|
||||
fcntl(sockfd, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
dbg_time("connect to %s sockfd = %d", name, sockfd);
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
static void setTimespecRelative(struct timespec *p_ts, long long msec)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, (struct timezone *) NULL);
|
||||
|
||||
/* what's really funny about this is that I know
|
||||
pthread_cond_timedwait just turns around and makes this
|
||||
a relative time again */
|
||||
p_ts->tv_sec = tv.tv_sec + (msec / 1000);
|
||||
p_ts->tv_nsec = (tv.tv_usec + (msec % 1000) * 1000L ) * 1000L;
|
||||
if ((unsigned long)p_ts->tv_nsec >= 1000000000UL) {
|
||||
p_ts->tv_sec += 1;
|
||||
p_ts->tv_nsec -= 1000000000UL;
|
||||
}
|
||||
}
|
||||
|
||||
int pthread_cond_timeout_np(pthread_cond_t *cond, pthread_mutex_t * mutex, unsigned msecs) {
|
||||
if (msecs != 0) {
|
||||
unsigned i;
|
||||
unsigned t = msecs/4;
|
||||
int ret = 0;
|
||||
|
||||
if (t == 0)
|
||||
t = 1;
|
||||
|
||||
for (i = 0; i < msecs; i += t) {
|
||||
struct timespec ts;
|
||||
setTimespecRelative(&ts, t);
|
||||
//very old uclibc do not support pthread_condattr_setclock(CLOCK_MONOTONIC)
|
||||
ret = pthread_cond_timedwait(cond, mutex, &ts); //to advoid system time change
|
||||
if (ret != ETIMEDOUT) {
|
||||
if(ret) dbg_time("ret=%d, msecs=%u, t=%u", ret, msecs, t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
} else {
|
||||
return pthread_cond_wait(cond, mutex);
|
||||
}
|
||||
}
|
||||
|
||||
const char * get_time(void) {
|
||||
static char time_buf[128];
|
||||
struct timeval tv;
|
||||
time_t time;
|
||||
suseconds_t millitm;
|
||||
struct tm *ti;
|
||||
|
||||
gettimeofday (&tv, NULL);
|
||||
|
||||
time= tv.tv_sec;
|
||||
millitm = (tv.tv_usec + 500) / 1000;
|
||||
|
||||
if (millitm == 1000) {
|
||||
++time;
|
||||
millitm = 0;
|
||||
}
|
||||
|
||||
ti = localtime(&time);
|
||||
sprintf(time_buf, "%02d-%02d_%02d:%02d:%02d:%03d", ti->tm_mon+1, ti->tm_mday, ti->tm_hour, ti->tm_min, ti->tm_sec, (int)millitm);
|
||||
return time_buf;
|
||||
}
|
||||
|
||||
unsigned long clock_msec(void)
|
||||
{
|
||||
struct timespec tm;
|
||||
clock_gettime( CLOCK_MONOTONIC, &tm);
|
||||
return (unsigned long)(tm.tv_sec*1000 + (tm.tv_nsec/1000000));
|
||||
}
|
||||
|
||||
FILE *logfilefp = NULL;
|
||||
|
||||
void update_resolv_conf(int iptype, const char *ifname, const char *dns1, const char *dns2) {
|
||||
const char *dns_file = "/etc/resolv.conf";
|
||||
FILE *dns_fp;
|
||||
char dns_line[256];
|
||||
#define MAX_DNS 16
|
||||
char *dns_info[MAX_DNS];
|
||||
char dns_tag[64];
|
||||
int dns_match = 0;
|
||||
int i;
|
||||
|
||||
snprintf(dns_tag, sizeof(dns_tag), "# IPV%d %s", iptype, ifname);
|
||||
|
||||
for (i = 0; i < MAX_DNS; i++)
|
||||
dns_info[i] = NULL;
|
||||
|
||||
dns_fp = fopen(dns_file, "r");
|
||||
if (dns_fp) {
|
||||
i = 0;
|
||||
dns_line[sizeof(dns_line)-1] = '\0';
|
||||
|
||||
while((fgets(dns_line, sizeof(dns_line)-1, dns_fp)) != NULL) {
|
||||
if ((strlen(dns_line) > 1) && (dns_line[strlen(dns_line) - 1] == '\n'))
|
||||
dns_line[strlen(dns_line) - 1] = '\0';
|
||||
//dbg_time("%s", dns_line);
|
||||
if (strstr(dns_line, dns_tag)) {
|
||||
dns_match++;
|
||||
continue;
|
||||
}
|
||||
dns_info[i++] = strdup(dns_line);
|
||||
if (i == MAX_DNS)
|
||||
break;
|
||||
}
|
||||
|
||||
fclose(dns_fp);
|
||||
}
|
||||
else if (errno != ENOENT) {
|
||||
dbg_time("fopen %s fail, errno:%d (%s)", dns_file, errno, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
if (dns1 == NULL && dns_match == 0)
|
||||
return;
|
||||
|
||||
dns_fp = fopen(dns_file, "w");
|
||||
if (dns_fp) {
|
||||
if (dns1)
|
||||
fprintf(dns_fp, "nameserver %s %s\n", dns1, dns_tag);
|
||||
if (dns2)
|
||||
fprintf(dns_fp, "nameserver %s %s\n", dns2, dns_tag);
|
||||
|
||||
for (i = 0; i < MAX_DNS && dns_info[i]; i++)
|
||||
fprintf(dns_fp, "%s\n", dns_info[i]);
|
||||
fclose(dns_fp);
|
||||
}
|
||||
else {
|
||||
dbg_time("fopen %s fail, errno:%d (%s)", dns_file, errno, strerror(errno));
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_DNS && dns_info[i]; i++)
|
||||
free(dns_info[i]);
|
||||
}
|
||||
|
||||
pid_t getpid_by_pdp(int pdp, const char* program_name)
|
||||
{
|
||||
glob_t gt;
|
||||
int ret;
|
||||
char filter[16];
|
||||
pid_t pid;
|
||||
|
||||
snprintf(filter, sizeof(filter), "-n %d", pdp);
|
||||
ret = glob("/proc/*/cmdline", GLOB_NOSORT, NULL, >);
|
||||
if (ret != 0) {
|
||||
dbg_time("glob error, errno = %d(%s)", errno, strerror(errno));
|
||||
return -1;
|
||||
} else {
|
||||
int i = 0, fd = -1;
|
||||
ssize_t nreads;
|
||||
char cmdline[512] = {0};
|
||||
|
||||
for (i = 0; i < (int)gt.gl_pathc; i++) {
|
||||
fd = open(gt.gl_pathv[i], O_RDONLY);
|
||||
if (fd == -1) {
|
||||
dbg_time("open %s failed, errno = %d(%s)", gt.gl_pathv[i], errno, strerror(errno));
|
||||
globfree(>);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nreads = read(fd, cmdline, sizeof(cmdline));
|
||||
if (nreads > 0) {
|
||||
int pos = 0;
|
||||
while (pos < nreads-1) {
|
||||
if (cmdline[pos] == '\0')
|
||||
cmdline[pos] = ' '; // space
|
||||
pos++;
|
||||
}
|
||||
// printf("%s\n", cmdline);
|
||||
}
|
||||
|
||||
if (strstr(cmdline, program_name) && strstr(cmdline, filter)) {
|
||||
char path[64] = {0};
|
||||
char pidstr[64] = {0};
|
||||
char *p;
|
||||
|
||||
dbg_time("%s: %s", gt.gl_pathv[i], cmdline);
|
||||
strcpy(path, gt.gl_pathv[i]);
|
||||
p = strstr(gt.gl_pathv[i], "/cmdline");
|
||||
*p = '\0';
|
||||
while (*(--p) != '/') ;
|
||||
|
||||
strcpy(pidstr, p+1);
|
||||
pid = atoi(pidstr);
|
||||
globfree(>);
|
||||
|
||||
return pid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
globfree(>);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ql_get_driver_rmnet_info(PROFILE_T *profile, RMNET_INFO *rmnet_info) {
|
||||
int ifc_ctl_sock;
|
||||
struct ifreq ifr;
|
||||
int rc;
|
||||
int request = 0x89F3;
|
||||
unsigned char data[512];
|
||||
|
||||
memset(rmnet_info, 0x00, sizeof(*rmnet_info));
|
||||
|
||||
ifc_ctl_sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (ifc_ctl_sock <= 0) {
|
||||
dbg_time("socket() failed: %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&ifr, 0, sizeof(struct ifreq));
|
||||
strncpy(ifr.ifr_name, profile->usbnet_adapter, IFNAMSIZ);
|
||||
ifr.ifr_name[IFNAMSIZ - 1] = 0;
|
||||
ifr.ifr_ifru.ifru_data = (void *)data;
|
||||
|
||||
rc = ioctl(ifc_ctl_sock, request, &ifr);
|
||||
if (rc < 0) {
|
||||
if (errno != ENOTSUP)
|
||||
dbg_time("ioctl(0x%x, qmap_settings) errno:%d (%s), rc=%d", request, errno, strerror(errno), rc);
|
||||
}
|
||||
else {
|
||||
memcpy(rmnet_info, data, sizeof(*rmnet_info));
|
||||
}
|
||||
|
||||
close(ifc_ctl_sock);
|
||||
}
|
||||
|
||||
void ql_set_driver_qmap_setting(PROFILE_T *profile, QMAP_SETTING *qmap_settings) {
|
||||
int ifc_ctl_sock;
|
||||
struct ifreq ifr;
|
||||
int rc;
|
||||
int request = 0x89F2;
|
||||
|
||||
ifc_ctl_sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (ifc_ctl_sock <= 0) {
|
||||
dbg_time("socket() failed: %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&ifr, 0, sizeof(struct ifreq));
|
||||
strncpy(ifr.ifr_name, profile->usbnet_adapter, IFNAMSIZ);
|
||||
ifr.ifr_name[IFNAMSIZ - 1] = 0;
|
||||
ifr.ifr_ifru.ifru_data = (void *)qmap_settings;
|
||||
|
||||
rc = ioctl(ifc_ctl_sock, request, &ifr);
|
||||
if (rc < 0) {
|
||||
dbg_time("ioctl(0x%x, qmap_settings) failed: %s, rc=%d", request, strerror(errno), rc);
|
||||
}
|
||||
|
||||
close(ifc_ctl_sock);
|
||||
}
|
||||
|
||||
void no_trunc_strncpy(char *dest, const char *src, size_t dest_size)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
for (i = 0; i < dest_size && *src; i++) {
|
||||
*dest++ = *src++;
|
||||
}
|
||||
|
||||
*dest = 0;
|
||||
}
|
||||
@ -1,52 +1,52 @@
|
||||
/**
|
||||
@file
|
||||
util.h
|
||||
|
||||
@brief
|
||||
This file provides the definitions, and declares some common APIs for list-algorithm.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _UTILS_H_
|
||||
#define _UTILS_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <glob.h>
|
||||
|
||||
struct listnode
|
||||
{
|
||||
struct listnode *next;
|
||||
struct listnode *prev;
|
||||
};
|
||||
|
||||
#define node_to_item(node, container, member) \
|
||||
(container *) (((char*) (node)) - offsetof(container, member))
|
||||
|
||||
#define list_declare(name) \
|
||||
struct listnode name = { \
|
||||
.next = &name, \
|
||||
.prev = &name, \
|
||||
}
|
||||
|
||||
#define list_for_each(node, list) \
|
||||
for (node = (list)->next; node != (list); node = node->next)
|
||||
|
||||
#define list_for_each_reverse(node, list) \
|
||||
for (node = (list)->prev; node != (list); node = node->prev)
|
||||
|
||||
void list_init(struct listnode *list);
|
||||
void list_add_tail(struct listnode *list, struct listnode *item);
|
||||
void list_add_head(struct listnode *head, struct listnode *item);
|
||||
void list_remove(struct listnode *item);
|
||||
|
||||
#define list_empty(list) ((list) == (list)->next)
|
||||
#define list_head(list) ((list)->next)
|
||||
#define list_tail(list) ((list)->prev)
|
||||
|
||||
int epoll_register(int epoll_fd, int fd, unsigned int events);
|
||||
int epoll_deregister(int epoll_fd, int fd);
|
||||
const char * get_time(void);
|
||||
unsigned long clock_msec(void);
|
||||
pid_t getpid_by_pdp(int, const char*);
|
||||
|
||||
#endif
|
||||
/**
|
||||
@file
|
||||
util.h
|
||||
|
||||
@brief
|
||||
This file provides the definitions, and declares some common APIs for list-algorithm.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _UTILS_H_
|
||||
#define _UTILS_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <glob.h>
|
||||
|
||||
struct listnode
|
||||
{
|
||||
struct listnode *next;
|
||||
struct listnode *prev;
|
||||
};
|
||||
|
||||
#define node_to_item(node, container, member) \
|
||||
(container *) (((char*) (node)) - offsetof(container, member))
|
||||
|
||||
#define list_declare(name) \
|
||||
struct listnode name = { \
|
||||
.next = &name, \
|
||||
.prev = &name, \
|
||||
}
|
||||
|
||||
#define list_for_each(node, list) \
|
||||
for (node = (list)->next; node != (list); node = node->next)
|
||||
|
||||
#define list_for_each_reverse(node, list) \
|
||||
for (node = (list)->prev; node != (list); node = node->prev)
|
||||
|
||||
void list_init(struct listnode *list);
|
||||
void list_add_tail(struct listnode *list, struct listnode *item);
|
||||
void list_add_head(struct listnode *head, struct listnode *item);
|
||||
void list_remove(struct listnode *item);
|
||||
|
||||
#define list_empty(list) ((list) == (list)->next)
|
||||
#define list_head(list) ((list)->next)
|
||||
#define list_tail(list) ((list)->prev)
|
||||
|
||||
int epoll_register(int epoll_fd, int fd, unsigned int events);
|
||||
int epoll_deregister(int epoll_fd, int fd);
|
||||
const char * get_time(void);
|
||||
unsigned long clock_msec(void);
|
||||
pid_t getpid_by_pdp(int, const char*);
|
||||
|
||||
#endif
|
||||
@ -1,39 +0,0 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:= quectel-CM-5G
|
||||
PKG_VERSION:=1.6.5
|
||||
PKG_RELEASE:=1
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/quectel-CM-5G
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=quectel-CM-5G app
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
mkdir -p $(PKG_BUILD_DIR)
|
||||
$(CP) ./src/* $(PKG_BUILD_DIR)/
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
$(MAKE) -C "$(PKG_BUILD_DIR)" \
|
||||
EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
|
||||
CROSS_COMPILE="$(TARGET_CROSS)" \
|
||||
ARCH="$(LINUX_KARCH)" \
|
||||
M="$(PKG_BUILD_DIR)" \
|
||||
CC="$(TARGET_CC)"
|
||||
endef
|
||||
|
||||
define Package/quectel-CM-5G/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin $(1)/lib/netifd/proto
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/quectel-CM $(1)/usr/bin
|
||||
$(INSTALL_BIN) ./files/rmnet_init.sh $(1)/lib/netifd
|
||||
$(INSTALL_BIN) ./files/rmnet.script $(1)/lib/netifd
|
||||
$(INSTALL_BIN) ./files/rmnet.sh $(1)/lib/netifd/proto
|
||||
$(INSTALL_BIN) ./files/rmnet6.sh $(1)/lib/netifd/proto
|
||||
$(INSTALL_BIN) ./files/rmnet6.script $(1)/lib/netifd
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,quectel-CM-5G))
|
||||
@ -1,48 +0,0 @@
|
||||
|
||||
config dnsmasq
|
||||
option domainneeded '1'
|
||||
option boguspriv '1'
|
||||
option filterwin2k '0'
|
||||
option localise_queries '1'
|
||||
option rebind_protection '1'
|
||||
option rebind_localhost '1'
|
||||
option local '/lan/'
|
||||
option domain 'lan'
|
||||
option expandhosts '1'
|
||||
option nonegcache '0'
|
||||
option authoritative '1'
|
||||
option readethers '1'
|
||||
option leasefile '/tmp/dhcp.leases'
|
||||
option resolvfile '/tmp/resolv.conf.auto'
|
||||
option nonwildcard '1'
|
||||
option localservice '1'
|
||||
|
||||
config dhcp 'lan'
|
||||
option interface 'lan'
|
||||
option start '100'
|
||||
option limit '150'
|
||||
option leasetime '12h'
|
||||
option ra 'relay'
|
||||
option dhcpv6 'disabled'
|
||||
option ndp 'relay'
|
||||
|
||||
config dhcp 'wan'
|
||||
option interface 'wan'
|
||||
option ignore '1'
|
||||
option ra 'relay'
|
||||
option dhcpv6 'disabled'
|
||||
option ndp 'relay'
|
||||
option ndproxy_routing '0'
|
||||
option master '1'
|
||||
|
||||
config dhcp 'wan6'
|
||||
option ra 'relay'
|
||||
option dhcpv6 'disabled'
|
||||
option ndp 'relay'
|
||||
option ndproxy_routing '0'
|
||||
option master '1'
|
||||
option interface 'wan6'
|
||||
|
||||
config odhcpd 'odhcpd'
|
||||
option loglevel '7'
|
||||
|
||||
@ -1,66 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Copyright (c) 2019 Qualcomm Technologies, Inc.
|
||||
# All Rights Reserved.
|
||||
# Confidential and Proprietary - Qualcomm Technologies, Inc.
|
||||
|
||||
|
||||
[ -z "$1" ] && echo "Error: should be run by rmnet" && exit 1
|
||||
[ -z "$2" ] && echo "Error: should be run by rmnet" && exit 1
|
||||
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/network.sh
|
||||
. /lib/netifd/netifd-proto.sh
|
||||
|
||||
setup_interface() {
|
||||
INTERFACE=$1
|
||||
CONFIG=/tmp/rmnet_$2_ipv4config
|
||||
logger "rmnet setup_interface $1 $2 here"
|
||||
#Fetch information from lower.
|
||||
[ -f ${CONFIG} ] || {
|
||||
proto_notify_error "$INTERFACE" "RMNET data call Not ready"
|
||||
proto_block_restart "$INTERFACE"
|
||||
return
|
||||
}
|
||||
. ${CONFIG}
|
||||
ip=$PUBLIC_IP
|
||||
DNS=$DNSSERVERS
|
||||
router=$GATEWAY
|
||||
subnet=$NETMASK
|
||||
interface=$IFNAME
|
||||
#Send the information to the netifd
|
||||
proto_init_update "$interface" 1 1
|
||||
#ip and subnet
|
||||
proto_add_ipv4_address "$ip" "${subnet:-255.255.255.0}"
|
||||
|
||||
#Any router? if not, remove below scripts
|
||||
#router format should be separated by space
|
||||
for i in $router; do
|
||||
proto_add_ipv4_route "$i" 32 "" "$ip"
|
||||
proto_add_ipv4_route 0.0.0.0 0 "$i" "$ip"
|
||||
done
|
||||
|
||||
#dns information tell the netifd.
|
||||
for dns in $DNS; do
|
||||
proto_add_dns_server "$dns"
|
||||
done
|
||||
|
||||
#Domain information tell the netifd
|
||||
for domain in $domain; do
|
||||
proto_add_dns_search "$domain"
|
||||
done
|
||||
|
||||
#proto_add_data
|
||||
[ -n "$ZONE" ] && json_add_string zone "$ZONE"
|
||||
proto_close_data
|
||||
|
||||
proto_send_update "$INTERFACE"
|
||||
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
renew)
|
||||
setup_interface $2 $3
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
@ -1,32 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Copyright (c) 2019 Qualcomm Technologies, Inc.
|
||||
# All Rights Reserved.
|
||||
# Confidential and Proprietary - Qualcomm Technologies, Inc.
|
||||
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/network.sh
|
||||
. ../netifd-proto.sh
|
||||
|
||||
init_proto "$@"
|
||||
|
||||
proto_rmnet_setup() {
|
||||
local cfg="$1"
|
||||
local iface="$2"
|
||||
|
||||
logger "rmnet started"
|
||||
#Call rmnet management script below!!
|
||||
logger "rmnet updated ${cfg} ${iface}"
|
||||
/lib/netifd/rmnet.script renew $cfg $iface
|
||||
}
|
||||
|
||||
proto_rmnet_teardown() {
|
||||
local cfg="$1"
|
||||
#Tear down rmnet manager script here.*/
|
||||
}
|
||||
|
||||
proto_rmnet_init_config() {
|
||||
#ddno_device=1
|
||||
available=1
|
||||
}
|
||||
|
||||
add_protocol rmnet
|
||||
@ -1,61 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Copyright (c) 2019 Qualcomm Technologies, Inc.
|
||||
# All Rights Reserved.
|
||||
# Confidential and Proprietary - Qualcomm Technologies, Inc.
|
||||
|
||||
|
||||
[ -z "$1" ] && echo "Error: should be run by rmnet" && exit 1
|
||||
[ -z "$2" ] && echo "Error: should be run by rmnet" && exit 1
|
||||
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/network.sh
|
||||
. /lib/netifd/netifd-proto.sh
|
||||
|
||||
setup_interface() {
|
||||
INTERFACE=$1
|
||||
CONFIG=/tmp/rmnet_$2_ipv6config
|
||||
logger "rmnet setup_interface $1 $2 here"
|
||||
#Fetch information from lower.
|
||||
[ -f ${CONFIG} ] || {
|
||||
proto_notify_error "$INTERFACE" "RMNET data call NOT ready"
|
||||
proto_block_restart "$INTERFACE"
|
||||
return
|
||||
}
|
||||
. ${CONFIG}
|
||||
ADDRESSES=$PUBLIC_IP
|
||||
interface=$IFNAME
|
||||
#Send the information to the netifd
|
||||
proto_init_update "$interface" 1 1
|
||||
|
||||
#ip and subnet
|
||||
proto_add_ipv6_address "${PUBLIC_IP}" "128"
|
||||
proto_add_ipv6_prefix "${PUBLIC_IP}/${PrefixLength}"
|
||||
|
||||
#router format should be separated by space
|
||||
proto_add_ipv6_route "$GATEWAY" 128
|
||||
proto_add_ipv6_route "::0" 0 "$GATEWAY" "" "" "${PUBLIC_IP}/${PrefixLength}"
|
||||
|
||||
#dns information tell the netifd.
|
||||
for dns in $DNSSERVERS; do
|
||||
proto_add_dns_server "$dns"
|
||||
done
|
||||
|
||||
#Domain information tell the netifd
|
||||
for domain in $domain; do
|
||||
proto_add_dns_search "$domain"
|
||||
done
|
||||
|
||||
#proto_add_data
|
||||
[ -n "$ZONE" ] && json_add_string zone "$ZONE"
|
||||
proto_close_data
|
||||
|
||||
proto_send_update "$INTERFACE"
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
renew|bound)
|
||||
setup_interface $2 $3
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
@ -1,32 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Copyright (c) 2019 Qualcomm Technologies, Inc.
|
||||
# All Rights Reserved.
|
||||
# Confidential and Proprietary - Qualcomm Technologies, Inc.
|
||||
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/network.sh
|
||||
. ../netifd-proto.sh
|
||||
|
||||
init_proto "$@"
|
||||
|
||||
proto_rmnet6_setup() {
|
||||
local cfg="$1"
|
||||
local iface="$2"
|
||||
|
||||
logger "rmnet6 started"
|
||||
#Call rmnet management script below!!
|
||||
/lib/netifd/rmnet6.script renew $cfg $iface
|
||||
logger "rmnet6 updated"
|
||||
}
|
||||
|
||||
proto_rmnet6_teardown() {
|
||||
local cfg="$1"
|
||||
#Tear down rmnet manager script here.*/
|
||||
}
|
||||
|
||||
proto_rmnet6_init_config() {
|
||||
#ddno_device=1
|
||||
available=1
|
||||
}
|
||||
|
||||
add_protocol rmnet6
|
||||
@ -1,31 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci set network.wan='interface'
|
||||
uci set network.wan.ifname='wwan0'
|
||||
uci set network.wan.proto='rmnet'
|
||||
|
||||
uci set network.wan6='interface'
|
||||
uci set network.wan6.ifname='wwan0'
|
||||
uci set network.wan6.proto='rmnet6'
|
||||
|
||||
uci set dhcp.lan.ra='relay'
|
||||
uci set dhcp.lan.dhcpv6='disabled'
|
||||
uci set dhcp.lan.ndp='relay'
|
||||
|
||||
uci set dhcp.wan.ra='relay'
|
||||
uci set dhcp.wan.dhcpv6='disabled'
|
||||
uci set dhcp.wan.ndp='relay'
|
||||
uci set dhcp.wan.ndproxy_routing='0'
|
||||
|
||||
uci set dhcp.wan6=dhcp
|
||||
uci set dhcp.wan6.interface='wan6'
|
||||
uci set dhcp.wan6.ra='relay'
|
||||
uci set dhcp.wan6.dhcpv6='disabled'
|
||||
uci set dhcp.wan6.ndp='relay'
|
||||
uci set dhcp.wan6.ndproxy_routing='0'
|
||||
uci set dhcp.wan6.master='1'
|
||||
|
||||
uci set dhcp.odhcpd=odhcpd
|
||||
uci set dhcp.odhcpd.loglevel='7'
|
||||
|
||||
uci commit
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
/* This driver supports wwan (3G/LTE/?) devices using a vendor
|
||||
* specific management protocol called Qualcomm MSM Interface (QMI) -
|
||||
@@ -828,26 +826,25 @@ static struct rtnl_link_stats64 *_rmnet_
|
||||
@@ -846,12 +846,20 @@ static struct rtnl_link_stats64 *_rmnet_
|
||||
stats64 = per_cpu_ptr(dev->stats64, cpu);
|
||||
|
||||
do {
|
||||
|
||||
@ -59,13 +59,15 @@ struct rmnet_nss_cb {
|
||||
int (*nss_tx)(struct sk_buff *skb);
|
||||
};
|
||||
static struct rmnet_nss_cb __read_mostly *nss_cb = NULL;
|
||||
#if defined(CONFIG_PINCTRL_IPQ807x) || defined(CONFIG_PINCTRL_IPQ5018)
|
||||
#ifdef CONFIG_RMNET_DATA
|
||||
#if defined(CONFIG_PINCTRL_IPQ807x) || defined(CONFIG_PINCTRL_IPQ5018) || defined(CONFIG_PINCTRL_IPQ8074)
|
||||
//#ifdef CONFIG_RMNET_DATA //spf12.x none, not effect for spf11.x
|
||||
#define CONFIG_QCA_NSS_DRV
|
||||
/* define at qsdk/qca/src/linux-4.4/net/rmnet_data/rmnet_data_main.c */
|
||||
/* define at qsdk/qca/src/linux-4.4/net/rmnet_data/rmnet_data_main.c */ //for spf11.x
|
||||
/* define at qsdk/qca/src/datarmnet/core/rmnet_config.c */ //for spf12.x
|
||||
/* set at qsdk/qca/src/data-kernel/drivers/rmnet-nss/rmnet_nss.c */
|
||||
/* need add DEPENDS:= kmod-rmnet-core in feeds/makefile */
|
||||
extern struct rmnet_nss_cb *rmnet_nss_callbacks __rcu __read_mostly;
|
||||
#endif
|
||||
//#endif
|
||||
#endif
|
||||
|
||||
/* This driver supports wwan (3G/LTE/?) devices using a vendor
|
||||
@ -91,7 +93,7 @@ extern struct rmnet_nss_cb *rmnet_nss_callbacks __rcu __read_mostly;
|
||||
* These devices may alternatively/additionally be configured using AT
|
||||
* commands on a serial interface
|
||||
*/
|
||||
#define VERSION_NUMBER "V1.2.2"
|
||||
#define VERSION_NUMBER "V1.2.6"
|
||||
#define QUECTEL_WWAN_VERSION "Quectel_Linux&Android_QMI_WWAN_Driver_"VERSION_NUMBER
|
||||
static const char driver_name[] = "qmi_wwan_q";
|
||||
|
||||
@ -115,6 +117,7 @@ static const u8 default_modem_addr[ETH_ALEN] = {0x02, 0x50, 0xf3};
|
||||
1 - QMAP (Aggregation protocol)
|
||||
X - QMAP (Multiplexing and Aggregation protocol)
|
||||
*/
|
||||
//#define CONFIG_CLEAR_HALT
|
||||
#define QUECTEL_WWAN_QMAP 4 //MAX is 7
|
||||
|
||||
#if defined(QUECTEL_WWAN_QMAP)
|
||||
@ -216,7 +219,7 @@ struct qmap_priv {
|
||||
struct timespec64 agg_time;
|
||||
struct hrtimer agg_hrtimer;
|
||||
struct work_struct agg_wq;
|
||||
|
||||
|
||||
#ifdef QUECTEL_BRIDGE_MODE
|
||||
uint bridge_mode;
|
||||
uint bridge_ipv4;
|
||||
@ -225,7 +228,7 @@ struct qmap_priv {
|
||||
unsigned char bridge_self_mac[ETH_ALEN];
|
||||
#endif
|
||||
#endif
|
||||
uint use_qca_nss;
|
||||
uint use_qca_nss;
|
||||
};
|
||||
|
||||
struct qmap_hdr {
|
||||
@ -319,10 +322,10 @@ static int bridge_arp_reply(struct net_device *net, struct sk_buff *skb, uint br
|
||||
reply->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
reply->pkt_type = PACKET_HOST;
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0)
|
||||
netif_rx_ni(reply);
|
||||
#else
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION( 5,18,0 ))
|
||||
netif_rx(reply);
|
||||
#else
|
||||
netif_rx_ni(reply);
|
||||
#endif
|
||||
}
|
||||
return 1;
|
||||
@ -357,14 +360,14 @@ static struct sk_buff *bridge_mode_tx_fixup(struct net_device *net, struct sk_bu
|
||||
bridge_mac[0], bridge_mac[1], bridge_mac[2], bridge_mac[3], bridge_mac[4], bridge_mac[5]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_BRIDGE_LAN
|
||||
//bridge Lan IP 192.168.0.0
|
||||
if (ehdr->h_proto == htons(ETH_P_IP) && (iph->daddr & 0xFFFF) == 0xA8C0)
|
||||
{
|
||||
struct sk_buff *reply = skb_copy(skb, GFP_ATOMIC);
|
||||
ehdr = eth_hdr(reply);
|
||||
|
||||
|
||||
memcpy(ehdr->h_source, default_modem_addr, ETH_ALEN);
|
||||
if(is_qmap_netdev(net))
|
||||
{
|
||||
@ -378,20 +381,16 @@ static struct sk_buff *bridge_mode_tx_fixup(struct net_device *net, struct sk_bu
|
||||
sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
|
||||
memcpy(ehdr->h_dest, pQmapDev->bridge_self_mac, ETH_ALEN);
|
||||
}
|
||||
|
||||
|
||||
//pr_info("%s br rx pkt addr: %02x:%02x:%02x:%02x:%02x:%02x -> %02x:%02x:%02x:%02x:%02x:%02x\n", netdev_name(net),
|
||||
// ehdr->h_source[0], ehdr->h_source[1], ehdr->h_source[2], ehdr->h_source[3], ehdr->h_source[4], ehdr->h_source[5],
|
||||
// ehdr->h_dest[0], ehdr->h_dest[1], ehdr->h_dest[2], ehdr->h_dest[3], ehdr->h_dest[4], ehdr->h_dest[5]);
|
||||
|
||||
|
||||
skb_reset_mac_header(reply);
|
||||
__skb_pull(reply, skb_network_offset(reply));
|
||||
reply->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
reply->pkt_type = PACKET_HOST;
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0)
|
||||
netif_rx_ni(reply);
|
||||
#else
|
||||
netif_rx(reply);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
@ -510,7 +509,7 @@ static ssize_t link_state_store(struct device *dev, struct device_attribute *att
|
||||
}
|
||||
}
|
||||
|
||||
if (usbnetdev->net->flags & IFF_UP) {
|
||||
if (usbnetdev->net->flags & IFF_UP) {
|
||||
if (!pQmapDev->link_state) {
|
||||
netif_carrier_off(usbnetdev->net);
|
||||
}
|
||||
@ -683,7 +682,7 @@ static void qmap_wake_queue(sQmiWwanQmap *pQmapDev)
|
||||
|
||||
if (!pQmapDev || !pQmapDev->use_rmnet_usb)
|
||||
return;
|
||||
|
||||
|
||||
for (i = 0; i < pQmapDev->qmap_mode; i++) {
|
||||
struct net_device *qmap_net = pQmapDev->mpQmapNetDev[i];
|
||||
|
||||
@ -693,7 +692,7 @@ static void qmap_wake_queue(sQmiWwanQmap *pQmapDev)
|
||||
}
|
||||
}
|
||||
|
||||
static struct sk_buff * add_qhdr(struct sk_buff *skb, u8 mux_id) {
|
||||
static struct sk_buff * add_qhdr(struct sk_buff *skb, u8 mux_id, int *hdr_data, int ip_offset) {
|
||||
struct qmap_hdr *qhdr;
|
||||
int pad = 0;
|
||||
|
||||
@ -701,44 +700,55 @@ static struct sk_buff * add_qhdr(struct sk_buff *skb, u8 mux_id) {
|
||||
if (pad) {
|
||||
pad = 4 - pad;
|
||||
if (skb_tailroom(skb) < pad) {
|
||||
printk("skb_tailroom small!\n");
|
||||
//printk("skb_tailroom small!\n");
|
||||
pad = 0;
|
||||
}
|
||||
if (pad)
|
||||
__skb_put(skb, pad);
|
||||
}
|
||||
|
||||
qhdr = (struct qmap_hdr *)skb_push(skb, sizeof(struct qmap_hdr));
|
||||
|
||||
if (hdr_data) {
|
||||
qhdr = (struct qmap_hdr *)hdr_data;
|
||||
qhdr->pkt_len = cpu_to_be16(skb->len - ip_offset);
|
||||
}
|
||||
else {
|
||||
qhdr = (struct qmap_hdr *)skb_push(skb, sizeof(struct qmap_hdr));
|
||||
qhdr->pkt_len = cpu_to_be16(skb->len - sizeof(struct qmap_hdr));
|
||||
}
|
||||
qhdr->cd_rsvd_pad = pad;
|
||||
qhdr->mux_id = mux_id;
|
||||
qhdr->pkt_len = cpu_to_be16(skb->len - sizeof(struct qmap_hdr));
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff * add_qhdr_v5(struct sk_buff *skb, u8 mux_id) {
|
||||
static struct sk_buff * add_qhdr_v5(struct sk_buff *skb, u8 mux_id, int *hdr_data, int ip_offset) {
|
||||
struct rmnet_map_header *map_header;
|
||||
struct rmnet_map_v5_csum_header *ul_header;
|
||||
u32 padding, map_datalen;
|
||||
int pad = 0;
|
||||
|
||||
map_datalen = skb->len;
|
||||
padding = map_datalen%4;
|
||||
if (padding) {
|
||||
padding = 4 - padding;
|
||||
if (skb_tailroom(skb) < padding) {
|
||||
printk("skb_tailroom small!\n");
|
||||
padding = 0;
|
||||
pad = (skb->len - ip_offset) %4;
|
||||
if (pad) {
|
||||
pad = 4 - pad;
|
||||
if (skb_tailroom(skb) < pad) {
|
||||
//printk("skb_tailroom small!\n");
|
||||
pad = 0;
|
||||
}
|
||||
if (padding)
|
||||
__skb_put(skb, padding);
|
||||
if (pad)
|
||||
__skb_put(skb, pad);
|
||||
}
|
||||
|
||||
if (hdr_data) {
|
||||
map_header = (struct rmnet_map_header *)hdr_data;
|
||||
map_header->pkt_len = htons(skb->len - ip_offset);
|
||||
}
|
||||
else {
|
||||
map_header = (struct rmnet_map_header *)skb_push(skb, (sizeof(struct rmnet_map_header) + sizeof(struct rmnet_map_v5_csum_header)));
|
||||
map_header->pkt_len = htons(skb->len - (sizeof(struct rmnet_map_header) + sizeof(struct rmnet_map_v5_csum_header)));
|
||||
}
|
||||
|
||||
map_header = (struct rmnet_map_header *)skb_push(skb, (sizeof(struct rmnet_map_header) + sizeof(struct rmnet_map_v5_csum_header)));
|
||||
map_header->cd_bit = 0;
|
||||
map_header->next_hdr = 1;
|
||||
map_header->pad_len = padding;
|
||||
map_header->pad_len = pad;
|
||||
map_header->mux_id = mux_id;
|
||||
map_header->pkt_len = htons(map_datalen + padding);
|
||||
|
||||
ul_header = (struct rmnet_map_v5_csum_header *)(map_header + 1);
|
||||
memset(ul_header, 0, sizeof(*ul_header));
|
||||
@ -761,48 +771,38 @@ static void rmnet_vnd_update_rx_stats(struct net_device *net,
|
||||
struct pcpu_sw_netstats *stats64 = this_cpu_ptr(dev->stats64);
|
||||
|
||||
u64_stats_update_begin(&stats64->syncp);
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0)
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION( 6,0,0 ))
|
||||
stats64->rx_packets += rx_packets;
|
||||
stats64->rx_bytes += rx_bytes;
|
||||
#else
|
||||
u64_stats_add(&stats64->rx_packets, rx_packets);
|
||||
u64_stats_add(&stats64->rx_bytes, rx_bytes);
|
||||
u64_stats_add(&stats64->rx_packets, rx_packets);
|
||||
u64_stats_add(&stats64->rx_bytes, rx_bytes);
|
||||
#endif
|
||||
u64_stats_update_end(&stats64->syncp);
|
||||
#else
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0)
|
||||
net->stats.rx_packets += rx_packets;
|
||||
net->stats.rx_bytes += rx_bytes;
|
||||
#else
|
||||
u64_stats_add(&net->stats.rx_packets, rx_packets);
|
||||
u64_stats_add(&net->stats.rx_bytes, rx_bytes);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static void rmnet_vnd_update_tx_stats(struct net_device *net,
|
||||
unsigned tx_packets, unsigned tx_bytes) {
|
||||
unsigned tx_packets, unsigned tx_bytes) {
|
||||
#if defined(MHI_NETDEV_STATUS64)
|
||||
struct qmap_priv *dev = netdev_priv(net);
|
||||
struct pcpu_sw_netstats *stats64 = this_cpu_ptr(dev->stats64);
|
||||
|
||||
u64_stats_update_begin(&stats64->syncp);
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0)
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION( 6,0,0 ))
|
||||
stats64->tx_packets += tx_packets;
|
||||
stats64->tx_bytes += tx_bytes;
|
||||
#else
|
||||
u64_stats_add(&stats64->tx_packets, tx_packets);
|
||||
u64_stats_add(&stats64->tx_bytes, tx_bytes);
|
||||
u64_stats_add(&stats64->tx_packets, tx_packets);
|
||||
u64_stats_add(&stats64->tx_bytes, tx_bytes);
|
||||
#endif
|
||||
u64_stats_update_end(&stats64->syncp);
|
||||
#else
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0)
|
||||
net->stats.tx_packets += tx_packets;
|
||||
net->stats.tx_bytes += tx_bytes;
|
||||
#else
|
||||
u64_stats_add(&net->stats.tx_packets, tx_packets);
|
||||
u64_stats_add(&net->tx_bytes, tx_bytes);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -822,26 +822,37 @@ static struct rtnl_link_stats64 *_rmnet_vnd_get_stats64(struct net_device *net,
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
struct pcpu_sw_netstats *stats64;
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION( 6,1,0 ))
|
||||
u64 rx_packets, rx_bytes;
|
||||
u64 tx_packets, tx_bytes;
|
||||
|
||||
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
|
||||
rx_packets = stats64->rx_packets;
|
||||
rx_bytes = stats64->rx_bytes;
|
||||
tx_packets = stats64->tx_packets;
|
||||
tx_bytes = stats64->tx_bytes;
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION( 6,6,0 ))
|
||||
} while (u64_stats_fetch_retry_irq(&stats64->syncp, start));
|
||||
|
||||
stats->rx_packets += rx_packets;
|
||||
stats->rx_bytes += rx_bytes;
|
||||
stats->tx_packets += tx_packets;
|
||||
stats->tx_bytes += tx_bytes;
|
||||
#else
|
||||
} while (u64_stats_fetch_retry(&stats64->syncp, start));
|
||||
#endif
|
||||
u64_stats_t rx_packets, rx_bytes;
|
||||
u64_stats_t tx_packets, tx_bytes;
|
||||
|
||||
stats64 = per_cpu_ptr(dev->stats64, cpu);
|
||||
|
||||
do {
|
||||
start = u64_stats_fetch_begin_irq(&stats64->syncp);
|
||||
rx_packets = stats64->rx_packets;
|
||||
rx_bytes = stats64->rx_bytes;
|
||||
tx_packets = stats64->tx_packets;
|
||||
tx_bytes = stats64->tx_bytes;
|
||||
} while (u64_stats_fetch_retry_irq(&stats64->syncp, start));
|
||||
|
||||
stats->rx_packets += u64_stats_read(&rx_packets);
|
||||
stats->rx_bytes += u64_stats_read(&rx_bytes);
|
||||
@ -897,7 +908,7 @@ static void rmnet_usb_tx_skb_destructor(struct sk_buff *skb) {
|
||||
|
||||
if (pQmapDev && pQmapDev->use_rmnet_usb) {
|
||||
int i;
|
||||
|
||||
|
||||
for (i = 0; i < pQmapDev->qmap_mode; i++) {
|
||||
struct net_device *qmap_net = pQmapDev->mpQmapNetDev[i];
|
||||
|
||||
@ -967,7 +978,7 @@ static void rmnet_usb_tx_agg_work(struct work_struct *work)
|
||||
ktime_get_ts64(&priv->agg_time);
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->agg_lock, flags);
|
||||
|
||||
|
||||
if (skb) {
|
||||
int err;
|
||||
#if 0
|
||||
@ -998,7 +1009,7 @@ static long agg_bypass_time __read_mostly = 10000000L;
|
||||
module_param(agg_bypass_time, long, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(agg_bypass_time, "Skip agg when apart spaced more than this");
|
||||
|
||||
static int rmnet_usb_tx_agg(struct sk_buff *skb, struct qmap_priv *priv) {
|
||||
static int rmnet_usb_tx_agg(struct sk_buff *skb, struct qmap_priv *priv, int *hdr_data, int hdr_len, int ip_offset) {
|
||||
struct qmi_wwan_state *info = (void *)&priv->dev->data;
|
||||
sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
|
||||
struct tx_agg_ctx *ctx = &pQmapDev->tx_ctx;
|
||||
@ -1021,15 +1032,22 @@ static int rmnet_usb_tx_agg(struct sk_buff *skb, struct qmap_priv *priv) {
|
||||
rmnet_vnd_update_tx_stats(pNet, 1, skb->len);
|
||||
|
||||
if (ctx->ul_data_aggregation_max_datagrams == 1) {
|
||||
skb->protocol = htons(ETH_P_MAP);
|
||||
skb->dev = priv->real_dev;
|
||||
agg_skb = alloc_skb(skb->len + hdr_len, GFP_ATOMIC);
|
||||
if (agg_skb) {
|
||||
memcpy(skb_put(agg_skb, hdr_len), hdr_data, hdr_len);
|
||||
memcpy(skb_put(agg_skb, skb->len - ip_offset), skb->data + ip_offset, skb->len - ip_offset);
|
||||
agg_skb->protocol = htons(ETH_P_MAP);
|
||||
agg_skb->dev = priv->real_dev;
|
||||
#if 0
|
||||
if (!skb->destructor)
|
||||
skb->destructor = rmnet_usb_tx_skb_destructor;
|
||||
if (!agg_skb->destructor)
|
||||
agg_skb->destructor = rmnet_usb_tx_skb_destructor;
|
||||
#endif
|
||||
err = dev_queue_xmit(skb);
|
||||
if (err != NET_XMIT_SUCCESS)
|
||||
err = dev_queue_xmit(agg_skb);
|
||||
if (err != NET_XMIT_SUCCESS)
|
||||
pNet->stats.tx_errors++;
|
||||
}
|
||||
dev_kfree_skb_any(skb);
|
||||
skb = NULL;
|
||||
return NET_XMIT_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1041,8 +1059,9 @@ new_packet:
|
||||
diff = timespec64_sub(now, priv->agg_time);
|
||||
|
||||
if (priv->agg_skb) {
|
||||
if ((priv->agg_skb->len + skb->len) < ctx->ul_data_aggregation_max_size) {
|
||||
memcpy(skb_put(priv->agg_skb, skb->len), skb->data, skb->len);
|
||||
if ((priv->agg_skb->len + skb->len + hdr_len) < ctx->ul_data_aggregation_max_size) {
|
||||
memcpy(skb_put(priv->agg_skb, hdr_len), hdr_data, hdr_len);
|
||||
memcpy(skb_put(priv->agg_skb, skb->len - ip_offset), skb->data + ip_offset, skb->len - ip_offset);
|
||||
priv->agg_count++;
|
||||
|
||||
if (diff.tv_sec > 0 || diff.tv_nsec > agg_time_limit) {
|
||||
@ -1052,14 +1071,14 @@ new_packet:
|
||||
ready2send = 1;
|
||||
}
|
||||
else if (xmit_more == 0) {
|
||||
struct rmnet_map_header *map_header = (struct rmnet_map_header *)skb->data;
|
||||
struct rmnet_map_header *map_header = (struct rmnet_map_header *)hdr_data;
|
||||
size_t offset = sizeof(struct rmnet_map_header);
|
||||
if (map_header->next_hdr)
|
||||
offset += sizeof(struct rmnet_map_v5_csum_header);
|
||||
|
||||
ready2send = rmnet_usb_tx_agg_skip(skb, offset);
|
||||
}
|
||||
|
||||
|
||||
dev_kfree_skb_any(skb);
|
||||
skb = NULL;
|
||||
}
|
||||
@ -1078,7 +1097,7 @@ new_packet:
|
||||
ready2send = 1;
|
||||
}
|
||||
else if (xmit_more == 0) {
|
||||
struct rmnet_map_header *map_header = (struct rmnet_map_header *)skb->data;
|
||||
struct rmnet_map_header *map_header = (struct rmnet_map_header *)hdr_data;
|
||||
size_t offset = sizeof(struct rmnet_map_header);
|
||||
if (map_header->next_hdr)
|
||||
offset += sizeof(struct rmnet_map_v5_csum_header);
|
||||
@ -1090,7 +1109,8 @@ new_packet:
|
||||
priv->agg_skb = alloc_skb(ctx->ul_data_aggregation_max_size, GFP_ATOMIC);
|
||||
if (priv->agg_skb) {
|
||||
skb_reset_network_header(priv->agg_skb); //protocol da1a is buggy, dev wwan0
|
||||
memcpy(skb_put(priv->agg_skb, skb->len), skb->data, skb->len);
|
||||
memcpy(skb_put(priv->agg_skb, hdr_len), hdr_data, hdr_len);
|
||||
memcpy(skb_put(priv->agg_skb, skb->len - ip_offset), skb->data + ip_offset, skb->len - ip_offset);
|
||||
priv->agg_count++;
|
||||
dev_kfree_skb_any(skb);
|
||||
skb = NULL;
|
||||
@ -1101,7 +1121,12 @@ new_packet:
|
||||
}
|
||||
|
||||
if (ready2send) {
|
||||
agg_skb = skb;
|
||||
agg_skb = alloc_skb(skb->len + hdr_len, GFP_ATOMIC);
|
||||
if (agg_skb) {
|
||||
memcpy(skb_put(agg_skb, hdr_len), hdr_data, hdr_len);
|
||||
memcpy(skb_put(agg_skb, skb->len - ip_offset), skb->data + ip_offset, skb->len - ip_offset);
|
||||
}
|
||||
dev_kfree_skb_any(skb);
|
||||
skb = NULL;
|
||||
}
|
||||
}
|
||||
@ -1142,6 +1167,9 @@ static netdev_tx_t rmnet_vnd_start_xmit(struct sk_buff *skb,
|
||||
{
|
||||
int err;
|
||||
struct qmap_priv *priv = netdev_priv(pNet);
|
||||
int qmap_hdr[2];
|
||||
int hdr_len = 0;
|
||||
int ip_offset = 0;
|
||||
|
||||
if (netif_queue_stopped(priv->real_dev)) {
|
||||
netif_stop_queue(pNet);
|
||||
@ -1159,18 +1187,24 @@ static netdev_tx_t rmnet_vnd_start_xmit(struct sk_buff *skb,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
ip_offset = ETH_HLEN;
|
||||
#else
|
||||
if (skb_pull(skb, ETH_HLEN) == NULL) {
|
||||
dev_kfree_skb_any (skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
//printk("%s 2 skb=%p, len=%d, protocol=%x, hdr_len=%d\n", __func__, skb, skb->len, skb->protocol, skb->hdr_len);
|
||||
|
||||
if (priv->qmap_version == 5) {
|
||||
add_qhdr(skb, priv->mux_id);
|
||||
add_qhdr(skb, priv->mux_id, qmap_hdr, ip_offset);
|
||||
hdr_len = 4;
|
||||
}
|
||||
else if (priv->qmap_version == 9) {
|
||||
add_qhdr_v5(skb, priv->mux_id);
|
||||
add_qhdr_v5(skb, priv->mux_id, qmap_hdr, ip_offset);
|
||||
hdr_len = 8;
|
||||
}
|
||||
else {
|
||||
dev_kfree_skb_any (skb);
|
||||
@ -1178,7 +1212,7 @@ static netdev_tx_t rmnet_vnd_start_xmit(struct sk_buff *skb,
|
||||
}
|
||||
//printk("%s skb=%p, len=%d, protocol=%x, hdr_len=%d\n", __func__, skb, skb->len, skb->protocol, skb->hdr_len);
|
||||
|
||||
err = rmnet_usb_tx_agg(skb, priv);
|
||||
err = rmnet_usb_tx_agg(skb, priv, qmap_hdr, hdr_len, ip_offset);
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -1246,7 +1280,7 @@ static rx_handler_result_t qca_nss_rx_handler(struct sk_buff **pskb)
|
||||
|
||||
if (!skb)
|
||||
return RX_HANDLER_CONSUMED;
|
||||
|
||||
|
||||
//printk("%s skb=%p, len=%d, protocol=%x, hdr_len=%d\n", __func__, skb, skb->len, skb->protocol, skb->hdr_len);
|
||||
|
||||
if (skb->pkt_type == PACKET_LOOPBACK)
|
||||
@ -1295,10 +1329,10 @@ static int qmap_register_device(sQmiWwanQmap * pDev, u8 offset_id)
|
||||
priv->dev = pDev->mpNetDev;
|
||||
priv->qmap_version = pDev->qmap_version;
|
||||
priv->mux_id = QUECTEL_QMAP_MUX_ID + offset_id;
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 17, 0)
|
||||
memcpy (qmap_net->dev_addr, real_dev->dev_addr, ETH_ALEN);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0)
|
||||
__dev_addr_set(qmap_net, real_dev->dev_addr, ETH_ALEN);
|
||||
#else
|
||||
eth_hw_addr_set (real_dev, qmap_net->dev_addr);
|
||||
memcpy (qmap_net->dev_addr, real_dev->dev_addr, ETH_ALEN);
|
||||
#endif
|
||||
|
||||
#ifdef QUECTEL_BRIDGE_MODE
|
||||
@ -1314,7 +1348,9 @@ static int qmap_register_device(sQmiWwanQmap * pDev, u8 offset_id)
|
||||
if (nss_cb && use_qca_nss) {
|
||||
rmnet_usb_rawip_setup(qmap_net);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PINCTRL_IPQ9574
|
||||
rmnet_usb_rawip_setup(qmap_net);
|
||||
#endif
|
||||
priv->agg_skb = NULL;
|
||||
priv->agg_count = 0;
|
||||
hrtimer_init(&priv->agg_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
@ -1350,7 +1386,7 @@ static int qmap_register_device(sQmiWwanQmap * pDev, u8 offset_id)
|
||||
netdev_info(qmap_net, "NSS context created\n");
|
||||
rtnl_lock();
|
||||
netdev_rx_handler_register(qmap_net, qca_nss_rx_handler, NULL);
|
||||
rtnl_unlock();
|
||||
rtnl_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1379,7 +1415,7 @@ static void qmap_unregister_device(sQmiWwanQmap * pDev, u8 offset_id) {
|
||||
pDev->mpQmapNetDev[offset_id] = NULL;
|
||||
netif_carrier_off( qmap_net );
|
||||
netif_stop_queue( qmap_net );
|
||||
|
||||
|
||||
hrtimer_cancel(&priv->agg_hrtimer);
|
||||
cancel_work_sync(&priv->agg_wq);
|
||||
spin_lock_irqsave(&priv->agg_lock, flags);
|
||||
@ -1460,7 +1496,11 @@ static int qmap_ndo_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||
#ifdef CONFIG_BRIDGE_LAN
|
||||
BRMAC_SETTING brmac_settings = {0};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CLEAR_HALT
|
||||
uint clear_halt = 0;
|
||||
#endif
|
||||
|
||||
|
||||
switch (cmd) {
|
||||
case 0x89F1: //SIOCDEVPRIVATE
|
||||
rc = copy_from_user(&link_state, ifr->ifr_ifru.ifru_data, sizeof(link_state));
|
||||
@ -1493,7 +1533,7 @@ static int qmap_ndo_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||
rc = copy_to_user(ifr->ifr_ifru.ifru_data, &pQmapDev->rmnet_info, sizeof(pQmapDev->rmnet_info));
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
#ifdef CONFIG_BRIDGE_LAN
|
||||
case 0x89F4: //SIOCDEVPRIVATE
|
||||
rc = copy_from_user(&brmac_settings, ifr->ifr_ifru.ifru_data, sizeof(brmac_settings));
|
||||
@ -1515,6 +1555,16 @@ static int qmap_ndo_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_CLEAR_HALT
|
||||
case 0x89F5: //SIOCDEVPRIVATE
|
||||
rc = copy_from_user(&clear_halt, ifr->ifr_ifru.ifru_data, sizeof(clear_halt));
|
||||
if (rc == 0 && clear_halt == 1) {
|
||||
usb_clear_halt(usbnetdev->udev,usbnetdev->in);
|
||||
usb_clear_halt(usbnetdev->udev,usbnetdev->out);
|
||||
pr_info("usb_clear_halt EPIN EPOUT\n");
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -1657,9 +1707,9 @@ static struct sk_buff *qmap_qmi_wwan_tx_fixup(struct usbnet *dev, struct sk_buff
|
||||
|
||||
if (skb) {
|
||||
if(pQmapDev->qmap_version == 5)
|
||||
add_qhdr(skb, QUECTEL_QMAP_MUX_ID);
|
||||
add_qhdr(skb, QUECTEL_QMAP_MUX_ID, NULL, 0);
|
||||
else
|
||||
add_qhdr_v5(skb, QUECTEL_QMAP_MUX_ID);
|
||||
add_qhdr_v5(skb, QUECTEL_QMAP_MUX_ID, NULL, 0);
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
@ -1690,7 +1740,7 @@ static void qmap_packet_decode(sQmiWwanQmap *pQmapDev,
|
||||
while (skb_in->len > sizeof(struct qmap_hdr)) {
|
||||
struct rmnet_map_header *map_header = (struct rmnet_map_header *)skb_in->data;
|
||||
struct rmnet_map_v5_csum_header *ul_header = NULL;
|
||||
size_t hdr_size = sizeof(struct rmnet_map_header);
|
||||
size_t hdr_size = sizeof(struct rmnet_map_header);
|
||||
struct net_device *qmap_net;
|
||||
int pkt_len = ntohs(map_header->pkt_len);
|
||||
int skb_len;
|
||||
@ -1702,7 +1752,7 @@ static void qmap_packet_decode(sQmiWwanQmap *pQmapDev,
|
||||
ul_header = (struct rmnet_map_v5_csum_header *)(map_header + 1);
|
||||
hdr_size += sizeof(struct rmnet_map_v5_csum_header);
|
||||
}
|
||||
|
||||
|
||||
skb_len = pkt_len - (map_header->pad_len&0x3F);
|
||||
skb_len -= dl_minimum_padding;
|
||||
|
||||
@ -1717,7 +1767,7 @@ static void qmap_packet_decode(sQmiWwanQmap *pQmapDev,
|
||||
dev_info(dev, "drop qmap unknow mux_id %x\n", map_header->mux_id);
|
||||
goto skip_pkt;
|
||||
}
|
||||
|
||||
|
||||
if (skb_len > qmap_net->mtu) {
|
||||
dev_info(dev, "drop skb_len=%x larger than mtu=%d\n", skb_len, qmap_net->mtu);
|
||||
goto error_pkt;
|
||||
@ -1760,7 +1810,7 @@ static void qmap_packet_decode(sQmiWwanQmap *pQmapDev,
|
||||
dev_info(dev, "unknow skb->protocol %02x\n", skb_in->data[hdr_size]);
|
||||
goto error_pkt;
|
||||
}
|
||||
|
||||
|
||||
qmap_skb = netdev_alloc_skb(qmap_net, skb_len);
|
||||
if (qmap_skb) {
|
||||
skb_put(qmap_skb, skb_len);
|
||||
@ -1815,7 +1865,7 @@ static int qmap_qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
|
||||
sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
|
||||
struct sk_buff *qmap_skb;
|
||||
struct sk_buff_head skb_chain;
|
||||
|
||||
|
||||
if (pQmapDev->qmap_mode == 0)
|
||||
return qmi_wwan_rx_fixup(dev, skb_in);
|
||||
|
||||
@ -1862,7 +1912,7 @@ static void (*_usbnet_get_stats64)(struct net_device *net, struct rtnl_link_stat
|
||||
static void qmi_wwan_get_stats64(struct net_device *net, struct rtnl_link_stats64 *stats) {
|
||||
if (_usbnet_get_stats64) ////c8b5d129ee293bcf972e7279ac996bb8a138505c
|
||||
return _usbnet_get_stats64(net, stats);
|
||||
|
||||
|
||||
netdev_stats_to_stats64(stats, &net->stats);
|
||||
}
|
||||
#else
|
||||
@ -1871,7 +1921,7 @@ static struct rtnl_link_stats64 * (*_usbnet_get_stats64)(struct net_device *net,
|
||||
static struct rtnl_link_stats64 * qmi_wwan_get_stats64(struct net_device *net, struct rtnl_link_stats64 *stats) {
|
||||
if (_usbnet_get_stats64)
|
||||
return _usbnet_get_stats64(net, stats);
|
||||
|
||||
|
||||
netdev_stats_to_stats64(stats, &net->stats);
|
||||
return stats;
|
||||
}
|
||||
@ -1896,7 +1946,7 @@ static int qmi_wwan_open (struct net_device *net) {
|
||||
}
|
||||
|
||||
static netdev_tx_t qmi_wwan_start_xmit (struct sk_buff *skb,
|
||||
struct net_device *net)
|
||||
struct net_device *net)
|
||||
{
|
||||
struct usbnet * usbnetdev = netdev_priv( net );
|
||||
struct qmi_wwan_state *info = (void *)&usbnetdev->data;
|
||||
@ -1907,7 +1957,7 @@ static netdev_tx_t qmi_wwan_start_xmit (struct sk_buff *skb,
|
||||
|
||||
if (netif_queue_stopped(net) && pQmapDev && pQmapDev->use_rmnet_usb) {
|
||||
int i;
|
||||
|
||||
|
||||
for (i = 0; i < pQmapDev->qmap_mode; i++) {
|
||||
struct net_device *qmap_net = pQmapDev->mpQmapNetDev[i];
|
||||
if (qmap_net) {
|
||||
@ -2066,17 +2116,17 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||
|
||||
/* make MAC addr easily distinguishable from an IP header */
|
||||
if (possibly_iphdr(dev->net->dev_addr)) {
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0)
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0)
|
||||
u8 temp_addr[ETH_ALEN];
|
||||
memcpy(temp_addr, dev->net->dev_addr, ETH_ALEN);
|
||||
temp_addr[0] |= 0x02; /* set local assignment bit */
|
||||
temp_addr[0] &= 0xbf; /* clear "IP" bit */
|
||||
__dev_addr_set(dev->net, temp_addr, ETH_ALEN);
|
||||
#else
|
||||
dev->net->dev_addr[0] |= 0x02; /* set local assignment bit */
|
||||
dev->net->dev_addr[0] &= 0xbf; /* clear "IP" bit */
|
||||
#else
|
||||
u8 addr = dev->net->dev_addr[0];
|
||||
|
||||
addr |= 0x02; /* set local assignment bit */
|
||||
addr &= 0xbf; /* clear "IP" bit */
|
||||
dev_addr_mod(dev->net, 0, &addr, 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (!_usbnet_get_stats64)
|
||||
_usbnet_get_stats64 = dev->net->netdev_ops->ndo_get_stats64;
|
||||
dev->net->netdev_ops = &qmi_wwan_netdev_ops;
|
||||
@ -2109,6 +2159,9 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||
NULL, 0, 100);
|
||||
}
|
||||
|
||||
usb_clear_halt(dev->udev,dev->in);
|
||||
usb_clear_halt(dev->udev,dev->out);
|
||||
|
||||
//to advoid module report mtu 1460, but rx 1500 bytes IP packets, and cause the customer's system crash
|
||||
//next setting can make usbnet.c:usbnet_change_mtu() do not modify rx_urb_size according to hard mtu
|
||||
dev->rx_urb_size = ETH_DATA_LEN + ETH_HLEN + 6;
|
||||
@ -2140,12 +2193,13 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||
int qmap_version = (dev->driver_info->data>>8)&0xFF;
|
||||
int qmap_size = (dev->driver_info->data)&0xFF;
|
||||
int idProduct = le16_to_cpu(dev->udev->descriptor.idProduct);
|
||||
int lte_a = (idProduct == 0x0306 || idProduct == 0x030B || idProduct == 0x0512 || idProduct == 0x0620 || idProduct == 0x0800 || idProduct == 0x0801);
|
||||
int lte_a = (idProduct == 0x0306 || idProduct == 0x030B || idProduct == 0x0512 || idProduct == 0x0620 ||
|
||||
idProduct == 0x0800 || idProduct == 0x0801 || idProduct == 0x0122);
|
||||
|
||||
if (qmap_size > 4096 || dev->udev->speed >= USB_SPEED_SUPER) { //if meet this requirements, must be LTE-A or 5G
|
||||
lte_a = 1;
|
||||
}
|
||||
|
||||
|
||||
pQmapDev->qmap_mode = qmap_mode;
|
||||
if (lte_a && pQmapDev->qmap_mode == 0) {
|
||||
pQmapDev->qmap_mode = 1; //force use QMAP
|
||||
@ -2162,13 +2216,13 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||
|
||||
if (pQmapDev->qmap_mode > 1)
|
||||
pQmapDev->use_rmnet_usb = 1;
|
||||
else if (idProduct == 0x0800 || idProduct == 0x0801)
|
||||
else if (idProduct == 0x0800 || idProduct == 0x0801 || idProduct == 0x0122)
|
||||
pQmapDev->use_rmnet_usb = 1; //benefit for ul data agg
|
||||
#ifdef QMI_NETDEV_ONE_CARD_MODE
|
||||
if(pQmapDev->use_rmnet_usb == 1 && pQmapDev->qmap_mode == 1)
|
||||
one_card_mode = 1;
|
||||
pQmapDev->rmnet_info.mux_id[0] = QUECTEL_QMAP_MUX_ID;
|
||||
#endif
|
||||
#endif
|
||||
pQmapDev->rmnet_info.size = sizeof(RMNET_INFO);
|
||||
pQmapDev->rmnet_info.rx_urb_size = pQmapDev->qmap_size;
|
||||
pQmapDev->rmnet_info.ep_type = 2; //DATA_EP_TYPE_HSUSB
|
||||
@ -2182,7 +2236,7 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||
pQmapDev->tx_ctx.ul_data_aggregation_max_size = 1500;
|
||||
#endif
|
||||
|
||||
if (pQmapDev->use_rmnet_usb && !one_card_mode) {
|
||||
if (pQmapDev->use_rmnet_usb && !one_card_mode) {
|
||||
pQmapDev->driver_info = rmnet_usb_info;
|
||||
pQmapDev->driver_info.data = dev->driver_info->data;
|
||||
dev->driver_info = &pQmapDev->driver_info;
|
||||
@ -2350,7 +2404,7 @@ static int rmnet_usb_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2411,7 +2465,7 @@ static const struct driver_info qmi_wwan_info = {
|
||||
};
|
||||
|
||||
#define qmi_wwan_raw_ip_info \
|
||||
.description = "WWAN/QMI device", \
|
||||
.description = "WWAN/QMI Raw IP device", \
|
||||
.flags = FLAG_WWAN | FLAG_RX_ASSEMBLE | FLAG_NOARP | FLAG_SEND_ZLP, \
|
||||
.bind = qmi_wwan_bind, \
|
||||
.unbind = qmi_wwan_unbind, \
|
||||
@ -2459,6 +2513,7 @@ static const struct usb_device_id products[] = {
|
||||
{ QMI_FIXED_INTF(0x05C6, 0x9215, 4) }, /* Quectel EC20 (MDM9215) */
|
||||
{ QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0125, 4, mdm9x07) }, /* Quectel EC20 (MDM9X07)/EC25/EG25 */
|
||||
{ QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0121, 4, mdm9x07) }, /* Quectel EC21 */
|
||||
{ QMI_FIXED_RAWIP_INTF(0x2C7C, 0x030E, 4, mdm9x07) }, /* Quectel EM05G */
|
||||
{ QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0191, 4, mdm9x07) }, /* Quectel EG91 */
|
||||
{ QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0195, 4, mdm9x07) }, /* Quectel EG95 */
|
||||
{ QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0700, 3, mdm9x07) }, /* Quectel BG95 (at+qcfgext="usbnet","rmnet") */
|
||||
@ -2470,6 +2525,7 @@ static const struct usb_device_id products[] = {
|
||||
{ QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0620, 4, mdm9x40) }, /* Quectel EG20 */
|
||||
{ QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0800, 4, sdx55) }, /* Quectel RG500 */
|
||||
{ QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0801, 4, sdx55) }, /* Quectel RG520 */
|
||||
{ QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0122, 4, sdx55) }, /* Quectel RG650 */
|
||||
{ } /* END */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, products);
|
||||
@ -2576,11 +2632,11 @@ static void qmap_qmi_wwan_disconnect(struct usb_interface *intf)
|
||||
}
|
||||
|
||||
tasklet_kill(&pQmapDev->txq);
|
||||
|
||||
|
||||
usbnet_disconnect(intf);
|
||||
/* struct usbnet *dev had free by usbnet_disconnect()->free_netdev().
|
||||
so we should access info. */
|
||||
//info->unused = 0;
|
||||
//info->unused = 0;
|
||||
kfree(pQmapDev);
|
||||
}
|
||||
#endif
|
||||
|
||||
Loading…
Reference in New Issue
Block a user