🎨 Sync 2026-06-07 18:17:40

This commit is contained in:
github-actions[bot] committed 2026-06-07 18:17:40 +08:00
1 parent 31e511aff8
commit 71aabc1bca
307 files changed
+14316 -109882

No files matched your search

+26 -22
View File
@@ -1,22 +1,26 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=fibocom-dial
PKG_RELEASE:=3
include $(INCLUDE_DIR)/package.mk
define Package/fibocom-dial
SECTION:=net
CATEGORY:=Network
SUBMENU:=WWAN
TITLE:=Dialing tool for Fibocom WWAN modules
endef
define Package/fibocom-dial/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/fibocom-dial $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/fibo_qmimsg_server $(1)/usr/bin/fibocom-qmimsg-server
$(INSTALL_BIN) $(PKG_BUILD_DIR)/multi-pdn-manager $(1)/usr/bin/fibocom-multi-pdn-manager
endef
$(eval $(call BuildPackage,fibocom-dial))
include $(TOPDIR)/rules.mk
PKG_NAME:=fibocom-dial
PKG_RELEASE:=4
include $(INCLUDE_DIR)/package.mk
define Package/fibocom-dial
SECTION:=utils
CATEGORY:=Utilities
TITLE:=Fibocom Dial
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
define Package/fibocom-dial/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/fibocom-dial $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/fibo_qmimsg_server $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/multi-pdn-manager $(1)/usr/bin
endef
$(eval $(call BuildPackage,fibocom-dial))
@@ -1,42 +0,0 @@
--- a/QmiWwanCM.c
+++ b/QmiWwanCM.c
@@ -8,7 +8,7 @@ typedef unsigned short sa_family_t;
#include "QMIThread.h"
#ifdef CONFIG_QMIWWAN
-#define FIBO_QMI_PROXY "fibo_qmimsg_server"
+#define FIBO_QMI_PROXY "fibocom-qmimsg-server"
static int cdc_wdm_fd = -1;
static UCHAR GetQCTLTransactionId(void)
--- a/fibo_qmimsg_server.c
+++ b/fibo_qmimsg_server.c
@@ -984,7 +984,7 @@ qmi_proxy_init_fail:
}
//2021-06-03 willa.liu@fibocom.com changed begin
static void qmi_start_server(void) {
- qmi_proxy_server_fd = create_local_server("fibo_qmimsg_server");
+ qmi_proxy_server_fd = create_local_server("fibocom-qmimsg-server");
printf("%s: qmi_proxy_server_fd = %d\n", __func__, qmi_proxy_server_fd);
if (qmi_proxy_server_fd == -1) {
dprintf("%s Failed to create %s, errno: %d (%s)\n", __func__, "fibocom-qmi-proxy", errno, strerror(errno));
--- a/multi-pdn-manager.c
+++ b/multi-pdn-manager.c
@@ -812,7 +812,7 @@ int main(int argc, char *argv[])
{
dbg_time("The Fibocom multi-pdn-manager is already running! So killall multi-pdn-manager!");
system("killall -9 fibocom-dial");
- system("killall -9 multi-pdn-manager");
+ system("killall -9 fibocom-multi-pdn-manager");
}
}
else
@@ -846,7 +846,7 @@ int main(int argc, char *argv[])
if (is_pcie_dial())
{
dbg_time("start qmi proxy server");
- //system("./fibo_qmimsg_server -d /dev/mhi_QMI0 &");
+ //system("./fibocom-qmimsg-server -d /dev/mhi_QMI0 &");
}
while (1)
{
+275 -275
View File
@@ -1,275 +1,275 @@
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include "QMIThread.h"
#ifdef CONFIG_GOBINET
// 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;
static int send_count = 0;
fd = qmiclientId[pRequest->QMIHdr.QMIType];
if (fd <= 0) {
dbg_time("%s QMIType: %d has no clientID", __func__,
pRequest->QMIHdr.QMIType);
return -ENODEV;
}
// Always ready to write
re_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;
send_count = 0;
}
else
{
send_count++;
dbg_time("%s write=%d, errno: %d (%s) send_count %d", __func__, ret, errno, strerror(errno), send_count);
if (send_count < 3)
{
sleep(1);
goto re_write;
}
}
} 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 = open(qcqmi, O_RDWR | O_NONBLOCK | O_NOCTTY);
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;
}
dbg_time("%s: QMIType = %d clientid %d", __func__, QMIType, ClientId);
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_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;
dbg_time("%s %d", __func__, __LINE__);
if (profile->ipv4_flag)
qmiclientId[QMUX_TYPE_WDS] = GobiNetGetClientID(qcqmi, QMUX_TYPE_WDS);
if (profile->ipv6_flag)
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);
// qmiclientId[QMUX_TYPE_WDS_ADMIN] =
// GobiNetGetClientID(qcqmi, QMUX_TYPE_WDS_ADMIN);
//if ((qmiclientId[QMUX_TYPE_WDS] == 0) && (qmiclientId[QMUX_TYPE_WDS_IPV6] == 0)) /*|| (clientWDA == -1)*/ {
if ((qmiclientId[QMUX_TYPE_DMS] == 0) ||
(qmiclientId[QMUX_TYPE_NAS] == 0) ||
(qmiclientId[QMUX_TYPE_UIM] == 0) ||
(profile->ipv4_flag ? ((qmiclientId[QMUX_TYPE_WDS] == 0) ? 1 : 0):0)||
(profile->ipv6_flag ? ((qmiclientId[QMUX_TYPE_WDS_IPV6] == 0) ? 1 : 0):0))
{
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 SIGTERM:
wait_for_request_quit = 1;
break;
default:
break;
}
}
continue;
}
{
ssize_t nreads;
static UCHAR QMIBuf[4096];
PQCQMIMSG pResponse = (PQCQMIMSG)QMIBuf;
nreads = read(fd, &pResponse->MUXMsg,
sizeof(QMIBuf) - 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;
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;
}
#else
static int GobiNetSendQMI(PQCQMIMSG pRequest) { return -1; }
static void *GobiNetThread(void *pData)
{
dbg_time("please set CONFIG_GOBINET");
return NULL;
}
#endif
const struct qmi_device_ops gobi_qmidev_ops = {
.deinit = GobiNetDeInit,
.send = GobiNetSendQMI,
.read = GobiNetThread,
};
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include "QMIThread.h"
#ifdef CONFIG_GOBINET
// 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;
static int send_count = 0;
fd = qmiclientId[pRequest->QMIHdr.QMIType];
if (fd <= 0) {
dbg_time("%s QMIType: %d has no clientID", __func__,
pRequest->QMIHdr.QMIType);
return -ENODEV;
}
// Always ready to write
re_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;
send_count = 0;
}
else
{
send_count++;
dbg_time("%s write=%d, errno: %d (%s) send_count %d", __func__, ret, errno, strerror(errno), send_count);
if (send_count < 3)
{
sleep(1);
goto re_write;
}
}
} 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 = open(qcqmi, O_RDWR | O_NONBLOCK | O_NOCTTY);
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;
}
dbg_time("%s: QMIType = %d clientid %d", __func__, QMIType, ClientId);
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_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;
dbg_time("%s %d", __func__, __LINE__);
if (profile->ipv4_flag)
qmiclientId[QMUX_TYPE_WDS] = GobiNetGetClientID(qcqmi, QMUX_TYPE_WDS);
if (profile->ipv6_flag)
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);
// qmiclientId[QMUX_TYPE_WDS_ADMIN] =
// GobiNetGetClientID(qcqmi, QMUX_TYPE_WDS_ADMIN);
//if ((qmiclientId[QMUX_TYPE_WDS] == 0) && (qmiclientId[QMUX_TYPE_WDS_IPV6] == 0)) /*|| (clientWDA == -1)*/ {
if ((qmiclientId[QMUX_TYPE_DMS] == 0) ||
(qmiclientId[QMUX_TYPE_NAS] == 0) ||
(qmiclientId[QMUX_TYPE_UIM] == 0) ||
(profile->ipv4_flag ? ((qmiclientId[QMUX_TYPE_WDS] == 0) ? 1 : 0):0)||
(profile->ipv6_flag ? ((qmiclientId[QMUX_TYPE_WDS_IPV6] == 0) ? 1 : 0):0))
{
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 SIGTERM:
wait_for_request_quit = 1;
break;
default:
break;
}
}
continue;
}
{
ssize_t nreads;
static UCHAR QMIBuf[4096];
PQCQMIMSG pResponse = (PQCQMIMSG)QMIBuf;
nreads = read(fd, &pResponse->MUXMsg,
sizeof(QMIBuf) - 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;
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;
}
#else
static int GobiNetSendQMI(PQCQMIMSG pRequest) { return -1; }
static void *GobiNetThread(void *pData)
{
dbg_time("please set CONFIG_GOBINET");
return NULL;
}
#endif
const struct qmi_device_ops gobi_qmidev_ops = {
.deinit = GobiNetDeInit,
.send = GobiNetSendQMI,
.read = GobiNetThread,
};
+363 -363
View File
@@ -1,363 +1,363 @@
/*===========================================================================
M P Q C T L. H
DESCRIPTION:
This module contains QMI QCTL module.
INITIALIZATION AND SEQUENCING REQUIREMENTS:
Copyright (C) 2011 by Qualcomm Technologies, Incorporated. All Rights Reserved.
===========================================================================*/
#ifndef MPQCTL_H
#define MPQCTL_H
#include "MPQMI.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 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_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;
};
} __attribute__((packed)) QMICTL_MSG, *PQMICTL_MSG;
#endif // MPQCTL_H
/*===========================================================================
M P Q C T L. H
DESCRIPTION:
This module contains QMI QCTL module.
INITIALIZATION AND SEQUENCING REQUIREMENTS:
Copyright (C) 2011 by Qualcomm Technologies, Incorporated. All Rights Reserved.
===========================================================================*/
#ifndef MPQCTL_H
#define MPQCTL_H
#include "MPQMI.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 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_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;
};
} __attribute__((packed)) QMICTL_MSG, *PQMICTL_MSG;
#endif // MPQCTL_H
+287 -287
View File
@@ -1,287 +1,287 @@
/*===========================================================================
M P Q M I. H
DESCRIPTION:
This module contains forward references to the QMI module.
INITIALIZATION AND SEQUENCING REQUIREMENTS:
Copyright (C) 2011 by Qualcomm Technologies, Incorporated. All Rights Reserved.
===========================================================================*/
/*===========================================================================
EDIT HISTORY FOR FILE
$Header: //depot/QMI/win/qcdrivers/ndis/MPQMI.h#3 $
when who what, where, why
-------- --- ----------------------------------------------------------
11/20/04 hg Initial version.
===========================================================================*/
#ifndef USBQMI_H
#define USBQMI_H
typedef char CHAR;
typedef unsigned char UCHAR;
typedef unsigned short USHORT;
typedef int INT;
typedef unsigned int UINT;
typedef long LONG;
typedef unsigned int ULONG;
typedef unsigned long long ULONG64;
typedef 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_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;
// 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
/*===========================================================================
M P Q M I. H
DESCRIPTION:
This module contains forward references to the QMI module.
INITIALIZATION AND SEQUENCING REQUIREMENTS:
Copyright (C) 2011 by Qualcomm Technologies, Incorporated. All Rights Reserved.
===========================================================================*/
/*===========================================================================
EDIT HISTORY FOR FILE
$Header: //depot/QMI/win/qcdrivers/ndis/MPQMI.h#3 $
when who what, where, why
-------- --- ----------------------------------------------------------
11/20/04 hg Initial version.
===========================================================================*/
#ifndef USBQMI_H
#define USBQMI_H
typedef char CHAR;
typedef unsigned char UCHAR;
typedef unsigned short USHORT;
typedef int INT;
typedef unsigned int UINT;
typedef long LONG;
typedef unsigned int ULONG;
typedef unsigned long long ULONG64;
typedef 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_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;
// 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
+437 -437
View File
@@ -1,437 +1,437 @@
#include "QMIThread.h"
static char line[1024];
static pthread_mutex_t dumpQMIMutex = PTHREAD_MUTEX_INITIALIZER;
#undef dbg
#define dbg(format, arg...) \
do { \
if (strlen(line) < sizeof(line)) \
snprintf(&line[strlen(line)], sizeof(line) - strlen(line), format, \
##arg); \
} while (0)
PQMI_TLV_HDR GetTLV(PQCQMUX_MSG_HDR pQMUXMsgHdr, int TLVType);
typedef struct {
UINT type;
const char *name;
} QMI_NAME_T;
#define qmi_name_item(type) \
{ \
type, #type \
}
static const QMI_NAME_T qmux_ctl_QMICTLType[] = {
// QMICTL Type
qmi_name_item(QMICTL_SET_INSTANCE_ID_REQ), // 0x0020
qmi_name_item(QMICTL_SET_INSTANCE_ID_RESP), // 0x0020
qmi_name_item(QMICTL_GET_VERSION_REQ), // 0x0021
qmi_name_item(QMICTL_GET_VERSION_RESP), // 0x0021
qmi_name_item(QMICTL_GET_CLIENT_ID_REQ), // 0x0022
qmi_name_item(QMICTL_GET_CLIENT_ID_RESP), // 0x0022
qmi_name_item(QMICTL_RELEASE_CLIENT_ID_REQ), // 0x0023
qmi_name_item(QMICTL_RELEASE_CLIENT_ID_RESP), // 0x0023
qmi_name_item(QMICTL_REVOKE_CLIENT_ID_IND), // 0x0024
qmi_name_item(QMICTL_INVALID_CLIENT_ID_IND), // 0x0025
qmi_name_item(QMICTL_SET_DATA_FORMAT_REQ), // 0x0026
qmi_name_item(QMICTL_SET_DATA_FORMAT_RESP), // 0x0026
qmi_name_item(QMICTL_SYNC_REQ), // 0x0027
qmi_name_item(QMICTL_SYNC_RESP), // 0x0027
qmi_name_item(QMICTL_SYNC_IND), // 0x0027
};
static const QMI_NAME_T qmux_CtlFlags[] = {
qmi_name_item(QMUX_CTL_FLAG_TYPE_CMD),
qmi_name_item(QMUX_CTL_FLAG_TYPE_RSP),
qmi_name_item(QMUX_CTL_FLAG_TYPE_IND),
};
static const QMI_NAME_T qmux_wds_Type[] = {
qmi_name_item(QMIWDS_SET_EVENT_REPORT_REQ), // 0x0001
qmi_name_item(QMIWDS_SET_EVENT_REPORT_RESP), // 0x0001
qmi_name_item(QMIWDS_EVENT_REPORT_IND), // 0x0001
qmi_name_item(QMIWDS_START_NETWORK_INTERFACE_REQ), // 0x0020
qmi_name_item(QMIWDS_START_NETWORK_INTERFACE_RESP), // 0x0020
qmi_name_item(QMIWDS_STOP_NETWORK_INTERFACE_REQ), // 0x0021
qmi_name_item(QMIWDS_STOP_NETWORK_INTERFACE_RESP), // 0x0021
qmi_name_item(QMIWDS_GET_PKT_SRVC_STATUS_REQ), // 0x0022
qmi_name_item(QMIWDS_GET_PKT_SRVC_STATUS_RESP), // 0x0022
qmi_name_item(QMIWDS_GET_PKT_SRVC_STATUS_IND), // 0x0022
qmi_name_item(QMIWDS_GET_CURRENT_CHANNEL_RATE_REQ), // 0x0023
qmi_name_item(QMIWDS_GET_CURRENT_CHANNEL_RATE_RESP), // 0x0023
qmi_name_item(QMIWDS_GET_PKT_STATISTICS_REQ), // 0x0024
qmi_name_item(QMIWDS_GET_PKT_STATISTICS_RESP), // 0x0024
//begin modified by zhangkaibo add create profile qmi. mantis 0049137,0048741 20200610
qmi_name_item(QMIWDS_CREATE_PROFILE_SETTINGS_REQ), // 0x0027
qmi_name_item(QMIWDS_CREATE_PROFILE_SETTINGS_RESP), // 0x0027
//end modified by zhangkaibo add create profile qmi. mantis 0049137,0048741 20200610
qmi_name_item(QMIWDS_MODIFY_PROFILE_SETTINGS_REQ), // 0x0028
qmi_name_item(QMIWDS_MODIFY_PROFILE_SETTINGS_RESP), // 0x0028
qmi_name_item(QMIWDS_GET_PROFILE_SETTINGS_REQ), // 0x002B
qmi_name_item(QMIWDS_GET_PROFILE_SETTINGS_RESP), // 0x002BD
qmi_name_item(QMIWDS_GET_DEFAULT_SETTINGS_REQ), // 0x002C
qmi_name_item(QMIWDS_GET_DEFAULT_SETTINGS_RESP), // 0x002C
qmi_name_item(QMIWDS_GET_RUNTIME_SETTINGS_REQ), // 0x002D
qmi_name_item(QMIWDS_GET_RUNTIME_SETTINGS_RESP), // 0x002D
qmi_name_item(QMIWDS_GET_MIP_MODE_REQ), // 0x002F
qmi_name_item(QMIWDS_GET_MIP_MODE_RESP), // 0x002F
qmi_name_item(QMIWDS_GET_DATA_BEARER_REQ), // 0x0037
qmi_name_item(QMIWDS_GET_DATA_BEARER_RESP), // 0x0037
qmi_name_item(QMIWDS_DUN_CALL_INFO_REQ), // 0x0038
qmi_name_item(QMIWDS_DUN_CALL_INFO_RESP), // 0x0038
qmi_name_item(QMIWDS_DUN_CALL_INFO_IND), // 0x0038
qmi_name_item(QMIWDS_SET_CLIENT_IP_FAMILY_PREF_REQ), // 0x004D
qmi_name_item(QMIWDS_SET_CLIENT_IP_FAMILY_PREF_RESP), // 0x004D
qmi_name_item(QMIWDS_SET_AUTO_CONNECT_REQ), // 0x0051
qmi_name_item(QMIWDS_SET_AUTO_CONNECT_RESP), // 0x0051
qmi_name_item(QMIWDS_BIND_MUX_DATA_PORT_REQ), // 0x00A2
qmi_name_item(QMIWDS_BIND_MUX_DATA_PORT_RESP), // 0x00A2
};
static const QMI_NAME_T qmux_dms_Type[] = {
// ======================= DMS ==============================
qmi_name_item(QMIDMS_SET_EVENT_REPORT_REQ), // 0x0001
qmi_name_item(QMIDMS_SET_EVENT_REPORT_RESP), // 0x0001
qmi_name_item(QMIDMS_EVENT_REPORT_IND), // 0x0001
qmi_name_item(QMIDMS_GET_DEVICE_CAP_REQ), // 0x0020
qmi_name_item(QMIDMS_GET_DEVICE_CAP_RESP), // 0x0020
qmi_name_item(QMIDMS_GET_DEVICE_MFR_REQ), // 0x0021
qmi_name_item(QMIDMS_GET_DEVICE_MFR_RESP), // 0x0021
qmi_name_item(QMIDMS_GET_DEVICE_MODEL_ID_REQ), // 0x0022
qmi_name_item(QMIDMS_GET_DEVICE_MODEL_ID_RESP), // 0x0022
qmi_name_item(QMIDMS_GET_DEVICE_REV_ID_REQ), // 0x0023
qmi_name_item(QMIDMS_GET_DEVICE_REV_ID_RESP), // 0x0023
qmi_name_item(QMIDMS_GET_MSISDN_REQ), // 0x0024
qmi_name_item(QMIDMS_GET_MSISDN_RESP), // 0x0024
qmi_name_item(QMIDMS_GET_DEVICE_SERIAL_NUMBERS_REQ), // 0x0025
qmi_name_item(QMIDMS_GET_DEVICE_SERIAL_NUMBERS_RESP), // 0x0025
qmi_name_item(QMIDMS_UIM_SET_PIN_PROTECTION_REQ), // 0x0027
qmi_name_item(QMIDMS_UIM_SET_PIN_PROTECTION_RESP), // 0x0027
qmi_name_item(QMIDMS_UIM_VERIFY_PIN_REQ), // 0x0028
qmi_name_item(QMIDMS_UIM_VERIFY_PIN_RESP), // 0x0028
qmi_name_item(QMIDMS_UIM_UNBLOCK_PIN_REQ), // 0x0029
qmi_name_item(QMIDMS_UIM_UNBLOCK_PIN_RESP), // 0x0029
qmi_name_item(QMIDMS_UIM_CHANGE_PIN_REQ), // 0x002A
qmi_name_item(QMIDMS_UIM_CHANGE_PIN_RESP), // 0x002A
qmi_name_item(QMIDMS_UIM_GET_PIN_STATUS_REQ), // 0x002B
qmi_name_item(QMIDMS_UIM_GET_PIN_STATUS_RESP), // 0x002B
qmi_name_item(QMIDMS_GET_DEVICE_HARDWARE_REV_REQ), // 0x002C
qmi_name_item(QMIDMS_GET_DEVICE_HARDWARE_REV_RESP), // 0x002C
qmi_name_item(QMIDMS_GET_OPERATING_MODE_REQ), // 0x002D
qmi_name_item(QMIDMS_GET_OPERATING_MODE_RESP), // 0x002D
qmi_name_item(QMIDMS_SET_OPERATING_MODE_REQ), // 0x002E
qmi_name_item(QMIDMS_SET_OPERATING_MODE_RESP), // 0x002E
qmi_name_item(QMIDMS_GET_ACTIVATED_STATUS_REQ), // 0x0031
qmi_name_item(QMIDMS_GET_ACTIVATED_STATUS_RESP), // 0x0031
qmi_name_item(QMIDMS_ACTIVATE_AUTOMATIC_REQ), // 0x0032
qmi_name_item(QMIDMS_ACTIVATE_AUTOMATIC_RESP), // 0x0032
qmi_name_item(QMIDMS_ACTIVATE_MANUAL_REQ), // 0x0033
qmi_name_item(QMIDMS_ACTIVATE_MANUAL_RESP), // 0x0033
qmi_name_item(QMIDMS_UIM_GET_ICCID_REQ), // 0x003C
qmi_name_item(QMIDMS_UIM_GET_ICCID_RESP), // 0x003C
qmi_name_item(QMIDMS_UIM_GET_CK_STATUS_REQ), // 0x0040
qmi_name_item(QMIDMS_UIM_GET_CK_STATUS_RESP), // 0x0040
qmi_name_item(QMIDMS_UIM_SET_CK_PROTECTION_REQ), // 0x0041
qmi_name_item(QMIDMS_UIM_SET_CK_PROTECTION_RESP), // 0x0041
qmi_name_item(QMIDMS_UIM_UNBLOCK_CK_REQ), // 0x0042
qmi_name_item(QMIDMS_UIM_UNBLOCK_CK_RESP), // 0x0042
qmi_name_item(QMIDMS_UIM_GET_IMSI_REQ), // 0x0043
qmi_name_item(QMIDMS_UIM_GET_IMSI_RESP), // 0x0043
qmi_name_item(QMIDMS_UIM_GET_STATE_REQ), // 0x0044
qmi_name_item(QMIDMS_UIM_GET_STATE_RESP), // 0x0044
qmi_name_item(QMIDMS_GET_BAND_CAP_REQ), // 0x0045
qmi_name_item(QMIDMS_GET_BAND_CAP_RESP), // 0x0045
};
static const QMI_NAME_T qmux_nas_Type[] = {
// ======================= NAS ==============================
qmi_name_item(QMINAS_SET_EVENT_REPORT_REQ), // 0x0002
qmi_name_item(QMINAS_SET_EVENT_REPORT_RESP), // 0x0002
qmi_name_item(QMINAS_EVENT_REPORT_IND), // 0x0002
qmi_name_item(QMINAS_GET_SIGNAL_STRENGTH_REQ), // 0x0020
qmi_name_item(QMINAS_GET_SIGNAL_STRENGTH_RESP), // 0x0020
qmi_name_item(QMINAS_PERFORM_NETWORK_SCAN_REQ), // 0x0021
qmi_name_item(QMINAS_PERFORM_NETWORK_SCAN_RESP), // 0x0021
qmi_name_item(QMINAS_INITIATE_NW_REGISTER_REQ), // 0x0022
qmi_name_item(QMINAS_INITIATE_NW_REGISTER_RESP), // 0x0022
qmi_name_item(QMINAS_INITIATE_ATTACH_REQ), // 0x0023
qmi_name_item(QMINAS_INITIATE_ATTACH_RESP), // 0x0023
qmi_name_item(QMINAS_GET_SERVING_SYSTEM_REQ), // 0x0024
qmi_name_item(QMINAS_GET_SERVING_SYSTEM_RESP), // 0x0024
qmi_name_item(QMINAS_SERVING_SYSTEM_IND), // 0x0024
qmi_name_item(QMINAS_GET_HOME_NETWORK_REQ), // 0x0025
qmi_name_item(QMINAS_GET_HOME_NETWORK_RESP), // 0x0025
qmi_name_item(QMINAS_GET_PREFERRED_NETWORK_REQ), // 0x0026
qmi_name_item(QMINAS_GET_PREFERRED_NETWORK_RESP), // 0x0026
qmi_name_item(QMINAS_SET_PREFERRED_NETWORK_REQ), // 0x0027
qmi_name_item(QMINAS_SET_PREFERRED_NETWORK_RESP), // 0x0027
qmi_name_item(QMINAS_GET_FORBIDDEN_NETWORK_REQ), // 0x0028
qmi_name_item(QMINAS_GET_FORBIDDEN_NETWORK_RESP), // 0x0028
qmi_name_item(QMINAS_SET_FORBIDDEN_NETWORK_REQ), // 0x0029
qmi_name_item(QMINAS_SET_FORBIDDEN_NETWORK_RESP), // 0x0029
qmi_name_item(QMINAS_SET_TECHNOLOGY_PREF_REQ), // 0x002A
qmi_name_item(QMINAS_SET_TECHNOLOGY_PREF_RESP), // 0x002A
qmi_name_item(QMINAS_GET_RF_BAND_INFO_REQ), // 0x0031
qmi_name_item(QMINAS_GET_RF_BAND_INFO_RESP), // 0x0031
qmi_name_item(QMINAS_GET_PLMN_NAME_REQ), // 0x0044
qmi_name_item(QMINAS_GET_PLMN_NAME_RESP), // 0x0044
qmi_name_item(FIBO_PACKET_TRANSFER_START_IND), // 0X100
qmi_name_item(FIBO_PACKET_TRANSFER_END_IND), // 0X101
qmi_name_item(QMINAS_GET_SYS_INFO_REQ), // 0x004D
qmi_name_item(QMINAS_GET_SYS_INFO_RESP), // 0x004D
qmi_name_item(QMINAS_SYS_INFO_IND), // 0x004D
};
static const QMI_NAME_T qmux_wms_Type[] = {
// ======================= WMS ==============================
qmi_name_item(QMIWMS_SET_EVENT_REPORT_REQ), // 0x0001
qmi_name_item(QMIWMS_SET_EVENT_REPORT_RESP), // 0x0001
qmi_name_item(QMIWMS_EVENT_REPORT_IND), // 0x0001
qmi_name_item(QMIWMS_RAW_SEND_REQ), // 0x0020
qmi_name_item(QMIWMS_RAW_SEND_RESP), // 0x0020
qmi_name_item(QMIWMS_RAW_WRITE_REQ), // 0x0021
qmi_name_item(QMIWMS_RAW_WRITE_RESP), // 0x0021
qmi_name_item(QMIWMS_RAW_READ_REQ), // 0x0022
qmi_name_item(QMIWMS_RAW_READ_RESP), // 0x0022
qmi_name_item(QMIWMS_MODIFY_TAG_REQ), // 0x0023
qmi_name_item(QMIWMS_MODIFY_TAG_RESP), // 0x0023
qmi_name_item(QMIWMS_DELETE_REQ), // 0x0024
qmi_name_item(QMIWMS_DELETE_RESP), // 0x0024
qmi_name_item(QMIWMS_GET_MESSAGE_PROTOCOL_REQ), // 0x0030
qmi_name_item(QMIWMS_GET_MESSAGE_PROTOCOL_RESP), // 0x0030
qmi_name_item(QMIWMS_LIST_MESSAGES_REQ), // 0x0031
qmi_name_item(QMIWMS_LIST_MESSAGES_RESP), // 0x0031
qmi_name_item(QMIWMS_GET_SMSC_ADDRESS_REQ), // 0x0034
qmi_name_item(QMIWMS_GET_SMSC_ADDRESS_RESP), // 0x0034
qmi_name_item(QMIWMS_SET_SMSC_ADDRESS_REQ), // 0x0035
qmi_name_item(QMIWMS_SET_SMSC_ADDRESS_RESP), // 0x0035
qmi_name_item(QMIWMS_GET_STORE_MAX_SIZE_REQ), // 0x0036
qmi_name_item(QMIWMS_GET_STORE_MAX_SIZE_RESP), // 0x0036
};
static const QMI_NAME_T qmux_wds_admin_Type[] = {
qmi_name_item(QMIWDS_ADMIN_SET_DATA_FORMAT_REQ), // 0x0020
qmi_name_item(QMIWDS_ADMIN_SET_DATA_FORMAT_RESP), // 0x0020
qmi_name_item(QMIWDS_ADMIN_GET_DATA_FORMAT_REQ), // 0x0021
qmi_name_item(QMIWDS_ADMIN_GET_DATA_FORMAT_RESP), // 0x0021
qmi_name_item(QMIWDS_ADMIN_SET_QMAP_SETTINGS_REQ), // 0x002B
qmi_name_item(QMIWDS_ADMIN_SET_QMAP_SETTINGS_RESP), // 0x002B
qmi_name_item(QMIWDS_ADMIN_GET_QMAP_SETTINGS_REQ), // 0x002C
qmi_name_item(QMIWDS_ADMIN_GET_QMAP_SETTINGS_RESP), // 0x002C
};
static const QMI_NAME_T qmux_uim_Type[] = {
qmi_name_item(QMIUIM_READ_TRANSPARENT_REQ), // 0x0020
qmi_name_item(QMIUIM_READ_TRANSPARENT_RESP), // 0x0020
qmi_name_item(QMIUIM_READ_TRANSPARENT_IND), // 0x0020
qmi_name_item(QMIUIM_READ_RECORD_REQ), // 0x0021
qmi_name_item(QMIUIM_READ_RECORD_RESP), // 0x0021
qmi_name_item(QMIUIM_READ_RECORD_IND), // 0x0021
qmi_name_item(QMIUIM_WRITE_TRANSPARENT_REQ), // 0x0022
qmi_name_item(QMIUIM_WRITE_TRANSPARENT_RESP), // 0x0022
qmi_name_item(QMIUIM_WRITE_TRANSPARENT_IND), // 0x0022
qmi_name_item(QMIUIM_WRITE_RECORD_REQ), // 0x0023
qmi_name_item(QMIUIM_WRITE_RECORD_RESP), // 0x0023
qmi_name_item(QMIUIM_WRITE_RECORD_IND), // 0x0023
qmi_name_item(QMIUIM_SET_PIN_PROTECTION_REQ), // 0x0025
qmi_name_item(QMIUIM_SET_PIN_PROTECTION_RESP), // 0x0025
qmi_name_item(QMIUIM_SET_PIN_PROTECTION_IND), // 0x0025
qmi_name_item(QMIUIM_VERIFY_PIN_REQ), // 0x0026
qmi_name_item(QMIUIM_VERIFY_PIN_RESP), // 0x0026
qmi_name_item(QMIUIM_VERIFY_PIN_IND), // 0x0026
qmi_name_item(QMIUIM_UNBLOCK_PIN_REQ), // 0x0027
qmi_name_item(QMIUIM_UNBLOCK_PIN_RESP), // 0x0027
qmi_name_item(QMIUIM_UNBLOCK_PIN_IND), // 0x0027
qmi_name_item(QMIUIM_CHANGE_PIN_REQ), // 0x0028
qmi_name_item(QMIUIM_CHANGE_PIN_RESP), // 0x0028
qmi_name_item(QMIUIM_CHANGE_PIN_IND), // 0x0028
qmi_name_item(QMIUIM_DEPERSONALIZATION_REQ), // 0x0029
qmi_name_item(QMIUIM_DEPERSONALIZATION_RESP), // 0x0029
qmi_name_item(QMIUIM_EVENT_REG_REQ), // 0x002E
qmi_name_item(QMIUIM_EVENT_REG_RESP), // 0x002E
qmi_name_item(QMIUIM_GET_CARD_STATUS_REQ), // 0x002F
qmi_name_item(QMIUIM_GET_CARD_STATUS_RESP), // 0x002F
qmi_name_item(QMIUIM_STATUS_CHANGE_IND), // 0x0032
};
static const char *qmi_name_get(const QMI_NAME_T *table, size_t size, int type,
const char *tag)
{
static char unknow[40];
size_t i;
if (qmux_CtlFlags == table) {
if (!strcmp(tag, "_REQ"))
tag = "_CMD";
else if (!strcmp(tag, "_RESP"))
tag = "_RSP";
}
for (i = 0; i < size; i++) {
if (table[i].type == (UINT)type) {
if (!tag || (strstr(table[i].name, tag)))
return table[i].name;
}
}
sprintf(unknow, "unknow_%x", type);
return unknow;
}
#define QMI_NAME(table, type) \
qmi_name_get(table, sizeof(table) / sizeof(table[0]), type, 0)
#define QMUX_NAME(table, type, tag) \
qmi_name_get(table, sizeof(table) / sizeof(table[0]), type, tag)
void dump_tlv(PQCQMUX_MSG_HDR pQMUXMsgHdr)
{
int TLVFind = 0;
int i;
// dbg("QCQMUX_TLV-----------------------------------\n");
// dbg("{Type,\tLength,\tValue}\n");
while (1) {
PQMI_TLV_HDR TLVHdr = GetTLV(pQMUXMsgHdr, 0x1000 + (++TLVFind));
if (TLVHdr == NULL)
break;
// if ((TLVHdr->TLVType == 0x02) && ((USHORT *)(TLVHdr+1))[0])
{
dbg("{%02x,\t%04x,\t", TLVHdr->TLVType,
le16_to_cpu(TLVHdr->TLVLength));
for (i = 0; i < le16_to_cpu(TLVHdr->TLVLength); i++) {
dbg("%02x ", ((UCHAR *)(TLVHdr + 1))[i]);
}
dbg("}\n");
}
} // while
}
void dump_ctl(PQCQMICTL_MSG_HDR CTLHdr)
{
const char *tag;
// dbg("QCQMICTL_MSG--------------------------------------------\n");
// dbg("CtlFlags: %02x\t\t%s\n", CTLHdr->CtlFlags,
// QMI_NAME(qmi_ctl_CtlFlags, CTLHdr->CtlFlags));
dbg("TransactionId: %02x\n", CTLHdr->TransactionId);
switch (CTLHdr->CtlFlags) {
case QMICTL_FLAG_REQUEST:
tag = "_REQ";
break;
case QMICTL_FLAG_RESPONSE:
tag = "_RESP";
break;
case QMICTL_FLAG_INDICATION:
tag = "_IND";
break;
default:
tag = 0;
break;
}
dbg("QMICTLType: %04x\t%s\n", le16_to_cpu(CTLHdr->QMICTLType),
QMUX_NAME(qmux_ctl_QMICTLType, le16_to_cpu(CTLHdr->QMICTLType), tag));
dbg("Length: %04x\n", le16_to_cpu(CTLHdr->Length));
dump_tlv((PQCQMUX_MSG_HDR)(&CTLHdr->QMICTLType));
}
int dump_qmux(QMI_SERVICE_TYPE serviceType, PQCQMUX_HDR QMUXHdr)
{
PQCQMUX_MSG_HDR QMUXMsgHdr = (PQCQMUX_MSG_HDR)(QMUXHdr + 1);
CHAR *tag;
// dbg("QCQMUX--------------------------------------------\n");
switch (QMUXHdr->CtlFlags & QMUX_CTL_FLAG_MASK_TYPE) {
case QMUX_CTL_FLAG_TYPE_CMD:
tag = "_REQ";
break;
case QMUX_CTL_FLAG_TYPE_RSP:
tag = "_RESP";
break;
case QMUX_CTL_FLAG_TYPE_IND:
tag = "_IND";
break;
default:
tag = 0;
break;
}
// dbg("CtlFlags: %02x\t\t%s\n", QMUXHdr->CtlFlags,
// QMUX_NAME(qmux_CtlFlags, QMUXHdr->CtlFlags, tag));
dbg("TransactionId: %04x\n", le16_to_cpu(QMUXHdr->TransactionId));
// dbg("QCQMUX_MSG_HDR-----------------------------------\n");
switch (serviceType) {
case QMUX_TYPE_DMS:
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
QMUX_NAME(qmux_dms_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
break;
case QMUX_TYPE_NAS:
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
QMUX_NAME(qmux_nas_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
break;
case QMUX_TYPE_WDS:
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
QMUX_NAME(qmux_wds_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
break;
case QMUX_TYPE_WMS:
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
QMUX_NAME(qmux_wms_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
break;
case QMUX_TYPE_WDS_ADMIN:
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
QMUX_NAME(qmux_wds_admin_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
break;
case QMUX_TYPE_UIM:
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
QMUX_NAME(qmux_uim_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
break;
case QMUX_TYPE_PDS:
case QMUX_TYPE_QOS:
case QMUX_TYPE_CTL:
default:
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
"PDS/QOS/CTL/unknown!");
break;
}
dbg("Length: %04x\n", le16_to_cpu(QMUXMsgHdr->Length));
dump_tlv(QMUXMsgHdr);
return 0;
}
void dump_qmi(void *dataBuffer, int dataLen)
{
PQCQMI_HDR QMIHdr = (PQCQMI_HDR)dataBuffer;
PQCQMUX_HDR QMUXHdr = (PQCQMUX_HDR)(QMIHdr + 1);
PQCQMICTL_MSG_HDR CTLHdr = (PQCQMICTL_MSG_HDR)(QMIHdr + 1);
int i;
if (!debug_qmi)
return;
pthread_mutex_lock(&dumpQMIMutex);
line[0] = 0;
for (i = 0; i < dataLen; i++) {
dbg("%02x ", ((unsigned char *)dataBuffer)[i]);
}
dbg_time("%s", line);
line[0] = 0;
// dbg("QCQMI_HDR-----------------------------------------");
// dbg("IFType: %02x\t\t%s", QMIHdr->IFType,
// QMI_NAME(qmi_IFType, QMIHdr->IFType)); dbg("Length: %04x",
// le16_to_cpu(QMIHdr->Length)); dbg("CtlFlags: %02x\t\t%s",
// QMIHdr->CtlFlags, QMI_NAME(qmi_CtlFlags, QMIHdr->CtlFlags));
// dbg("QMIType: %02x\t\t%s", QMIHdr->QMIType, QMI_NAME(qmi_QMIType,
// QMIHdr->QMIType)); dbg("ClientId: %02x", QMIHdr->ClientId);
if (QMIHdr->QMIType == QMUX_TYPE_CTL) {
dump_ctl(CTLHdr);
} else {
dump_qmux(QMIHdr->QMIType, QMUXHdr);
}
dbg_time("%s", line);
pthread_mutex_unlock(&dumpQMIMutex);
}
#include "QMIThread.h"
static char line[1024];
static pthread_mutex_t dumpQMIMutex = PTHREAD_MUTEX_INITIALIZER;
#undef dbg
#define dbg(format, arg...) \
do { \
if (strlen(line) < sizeof(line)) \
snprintf(&line[strlen(line)], sizeof(line) - strlen(line), format, \
##arg); \
} while (0)
PQMI_TLV_HDR GetTLV(PQCQMUX_MSG_HDR pQMUXMsgHdr, int TLVType);
typedef struct {
UINT type;
const char *name;
} QMI_NAME_T;
#define qmi_name_item(type) \
{ \
type, #type \
}
static const QMI_NAME_T qmux_ctl_QMICTLType[] = {
// QMICTL Type
qmi_name_item(QMICTL_SET_INSTANCE_ID_REQ), // 0x0020
qmi_name_item(QMICTL_SET_INSTANCE_ID_RESP), // 0x0020
qmi_name_item(QMICTL_GET_VERSION_REQ), // 0x0021
qmi_name_item(QMICTL_GET_VERSION_RESP), // 0x0021
qmi_name_item(QMICTL_GET_CLIENT_ID_REQ), // 0x0022
qmi_name_item(QMICTL_GET_CLIENT_ID_RESP), // 0x0022
qmi_name_item(QMICTL_RELEASE_CLIENT_ID_REQ), // 0x0023
qmi_name_item(QMICTL_RELEASE_CLIENT_ID_RESP), // 0x0023
qmi_name_item(QMICTL_REVOKE_CLIENT_ID_IND), // 0x0024
qmi_name_item(QMICTL_INVALID_CLIENT_ID_IND), // 0x0025
qmi_name_item(QMICTL_SET_DATA_FORMAT_REQ), // 0x0026
qmi_name_item(QMICTL_SET_DATA_FORMAT_RESP), // 0x0026
qmi_name_item(QMICTL_SYNC_REQ), // 0x0027
qmi_name_item(QMICTL_SYNC_RESP), // 0x0027
qmi_name_item(QMICTL_SYNC_IND), // 0x0027
};
static const QMI_NAME_T qmux_CtlFlags[] = {
qmi_name_item(QMUX_CTL_FLAG_TYPE_CMD),
qmi_name_item(QMUX_CTL_FLAG_TYPE_RSP),
qmi_name_item(QMUX_CTL_FLAG_TYPE_IND),
};
static const QMI_NAME_T qmux_wds_Type[] = {
qmi_name_item(QMIWDS_SET_EVENT_REPORT_REQ), // 0x0001
qmi_name_item(QMIWDS_SET_EVENT_REPORT_RESP), // 0x0001
qmi_name_item(QMIWDS_EVENT_REPORT_IND), // 0x0001
qmi_name_item(QMIWDS_START_NETWORK_INTERFACE_REQ), // 0x0020
qmi_name_item(QMIWDS_START_NETWORK_INTERFACE_RESP), // 0x0020
qmi_name_item(QMIWDS_STOP_NETWORK_INTERFACE_REQ), // 0x0021
qmi_name_item(QMIWDS_STOP_NETWORK_INTERFACE_RESP), // 0x0021
qmi_name_item(QMIWDS_GET_PKT_SRVC_STATUS_REQ), // 0x0022
qmi_name_item(QMIWDS_GET_PKT_SRVC_STATUS_RESP), // 0x0022
qmi_name_item(QMIWDS_GET_PKT_SRVC_STATUS_IND), // 0x0022
qmi_name_item(QMIWDS_GET_CURRENT_CHANNEL_RATE_REQ), // 0x0023
qmi_name_item(QMIWDS_GET_CURRENT_CHANNEL_RATE_RESP), // 0x0023
qmi_name_item(QMIWDS_GET_PKT_STATISTICS_REQ), // 0x0024
qmi_name_item(QMIWDS_GET_PKT_STATISTICS_RESP), // 0x0024
//begin modified by zhangkaibo add create profile qmi. mantis 0049137,0048741 20200610
qmi_name_item(QMIWDS_CREATE_PROFILE_SETTINGS_REQ), // 0x0027
qmi_name_item(QMIWDS_CREATE_PROFILE_SETTINGS_RESP), // 0x0027
//end modified by zhangkaibo add create profile qmi. mantis 0049137,0048741 20200610
qmi_name_item(QMIWDS_MODIFY_PROFILE_SETTINGS_REQ), // 0x0028
qmi_name_item(QMIWDS_MODIFY_PROFILE_SETTINGS_RESP), // 0x0028
qmi_name_item(QMIWDS_GET_PROFILE_SETTINGS_REQ), // 0x002B
qmi_name_item(QMIWDS_GET_PROFILE_SETTINGS_RESP), // 0x002BD
qmi_name_item(QMIWDS_GET_DEFAULT_SETTINGS_REQ), // 0x002C
qmi_name_item(QMIWDS_GET_DEFAULT_SETTINGS_RESP), // 0x002C
qmi_name_item(QMIWDS_GET_RUNTIME_SETTINGS_REQ), // 0x002D
qmi_name_item(QMIWDS_GET_RUNTIME_SETTINGS_RESP), // 0x002D
qmi_name_item(QMIWDS_GET_MIP_MODE_REQ), // 0x002F
qmi_name_item(QMIWDS_GET_MIP_MODE_RESP), // 0x002F
qmi_name_item(QMIWDS_GET_DATA_BEARER_REQ), // 0x0037
qmi_name_item(QMIWDS_GET_DATA_BEARER_RESP), // 0x0037
qmi_name_item(QMIWDS_DUN_CALL_INFO_REQ), // 0x0038
qmi_name_item(QMIWDS_DUN_CALL_INFO_RESP), // 0x0038
qmi_name_item(QMIWDS_DUN_CALL_INFO_IND), // 0x0038
qmi_name_item(QMIWDS_SET_CLIENT_IP_FAMILY_PREF_REQ), // 0x004D
qmi_name_item(QMIWDS_SET_CLIENT_IP_FAMILY_PREF_RESP), // 0x004D
qmi_name_item(QMIWDS_SET_AUTO_CONNECT_REQ), // 0x0051
qmi_name_item(QMIWDS_SET_AUTO_CONNECT_RESP), // 0x0051
qmi_name_item(QMIWDS_BIND_MUX_DATA_PORT_REQ), // 0x00A2
qmi_name_item(QMIWDS_BIND_MUX_DATA_PORT_RESP), // 0x00A2
};
static const QMI_NAME_T qmux_dms_Type[] = {
// ======================= DMS ==============================
qmi_name_item(QMIDMS_SET_EVENT_REPORT_REQ), // 0x0001
qmi_name_item(QMIDMS_SET_EVENT_REPORT_RESP), // 0x0001
qmi_name_item(QMIDMS_EVENT_REPORT_IND), // 0x0001
qmi_name_item(QMIDMS_GET_DEVICE_CAP_REQ), // 0x0020
qmi_name_item(QMIDMS_GET_DEVICE_CAP_RESP), // 0x0020
qmi_name_item(QMIDMS_GET_DEVICE_MFR_REQ), // 0x0021
qmi_name_item(QMIDMS_GET_DEVICE_MFR_RESP), // 0x0021
qmi_name_item(QMIDMS_GET_DEVICE_MODEL_ID_REQ), // 0x0022
qmi_name_item(QMIDMS_GET_DEVICE_MODEL_ID_RESP), // 0x0022
qmi_name_item(QMIDMS_GET_DEVICE_REV_ID_REQ), // 0x0023
qmi_name_item(QMIDMS_GET_DEVICE_REV_ID_RESP), // 0x0023
qmi_name_item(QMIDMS_GET_MSISDN_REQ), // 0x0024
qmi_name_item(QMIDMS_GET_MSISDN_RESP), // 0x0024
qmi_name_item(QMIDMS_GET_DEVICE_SERIAL_NUMBERS_REQ), // 0x0025
qmi_name_item(QMIDMS_GET_DEVICE_SERIAL_NUMBERS_RESP), // 0x0025
qmi_name_item(QMIDMS_UIM_SET_PIN_PROTECTION_REQ), // 0x0027
qmi_name_item(QMIDMS_UIM_SET_PIN_PROTECTION_RESP), // 0x0027
qmi_name_item(QMIDMS_UIM_VERIFY_PIN_REQ), // 0x0028
qmi_name_item(QMIDMS_UIM_VERIFY_PIN_RESP), // 0x0028
qmi_name_item(QMIDMS_UIM_UNBLOCK_PIN_REQ), // 0x0029
qmi_name_item(QMIDMS_UIM_UNBLOCK_PIN_RESP), // 0x0029
qmi_name_item(QMIDMS_UIM_CHANGE_PIN_REQ), // 0x002A
qmi_name_item(QMIDMS_UIM_CHANGE_PIN_RESP), // 0x002A
qmi_name_item(QMIDMS_UIM_GET_PIN_STATUS_REQ), // 0x002B
qmi_name_item(QMIDMS_UIM_GET_PIN_STATUS_RESP), // 0x002B
qmi_name_item(QMIDMS_GET_DEVICE_HARDWARE_REV_REQ), // 0x002C
qmi_name_item(QMIDMS_GET_DEVICE_HARDWARE_REV_RESP), // 0x002C
qmi_name_item(QMIDMS_GET_OPERATING_MODE_REQ), // 0x002D
qmi_name_item(QMIDMS_GET_OPERATING_MODE_RESP), // 0x002D
qmi_name_item(QMIDMS_SET_OPERATING_MODE_REQ), // 0x002E
qmi_name_item(QMIDMS_SET_OPERATING_MODE_RESP), // 0x002E
qmi_name_item(QMIDMS_GET_ACTIVATED_STATUS_REQ), // 0x0031
qmi_name_item(QMIDMS_GET_ACTIVATED_STATUS_RESP), // 0x0031
qmi_name_item(QMIDMS_ACTIVATE_AUTOMATIC_REQ), // 0x0032
qmi_name_item(QMIDMS_ACTIVATE_AUTOMATIC_RESP), // 0x0032
qmi_name_item(QMIDMS_ACTIVATE_MANUAL_REQ), // 0x0033
qmi_name_item(QMIDMS_ACTIVATE_MANUAL_RESP), // 0x0033
qmi_name_item(QMIDMS_UIM_GET_ICCID_REQ), // 0x003C
qmi_name_item(QMIDMS_UIM_GET_ICCID_RESP), // 0x003C
qmi_name_item(QMIDMS_UIM_GET_CK_STATUS_REQ), // 0x0040
qmi_name_item(QMIDMS_UIM_GET_CK_STATUS_RESP), // 0x0040
qmi_name_item(QMIDMS_UIM_SET_CK_PROTECTION_REQ), // 0x0041
qmi_name_item(QMIDMS_UIM_SET_CK_PROTECTION_RESP), // 0x0041
qmi_name_item(QMIDMS_UIM_UNBLOCK_CK_REQ), // 0x0042
qmi_name_item(QMIDMS_UIM_UNBLOCK_CK_RESP), // 0x0042
qmi_name_item(QMIDMS_UIM_GET_IMSI_REQ), // 0x0043
qmi_name_item(QMIDMS_UIM_GET_IMSI_RESP), // 0x0043
qmi_name_item(QMIDMS_UIM_GET_STATE_REQ), // 0x0044
qmi_name_item(QMIDMS_UIM_GET_STATE_RESP), // 0x0044
qmi_name_item(QMIDMS_GET_BAND_CAP_REQ), // 0x0045
qmi_name_item(QMIDMS_GET_BAND_CAP_RESP), // 0x0045
};
static const QMI_NAME_T qmux_nas_Type[] = {
// ======================= NAS ==============================
qmi_name_item(QMINAS_SET_EVENT_REPORT_REQ), // 0x0002
qmi_name_item(QMINAS_SET_EVENT_REPORT_RESP), // 0x0002
qmi_name_item(QMINAS_EVENT_REPORT_IND), // 0x0002
qmi_name_item(QMINAS_GET_SIGNAL_STRENGTH_REQ), // 0x0020
qmi_name_item(QMINAS_GET_SIGNAL_STRENGTH_RESP), // 0x0020
qmi_name_item(QMINAS_PERFORM_NETWORK_SCAN_REQ), // 0x0021
qmi_name_item(QMINAS_PERFORM_NETWORK_SCAN_RESP), // 0x0021
qmi_name_item(QMINAS_INITIATE_NW_REGISTER_REQ), // 0x0022
qmi_name_item(QMINAS_INITIATE_NW_REGISTER_RESP), // 0x0022
qmi_name_item(QMINAS_INITIATE_ATTACH_REQ), // 0x0023
qmi_name_item(QMINAS_INITIATE_ATTACH_RESP), // 0x0023
qmi_name_item(QMINAS_GET_SERVING_SYSTEM_REQ), // 0x0024
qmi_name_item(QMINAS_GET_SERVING_SYSTEM_RESP), // 0x0024
qmi_name_item(QMINAS_SERVING_SYSTEM_IND), // 0x0024
qmi_name_item(QMINAS_GET_HOME_NETWORK_REQ), // 0x0025
qmi_name_item(QMINAS_GET_HOME_NETWORK_RESP), // 0x0025
qmi_name_item(QMINAS_GET_PREFERRED_NETWORK_REQ), // 0x0026
qmi_name_item(QMINAS_GET_PREFERRED_NETWORK_RESP), // 0x0026
qmi_name_item(QMINAS_SET_PREFERRED_NETWORK_REQ), // 0x0027
qmi_name_item(QMINAS_SET_PREFERRED_NETWORK_RESP), // 0x0027
qmi_name_item(QMINAS_GET_FORBIDDEN_NETWORK_REQ), // 0x0028
qmi_name_item(QMINAS_GET_FORBIDDEN_NETWORK_RESP), // 0x0028
qmi_name_item(QMINAS_SET_FORBIDDEN_NETWORK_REQ), // 0x0029
qmi_name_item(QMINAS_SET_FORBIDDEN_NETWORK_RESP), // 0x0029
qmi_name_item(QMINAS_SET_TECHNOLOGY_PREF_REQ), // 0x002A
qmi_name_item(QMINAS_SET_TECHNOLOGY_PREF_RESP), // 0x002A
qmi_name_item(QMINAS_GET_RF_BAND_INFO_REQ), // 0x0031
qmi_name_item(QMINAS_GET_RF_BAND_INFO_RESP), // 0x0031
qmi_name_item(QMINAS_GET_PLMN_NAME_REQ), // 0x0044
qmi_name_item(QMINAS_GET_PLMN_NAME_RESP), // 0x0044
qmi_name_item(FIBO_PACKET_TRANSFER_START_IND), // 0X100
qmi_name_item(FIBO_PACKET_TRANSFER_END_IND), // 0X101
qmi_name_item(QMINAS_GET_SYS_INFO_REQ), // 0x004D
qmi_name_item(QMINAS_GET_SYS_INFO_RESP), // 0x004D
qmi_name_item(QMINAS_SYS_INFO_IND), // 0x004D
};
static const QMI_NAME_T qmux_wms_Type[] = {
// ======================= WMS ==============================
qmi_name_item(QMIWMS_SET_EVENT_REPORT_REQ), // 0x0001
qmi_name_item(QMIWMS_SET_EVENT_REPORT_RESP), // 0x0001
qmi_name_item(QMIWMS_EVENT_REPORT_IND), // 0x0001
qmi_name_item(QMIWMS_RAW_SEND_REQ), // 0x0020
qmi_name_item(QMIWMS_RAW_SEND_RESP), // 0x0020
qmi_name_item(QMIWMS_RAW_WRITE_REQ), // 0x0021
qmi_name_item(QMIWMS_RAW_WRITE_RESP), // 0x0021
qmi_name_item(QMIWMS_RAW_READ_REQ), // 0x0022
qmi_name_item(QMIWMS_RAW_READ_RESP), // 0x0022
qmi_name_item(QMIWMS_MODIFY_TAG_REQ), // 0x0023
qmi_name_item(QMIWMS_MODIFY_TAG_RESP), // 0x0023
qmi_name_item(QMIWMS_DELETE_REQ), // 0x0024
qmi_name_item(QMIWMS_DELETE_RESP), // 0x0024
qmi_name_item(QMIWMS_GET_MESSAGE_PROTOCOL_REQ), // 0x0030
qmi_name_item(QMIWMS_GET_MESSAGE_PROTOCOL_RESP), // 0x0030
qmi_name_item(QMIWMS_LIST_MESSAGES_REQ), // 0x0031
qmi_name_item(QMIWMS_LIST_MESSAGES_RESP), // 0x0031
qmi_name_item(QMIWMS_GET_SMSC_ADDRESS_REQ), // 0x0034
qmi_name_item(QMIWMS_GET_SMSC_ADDRESS_RESP), // 0x0034
qmi_name_item(QMIWMS_SET_SMSC_ADDRESS_REQ), // 0x0035
qmi_name_item(QMIWMS_SET_SMSC_ADDRESS_RESP), // 0x0035
qmi_name_item(QMIWMS_GET_STORE_MAX_SIZE_REQ), // 0x0036
qmi_name_item(QMIWMS_GET_STORE_MAX_SIZE_RESP), // 0x0036
};
static const QMI_NAME_T qmux_wds_admin_Type[] = {
qmi_name_item(QMIWDS_ADMIN_SET_DATA_FORMAT_REQ), // 0x0020
qmi_name_item(QMIWDS_ADMIN_SET_DATA_FORMAT_RESP), // 0x0020
qmi_name_item(QMIWDS_ADMIN_GET_DATA_FORMAT_REQ), // 0x0021
qmi_name_item(QMIWDS_ADMIN_GET_DATA_FORMAT_RESP), // 0x0021
qmi_name_item(QMIWDS_ADMIN_SET_QMAP_SETTINGS_REQ), // 0x002B
qmi_name_item(QMIWDS_ADMIN_SET_QMAP_SETTINGS_RESP), // 0x002B
qmi_name_item(QMIWDS_ADMIN_GET_QMAP_SETTINGS_REQ), // 0x002C
qmi_name_item(QMIWDS_ADMIN_GET_QMAP_SETTINGS_RESP), // 0x002C
};
static const QMI_NAME_T qmux_uim_Type[] = {
qmi_name_item(QMIUIM_READ_TRANSPARENT_REQ), // 0x0020
qmi_name_item(QMIUIM_READ_TRANSPARENT_RESP), // 0x0020
qmi_name_item(QMIUIM_READ_TRANSPARENT_IND), // 0x0020
qmi_name_item(QMIUIM_READ_RECORD_REQ), // 0x0021
qmi_name_item(QMIUIM_READ_RECORD_RESP), // 0x0021
qmi_name_item(QMIUIM_READ_RECORD_IND), // 0x0021
qmi_name_item(QMIUIM_WRITE_TRANSPARENT_REQ), // 0x0022
qmi_name_item(QMIUIM_WRITE_TRANSPARENT_RESP), // 0x0022
qmi_name_item(QMIUIM_WRITE_TRANSPARENT_IND), // 0x0022
qmi_name_item(QMIUIM_WRITE_RECORD_REQ), // 0x0023
qmi_name_item(QMIUIM_WRITE_RECORD_RESP), // 0x0023
qmi_name_item(QMIUIM_WRITE_RECORD_IND), // 0x0023
qmi_name_item(QMIUIM_SET_PIN_PROTECTION_REQ), // 0x0025
qmi_name_item(QMIUIM_SET_PIN_PROTECTION_RESP), // 0x0025
qmi_name_item(QMIUIM_SET_PIN_PROTECTION_IND), // 0x0025
qmi_name_item(QMIUIM_VERIFY_PIN_REQ), // 0x0026
qmi_name_item(QMIUIM_VERIFY_PIN_RESP), // 0x0026
qmi_name_item(QMIUIM_VERIFY_PIN_IND), // 0x0026
qmi_name_item(QMIUIM_UNBLOCK_PIN_REQ), // 0x0027
qmi_name_item(QMIUIM_UNBLOCK_PIN_RESP), // 0x0027
qmi_name_item(QMIUIM_UNBLOCK_PIN_IND), // 0x0027
qmi_name_item(QMIUIM_CHANGE_PIN_REQ), // 0x0028
qmi_name_item(QMIUIM_CHANGE_PIN_RESP), // 0x0028
qmi_name_item(QMIUIM_CHANGE_PIN_IND), // 0x0028
qmi_name_item(QMIUIM_DEPERSONALIZATION_REQ), // 0x0029
qmi_name_item(QMIUIM_DEPERSONALIZATION_RESP), // 0x0029
qmi_name_item(QMIUIM_EVENT_REG_REQ), // 0x002E
qmi_name_item(QMIUIM_EVENT_REG_RESP), // 0x002E
qmi_name_item(QMIUIM_GET_CARD_STATUS_REQ), // 0x002F
qmi_name_item(QMIUIM_GET_CARD_STATUS_RESP), // 0x002F
qmi_name_item(QMIUIM_STATUS_CHANGE_IND), // 0x0032
};
static const char *qmi_name_get(const QMI_NAME_T *table, size_t size, int type,
const char *tag)
{
static char unknow[40];
size_t i;
if (qmux_CtlFlags == table) {
if (!strcmp(tag, "_REQ"))
tag = "_CMD";
else if (!strcmp(tag, "_RESP"))
tag = "_RSP";
}
for (i = 0; i < size; i++) {
if (table[i].type == (UINT)type) {
if (!tag || (strstr(table[i].name, tag)))
return table[i].name;
}
}
sprintf(unknow, "unknow_%x", type);
return unknow;
}
#define QMI_NAME(table, type) \
qmi_name_get(table, sizeof(table) / sizeof(table[0]), type, 0)
#define QMUX_NAME(table, type, tag) \
qmi_name_get(table, sizeof(table) / sizeof(table[0]), type, tag)
void dump_tlv(PQCQMUX_MSG_HDR pQMUXMsgHdr)
{
int TLVFind = 0;
int i;
// dbg("QCQMUX_TLV-----------------------------------\n");
// dbg("{Type,\tLength,\tValue}\n");
while (1) {
PQMI_TLV_HDR TLVHdr = GetTLV(pQMUXMsgHdr, 0x1000 + (++TLVFind));
if (TLVHdr == NULL)
break;
// if ((TLVHdr->TLVType == 0x02) && ((USHORT *)(TLVHdr+1))[0])
{
dbg("{%02x,\t%04x,\t", TLVHdr->TLVType,
le16_to_cpu(TLVHdr->TLVLength));
for (i = 0; i < le16_to_cpu(TLVHdr->TLVLength); i++) {
dbg("%02x ", ((UCHAR *)(TLVHdr + 1))[i]);
}
dbg("}\n");
}
} // while
}
void dump_ctl(PQCQMICTL_MSG_HDR CTLHdr)
{
const char *tag;
// dbg("QCQMICTL_MSG--------------------------------------------\n");
// dbg("CtlFlags: %02x\t\t%s\n", CTLHdr->CtlFlags,
// QMI_NAME(qmi_ctl_CtlFlags, CTLHdr->CtlFlags));
dbg("TransactionId: %02x\n", CTLHdr->TransactionId);
switch (CTLHdr->CtlFlags) {
case QMICTL_FLAG_REQUEST:
tag = "_REQ";
break;
case QMICTL_FLAG_RESPONSE:
tag = "_RESP";
break;
case QMICTL_FLAG_INDICATION:
tag = "_IND";
break;
default:
tag = 0;
break;
}
dbg("QMICTLType: %04x\t%s\n", le16_to_cpu(CTLHdr->QMICTLType),
QMUX_NAME(qmux_ctl_QMICTLType, le16_to_cpu(CTLHdr->QMICTLType), tag));
dbg("Length: %04x\n", le16_to_cpu(CTLHdr->Length));
dump_tlv((PQCQMUX_MSG_HDR)(&CTLHdr->QMICTLType));
}
int dump_qmux(QMI_SERVICE_TYPE serviceType, PQCQMUX_HDR QMUXHdr)
{
PQCQMUX_MSG_HDR QMUXMsgHdr = (PQCQMUX_MSG_HDR)(QMUXHdr + 1);
CHAR *tag;
// dbg("QCQMUX--------------------------------------------\n");
switch (QMUXHdr->CtlFlags & QMUX_CTL_FLAG_MASK_TYPE) {
case QMUX_CTL_FLAG_TYPE_CMD:
tag = "_REQ";
break;
case QMUX_CTL_FLAG_TYPE_RSP:
tag = "_RESP";
break;
case QMUX_CTL_FLAG_TYPE_IND:
tag = "_IND";
break;
default:
tag = 0;
break;
}
// dbg("CtlFlags: %02x\t\t%s\n", QMUXHdr->CtlFlags,
// QMUX_NAME(qmux_CtlFlags, QMUXHdr->CtlFlags, tag));
dbg("TransactionId: %04x\n", le16_to_cpu(QMUXHdr->TransactionId));
// dbg("QCQMUX_MSG_HDR-----------------------------------\n");
switch (serviceType) {
case QMUX_TYPE_DMS:
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
QMUX_NAME(qmux_dms_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
break;
case QMUX_TYPE_NAS:
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
QMUX_NAME(qmux_nas_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
break;
case QMUX_TYPE_WDS:
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
QMUX_NAME(qmux_wds_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
break;
case QMUX_TYPE_WMS:
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
QMUX_NAME(qmux_wms_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
break;
case QMUX_TYPE_WDS_ADMIN:
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
QMUX_NAME(qmux_wds_admin_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
break;
case QMUX_TYPE_UIM:
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
QMUX_NAME(qmux_uim_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
break;
case QMUX_TYPE_PDS:
case QMUX_TYPE_QOS:
case QMUX_TYPE_CTL:
default:
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
"PDS/QOS/CTL/unknown!");
break;
}
dbg("Length: %04x\n", le16_to_cpu(QMUXMsgHdr->Length));
dump_tlv(QMUXMsgHdr);
return 0;
}
void dump_qmi(void *dataBuffer, int dataLen)
{
PQCQMI_HDR QMIHdr = (PQCQMI_HDR)dataBuffer;
PQCQMUX_HDR QMUXHdr = (PQCQMUX_HDR)(QMIHdr + 1);
PQCQMICTL_MSG_HDR CTLHdr = (PQCQMICTL_MSG_HDR)(QMIHdr + 1);
int i;
if (!debug_qmi)
return;
pthread_mutex_lock(&dumpQMIMutex);
line[0] = 0;
for (i = 0; i < dataLen; i++) {
dbg("%02x ", ((unsigned char *)dataBuffer)[i]);
}
dbg_time("%s", line);
line[0] = 0;
// dbg("QCQMI_HDR-----------------------------------------");
// dbg("IFType: %02x\t\t%s", QMIHdr->IFType,
// QMI_NAME(qmi_IFType, QMIHdr->IFType)); dbg("Length: %04x",
// le16_to_cpu(QMIHdr->Length)); dbg("CtlFlags: %02x\t\t%s",
// QMIHdr->CtlFlags, QMI_NAME(qmi_CtlFlags, QMIHdr->CtlFlags));
// dbg("QMIType: %02x\t\t%s", QMIHdr->QMIType, QMI_NAME(qmi_QMIType,
// QMIHdr->QMIType)); dbg("ClientId: %02x", QMIHdr->ClientId);
if (QMIHdr->QMIType == QMUX_TYPE_CTL) {
dump_ctl(CTLHdr);
} else {
dump_qmux(QMIHdr->QMIType, QMUXHdr);
}
dbg_time("%s", line);
pthread_mutex_unlock(&dumpQMIMutex);
}
+3671 -3671
View File
File diff suppressed because it is too large. Load diff
+42 -42
View File
@@ -1,42 +1,42 @@
ifneq ($(CROSS_COMPILE),)
CROSS-COMPILE:=$(CROSS_COMPILE)
endif
CFLAGS += -DGHT_FEATURE_PCIE_AUTO
ifeq ($(CC),cc)
CC:=$(CROSS-COMPILE)gcc
endif
LD:=$(CROSS-COMPILE)ld
SRC=QmiWwanCM.c GobiNetCM.c main.c MPQMUX.c QMIThread.c util.c qmap_bridge_mode.c query_pcie_mode.c
FB_DHCP=udhcpc.c
FIBO_PROXY_SRC=fibo_qmimsg_server.c
LIBMNL=libmnl/ifutils.c libmnl/attr.c libmnl/callback.c libmnl/nlmsg.c libmnl/socket.c
FB_NDHCP=udhcpc_netlink.c
FB_NDHCP+=${LIBMNL}
release: clean
$(CC) $(CFLAGS) -Wall -s ${SRC} ${FB_NDHCP} -o fibocom-dial -lpthread -ldl
$(CC) -Wall -s multi-pdn-manager.c query_pcie_mode.c util.c -o multi-pdn-manager -lpthread -ldl
$(CC) -Wall -s ${FIBO_PROXY_SRC} -o fibo_qmimsg_server -lpthread -ldl
dhcp: clean
$(CC) $(CFLAGS) -Wall -s ${SRC} ${FB_DHCP} -o fibocom-dial -lpthread -ldl
$(CC) -Wall -s multi-pdn-manager.c query_pcie_mode.c util.c -o multi-pdn-manager -lpthread -ldl
$(CC) -Wall -s ${FIBO_PROXY_SRC} -o fibo_qmimsg_server -lpthread -ldl
ndhcp: clean
$(CC) $(CFLAGS) -Wall -s ${SRC} ${FB_NDHCP} -o fibocom-dial -lpthread -ldl
$(CC) -Wall -s multi-pdn-manager.c query_pcie_mode.cutil.c -o multi-pdn-manager -lpthread -ldl
$(CC) -Wall -s ${FIBO_PROXY_SRC} -o fibo_qmimsg_server -lpthread -ldl
qmi-proxy:
$(CC) -Wall -s fibo-qmi-proxy.c -o fibo-qmi-proxy -lpthread -ldl
clean:
rm -rf fibocom-dial *~ multi-pdn-manager fibo_qmimsg_server
ifneq ($(CROSS_COMPILE),)
CROSS-COMPILE:=$(CROSS_COMPILE)
endif
CFLAGS += -DGHT_FEATURE_PCIE_AUTO
ifeq ($(CC),cc)
CC:=$(CROSS-COMPILE)gcc
endif
LD:=$(CROSS-COMPILE)ld
SRC=QmiWwanCM.c GobiNetCM.c main.c MPQMUX.c QMIThread.c util.c qmap_bridge_mode.c query_pcie_mode.c
FB_DHCP=udhcpc.c
FIBO_PROXY_SRC=fibo_qmimsg_server.c
LIBMNL=libmnl/ifutils.c libmnl/attr.c libmnl/callback.c libmnl/nlmsg.c libmnl/socket.c
FB_NDHCP=udhcpc_netlink.c
FB_NDHCP+=${LIBMNL}
release: clean
$(CC) $(CFLAGS) -Wall -s ${SRC} ${FB_NDHCP} -o fibocom-dial -lpthread -ldl
$(CC) -Wall -s multi-pdn-manager.c query_pcie_mode.c util.c -o multi-pdn-manager -lpthread -ldl
$(CC) -Wall -s ${FIBO_PROXY_SRC} -o fibo_qmimsg_server -lpthread -ldl
dhcp: clean
$(CC) $(CFLAGS) -Wall -s ${SRC} ${FB_DHCP} -o fibocom-dial -lpthread -ldl
$(CC) -Wall -s multi-pdn-manager.c query_pcie_mode.c util.c -o multi-pdn-manager -lpthread -ldl
$(CC) -Wall -s ${FIBO_PROXY_SRC} -o fibo_qmimsg_server -lpthread -ldl
ndhcp: clean
$(CC) $(CFLAGS) -Wall -s ${SRC} ${FB_NDHCP} -o fibocom-dial -lpthread -ldl
$(CC) -Wall -s multi-pdn-manager.c query_pcie_mode.cutil.c -o multi-pdn-manager -lpthread -ldl
$(CC) -Wall -s ${FIBO_PROXY_SRC} -o fibo_qmimsg_server -lpthread -ldl
qmi-proxy:
$(CC) -Wall -s fibo-qmi-proxy.c -o fibo-qmi-proxy -lpthread -ldl
clean:
rm -rf fibocom-dial *~ multi-pdn-manager fibo_qmimsg_server
+2551 -2551
View File
File diff suppressed because it is too large. Load diff
+260 -260
View File
@@ -1,260 +1,260 @@
#ifndef __QMI_THREAD_H__
#define __QMI_THREAD_H__
#define CONFIG_GOBINET
#define CONFIG_QMIWWAN
#define CONFIG_SIM
#define CONFIG_APN
#define CONFIG_VERSION
//2021-03-24 willa.liu@fibocom.com changed begin for support mantis 0071817
#define CONFIG_IMSI_ICCID
//2021-03-24 willa.liu@fibocom.com changed end for support mantis 0071817
#define CONFIG_DEFAULT_PDP 1
#define CONFIG_DEFAULT_PDPINDEX 1
//#define CONFIG_IMSI_ICCID
#define CONFIG_RESET_RADIO \
(45) // Reset Radiao(AT+CFUN=4,AT+CFUN=1) when cann not register network or
// setup data call in 45 seconds
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>
#include "MPQCTL.h"
#include "MPQMI.h"
#include "MPQMUX.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
//begin modified by zhangkaibo add 5G network detect feature on x55 platform. 20200605
#define WWAN_DATA_CLASS_5G 0x00000040
//end modified by zhangkaibo add 5G network detect feature on x55 platform. 20200605
#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;
CHAR *str;
};
#pragma pack(push, 1)
typedef struct _QCQMIMSG {
QCQMI_HDR QMIHdr;
union {
QMICTL_MSG CTLMsg;
QMUX_MSG MUXMsg;
//2021-03-24 willa.liu@fibocom.com changed begin for support mantis 0071817
QMUX_MSG QMUXMsgHdrResp;
//2021-03-24 willa.liu@fibocom.com changed end for support mantis 0071817
};
} __attribute__((packed)) QCQMIMSG, *PQCQMIMSG;
#pragma pack(pop)
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;
#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);
};
extern int (*qmidev_send)(PQCQMIMSG pRequest);
#ifndef bool
#define bool uint8_t
#endif
//2021-03-15 zhangkaibo@fibocom.com changed begin for oa 20210311037
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;
//2021-03-15 zhangkaibo@fibocom.com changed end for oa 20210311037
typedef struct __PROFILE {
char *qmichannel;
char *usbnet_adapter;
char *qmapnet_adapter;
const char *driver_name;
int qmap_mode;
int qmap_size;
int qmap_version;
const char *apn;
const char *user;
const char *password;
const char *pincode;
int auth;
int pdp;
int pdpindex;
int pdpnum;
int curIpFamily;
int rawIP;
int muxid;
IPV4_T ipv4;
IPV6_T ipv6;
int ipv4_flag;
int ipv6_flag;
//2021-02-25 willa.liu@fibocom.com changed begin for support eipd SN-20210129001
int ipv6_prigateway_flag;
//2021-02-25 willa.liu@fibocom.com changed begin for support eipd SN-20210129001
int dual_flag;
int apntype;
const struct qmi_device_ops *qmi_ops;
bool loopback_state;
int replication_factor;
//2021-02-08 zhangkaibo@fibocom.com changed begin for mantis 0070613
int interfacenum;
//2021-02-08 zhangkaibo@fibocom.com changed end for mantis 0070613
//2021-03-15 zhangkaibo@fibocom.com changed begin for oa 20210311037
RMNET_INFO rmnet_info;
//2021-03-15 zhangkaibo@fibocom.com changed end for oa 20210311037
} PROFILE_T;
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;
//2021-03-24 willa.liu@fibocom.com changed begin for support mantis 0071817
typedef enum {
SIM_Card0 = 0,
SIM_Card1 = 1
} SIM_Select;
//2021-03-24 willa.liu@fibocom.com changed end for support mantis 0071817
#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
extern int pthread_cond_timeout_np(pthread_cond_t *cond, pthread_mutex_t *mutex,
unsigned msecs);
extern int QmiThreadSendQMI(PQCQMIMSG pRequest, PQCQMIMSG *ppResponse);
extern int QmiThreadSendQMITimeout(PQCQMIMSG pRequest, PQCQMIMSG *ppResponse,
unsigned msecs);
extern void QmiThreadRecvQMI(PQCQMIMSG pResponse);
extern int fibo_raw_ip_mode_check(const char *ifname);
extern void udhcpc_start(PROFILE_T *profile);
extern void udhcpc_stop(PROFILE_T *profile);
extern void udhcpc_start_pcie(PROFILE_T *profile);
extern void udhcpc_stop_pcie(PROFILE_T *profile);
extern void dump_qmi(void *dataBuffer, int dataLen);
extern void qmidevice_send_event_to_main(int triger_event);
extern int requestSetEthMode(PROFILE_T *profile);
//2021-03-24 willa.liu@fibocom.com changed begin for support mantis 0071817
//extern int requestGetSIMStatus(SIM_Status *pSIMStatus);
extern int requestGetSIMStatus(SIM_Status *pSIMStatus , const int sim_select);
//2021-03-24 willa.liu@fibocom.com changed end for support mantis 0071817
extern int requestEnterSimPin(const CHAR *pPinCode);
extern int requestGetICCID(void);
extern int requestGetIMSI(void);
extern int requestRegistrationState(UCHAR *pPSAttachedState);
extern int requestQueryDataCall(UCHAR *pConnectionStatus, int curIpFamily);
extern int requestSetupDataCall(PROFILE_T *profile, int curIpFamily);
extern int requestDeactivateDefaultPDP(PROFILE_T *profile, int curIpFamily);
extern int requestSetProfile(PROFILE_T *profile);
extern int requestGetProfile(PROFILE_T *profile);
extern int requestBaseBandVersion(const char **pp_reversion);
extern int requestGetIPAddress(PROFILE_T *profile, int curIpFamily);
extern int requestSetOperatingMode(UCHAR OperatingMode);
int requestRegistrationState2(UCHAR *pPSAttachedState);
extern int fibo_qmap_mode_set(PROFILE_T *profile);
extern int fibo_bridge_mode_detect(PROFILE_T *profile);
extern int fibo_qmap_mode_detect(PROFILE_T *profile);
extern const struct qmi_device_ops qmiwwan_qmidev_ops;
#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 USHORT g_MobileCountryCode;
extern USHORT g_MobileNetworkCode;
extern int qmidevice_control_fd[2];
extern int qmiclientId[QMUX_TYPE_WDS_ADMIN + 1];
extern void dbg_time(const char *fmt, ...);
extern USHORT le16_to_cpu(USHORT v16);
extern UINT le32_to_cpu(UINT v32);
extern USHORT cpu_to_le16(USHORT v16);
extern UINT cpu_to_le32(UINT v32);
#endif
#ifndef __QMI_THREAD_H__
#define __QMI_THREAD_H__
#define CONFIG_GOBINET
#define CONFIG_QMIWWAN
#define CONFIG_SIM
#define CONFIG_APN
#define CONFIG_VERSION
//2021-03-24 willa.liu@fibocom.com changed begin for support mantis 0071817
#define CONFIG_IMSI_ICCID
//2021-03-24 willa.liu@fibocom.com changed end for support mantis 0071817
#define CONFIG_DEFAULT_PDP 1
#define CONFIG_DEFAULT_PDPINDEX 1
//#define CONFIG_IMSI_ICCID
#define CONFIG_RESET_RADIO \
(45) // Reset Radiao(AT+CFUN=4,AT+CFUN=1) when cann not register network or
// setup data call in 45 seconds
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>
#include "MPQCTL.h"
#include "MPQMI.h"
#include "MPQMUX.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
//begin modified by zhangkaibo add 5G network detect feature on x55 platform. 20200605
#define WWAN_DATA_CLASS_5G 0x00000040
//end modified by zhangkaibo add 5G network detect feature on x55 platform. 20200605
#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;
CHAR *str;
};
#pragma pack(push, 1)
typedef struct _QCQMIMSG {
QCQMI_HDR QMIHdr;
union {
QMICTL_MSG CTLMsg;
QMUX_MSG MUXMsg;
//2021-03-24 willa.liu@fibocom.com changed begin for support mantis 0071817
QMUX_MSG QMUXMsgHdrResp;
//2021-03-24 willa.liu@fibocom.com changed end for support mantis 0071817
};
} __attribute__((packed)) QCQMIMSG, *PQCQMIMSG;
#pragma pack(pop)
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;
#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);
};
extern int (*qmidev_send)(PQCQMIMSG pRequest);
#ifndef bool
#define bool uint8_t
#endif
//2021-03-15 zhangkaibo@fibocom.com changed begin for oa 20210311037
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;
//2021-03-15 zhangkaibo@fibocom.com changed end for oa 20210311037
typedef struct __PROFILE {
char *qmichannel;
char *usbnet_adapter;
char *qmapnet_adapter;
const char *driver_name;
int qmap_mode;
int qmap_size;
int qmap_version;
const char *apn;
const char *user;
const char *password;
const char *pincode;
int auth;
int pdp;
int pdpindex;
int pdpnum;
int curIpFamily;
int rawIP;
int muxid;
IPV4_T ipv4;
IPV6_T ipv6;
int ipv4_flag;
int ipv6_flag;
//2021-02-25 willa.liu@fibocom.com changed begin for support eipd SN-20210129001
int ipv6_prigateway_flag;
//2021-02-25 willa.liu@fibocom.com changed begin for support eipd SN-20210129001
int dual_flag;
int apntype;
const struct qmi_device_ops *qmi_ops;
bool loopback_state;
int replication_factor;
//2021-02-08 zhangkaibo@fibocom.com changed begin for mantis 0070613
int interfacenum;
//2021-02-08 zhangkaibo@fibocom.com changed end for mantis 0070613
//2021-03-15 zhangkaibo@fibocom.com changed begin for oa 20210311037
RMNET_INFO rmnet_info;
//2021-03-15 zhangkaibo@fibocom.com changed end for oa 20210311037
} PROFILE_T;
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;
//2021-03-24 willa.liu@fibocom.com changed begin for support mantis 0071817
typedef enum {
SIM_Card0 = 0,
SIM_Card1 = 1
} SIM_Select;
//2021-03-24 willa.liu@fibocom.com changed end for support mantis 0071817
#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
extern int pthread_cond_timeout_np(pthread_cond_t *cond, pthread_mutex_t *mutex,
unsigned msecs);
extern int QmiThreadSendQMI(PQCQMIMSG pRequest, PQCQMIMSG *ppResponse);
extern int QmiThreadSendQMITimeout(PQCQMIMSG pRequest, PQCQMIMSG *ppResponse,
unsigned msecs);
extern void QmiThreadRecvQMI(PQCQMIMSG pResponse);
extern int fibo_raw_ip_mode_check(const char *ifname);
extern void udhcpc_start(PROFILE_T *profile);
extern void udhcpc_stop(PROFILE_T *profile);
extern void udhcpc_start_pcie(PROFILE_T *profile);
extern void udhcpc_stop_pcie(PROFILE_T *profile);
extern void dump_qmi(void *dataBuffer, int dataLen);
extern void qmidevice_send_event_to_main(int triger_event);
extern int requestSetEthMode(PROFILE_T *profile);
//2021-03-24 willa.liu@fibocom.com changed begin for support mantis 0071817
//extern int requestGetSIMStatus(SIM_Status *pSIMStatus);
extern int requestGetSIMStatus(SIM_Status *pSIMStatus , const int sim_select);
//2021-03-24 willa.liu@fibocom.com changed end for support mantis 0071817
extern int requestEnterSimPin(const CHAR *pPinCode);
extern int requestGetICCID(void);
extern int requestGetIMSI(void);
extern int requestRegistrationState(UCHAR *pPSAttachedState);
extern int requestQueryDataCall(UCHAR *pConnectionStatus, int curIpFamily);
extern int requestSetupDataCall(PROFILE_T *profile, int curIpFamily);
extern int requestDeactivateDefaultPDP(PROFILE_T *profile, int curIpFamily);
extern int requestSetProfile(PROFILE_T *profile);
extern int requestGetProfile(PROFILE_T *profile);
extern int requestBaseBandVersion(const char **pp_reversion);
extern int requestGetIPAddress(PROFILE_T *profile, int curIpFamily);
extern int requestSetOperatingMode(UCHAR OperatingMode);
int requestRegistrationState2(UCHAR *pPSAttachedState);
extern int fibo_qmap_mode_set(PROFILE_T *profile);
extern int fibo_bridge_mode_detect(PROFILE_T *profile);
extern int fibo_qmap_mode_detect(PROFILE_T *profile);
extern const struct qmi_device_ops qmiwwan_qmidev_ops;
#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 USHORT g_MobileCountryCode;
extern USHORT g_MobileNetworkCode;
extern int qmidevice_control_fd[2];
extern int qmiclientId[QMUX_TYPE_WDS_ADMIN + 1];
extern void dbg_time(const char *fmt, ...);
extern USHORT le16_to_cpu(USHORT v16);
extern UINT le32_to_cpu(UINT v32);
extern USHORT cpu_to_le16(USHORT v16);
extern UINT cpu_to_le32(UINT v32);
#endif
+426 -426
View File
@@ -1,426 +1,426 @@
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
typedef unsigned short sa_family_t;
#include <linux/un.h>
#include "QMIThread.h"
#ifdef CONFIG_QMIWWAN
#define FIBO_QMI_PROXY "fibo_qmimsg_server"
static int cdc_wdm_fd = -1;
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)
{
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 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_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 int 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;
dbg_time("%s: QMIType = %d clientid %d", __func__, QMIType, 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_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->qmap_mode == 0 || profile->qmap_mode == 1) {
for (i = 0; i < 10; i++) {
ret = QmiThreadSendQMITimeout(
ComposeQCTLMsg(QMICTL_SYNC_REQ, NULL, NULL), NULL, 1 * 1000);
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 (pResponse->CTLMsg.GetVersionRsp.TypeVersion[NumElements]
.QMUXType == QMUX_TYPE_WDS_ADMIN)
profile->qmap_version = (pResponse->CTLMsg.GetVersionRsp
.TypeVersion[NumElements]
.MinorVersion > 16);
}
}
}
}
if (pResponse)
free(pResponse);
if (profile->ipv4_flag)
qmiclientId[QMUX_TYPE_WDS] = QmiWwanGetClientID(QMUX_TYPE_WDS);
if (profile->ipv6_flag)
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);
if (profile->qmap_mode == 0 || profile->qmap_mode == 1)
qmiclientId[QMUX_TYPE_WDS_ADMIN] =
QmiWwanGetClientID(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(i, qmiclientId[i]);
qmiclientId[i] = 0;
}
}
return 0;
}
static int qmi_proxy_open(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("%s connect %s errno: %d (%s)\n", __func__, name, errno,
strerror(errno));
return -1;
}
(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse_addr,
sizeof(reuse_addr)));
dbg_time("connect to %s sockfd = %d\n", name, sockfd);
return sockfd;
}
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)) {
nreads += read(fd, pHdr + 1,
le16_to_cpu(pHdr->Length) + 1 - sizeof(QCQMI_HDR));
}
return nreads;
}
static void *QmiWwanThread(void *pData)
{
PROFILE_T *profile = (PROFILE_T *)pData;
const char *cdc_wdm = (const char *)profile->qmichannel;
if (profile->qmap_mode == 0 || profile->qmap_mode == 1)
cdc_wdm_fd = open(cdc_wdm, O_RDWR | O_NONBLOCK | O_NOCTTY);
else
cdc_wdm_fd = qmi_proxy_open(FIBO_QMI_PROXY);
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;
}
fcntl(cdc_wdm_fd, F_SETFL, fcntl(cdc_wdm_fd, F_GETFL) | O_NONBLOCK);
fcntl(cdc_wdm_fd, F_SETFD, FD_CLOEXEC);
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, -1);
} while ((ret < 0) && (errno == EINTR));
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 SIGTERM:
case SIGHUP:
case SIGINT:
QmiThreadRecvQMI(NULL);
break;
default:
break;
}
}
}
if (fd == cdc_wdm_fd) {
ssize_t nreads;
UCHAR QMIBuf[4096];
PQCQMIMSG pResponse = (PQCQMIMSG)QMIBuf;
if (profile->qmap_mode == 0 || profile->qmap_mode == 1)
nreads = read(fd, QMIBuf, sizeof(QMIBuf));
else
nreads = qmi_proxy_read(fd, QMIBuf, sizeof(QMIBuf));
// 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;
}
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;
}
#endif
const struct qmi_device_ops qmiwwan_qmidev_ops = {
.init = QmiWwanInit,
.deinit = QmiWwanDeInit,
.send = QmiWwanSendQMI,
.read = QmiWwanThread,
};
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
typedef unsigned short sa_family_t;
#include <linux/un.h>
#include "QMIThread.h"
#ifdef CONFIG_QMIWWAN
#define FIBO_QMI_PROXY "fibo_qmimsg_server"
static int cdc_wdm_fd = -1;
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)
{
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 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_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 int 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;
dbg_time("%s: QMIType = %d clientid %d", __func__, QMIType, 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_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->qmap_mode == 0 || profile->qmap_mode == 1) {
for (i = 0; i < 10; i++) {
ret = QmiThreadSendQMITimeout(
ComposeQCTLMsg(QMICTL_SYNC_REQ, NULL, NULL), NULL, 1 * 1000);
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 (pResponse->CTLMsg.GetVersionRsp.TypeVersion[NumElements]
.QMUXType == QMUX_TYPE_WDS_ADMIN)
profile->qmap_version = (pResponse->CTLMsg.GetVersionRsp
.TypeVersion[NumElements]
.MinorVersion > 16);
}
}
}
}
if (pResponse)
free(pResponse);
if (profile->ipv4_flag)
qmiclientId[QMUX_TYPE_WDS] = QmiWwanGetClientID(QMUX_TYPE_WDS);
if (profile->ipv6_flag)
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);
if (profile->qmap_mode == 0 || profile->qmap_mode == 1)
qmiclientId[QMUX_TYPE_WDS_ADMIN] =
QmiWwanGetClientID(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(i, qmiclientId[i]);
qmiclientId[i] = 0;
}
}
return 0;
}
static int qmi_proxy_open(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("%s connect %s errno: %d (%s)\n", __func__, name, errno,
strerror(errno));
return -1;
}
(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse_addr,
sizeof(reuse_addr)));
dbg_time("connect to %s sockfd = %d\n", name, sockfd);
return sockfd;
}
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)) {
nreads += read(fd, pHdr + 1,
le16_to_cpu(pHdr->Length) + 1 - sizeof(QCQMI_HDR));
}
return nreads;
}
static void *QmiWwanThread(void *pData)
{
PROFILE_T *profile = (PROFILE_T *)pData;
const char *cdc_wdm = (const char *)profile->qmichannel;
if (profile->qmap_mode == 0 || profile->qmap_mode == 1)
cdc_wdm_fd = open(cdc_wdm, O_RDWR | O_NONBLOCK | O_NOCTTY);
else
cdc_wdm_fd = qmi_proxy_open(FIBO_QMI_PROXY);
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;
}
fcntl(cdc_wdm_fd, F_SETFL, fcntl(cdc_wdm_fd, F_GETFL) | O_NONBLOCK);
fcntl(cdc_wdm_fd, F_SETFD, FD_CLOEXEC);
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, -1);
} while ((ret < 0) && (errno == EINTR));
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 SIGTERM:
case SIGHUP:
case SIGINT:
QmiThreadRecvQMI(NULL);
break;
default:
break;
}
}
}
if (fd == cdc_wdm_fd) {
ssize_t nreads;
UCHAR QMIBuf[4096];
PQCQMIMSG pResponse = (PQCQMIMSG)QMIBuf;
if (profile->qmap_mode == 0 || profile->qmap_mode == 1)
nreads = read(fd, QMIBuf, sizeof(QMIBuf));
else
nreads = qmi_proxy_read(fd, QMIBuf, sizeof(QMIBuf));
// 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;
}
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;
}
#endif
const struct qmi_device_ops qmiwwan_qmidev_ops = {
.init = QmiWwanInit,
.deinit = QmiWwanDeInit,
.send = QmiWwanSendQMI,
.read = QmiWwanThread,
};
File diff suppressed because it is too large. Load diff
+47 -47
View File
@@ -1,67 +1,67 @@
[Setting]
qmap_num=4
[profile1]
[Setting]
qmap_num=4
[profile1]
apn=1234567890
user=qwertyuio
password=asdfghjkl
auth=2
ipfamily=1
pin=
[profile2]
pin=
[profile2]
apn=ctnet
user=
password=
auth=0
ipfamily=1
pin=
[profile3]
pin=
[profile3]
apn=ctnet
user=
password=
auth=0
ipfamily=1
pin=
[profile4]
pin=
[profile4]
apn=ctnet
user=
password=
auth=0
ipfamily=1
pin=
[profile5]
apn=ctnet
user=
password=
auth=
ipfamily=1
pin=
[profile6]
apn=ctnet
user=
password=
auth=
ipfamily=1
pin=
[profile7]
apn=ctnet
user=
password=
auth=
ipfamily=1
pin=
[profile8]
apn=ctnet
user=
password=
auth=
ipfamily=1
pin=
pin=
[profile5]
apn=ctnet
user=
password=
auth=
ipfamily=1
pin=
[profile6]
apn=ctnet
user=
password=
auth=
ipfamily=1
pin=
[profile7]
apn=ctnet
user=
password=
auth=
ipfamily=1
pin=
[profile8]
apn=ctnet
user=
password=
auth=
ipfamily=1
pin=
+438 -438
View File
@@ -1,438 +1,438 @@
#include "QMIThread.h"
//2021-03-15 zhangkaibo@fibocom.com changed begin for oa 20210311037
#include <net/if.h>
//2021-03-15 zhangkaibo@fibocom.com changed end for oa 20210311037
static size_t fibo_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=%zd, buf_size=%zd, "
"errno: %d (%s)",
__func__, filename, n, size, errno, strerror(errno));
}
fclose(fp);
}
return n > 0 ? n : 0;
}
static size_t fibo_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=%zd, buf_size=%zd, "
"errno: %d (%s)",
__func__, filename, n, size, errno, strerror(errno));
}
fclose(fp);
}
return n > 0 ? n : 0;
}
static int fibo_iface_is_in_bridge(const char *iface)
{
char filename[256];
snprintf(filename, sizeof(filename), "/sys/class/net/%s/brport", iface);
return (access(filename, F_OK) == 0 || errno != ENOENT);
}
int fibo_bridge_mode_detect(PROFILE_T *profile)
{
const char *ifname = profile->qmapnet_adapter ? 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;
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_mode, F_OK) && errno == ENOENT) {
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, F_OK) && errno == ENOENT) {
bridge_mode[0] = '\0';
}
}
in_bridge = fibo_iface_is_in_bridge(ifname);
if (in_bridge) {
dbg_time("notice: iface %s had add to bridge\n", ifname);
}
if (in_bridge && bridge_mode[0] == '\0') {
dbg_time("warnning: can not find bride_mode file for %s\n", ifname);
return 1;
}
n = fibo_fread(bridge_mode, buf, sizeof(buf));
if (in_bridge) {
if (n <= 0 || buf[0] == '0') {
dbg_time("warnning: should set 1 to bride_mode file for %s\n",
ifname);
return 1;
}
} else {
if (n <= 0 || buf[0] == '0') {
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);
fibo_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);
fibo_fwrite(bridge_ipv4, ipv4, strlen(ipv4));
}
return 1;
}
//2021-03-15 zhangkaibo@fibocom.com changed begin for oa 20210311037
void fibo_get_driver_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) {
dbg_time("ioctl(0x%x, qmap_settings) failed: %s, rc=%d", request, strerror(errno), rc);
}
else {
memcpy(rmnet_info, data, sizeof(*rmnet_info));
}
close(ifc_ctl_sock);
}
//2021-03-15 zhangkaibo@fibocom.com changed end for oa 20210311037
int fibo_qmap_mode_detect(PROFILE_T *profile)
{
int n;
char buf[128];
char qmap_netcard[128];
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--;
profile->driver_name = strdup(&pl->filename[n + 1]);
//2021-03-15 zhangkaibo@fibocom.com changed begin for oa 20210311037
fibo_get_driver_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->rmnet_info.mux_id[offset_id];
profile->qmapnet_adapter = strdup( profile->rmnet_info.ifname[offset_id]);
profile->qmap_size = profile->rmnet_info.rx_urb_size;
profile->qmap_version = profile->rmnet_info.qmap_version;
}
goto _out;
}
//2021-03-15 zhangkaibo@fibocom.com changed end for oa 20210311037
if (qmidev_is_pciemhi(profile->qmichannel)) {
profile->qmap_mode = 1;
if (profile->muxid == 0 || profile->muxid == 0x81)
{
profile->muxid = 0x81;
}
else
{
if (profile->muxid < 0x80)
profile->muxid += 0x81;
profile->qmap_mode = 2;
}
profile->qmapnet_adapter = strdup(profile->usbnet_adapter);
goto _final_process;
}
snprintf(pl->filename, sizeof(pl->filename), "/sys/class/net/%s/qmap_num",
profile->usbnet_adapter);
//2021-01-27 willa.liu@fibocom.com changed begin for support mantis 0068849
if (access(pl->filename, F_OK) == 0) {
dbg_time("access %s", pl->filename);
if (errno != ENOENT) {
dbg_time("fail to access %s, errno: %d (%s)", pl->filename, errno,
strerror(errno));
goto _out;
}
//2021-02-01 willa.liu@fibocom.com changed begin for support mantis 0069837
/*
snprintf(pl->filename, sizeof(pl->filename),
"/sys/module/%s/parameters/qmap_num", 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_num",
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;
}
}
}
*/
//2021-02-01 willa.liu@fibocom.com changed end for support mantis 0069837
}
else
{
snprintf(pl->filename, sizeof(pl->filename), "/sys/class/net/%s/qmap_mode",
profile->usbnet_adapter);
if (access(pl->filename, F_OK) == 0) {
dbg_time("access %s", pl->filename);
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 = fibo_fread(pl->filename, buf, sizeof(buf));
if(n > 0)
{
profile->qmap_mode = atoi(buf);
if(profile->qmap_mode >= 1 && qmidev_is_pciemhi(profile->qmichannel))
{
profile->muxid =
profile->pdp + 0x80;
sprintf(qmap_netcard, "%s.%d", profile->usbnet_adapter,profile->pdp);
profile->qmapnet_adapter = strdup(qmap_netcard);
}
if(qmidev_is_gobinet(profile->qmichannel) || qmidev_is_qmiwwan(profile->qmichannel))
{
if(profile->qmap_mode > 1)
{
profile->muxid =
profile->pdp + 0x80;
sprintf(qmap_netcard, "%s.%d", profile->usbnet_adapter,profile->pdp);
profile->qmapnet_adapter = strdup(qmap_netcard);
}
if(profile->qmap_mode == 1)
{
profile->muxid = 0x81;
profile->qmapnet_adapter = strdup(profile->usbnet_adapter);
}
}
}
if (0) {
profile->qmap_mode = atoi(buf);
if (profile->qmap_mode > 1 && qmidev_is_gobinet(profile->qmichannel)) {
profile->muxid =
profile->pdp + 0x80; // muxis is 0x8X for PDN-X
sprintf(qmap_netcard, "%s.%d", profile->usbnet_adapter,profile->pdp);
profile->qmapnet_adapter = strdup(qmap_netcard);
}
if (profile->qmap_mode >= 1 && !qmidev_is_gobinet(profile->qmichannel)) {
profile->muxid =
profile->pdp + 0x80; // muxis is 0x8X for PDN-X
sprintf(qmap_netcard, "%s.%d", profile->usbnet_adapter,profile->pdp);
profile->qmapnet_adapter = strdup(qmap_netcard);
}
if (profile->qmap_mode == 1 && qmidev_is_gobinet(profile->qmichannel)) {
profile->muxid = 0x81;
profile->qmapnet_adapter = strdup(profile->usbnet_adapter);
//2021-01-27 willa.liu@fibocom.com changed end for support mantis 0068849
}
}
} 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 = fibo_fread(pl->filename, buf, sizeof(buf));
if (n >= 5) {
profile->qmap_mode = n / 5; // 0x81\n0x82\n0x83\n
if (profile->qmap_mode > 1) {
// PDN-X map to qmimux-X
profile->muxid = (buf[5 * (profile->pdp - 1) + 2] - '0') * 16 +
(buf[5 * (profile->pdp - 1) + 3] - '0');
sprintf(qmap_netcard, "qmimux%d", profile->pdp - 1);
profile->qmapnet_adapter = strdup(qmap_netcard);
} else if (profile->qmap_mode == 1) {
profile->muxid =
(buf[5 * 0 + 2] - '0') * 16 + (buf[5 * 0 + 3] - '0');
sprintf(qmap_netcard, "qmimux%d", 0);
profile->qmapnet_adapter = strdup(qmap_netcard);
}
}
}
_out:
if (profile->qmap_mode) {
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 = fibo_fread(pl->filename, buf, sizeof(buf));
if (n > 0) {
profile->qmap_size = atoi(buf);
}
}
}
_final_process:
if (profile->qmap_mode)
dbg_time("qmap_mode = %d, muxid = 0x%02x, qmap_netcard = %s",
profile->qmap_mode, profile->muxid, profile->qmapnet_adapter);
free(pl);
return 0;
}
int fibo_qmap_mode_set(PROFILE_T *profile)
{
int n;
char buf[128];
struct {
char filename[255 * 2];
char linkname[255 * 2];
} * pl;
if (qmidev_is_pciemhi(profile->qmichannel))
{
dbg_time("pcie mode exit fibo_qmap_mode_set ");
return 0;
}
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--;
profile->driver_name = strdup(&pl->filename[n + 1]);
snprintf(pl->filename, sizeof(pl->filename), "/sys/class/net/%s/qmap_num",
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_mnum", 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_num",
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)) {
snprintf(buf, sizeof(buf), "%d", profile->pdpnum);
n = fibo_fwrite(pl->filename, buf, strlen(buf));
}
_out:
free(pl);
return 0;
}
#include "QMIThread.h"
//2021-03-15 zhangkaibo@fibocom.com changed begin for oa 20210311037
#include <net/if.h>
//2021-03-15 zhangkaibo@fibocom.com changed end for oa 20210311037
static size_t fibo_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=%zd, buf_size=%zd, "
"errno: %d (%s)",
__func__, filename, n, size, errno, strerror(errno));
}
fclose(fp);
}
return n > 0 ? n : 0;
}
static size_t fibo_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=%zd, buf_size=%zd, "
"errno: %d (%s)",
__func__, filename, n, size, errno, strerror(errno));
}
fclose(fp);
}
return n > 0 ? n : 0;
}
static int fibo_iface_is_in_bridge(const char *iface)
{
char filename[256];
snprintf(filename, sizeof(filename), "/sys/class/net/%s/brport", iface);
return (access(filename, F_OK) == 0 || errno != ENOENT);
}
int fibo_bridge_mode_detect(PROFILE_T *profile)
{
const char *ifname = profile->qmapnet_adapter ? 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;
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_mode, F_OK) && errno == ENOENT) {
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, F_OK) && errno == ENOENT) {
bridge_mode[0] = '\0';
}
}
in_bridge = fibo_iface_is_in_bridge(ifname);
if (in_bridge) {
dbg_time("notice: iface %s had add to bridge\n", ifname);
}
if (in_bridge && bridge_mode[0] == '\0') {
dbg_time("warnning: can not find bride_mode file for %s\n", ifname);
return 1;
}
n = fibo_fread(bridge_mode, buf, sizeof(buf));
if (in_bridge) {
if (n <= 0 || buf[0] == '0') {
dbg_time("warnning: should set 1 to bride_mode file for %s\n",
ifname);
return 1;
}
} else {
if (n <= 0 || buf[0] == '0') {
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);
fibo_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);
fibo_fwrite(bridge_ipv4, ipv4, strlen(ipv4));
}
return 1;
}
//2021-03-15 zhangkaibo@fibocom.com changed begin for oa 20210311037
void fibo_get_driver_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) {
dbg_time("ioctl(0x%x, qmap_settings) failed: %s, rc=%d", request, strerror(errno), rc);
}
else {
memcpy(rmnet_info, data, sizeof(*rmnet_info));
}
close(ifc_ctl_sock);
}
//2021-03-15 zhangkaibo@fibocom.com changed end for oa 20210311037
int fibo_qmap_mode_detect(PROFILE_T *profile)
{
int n;
char buf[128];
char qmap_netcard[128];
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--;
profile->driver_name = strdup(&pl->filename[n + 1]);
//2021-03-15 zhangkaibo@fibocom.com changed begin for oa 20210311037
fibo_get_driver_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->rmnet_info.mux_id[offset_id];
profile->qmapnet_adapter = strdup( profile->rmnet_info.ifname[offset_id]);
profile->qmap_size = profile->rmnet_info.rx_urb_size;
profile->qmap_version = profile->rmnet_info.qmap_version;
}
goto _out;
}
//2021-03-15 zhangkaibo@fibocom.com changed end for oa 20210311037
if (qmidev_is_pciemhi(profile->qmichannel)) {
profile->qmap_mode = 1;
if (profile->muxid == 0 || profile->muxid == 0x81)
{
profile->muxid = 0x81;
}
else
{
if (profile->muxid < 0x80)
profile->muxid += 0x81;
profile->qmap_mode = 2;
}
profile->qmapnet_adapter = strdup(profile->usbnet_adapter);
goto _final_process;
}
snprintf(pl->filename, sizeof(pl->filename), "/sys/class/net/%s/qmap_num",
profile->usbnet_adapter);
//2021-01-27 willa.liu@fibocom.com changed begin for support mantis 0068849
if (access(pl->filename, F_OK) == 0) {
dbg_time("access %s", pl->filename);
if (errno != ENOENT) {
dbg_time("fail to access %s, errno: %d (%s)", pl->filename, errno,
strerror(errno));
goto _out;
}
//2021-02-01 willa.liu@fibocom.com changed begin for support mantis 0069837
/*
snprintf(pl->filename, sizeof(pl->filename),
"/sys/module/%s/parameters/qmap_num", 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_num",
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;
}
}
}
*/
//2021-02-01 willa.liu@fibocom.com changed end for support mantis 0069837
}
else
{
snprintf(pl->filename, sizeof(pl->filename), "/sys/class/net/%s/qmap_mode",
profile->usbnet_adapter);
if (access(pl->filename, F_OK) == 0) {
dbg_time("access %s", pl->filename);
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 = fibo_fread(pl->filename, buf, sizeof(buf));
if(n > 0)
{
profile->qmap_mode = atoi(buf);
if(profile->qmap_mode >= 1 && qmidev_is_pciemhi(profile->qmichannel))
{
profile->muxid =
profile->pdp + 0x80;
sprintf(qmap_netcard, "%s.%d", profile->usbnet_adapter,profile->pdp);
profile->qmapnet_adapter = strdup(qmap_netcard);
}
if(qmidev_is_gobinet(profile->qmichannel) || qmidev_is_qmiwwan(profile->qmichannel))
{
if(profile->qmap_mode > 1)
{
profile->muxid =
profile->pdp + 0x80;
sprintf(qmap_netcard, "%s.%d", profile->usbnet_adapter,profile->pdp);
profile->qmapnet_adapter = strdup(qmap_netcard);
}
if(profile->qmap_mode == 1)
{
profile->muxid = 0x81;
profile->qmapnet_adapter = strdup(profile->usbnet_adapter);
}
}
}
if (0) {
profile->qmap_mode = atoi(buf);
if (profile->qmap_mode > 1 && qmidev_is_gobinet(profile->qmichannel)) {
profile->muxid =
profile->pdp + 0x80; // muxis is 0x8X for PDN-X
sprintf(qmap_netcard, "%s.%d", profile->usbnet_adapter,profile->pdp);
profile->qmapnet_adapter = strdup(qmap_netcard);
}
if (profile->qmap_mode >= 1 && !qmidev_is_gobinet(profile->qmichannel)) {
profile->muxid =
profile->pdp + 0x80; // muxis is 0x8X for PDN-X
sprintf(qmap_netcard, "%s.%d", profile->usbnet_adapter,profile->pdp);
profile->qmapnet_adapter = strdup(qmap_netcard);
}
if (profile->qmap_mode == 1 && qmidev_is_gobinet(profile->qmichannel)) {
profile->muxid = 0x81;
profile->qmapnet_adapter = strdup(profile->usbnet_adapter);
//2021-01-27 willa.liu@fibocom.com changed end for support mantis 0068849
}
}
} 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 = fibo_fread(pl->filename, buf, sizeof(buf));
if (n >= 5) {
profile->qmap_mode = n / 5; // 0x81\n0x82\n0x83\n
if (profile->qmap_mode > 1) {
// PDN-X map to qmimux-X
profile->muxid = (buf[5 * (profile->pdp - 1) + 2] - '0') * 16 +
(buf[5 * (profile->pdp - 1) + 3] - '0');
sprintf(qmap_netcard, "qmimux%d", profile->pdp - 1);
profile->qmapnet_adapter = strdup(qmap_netcard);
} else if (profile->qmap_mode == 1) {
profile->muxid =
(buf[5 * 0 + 2] - '0') * 16 + (buf[5 * 0 + 3] - '0');
sprintf(qmap_netcard, "qmimux%d", 0);
profile->qmapnet_adapter = strdup(qmap_netcard);
}
}
}
_out:
if (profile->qmap_mode) {
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 = fibo_fread(pl->filename, buf, sizeof(buf));
if (n > 0) {
profile->qmap_size = atoi(buf);
}
}
}
_final_process:
if (profile->qmap_mode)
dbg_time("qmap_mode = %d, muxid = 0x%02x, qmap_netcard = %s",
profile->qmap_mode, profile->muxid, profile->qmapnet_adapter);
free(pl);
return 0;
}
int fibo_qmap_mode_set(PROFILE_T *profile)
{
int n;
char buf[128];
struct {
char filename[255 * 2];
char linkname[255 * 2];
} * pl;
if (qmidev_is_pciemhi(profile->qmichannel))
{
dbg_time("pcie mode exit fibo_qmap_mode_set ");
return 0;
}
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--;
profile->driver_name = strdup(&pl->filename[n + 1]);
snprintf(pl->filename, sizeof(pl->filename), "/sys/class/net/%s/qmap_num",
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_mnum", 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_num",
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)) {
snprintf(buf, sizeof(buf), "%d", profile->pdpnum);
n = fibo_fwrite(pl->filename, buf, strlen(buf));
}
_out:
free(pl);
return 0;
}
+160 -160
View File
@@ -1,160 +1,160 @@
//2021-03-24 willa.liu@fibocom.com changed begin for support mantis 0071817
#include "QMIThread.h"
#include "query_pcie_mode.h"
int speed_arr[] = { B115200, B19200, B9600, B4800, B2400, B1200, B300,//
B38400, B19200, B9600, B4800, B2400, B1200, B300,
};
int name_arr[] = {115200, 19200, 9600, 4800, 2400, 1200, 300,
38400, 19200, 9600, 4800, 2400, 1200, 300,
};
int get_pcie_mode_debug = 0;
//2021-02-24 willa.liu@fibocom.com changed begin for support eipd SN-20210129001
int get_private_gateway_debug = 1;
//2021-02-24 willa.liu@fibocom.com changed end for support eipd SN-20210129001
//static int xset1(int fd, struct termios *tio, const char *device)
int xset1(int fd, struct termios *tio, const char *device)
{
int ret = tcsetattr(fd, TCSAFLUSH, tio);
if (ret) {
printf("can't tcsetattr for %s", device);
}
return ret;
}
// set raw tty mode
//static void xget1(int fd, struct termios *t, struct termios *oldt)
void xget1(int fd, struct termios *t, struct termios *oldt)
{
tcgetattr(fd, oldt);
*t = *oldt;
cfmakeraw(t);
// t->c_lflag &= ~(ISIG|ICANON|ECHO|IEXTEN);
// t->c_iflag &= ~(BRKINT|IXON|ICRNL);
// t->c_oflag &= ~(ONLCR);
// t->c_cc[VMIN] = 1;
// t->c_cc[VTIME] = 0;
}
//static int get_pcie_mode()
int get_pcie_mode()
//2021-03-24 willa.liu@fibocom.com changed end for support mantis 0071817
{
int i;
int fd;
int ret;
char buffer[409600] = {0};
int rate;
char* sendbuffer;
int totallen = 0;
fd_set readfds;
struct timeval timeout;
struct termios tio0, tiosfd, tio;
int timeoutVal = 5;
char *dev = "/dev/ttyUSB1"; //The port under Linux is operated by opening the device file
rate = 115200;
sendbuffer = "at+gtpcie=3";
printf ( "dev: %s\nrate:%d\nsendbuffer:%s\n", dev,rate,sendbuffer);
fd = open(dev, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd < 0)
goto ERR;
fcntl(fd, F_SETFL, O_RDWR);
// put device to "raw mode"
xget1(fd, &tio, &tiosfd);
// set device speed
for ( i = 0;i < sizeof ( speed_arr ) / sizeof ( int );i++ )
{
if ( rate == name_arr[i] ) //Judge if the pass is equal to the pass
{
break;
}
}
if(i >= sizeof ( speed_arr ) / sizeof ( int ))
{
printf("bound rate set failed\n");
goto ERR;
}
cfsetspeed(&tio, speed_arr[i]);
if (xset1(fd, &tio, dev))
goto ERR;
tcflush ( fd, TCIOFLUSH );
sprintf(buffer, "%s\r", sendbuffer);
ret = write ( fd, buffer, strlen(buffer) );
if(ret < 0)
{
printf ( "write failed\n" );
goto ERR;
}
if(get_pcie_mode_debug)printf("write %d\n", ret);
FD_ZERO ( &readfds );
FD_SET ( fd, &readfds );
while(1)
{
timeout.tv_sec = timeoutVal;
timeout.tv_usec = 0;
ret = select ( fd+1, &readfds, ( fd_set * ) 0, ( fd_set * ) 0, &timeout );
if(ret > 0)
{
ret = read ( fd, buffer+totallen, sizeof(buffer)-totallen-1 );
if(ret < 0)
{
printf ( "read failed\n" );
goto ERR;
}
if(ret == 0)
{
goto ERR;
}
totallen += ret;
buffer[totallen] = '\0';
if(get_pcie_mode_debug)printf("read %d(%s)\n", ret, &buffer[totallen-ret]);
if(totallen == sizeof(buffer)-1)
break;
if(strstr(buffer,"\nOK") || strstr(buffer,"\nERROR")
|| strstr(buffer,"\n+CME ERROR:") || strstr(buffer,"\n+CMS ERROR:"))
{
if(get_pcie_mode_debug)printf("match OK/ERROR");
if(get_pcie_mode_debug)printf("%s", buffer);
break;
}
}
else
{
printf ( "select timeout\n" );
goto ERR;
}
}
tcsetattr(fd, TCSAFLUSH, &tiosfd);
//printf("buffer:\n %s\n", buffer);
printf("%s\n", buffer);
if(strstr(buffer,"\nERROR") || strstr(buffer,"\n+CME ERROR:") || strstr(buffer,"\n+CMS ERROR:"))
goto ERR;
close ( fd );
return 0;
ERR:
if(fd > 0)
close(fd);
return -1;
}
//2021-03-24 willa.liu@fibocom.com changed begin for support mantis 0071817
#include "QMIThread.h"
#include "query_pcie_mode.h"
int speed_arr[] = { B115200, B19200, B9600, B4800, B2400, B1200, B300,//
B38400, B19200, B9600, B4800, B2400, B1200, B300,
};
int name_arr[] = {115200, 19200, 9600, 4800, 2400, 1200, 300,
38400, 19200, 9600, 4800, 2400, 1200, 300,
};
int get_pcie_mode_debug = 0;
//2021-02-24 willa.liu@fibocom.com changed begin for support eipd SN-20210129001
int get_private_gateway_debug = 1;
//2021-02-24 willa.liu@fibocom.com changed end for support eipd SN-20210129001
//static int xset1(int fd, struct termios *tio, const char *device)
int xset1(int fd, struct termios *tio, const char *device)
{
int ret = tcsetattr(fd, TCSAFLUSH, tio);
if (ret) {
printf("can't tcsetattr for %s", device);
}
return ret;
}
// set raw tty mode
//static void xget1(int fd, struct termios *t, struct termios *oldt)
void xget1(int fd, struct termios *t, struct termios *oldt)
{
tcgetattr(fd, oldt);
*t = *oldt;
cfmakeraw(t);
// t->c_lflag &= ~(ISIG|ICANON|ECHO|IEXTEN);
// t->c_iflag &= ~(BRKINT|IXON|ICRNL);
// t->c_oflag &= ~(ONLCR);
// t->c_cc[VMIN] = 1;
// t->c_cc[VTIME] = 0;
}
//static int get_pcie_mode()
int get_pcie_mode()
//2021-03-24 willa.liu@fibocom.com changed end for support mantis 0071817
{
int i;
int fd;
int ret;
char buffer[409600] = {0};
int rate;
char* sendbuffer;
int totallen = 0;
fd_set readfds;
struct timeval timeout;
struct termios tio0, tiosfd, tio;
int timeoutVal = 5;
char *dev = "/dev/ttyUSB1"; //The port under Linux is operated by opening the device file
rate = 115200;
sendbuffer = "at+gtpcie=3";
printf ( "dev: %s\nrate:%d\nsendbuffer:%s\n", dev,rate,sendbuffer);
fd = open(dev, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd < 0)
goto ERR;
fcntl(fd, F_SETFL, O_RDWR);
// put device to "raw mode"
xget1(fd, &tio, &tiosfd);
// set device speed
for ( i = 0;i < sizeof ( speed_arr ) / sizeof ( int );i++ )
{
if ( rate == name_arr[i] ) //Judge if the pass is equal to the pass
{
break;
}
}
if(i >= sizeof ( speed_arr ) / sizeof ( int ))
{
printf("bound rate set failed\n");
goto ERR;
}
cfsetspeed(&tio, speed_arr[i]);
if (xset1(fd, &tio, dev))
goto ERR;
tcflush ( fd, TCIOFLUSH );
sprintf(buffer, "%s\r", sendbuffer);
ret = write ( fd, buffer, strlen(buffer) );
if(ret < 0)
{
printf ( "write failed\n" );
goto ERR;
}
if(get_pcie_mode_debug)printf("write %d\n", ret);
FD_ZERO ( &readfds );
FD_SET ( fd, &readfds );
while(1)
{
timeout.tv_sec = timeoutVal;
timeout.tv_usec = 0;
ret = select ( fd+1, &readfds, ( fd_set * ) 0, ( fd_set * ) 0, &timeout );
if(ret > 0)
{
ret = read ( fd, buffer+totallen, sizeof(buffer)-totallen-1 );
if(ret < 0)
{
printf ( "read failed\n" );
goto ERR;
}
if(ret == 0)
{
goto ERR;
}
totallen += ret;
buffer[totallen] = '\0';
if(get_pcie_mode_debug)printf("read %d(%s)\n", ret, &buffer[totallen-ret]);
if(totallen == sizeof(buffer)-1)
break;
if(strstr(buffer,"\nOK") || strstr(buffer,"\nERROR")
|| strstr(buffer,"\n+CME ERROR:") || strstr(buffer,"\n+CMS ERROR:"))
{
if(get_pcie_mode_debug)printf("match OK/ERROR");
if(get_pcie_mode_debug)printf("%s", buffer);
break;
}
}
else
{
printf ( "select timeout\n" );
goto ERR;
}
}
tcsetattr(fd, TCSAFLUSH, &tiosfd);
//printf("buffer:\n %s\n", buffer);
printf("%s\n", buffer);
if(strstr(buffer,"\nERROR") || strstr(buffer,"\n+CME ERROR:") || strstr(buffer,"\n+CMS ERROR:"))
goto ERR;
close ( fd );
return 0;
ERR:
if(fd > 0)
close(fd);
return -1;
}
+17 -17
View File
@@ -1,17 +1,17 @@
#ifndef __QUERY_PCIE_MODE__
#define __QUERY_PCIE_MODE__
extern int speed_arr[14];
extern int name_arr[14];
extern int get_pcie_mode_debug;
extern int get_private_gateway_debug;
extern int xset1(int fd, struct termios *tio, const char *device);
// set raw tty mode
extern void xget1(int fd, struct termios *t, struct termios *oldt);
extern int get_pcie_mode();
#endif
#ifndef __QUERY_PCIE_MODE__
#define __QUERY_PCIE_MODE__
extern int speed_arr[14];
extern int name_arr[14];
extern int get_pcie_mode_debug;
extern int get_private_gateway_debug;
extern int xset1(int fd, struct termios *tio, const char *device);
// set raw tty mode
extern void xget1(int fd, struct termios *t, struct termios *oldt);
extern int get_pcie_mode();
#endif
+289 -289
View File
@@ -1,289 +1,289 @@
#include <arpa/inet.h>
#include <endian.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include "QMIThread.h"
#include "util.h"
static int dibbler_client_alive = 0;
static int fibo_system(const char *shell_cmd)
{
int ret = 0;
dbg_time("%s", shell_cmd);
ret = system(shell_cmd);
if (ret) {
// dbg_time("Fail to system(\"%s\") = %d, errno: %d (%s)", shell_cmd,
// ret, errno, strerror(errno));
}
return ret;
}
static void fibo_set_mtu(const char *ifname, int ifru_mtu)
{
int inet_sock;
struct ifreq ifr;
inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
if (inet_sock > 0) {
strcpy(ifr.ifr_name, ifname);
if (!ioctl(inet_sock, SIOCGIFMTU, &ifr)) {
if (ifr.ifr_ifru.ifru_mtu != ifru_mtu) {
dbg_time("change mtu %d -> %d", ifr.ifr_ifru.ifru_mtu,
ifru_mtu);
ifr.ifr_ifru.ifru_mtu = ifru_mtu;
ioctl(inet_sock, SIOCSIFMTU, &ifr);
}
}
close(inet_sock);
}
}
static void *udhcpc_thread_function(void *arg)
{
FILE *udhcpc_fp;
char *udhcpc_cmd = (char *)arg;
if (udhcpc_cmd == NULL)
return NULL;
dbg_time("%s", udhcpc_cmd);
udhcpc_fp = popen(udhcpc_cmd, "r");
free(udhcpc_cmd);
if (udhcpc_fp) {
char buf[0xff];
buf[sizeof(buf) - 1] = '\0';
while ((fgets(buf, sizeof(buf) - 1, udhcpc_fp)) != NULL) {
if ((strlen(buf) > 1) && (buf[strlen(buf) - 1] == '\n'))
buf[strlen(buf) - 1] = '\0';
dbg_time("%s", buf);
}
pclose(udhcpc_fp);
}
return NULL;
}
void fibo_set_driver_link_state(PROFILE_T *profile, int link_state)
{
char link_file[128];
int fd;
int new_state = 0;
dbg_time("enter %s ", __func__);
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"))) {
// snprintf(link_file, sizeof(link_file), "busybox ifconfig %s down",
// profile->usbnet_adapter);
// fibo_system(link_file);
}
}
close(fd);
}
int fibo_raw_ip_mode_check(const char *ifname)
{
int fd;
char raw_ip[128];
char shell_cmd[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') {
snprintf(shell_cmd, sizeof(shell_cmd), "busybox ifconfig %s down", ifname);
fibo_system(shell_cmd);
dbg_time("echo Y > /sys/class/net/%s/qmi/raw_ip", ifname);
mode[0] = 'Y';
write(fd, mode, 2);
mode_change = 1;
snprintf(shell_cmd, sizeof(shell_cmd), "busybox ifconfig %s up", ifname);
fibo_system(shell_cmd);
}
close(fd);
return mode_change;
}
void udhcpc_start(PROFILE_T *profile)
{
char *ifname = profile->usbnet_adapter;
char shell_cmd[128];
fibo_set_driver_link_state(profile, 1);
if (profile->qmapnet_adapter) {
ifname = profile->qmapnet_adapter;
}
dbg_time("1 %s", profile->qmichannel);
if (qmidev_is_qmiwwan(profile->qmichannel)) {
dbg_time("2 %s", ifname);
fibo_raw_ip_mode_check(ifname);
}
if (profile->rawIP && profile->ipv4.Address && profile->ipv4.Mtu) {
fibo_set_mtu(ifname, (profile->ipv4.Mtu));
}
fibo_system("echo 1 > /sys/module/fibo_mhi/parameters/macaddr_check");
//begin modified by zhangkaibo fix ipv6 dial process flow. mantis 0048789 20200605
// if (strcmp(ifname, profile->usbnet_adapter)) {
// snprintf(shell_cmd, sizeof(shell_cmd) - 1, "busybox ifconfig %s up",
// profile->usbnet_adapter);
// fibo_system(shell_cmd);
// }
//begin modified by zhangkaibo fix ipv6 dial process flow. mantis 0048789 20200605
// For IPv6, down & up will send protocol packets, and that's needed.
if (profile->ipv6_flag) {
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "busybox ifconfig %s down", ifname);
fibo_system(shell_cmd);
}
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "busybox ifconfig %s up", ifname);
fibo_system(shell_cmd);
//begin modified by zhangming Added NOARP and Multilcast on flag bit commands. mantis 0050106 20200713
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "ip link set %s arp off multicast on", ifname);
fibo_system(shell_cmd);
//begin modified by zhangming Added NOARP and Multilcast on flag bit commands. mantis 0050106 20200713
//Modified unicom dual stack dialing unsuccessful problem
// for bridge mode, only one public IP, so do udhcpc manually
if (fibo_bridge_mode_detect(profile)) {
return;
}
/* Do DHCP using busybox tools */
{
char udhcpc_cmd[128];
pthread_attr_t udhcpc_thread_attr;
pthread_t udhcpc_thread_id;
pthread_attr_init(&udhcpc_thread_attr);
pthread_attr_setdetachstate(&udhcpc_thread_attr,
PTHREAD_CREATE_DETACHED);
if (profile->ipv4.Address) {
if (access("/usr/share/udhcpc/default.script", X_OK)) {
dbg_time(
"Fail to access /usr/share/udhcpc/default.script, "
"errno: %d (%s)",
errno, strerror(errno));
}
//-f,--foreground Run in foreground
//-b,--background Background if lease is not obtained
//-n,--now Exit if lease is not obtained
//-q,--quit Exit after obtaining lease
//-t,--retries N Send up to N discover packets (default 3)
snprintf(udhcpc_cmd, sizeof(udhcpc_cmd),
"busybox udhcpc -f -n -q -t 5 -i %s", ifname);
if (!access("/lib/netifd/dhcp.script", X_OK) &&
!access("/sbin/ifup", X_OK) &&
!access("/sbin/ifstatus", X_OK)) {
dbg_time("you are use OpenWrt?");
dbg_time("should not calling udhcpc manually?");
dbg_time("should modify /etc/config/network as below?");
dbg_time("config interface wan");
dbg_time("\toption ifname %s", ifname);
dbg_time("\toption proto dhcp");
dbg_time(
"should use \"/sbin/ifstaus wan\" to check %s 's status?",
ifname);
}
pthread_create(&udhcpc_thread_id, NULL, udhcpc_thread_function,
(void *)strdup(udhcpc_cmd));
sleep(1);
}
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);
}
}
}
}
void udhcpc_stop(PROFILE_T *profile)
{
char *ifname = profile->usbnet_adapter;
char shell_cmd[128];
char reset_ip[128];
dbg_time("enter %s ", __func__);
if (profile->qmapnet_adapter) {
ifname = profile->qmapnet_adapter;
}
if (dibbler_client_alive) {
system("killall dibbler-client");
dibbler_client_alive = 0;
}
//snprintf(shell_cmd, sizeof(shell_cmd) - 1, "busybox ifconfig %s down",
// profile->usbnet_adapter);
//fibo_system(shell_cmd);
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "busybox ifconfig %s down", ifname);
fibo_system(shell_cmd);
snprintf(reset_ip, sizeof(reset_ip) - 1, "busybox ifconfig %s 0.0.0.0", ifname);
fibo_system(reset_ip);
}
#include <arpa/inet.h>
#include <endian.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include "QMIThread.h"
#include "util.h"
static int dibbler_client_alive = 0;
static int fibo_system(const char *shell_cmd)
{
int ret = 0;
dbg_time("%s", shell_cmd);
ret = system(shell_cmd);
if (ret) {
// dbg_time("Fail to system(\"%s\") = %d, errno: %d (%s)", shell_cmd,
// ret, errno, strerror(errno));
}
return ret;
}
static void fibo_set_mtu(const char *ifname, int ifru_mtu)
{
int inet_sock;
struct ifreq ifr;
inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
if (inet_sock > 0) {
strcpy(ifr.ifr_name, ifname);
if (!ioctl(inet_sock, SIOCGIFMTU, &ifr)) {
if (ifr.ifr_ifru.ifru_mtu != ifru_mtu) {
dbg_time("change mtu %d -> %d", ifr.ifr_ifru.ifru_mtu,
ifru_mtu);
ifr.ifr_ifru.ifru_mtu = ifru_mtu;
ioctl(inet_sock, SIOCSIFMTU, &ifr);
}
}
close(inet_sock);
}
}
static void *udhcpc_thread_function(void *arg)
{
FILE *udhcpc_fp;
char *udhcpc_cmd = (char *)arg;
if (udhcpc_cmd == NULL)
return NULL;
dbg_time("%s", udhcpc_cmd);
udhcpc_fp = popen(udhcpc_cmd, "r");
free(udhcpc_cmd);
if (udhcpc_fp) {
char buf[0xff];
buf[sizeof(buf) - 1] = '\0';
while ((fgets(buf, sizeof(buf) - 1, udhcpc_fp)) != NULL) {
if ((strlen(buf) > 1) && (buf[strlen(buf) - 1] == '\n'))
buf[strlen(buf) - 1] = '\0';
dbg_time("%s", buf);
}
pclose(udhcpc_fp);
}
return NULL;
}
void fibo_set_driver_link_state(PROFILE_T *profile, int link_state)
{
char link_file[128];
int fd;
int new_state = 0;
dbg_time("enter %s ", __func__);
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"))) {
// snprintf(link_file, sizeof(link_file), "busybox ifconfig %s down",
// profile->usbnet_adapter);
// fibo_system(link_file);
}
}
close(fd);
}
int fibo_raw_ip_mode_check(const char *ifname)
{
int fd;
char raw_ip[128];
char shell_cmd[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') {
snprintf(shell_cmd, sizeof(shell_cmd), "busybox ifconfig %s down", ifname);
fibo_system(shell_cmd);
dbg_time("echo Y > /sys/class/net/%s/qmi/raw_ip", ifname);
mode[0] = 'Y';
write(fd, mode, 2);
mode_change = 1;
snprintf(shell_cmd, sizeof(shell_cmd), "busybox ifconfig %s up", ifname);
fibo_system(shell_cmd);
}
close(fd);
return mode_change;
}
void udhcpc_start(PROFILE_T *profile)
{
char *ifname = profile->usbnet_adapter;
char shell_cmd[128];
fibo_set_driver_link_state(profile, 1);
if (profile->qmapnet_adapter) {
ifname = profile->qmapnet_adapter;
}
dbg_time("1 %s", profile->qmichannel);
if (qmidev_is_qmiwwan(profile->qmichannel)) {
dbg_time("2 %s", ifname);
fibo_raw_ip_mode_check(ifname);
}
if (profile->rawIP && profile->ipv4.Address && profile->ipv4.Mtu) {
fibo_set_mtu(ifname, (profile->ipv4.Mtu));
}
fibo_system("echo 1 > /sys/module/fibo_mhi/parameters/macaddr_check");
//begin modified by zhangkaibo fix ipv6 dial process flow. mantis 0048789 20200605
// if (strcmp(ifname, profile->usbnet_adapter)) {
// snprintf(shell_cmd, sizeof(shell_cmd) - 1, "busybox ifconfig %s up",
// profile->usbnet_adapter);
// fibo_system(shell_cmd);
// }
//begin modified by zhangkaibo fix ipv6 dial process flow. mantis 0048789 20200605
// For IPv6, down & up will send protocol packets, and that's needed.
if (profile->ipv6_flag) {
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "busybox ifconfig %s down", ifname);
fibo_system(shell_cmd);
}
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "busybox ifconfig %s up", ifname);
fibo_system(shell_cmd);
//begin modified by zhangming Added NOARP and Multilcast on flag bit commands. mantis 0050106 20200713
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "ip link set %s arp off multicast on", ifname);
fibo_system(shell_cmd);
//begin modified by zhangming Added NOARP and Multilcast on flag bit commands. mantis 0050106 20200713
//Modified unicom dual stack dialing unsuccessful problem
// for bridge mode, only one public IP, so do udhcpc manually
if (fibo_bridge_mode_detect(profile)) {
return;
}
/* Do DHCP using busybox tools */
{
char udhcpc_cmd[128];
pthread_attr_t udhcpc_thread_attr;
pthread_t udhcpc_thread_id;
pthread_attr_init(&udhcpc_thread_attr);
pthread_attr_setdetachstate(&udhcpc_thread_attr,
PTHREAD_CREATE_DETACHED);
if (profile->ipv4.Address) {
if (access("/usr/share/udhcpc/default.script", X_OK)) {
dbg_time(
"Fail to access /usr/share/udhcpc/default.script, "
"errno: %d (%s)",
errno, strerror(errno));
}
//-f,--foreground Run in foreground
//-b,--background Background if lease is not obtained
//-n,--now Exit if lease is not obtained
//-q,--quit Exit after obtaining lease
//-t,--retries N Send up to N discover packets (default 3)
snprintf(udhcpc_cmd, sizeof(udhcpc_cmd),
"busybox udhcpc -f -n -q -t 5 -i %s", ifname);
if (!access("/lib/netifd/dhcp.script", X_OK) &&
!access("/sbin/ifup", X_OK) &&
!access("/sbin/ifstatus", X_OK)) {
dbg_time("you are use OpenWrt?");
dbg_time("should not calling udhcpc manually?");
dbg_time("should modify /etc/config/network as below?");
dbg_time("config interface wan");
dbg_time("\toption ifname %s", ifname);
dbg_time("\toption proto dhcp");
dbg_time(
"should use \"/sbin/ifstaus wan\" to check %s 's status?",
ifname);
}
pthread_create(&udhcpc_thread_id, NULL, udhcpc_thread_function,
(void *)strdup(udhcpc_cmd));
sleep(1);
}
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);
}
}
}
}
void udhcpc_stop(PROFILE_T *profile)
{
char *ifname = profile->usbnet_adapter;
char shell_cmd[128];
char reset_ip[128];
dbg_time("enter %s ", __func__);
if (profile->qmapnet_adapter) {
ifname = profile->qmapnet_adapter;
}
if (dibbler_client_alive) {
system("killall dibbler-client");
dibbler_client_alive = 0;
}
//snprintf(shell_cmd, sizeof(shell_cmd) - 1, "busybox ifconfig %s down",
// profile->usbnet_adapter);
//fibo_system(shell_cmd);
snprintf(shell_cmd, sizeof(shell_cmd) - 1, "busybox ifconfig %s down", ifname);
fibo_system(shell_cmd);
snprintf(reset_ip, sizeof(reset_ip) - 1, "busybox ifconfig %s 0.0.0.0", ifname);
fibo_system(reset_ip);
}
+142 -142
View File
@@ -1,142 +1,142 @@
#include <sys/time.h>
#include "QMIThread.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>
#define is_bigendian() ((*(char *)&i) == 0)
FILE *logfilefp = NULL;
static pthread_mutex_t printfMutex = PTHREAD_MUTEX_INITIALIZER;
static char line[1024];
const int i = 1;
// defined in atchannel.c
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;
}
int pthread_cond_timeout_np(pthread_cond_t *cond, pthread_mutex_t *mutex,
unsigned msecs)
{
if (msecs != 0) {
struct timespec ts;
setTimespecRelative(&ts, msecs);
return pthread_cond_timedwait(cond, mutex, &ts);
} else {
return pthread_cond_wait(cond, mutex);
}
}
static const char *get_time(void)
{
static char time_buf[50];
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;
}
void dbg_time(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
pthread_mutex_lock(&printfMutex);
snprintf(line, sizeof(line), "%s ", get_time());
vsnprintf(line + strlen(line), sizeof(line) - strlen(line), fmt, args);
fprintf(stdout, "%s\n", line);
if (logfilefp) {
fprintf(logfilefp, "%s\n", line);
}
fflush(logfilefp);
pthread_mutex_unlock(&printfMutex);
}
USHORT le16_to_cpu(USHORT v16)
{
USHORT tmp = v16;
if (is_bigendian()) {
unsigned char *s = (unsigned char *)(&v16);
unsigned char *d = (unsigned char *)(&tmp);
d[0] = s[1];
d[1] = s[0];
}
return tmp;
}
UINT le32_to_cpu(UINT v32)
{
UINT tmp = v32;
if (is_bigendian()) {
unsigned char *s = (unsigned char *)(&v32);
unsigned char *d = (unsigned char *)(&tmp);
d[0] = s[3];
d[1] = s[2];
d[2] = s[1];
d[3] = s[0];
}
return tmp;
}
USHORT cpu_to_le16(USHORT v16)
{
USHORT tmp = v16;
if (is_bigendian()) {
unsigned char *s = (unsigned char *)(&v16);
unsigned char *d = (unsigned char *)(&tmp);
d[0] = s[1];
d[1] = s[0];
}
return tmp;
}
UINT cpu_to_le32(UINT v32)
{
UINT tmp = v32;
if (is_bigendian()) {
unsigned char *s = (unsigned char *)(&v32);
unsigned char *d = (unsigned char *)(&tmp);
d[0] = s[3];
d[1] = s[2];
d[2] = s[1];
d[3] = s[0];
}
return tmp;
}
#include <sys/time.h>
#include "QMIThread.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>
#define is_bigendian() ((*(char *)&i) == 0)
FILE *logfilefp = NULL;
static pthread_mutex_t printfMutex = PTHREAD_MUTEX_INITIALIZER;
static char line[1024];
const int i = 1;
// defined in atchannel.c
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;
}
int pthread_cond_timeout_np(pthread_cond_t *cond, pthread_mutex_t *mutex,
unsigned msecs)
{
if (msecs != 0) {
struct timespec ts;
setTimespecRelative(&ts, msecs);
return pthread_cond_timedwait(cond, mutex, &ts);
} else {
return pthread_cond_wait(cond, mutex);
}
}
static const char *get_time(void)
{
static char time_buf[50];
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;
}
void dbg_time(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
pthread_mutex_lock(&printfMutex);
snprintf(line, sizeof(line), "%s ", get_time());
vsnprintf(line + strlen(line), sizeof(line) - strlen(line), fmt, args);
fprintf(stdout, "%s\n", line);
if (logfilefp) {
fprintf(logfilefp, "%s\n", line);
}
fflush(logfilefp);
pthread_mutex_unlock(&printfMutex);
}
USHORT le16_to_cpu(USHORT v16)
{
USHORT tmp = v16;
if (is_bigendian()) {
unsigned char *s = (unsigned char *)(&v16);
unsigned char *d = (unsigned char *)(&tmp);
d[0] = s[1];
d[1] = s[0];
}
return tmp;
}
UINT le32_to_cpu(UINT v32)
{
UINT tmp = v32;
if (is_bigendian()) {
unsigned char *s = (unsigned char *)(&v32);
unsigned char *d = (unsigned char *)(&tmp);
d[0] = s[3];
d[1] = s[2];
d[2] = s[1];
d[3] = s[0];
}
return tmp;
}
USHORT cpu_to_le16(USHORT v16)
{
USHORT tmp = v16;
if (is_bigendian()) {
unsigned char *s = (unsigned char *)(&v16);
unsigned char *d = (unsigned char *)(&tmp);
d[0] = s[1];
d[1] = s[0];
}
return tmp;
}
UINT cpu_to_le32(UINT v32)
{
UINT tmp = v32;
if (is_bigendian()) {
unsigned char *s = (unsigned char *)(&v32);
unsigned char *d = (unsigned char *)(&tmp);
d[0] = s[3];
d[1] = s[2];
d[2] = s[1];
d[3] = s[0];
}
return tmp;
}
+53 -53
View File
@@ -1,53 +1,53 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _UTILS_H_
#define _UTILS_H_
#include <stddef.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 dbg_time(const char *fmt, ...);
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);
#endif
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _UTILS_H_
#define _UTILS_H_
#include <stddef.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 dbg_time(const char *fmt, ...);
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);
#endif
-22
View File
@@ -1,22 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=fibocom-qmi-wwan
PKG_VERSION:=1.0.5
PKG_RELEASE:=1
include $(INCLUDE_DIR)/kernel.mk
include $(INCLUDE_DIR)/package.mk
define KernelPackage/usb-net-qmi-wwan-fibocom
SUBMENU:=USB Support
TITLE:=QMI WWAN driver for Fibocom modules
DEPENDS:=+kmod-usb-net +kmod-usb-wdm
FILES:=$(PKG_BUILD_DIR)/qmi_wwan_f.ko
AUTOLOAD:=$(call AutoLoad,82,qmi_wwan_f)
endef
define Build/Compile
+$(KERNEL_MAKE) M="$(PKG_BUILD_DIR)" modules
endef
$(eval $(call KernelPackage,usb-net-qmi-wwan-fibocom))
@@ -1,75 +0,0 @@
--- a/qmi_wwan_f.c
+++ b/qmi_wwan_f.c
@@ -712,7 +712,11 @@ static struct rtnl_link_stats64 *_rmnet_
stats64 = per_cpu_ptr(dev->stats64, cpu);
do {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6,6,0)
start = u64_stats_fetch_begin_irq(&stats64->syncp);
+#else
+ start = u64_stats_fetch_begin(&stats64->syncp);
+#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0)
rx_packets = stats64->rx_packets;
rx_bytes = stats64->rx_bytes;
@@ -724,7 +728,11 @@ static struct rtnl_link_stats64 *_rmnet_
tx_packets = u64_stats_read(&stats64->tx_packets);
tx_bytes = u64_stats_read(&stats64->tx_bytes);
#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6,6,0)
} while (u64_stats_fetch_retry_irq(&stats64->syncp, start));
+#else
+ } while (u64_stats_fetch_retry(&stats64->syncp, start));
+#endif
stats->rx_packets += rx_packets;
stats->rx_bytes += rx_bytes;
@@ -1187,7 +1195,11 @@ static int qmap_register_device(sQmiWwan
priv->mux_id = FIBOCOM_QMAP_MUX_ID + offset_id;
sprintf(qmap_net->name, "%s.%d", real_dev->name, offset_id + 1);
qmap_net->netdev_ops = &qmap_netdev_ops;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5,17,0)
memcpy (qmap_net->dev_addr, real_dev->dev_addr, ETH_ALEN);
+#else
+ __dev_addr_set(qmap_net, real_dev->dev_addr, ETH_ALEN);
+#endif
#ifdef FIBOCOM_BRIDGE_MODE
priv->bridge_mode = !!(pDev->bridge_mode & BIT(offset_id));
@@ -1196,8 +1208,12 @@ static int qmap_register_device(sQmiWwan
priv->agg_skb = NULL;
priv->agg_count = 0;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6,18,0)
hrtimer_init(&priv->agg_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
priv->agg_hrtimer.function = rmnet_usb_tx_agg_timer_cb;
+#else
+ hrtimer_setup(&priv->agg_hrtimer, rmnet_usb_tx_agg_timer_cb, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+#endif
INIT_WORK(&priv->agg_wq, rmnet_usb_tx_agg_work);
ktime_get_ts64(&priv->agg_time);
spin_lock_init(&priv->agg_lock);
@@ -1319,7 +1335,7 @@ typedef struct {
unsigned int dl_minimum_padding; //0x1A
} QMAP_SETTING;
-int qma_setting_store(struct device *dev, QMAP_SETTING *qmap_settings, size_t size) {
+static int qma_setting_store(struct device *dev, QMAP_SETTING *qmap_settings, size_t size) {
struct net_device *netdev = to_net_dev(dev);
struct usbnet * usbnetdev = netdev_priv( netdev );
struct qmi_wwan_state *info = (void *)&usbnetdev->data;
@@ -1760,8 +1776,14 @@ static void ql_net_get_drvinfo(struct ne
{
/* Inherit standard device info */
usbnet_get_drvinfo(net, info);
+ /* strlcpy() is deprecated in kernel 6.8.0+, using strscpy instead */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0))
strlcpy(info->driver, driver_name, sizeof(info->driver));
strlcpy(info->version, VERSION_NUMBER, sizeof(info->version));
+#else
+ strscpy(info->driver, driver_name, sizeof(info->driver));
+ strscpy(info->version, VERSION_NUMBER, sizeof(info->version));
+#endif
}
static struct ethtool_ops ql_net_ethtool_ops;
@@ -1,30 +0,0 @@
From 85990e155cb684ec6380bcf70f588255ec41dc69 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=80=AC=E5=90=8D=E7=94=B1=E5=B8=8C?=
<wanglei199909210927@gmail.com>
Date: Wed, 5 Nov 2025 14:16:56 +0800
Subject: [PATCH] qmi_wwan: return correct tx/rx stats in kernel 6.10+ (#130)
---
driver/fibocom_QMI_WWAN/src/qmi_wwan_f.c | 9 ++++++++-
driver/quectel_QMI_WWAN/src/qmi_wwan_q.c | 7 +++++++
2 files changed, 15 insertions(+), 1 deletion(-)
--- a/qmi_wwan_f.c
+++ b/qmi_wwan_f.c
@@ -1910,8 +1910,15 @@ static int qmi_wwan_bind(struct usbnet *
dev_addr_mod(dev->net, 0, &addr, 1);
#endif
}
- if (!_usbnet_get_stats64)
+ if (!_usbnet_get_stats64)
+#if (LINUX_VERSION_CODE < KERNEL_VERSION( 6,10,0 ))
_usbnet_get_stats64 = dev->net->netdev_ops->ndo_get_stats64;
+#else
+ /* From kernel 6.10+, usbnet sets pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS (352f5b3282), but removed ndo_get_stats64 (9cb3d523c1) */
+ /* Use dev_get_tstats64 to read per-CPU stats when NETDEV_PCPU_STAT_TSTATS was set */
+ if (dev->net->pcpu_stat_type == NETDEV_PCPU_STAT_TSTATS)
+ _usbnet_get_stats64 = dev_get_tstats64;
+#endif
dev->net->netdev_ops = &qmi_wwan_netdev_ops;
ql_net_ethtool_ops = *dev->net->ethtool_ops;
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=qmi_wwan_f
PKG_VERSION:=1.0
PKG_RELEASE:=4
PKG_RELEASE:=5
include $(INCLUDE_DIR)/kernel.mk
include $(INCLUDE_DIR)/package.mk
+23 -5
View File
@@ -712,19 +712,27 @@ static struct rtnl_link_stats64 *_rmnet_vnd_get_stats64(struct net_device *net,
stats64 = per_cpu_ptr(dev->stats64, cpu);
do {
#if LINUX_VERSION_CODE < KERNEL_VERSION(6,6,0)
start = u64_stats_fetch_begin_irq(&stats64->syncp);
#else
start = u64_stats_fetch_begin(&stats64->syncp);
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0)
rx_packets = stats64->rx_packets;
rx_bytes = stats64->rx_bytes;
tx_packets = stats64->tx_packets;
tx_bytes = stats64->tx_bytes;
#else
rx_packets = u64_stats_read(&stats64->rx_packets);
rx_bytes = u64_stats_read(&stats64->rx_bytes);
tx_packets = u64_stats_read(&stats64->tx_packets);
tx_bytes = u64_stats_read(&stats64->tx_bytes);
rx_packets = u64_stats_read(&stats64->rx_packets);
rx_bytes = u64_stats_read(&stats64->rx_bytes);
tx_packets = u64_stats_read(&stats64->tx_packets);
tx_bytes = u64_stats_read(&stats64->tx_bytes);
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(6,6,0)
} while (u64_stats_fetch_retry_irq(&stats64->syncp, start));
#else
} while (u64_stats_fetch_retry(&stats64->syncp, start));
#endif
stats->rx_packets += rx_packets;
stats->rx_bytes += rx_bytes;
@@ -1187,7 +1195,11 @@ static int qmap_register_device(sQmiWwanQmap * pDev, u8 offset_id)
priv->mux_id = FIBOCOM_QMAP_MUX_ID + offset_id;
sprintf(qmap_net->name, "%s.%d", real_dev->name, offset_id + 1);
qmap_net->netdev_ops = &qmap_netdev_ops;
memcpy (qmap_net->dev_addr, real_dev->dev_addr, ETH_ALEN);
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,17,0)
memcpy(qmap_net->dev_addr, real_dev->dev_addr, ETH_ALEN);
#else
__dev_addr_set(qmap_net, real_dev->dev_addr, ETH_ALEN);
#endif
#ifdef FIBOCOM_BRIDGE_MODE
priv->bridge_mode = !!(pDev->bridge_mode & BIT(offset_id));
@@ -1760,8 +1772,14 @@ static void ql_net_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *i
{
/* Inherit standard device info */
usbnet_get_drvinfo(net, info);
/* strlcpy() is deprecated in kernel 6.8.0+, using strscpy instead */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(6,8,0))
strlcpy(info->driver, driver_name, sizeof(info->driver));
strlcpy(info->version, VERSION_NUMBER, sizeof(info->version));
#else
strscpy(info->driver, driver_name, sizeof(info->driver));
strscpy(info->version, VERSION_NUMBER, sizeof(info->version));
#endif
}
static struct ethtool_ops ql_net_ethtool_ops;
+13 -1
View File
@@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=gecoosac
PKG_VERSION:=2.2.20251015
PKG_RELEASE:=1
PKG_RELEASE:=2
ifeq ($(ARCH),aarch64)
PKG_ARCH:=ac_linux_arm64
@@ -44,12 +44,24 @@ define Package/$(PKG_NAME)
DEPENDS:=@(aarch64||arm||i386||mips||mipsel||x86_64)
endef
define Package/$(PKG_NAME)/conffiles
/etc/config/gecoosac
/etc/gecoosac/
endef
define Build/Compile
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/usr/bin
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/etc/init.d/gecoosac $(1)/etc/init.d/gecoosac
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_CONF) ./files/etc/config/gecoosac $(1)/etc/config/gecoosac
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/etc/uci-defaults/gecoosac $(1)/etc/uci-defaults/gecoosac
$(INSTALL_DIR) $(1)/etc/gecoosac/tls
endef
$(eval $(call BuildPackage,$(PKG_NAME)))
+15
View File
@@ -0,0 +1,15 @@
config gecoosac 'config'
option enabled '0'
option port '60650'
option isonlyoneprot '0'
option m_port '8080'
option https '0'
option crt_file '/etc/gecoosac/tls/gecoosac.crt'
option key_file '/etc/gecoosac/tls/gecoosac.key'
option upload_dir '/tmp/gecoosac/upload/'
option db_dir '/etc/gecoosac/'
option piddir '/var/run/'
option lang 'zh'
option debug '0'
option showtip '1'
option log '0'
+136
View File
@@ -0,0 +1,136 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2024 ImmortalWrt
. /lib/functions.sh
. /lib/functions/procd.sh
USE_PROCD=1
START=90
STOP=10
PROG=/usr/bin/gecoosac
DEFAULT_DB_DIR=/etc/gecoosac/
DEFAULT_UPLOAD_DIR=/tmp/gecoosac/upload/
DEFAULT_CRT_FILE=/etc/gecoosac/tls/gecoosac.crt
DEFAULT_KEY_FILE=/etc/gecoosac/tls/gecoosac.key
DEFAULT_PID_DIR=/var/run/
DEFAULT_LANG=zh
init_conf() {
config_load "gecoosac"
config_get "db_dir" "config" "db_dir" "$DEFAULT_DB_DIR"
config_get "upload_dir" "config" "upload_dir" "$DEFAULT_UPLOAD_DIR"
config_get "enabled" "config" "enabled" "0"
config_get "port" "config" "port" "60650"
config_get "isonlyoneprot" "config" "isonlyoneprot" "0"
config_get "m_port" "config" "m_port" "8080"
config_get "https" "config" "https" "0"
config_get "crt_file" "config" "crt_file" "$DEFAULT_CRT_FILE"
config_get "key_file" "config" "key_file" "$DEFAULT_KEY_FILE"
config_get "piddir" "config" "piddir" "$DEFAULT_PID_DIR"
config_get "lang" "config" "lang" "$DEFAULT_LANG"
config_get "debug" "config" "debug" "0"
config_get "showtip" "config" "showtip" "1"
config_get "log" "config" "log" "0"
}
is_abs_path() {
case "$1" in
/*) return 0 ;;
*) return 1 ;;
esac
}
is_port() {
case "$1" in
""|*[!0-9]*) return 1 ;;
esac
[ "$1" -ge 1 ] 2>/dev/null && [ "$1" -le 65535 ]
}
normalize_conf() {
is_abs_path "$upload_dir" || upload_dir="$DEFAULT_UPLOAD_DIR"
is_abs_path "$db_dir" || db_dir="$DEFAULT_DB_DIR"
is_abs_path "$crt_file" || crt_file="$DEFAULT_CRT_FILE"
is_abs_path "$key_file" || key_file="$DEFAULT_KEY_FILE"
is_abs_path "$piddir" && [ "$piddir" != "/" ] || piddir="$DEFAULT_PID_DIR"
is_port "$port" || port="60650"
is_port "$m_port" || m_port="8080"
[ "$enabled" = "1" ] || enabled="0"
[ "$isonlyoneprot" = "1" ] || isonlyoneprot="0"
[ "$https" = "1" ] || https="0"
case "$lang" in
zh|en) ;;
*) lang="$DEFAULT_LANG" ;;
esac
[ "$debug" = "1" ] || debug="0"
[ "$showtip" = "0" ] || showtip="1"
[ "$log" = "1" ] || log="0"
}
ensure_dirs() {
mkdir -p "$upload_dir" "$db_dir" "$piddir" /etc/gecoosac/tls
}
start_service() {
init_conf
normalize_conf
[ "$enabled" = "1" ] || return 0
if [ ! -x "$PROG" ]; then
logger -t gecoosac "program not found: $PROG"
return 1
fi
ensure_dirs
if [ "$isonlyoneprot" = "0" ] && [ "$https" = "1" ]; then
if [ ! -r "$crt_file" ] || [ ! -r "$key_file" ]; then
logger -t gecoosac "HTTPS is enabled but certificate or key file is missing"
return 1
fi
fi
procd_open_instance gecoosac
procd_set_param command "$PROG"
procd_append_param command -f "$upload_dir"
procd_append_param command -p "$port"
procd_append_param command -debug "$debug"
procd_append_param command -dbpath "$db_dir"
procd_append_param command -token "1"
procd_append_param command -lang "$lang"
procd_append_param command -piddir "$piddir"
if [ "$isonlyoneprot" = "0" ]; then
procd_append_param command -isonlyoneprot "0"
procd_append_param command -mp "$m_port"
if [ "$https" = "1" ]; then
procd_append_param command -https "1"
procd_append_param command -crt "$crt_file"
procd_append_param command -key "$key_file"
else
procd_append_param command -https "0"
fi
else
procd_append_param command -isonlyoneprot "1"
fi
procd_append_param command -showtip "$showtip"
procd_set_param env GIN_MODE=release
procd_set_param file /etc/config/gecoosac
procd_set_param pidfile "${piddir%/}/gecoosac.pid"
procd_set_param stdout "$log"
procd_set_param stderr "$log"
procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
procd_close_instance
}
reload_service() {
stop
start
}
service_triggers() {
procd_add_reload_trigger "gecoosac"
}
+39
View File
@@ -0,0 +1,39 @@
#!/bin/sh
changed=0
ensure_section() {
uci -q get gecoosac.config >/dev/null && return 0
uci -q set gecoosac.config=gecoosac
changed=1
}
set_default() {
local option="$1"
local value="$2"
uci -q get "gecoosac.config.${option}" >/dev/null && return 0
uci -q set "gecoosac.config.${option}=${value}"
changed=1
}
ensure_section
set_default enabled 0
set_default port 60650
set_default isonlyoneprot 0
set_default m_port 8080
set_default https 0
set_default crt_file /etc/gecoosac/tls/gecoosac.crt
set_default key_file /etc/gecoosac/tls/gecoosac.key
set_default upload_dir /tmp/gecoosac/upload/
set_default db_dir /etc/gecoosac/
set_default piddir /var/run/
set_default lang zh
set_default debug 0
# Preserve the previous package behavior for upgraded configs that never had showtip.
set_default showtip 0
set_default log 0
[ "$changed" = "1" ] && uci -q commit gecoosac
exit 0
+1 -5
View File
@@ -7,16 +7,12 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-gecoosac
PKG_VERSION:=2.2
PKG_RELEASE:=1
PKG_RELEASE:=2
LUCI_TITLE:=LuCI Support for gecoosac
LUCI_DEPENDS:=+luci-compat +gecoosac
LUCI_PKGARCH:=all
define Package/$(PKG_NAME)/conffiles
/etc/gecoosac
endef
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature
@@ -1,8 +1,11 @@
module("luci.controller.gecoosac", package.seeall)
local fs = require "nixio.fs"
local sys = require "luci.sys"
function index()
if not nixio.fs.access("/etc/config/gecoosac") then
if not fs.access("/etc/config/gecoosac") then
return
end
local page
@@ -13,17 +16,9 @@ function index()
end
function act_status()
local e = {}
local binpath = "/usr/bin/gecoosac"
e = {
running = luci.sys.call("pgrep " .. binpath .. " >/dev/null") == 0
local e = {
running = sys.call("/etc/init.d/gecoosac status >/dev/null 2>&1") == 0
}
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function clear_upload()
local path = "/tmp/gecoosac/upload/"
luci.sys.call("rm -rf " .. path .. "/*")
luci.http.status(200, "OK")
end
+126 -22
View File
@@ -1,11 +1,88 @@
function program_exists(program)
local handle = io.popen('which ' .. program)
local result = handle:read('*a')
handle:close()
return result ~= ''
local fs = require "nixio.fs"
local DEFAULT_UPLOAD_DIR = "/tmp/gecoosac/upload/"
local DEFAULT_DB_DIR = "/etc/gecoosac/"
local DEFAULT_CRT_FILE = "/etc/gecoosac/tls/gecoosac.crt"
local DEFAULT_KEY_FILE = "/etc/gecoosac/tls/gecoosac.key"
local DEFAULT_PID_DIR = "/var/run/"
local function trim(value)
return (value or ""):gsub("^%s+", ""):gsub("%s+$", "")
end
if program_exists("/usr/bin/gecoosac") then
local function is_abs_path(value)
return type(value) == "string" and value:match("^/") and not value:find("[%z\r\n]")
end
local function validate_abs_path(self, value)
value = trim(value)
if is_abs_path(value) then
return value
end
return nil, translate("Expecting an absolute path")
end
local function is_upload_path(path)
path = trim(path):gsub("/+$", "")
return path == "/tmp/gecoosac/upload" or path:match("/gecoosac/upload$") ~= nil
end
local function remove_tree(path)
local stat = fs.lstat and fs.lstat(path) or fs.stat(path)
if not stat then
return
end
if stat.type == "dir" then
local iter = fs.dir(path)
if iter then
for entry in iter do
if entry ~= "." and entry ~= ".." then
remove_tree(path .. "/" .. entry)
end
end
end
fs.rmdir(path)
else
fs.unlink(path)
end
end
local function clear_upload_dir(path)
path = trim(path)
if path == "" then
path = DEFAULT_UPLOAD_DIR
end
path = path:gsub("/+$", "")
if not is_abs_path(path) then
return nil, translate("Expecting an absolute path")
end
local real = fs.realpath(path) or path
real = real:gsub("/+$", "")
if not is_upload_path(real) then
return nil, translate("Only Gecoos upload directories can be cleared")
end
if fs.stat(real, "type") ~= "dir" then
return true
end
local iter = fs.dir(real)
if iter then
for entry in iter do
if entry ~= "." and entry ~= ".." then
remove_tree(real .. "/" .. entry)
end
end
end
return true
end
if fs.access("/usr/bin/gecoosac") then
m = Map("gecoosac", translate("Gecoos AC"), translate("Batch management Gecoos AP, Default password: admin") .. "<br>" .. translatef("The current AC version %s, only supports AP 7.6 and above.","2.2"))
else
m = Map("gecoosac", translate("Gecoos AC"), translate("Batch management Gecoos AP, Default password: admin") .. "<br>" .. translate("The AC program does not exist, please check."))
@@ -27,48 +104,75 @@ o.datatype = "port"
o.rmempty = false
o = s:option(Flag, "isonlyoneprot", translate("Single Port Mode"), translate("Do not enable the independent management port, only use one port for management."))
o.default = 1
o.default = 0
o.rmempty = false
o = s:option(Value, "m_port", translate("Set management port"))
o.placeholder = 8080
o.default = 8080
o.datatype = "port"
o:depends("isonlyoneprot", false)
o:depends("isonlyoneprot", "0")
o = s:option(Flag, "https", translate("Enable HTTPS service"), translate("A certificate file must be specified, otherwise it will fail to start."))
o.default = 0
o:depends("isonlyoneprot", false)
o:depends("isonlyoneprot", "0")
o = s:option(Value, "crt_file", translate("Specify crt certificate file"))
o.placeholder = "/etc/gecoosac/tls/1.crt"
o.default = "/etc/gecoosac/tls/1.crt"
o:depends("https", true)
o.placeholder = DEFAULT_CRT_FILE
o.default = DEFAULT_CRT_FILE
o.validate = validate_abs_path
o:depends({isonlyoneprot = "0", https = "1"})
o = s:option(Value, "key_file", translate("Specify key certificate file"))
o.placeholder = "/etc/gecoosac/tls/1.key"
o.default = "/etc/gecoosac/tls/1.key"
o:depends("https", true)
o.placeholder = DEFAULT_KEY_FILE
o.default = DEFAULT_KEY_FILE
o.validate = validate_abs_path
o:depends({isonlyoneprot = "0", https = "1"})
upload_dir = s:option(Value, "upload_dir", translate("Upload dir path"), translate("The path to upload AP upgrade firmware"))
upload_dir.placeholder = "/tmp/gecoosac/upload/"
upload_dir.default = "/tmp/gecoosac/upload/"
upload_dir.placeholder = DEFAULT_UPLOAD_DIR
upload_dir.default = DEFAULT_UPLOAD_DIR
upload_dir.rmempty = false
upload_dir.validate = validate_abs_path
db_dir = s:option(Value, "db_dir", translate("Database dir path"), translate("The path to store the config database"))
db_dir.placeholder = "/etc/gecoosac/"
db_dir.default = "/etc/gecoosac/"
db_dir.placeholder = DEFAULT_DB_DIR
db_dir.default = DEFAULT_DB_DIR
db_dir.rmempty = false
db_dir.validate = validate_abs_path
o = s:option(Value, "piddir", translate("PID dir path"), translate("The path to store the AC program pid file"))
o.placeholder = DEFAULT_PID_DIR
o.default = DEFAULT_PID_DIR
o.rmempty = false
o.validate = validate_abs_path
o = s:option(ListValue, "lang", translate("Language"))
o:value("zh", translate("Chinese"))
o:value("en", translate("English"))
o.default = "zh"
o.rmempty = false
debug = s:option(Flag, "debug", translate("Debug Mode"))
debug.default = 0
debug.rmempty = false
showtip = s:option(Flag, "showtip", translate("Show IP Tip"), translate("Show the IP 6.7.8.9 setup tip when it is not configured."))
showtip.default = 1
showtip.rmempty = false
log = s:option(Flag, "log", translate("Enable Log"))
log.default = 1
log.default = 0
log.rmempty = false
clear_upload = s:option(Button, "clear_upload", translate("Clear Upload Directory"))
clear_upload.inputstyle = "remove"
clear_upload.write = function(self, section)
local path = upload_dir:formvalue(section) or "/tmp/gecoosac/upload/"
luci.sys.call("rm -rf " .. path .. "/*")
local path = upload_dir:formvalue(section) or upload_dir:cfgvalue(section) or DEFAULT_UPLOAD_DIR
local ok, err = clear_upload_dir(path)
if not ok then
self.map.message = err or translate("Upload directory was not cleared")
end
end
return m
@@ -1,7 +1,8 @@
<%
local uci=require"luci.model.uci".cursor()
local json=require"luci.jsonc"
local isonlyoneprot = uci:get("gecoosac", "config", "isonlyoneprot") or "1"
local isonlyoneprot = uci:get("gecoosac", "config", "isonlyoneprot") or "0"
local https = uci:get("gecoosac", "config", "https") or "0"
local port = uci:get("gecoosac", "config", "port") or "60650"
local m_port = uci:get("gecoosac", "config", "m_port") or "8080"
@@ -14,8 +15,8 @@ if isonlyoneprot == "0" then
end
-%>
<script type="text/javascript">//<![CDATA[
var Port = "<%=port%>"
var Http = "<%=http%>"
var Port = <%=json.stringify(port)%>;
var Http = <%=json.stringify(http)%>;
XHR.poll(3, '<%=url([[admin]], [[services]], [[gecoosac]], [[status]])%>', null,
function(x, data) {
var tb = document.getElementById('gecoosac_status');
@@ -30,8 +31,16 @@ XHR.poll(3, '<%=url([[admin]], [[services]], [[gecoosac]], [[status]])%>', null,
}
);
function clientHost() {
var host = window.location.hostname;
if (host.indexOf(':') !== -1 && host.charAt(0) !== '[') {
host = '[' + host + ']';
}
return host;
}
function openClient() {
var url = Http + window.location.hostname + ":" + Port;
var url = Http + clientHost() + ":" + Port;
window.open(url);
}
//]]>
+33
View File
@@ -55,6 +55,30 @@ msgstr "数据库目录"
msgid "The path to store the config database"
msgstr "存放配置数据库的路径"
msgid "PID dir path"
msgstr "PID 目录"
msgid "The path to store the AC program pid file"
msgstr "存放 AC 程序 PID 文件的路径"
msgid "Language"
msgstr "语言"
msgid "Chinese"
msgstr "中文"
msgid "English"
msgstr "英文"
msgid "Debug Mode"
msgstr "调试模式"
msgid "Show IP Tip"
msgstr "显示 IP 提示"
msgid "Show the IP 6.7.8.9 setup tip when it is not configured."
msgstr "未配置 6.7.8.9 时显示相关提示信息。"
msgid "Enable Log"
msgstr "启用日志"
@@ -72,3 +96,12 @@ msgstr "收集数据..."
msgid "Clear Upload Directory"
msgstr "清理上传目录"
msgid "Expecting an absolute path"
msgstr "请输入绝对路径"
msgid "Only Gecoos upload directories can be cleared"
msgstr "只能清理集客 AC 上传目录"
msgid "Upload directory was not cleared"
msgstr "上传目录未清理"
@@ -1,8 +0,0 @@
config gecoosac 'config'
option enabled '0'
option port '60650'
option isonlyoneprot '1'
option upload_dir '/tmp/gecoosac/upload/'
option db_dir '/etc/gecoosac/'
option log '0'
@@ -1,45 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDljCCAn6gAwIBAgIIeEgcfPZbDC0wDQYJKoZIhvcNAQELBQAwejELMAkGA1UE
BhMCQ04xFzAVBgNVBAoTDktleU1hbmFnZXIub3JnMTEwLwYDVQQLEyhLZXlNYW5h
Z2VyIFRlc3QgUm9vdCAtIEZvciBUZXN0IFVzZSBPbmx5MR8wHQYDVQQDExZLZXlN
YW5hZ2VyIFRlc3QgUlNBIENBMCAXDTI0MTIxMTA0MDUyNloYDzIxMjQxMjExMDQw
NTI2WjAZMQswCQYDVQQGEwJDTjEKMAgGA1UEAwwBKjCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBALM3K/5+yX6H9Dvq8TrKuk0KtFBqmDDP3lKXMpMkWjDn
4OtKGq4QtaPPJfGBjitYecyHLWbqGZlWU2H8ug/kL/PtAFgtTgiFvObePbP4VUVO
lICitAWCSMo7xsvt/XSGLOF3dV1tCoEcjK9GtJEMOyoqHMOgbuZ986wIR4LkgULz
3A2uC5abXP5Exa6phMCv3MojjaVgOFEIuC4371ZeLU/YXja9ssQ0Bs8PzOIjCP7i
pce94hYYSgAH3Ua1ZcWVZVEbCytoaOGWXkrhNTVZ+nAarlFY4fgN3yCi+YgFipKU
1H9oNr4PgLsxhtM3f19wwu9XNY1RF72cfRPS/mPy86sCAwEAAaN/MH0wDgYDVR0P
AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4E
FgQUOW6TXeYQEZs1tMI05Vx2aSb9dk0wHwYDVR0jBBgwFoAUfzXMx0QcDHIhuynW
4rB+75TRqw8wDAYDVR0RBAUwA4IBKjANBgkqhkiG9w0BAQsFAAOCAQEAl63ixtfN
azLCIvIKGhjhqk2aU9NZtnsjYO729bNSk8SGtqVvCyXO8FJwdhoybtBlSkxjyvrb
nsR+QbeYGu0ZPsSsJJKuwlsM+ZoTOEGRQrhT7AkkXsNQHSalDCWczPW45xWHkg/s
P9xIGeySWMu4CJ1/eZYczT6bzS0eLd05camVCeU2E5N/M7hAO4SnK0agFZnaUEjp
13KZA3MfFNXZ2Q7na9CRjTbpqDCOpsLteP22fwUq7zutwvkQsQQYnQuVlpiUjSsV
MvY7oxkTi9M5BtowdEtVpWkVO2WOMs5dy2kxfgcIJ5KRZLmU+cPsWgsE76fErIYs
FU2leWlNpSvuMw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIID2jCCAsKgAwIBAgIILz9r/y+4/ZgwDQYJKoZIhvcNAQELBQAwezELMAkGA1UE
BhMCQ04xFzAVBgNVBAoTDktleU1hbmFnZXIub3JnMTEwLwYDVQQLEyhLZXlNYW5h
Z2VyIFRlc3QgUm9vdCAtIEZvciBUZXN0IFVzZSBPbmx5MSAwHgYDVQQDExdLZXlN
YW5hZ2VyIFRlc3QgUm9vdCBDQTAeFw0yNDEyMTEwMzI3MzJaFw0zNDEyMTEwMzI3
MzJaMHoxCzAJBgNVBAYTAkNOMRcwFQYDVQQKEw5LZXlNYW5hZ2VyLm9yZzExMC8G
A1UECxMoS2V5TWFuYWdlciBUZXN0IFJvb3QgLSBGb3IgVGVzdCBVc2UgT25seTEf
MB0GA1UEAxMWS2V5TWFuYWdlciBUZXN0IFJTQSBDQTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAMa7Tdag8tcvEwqRMD+gVEd4G3XeQyYzSYGLAa9DGji4
qUDUcBi0Ml2AndHtNNPcAk4vBUsZ10jjpNtOWtsy+r8VivBIlM5PE38JLhlZWao9
JvT1duxfxss+Q7xdT1oO++CDN/6avPXmDD1dmbTD09/cxcPW8M/3aaHfbI5GWxlr
ZLu8N50yQQxiXLEJad3n7fPjAosGroqa5FcsJ2vDQHuK13mpZG1eBoNZe6/OAzAz
yYkUKyixpS4xc8Agb9BCl7M9Tvkr8VkELGoFPWBMwBsa4BD0OYE7Vc+ZFEqhyzva
mOpicU1xl8mMkNIhiIaSU52fzRgYryZKmxPfYo8JaRUCAwEAAaNjMGEwDgYDVR0P
AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH81zMdEHAxyIbsp
1uKwfu+U0asPMB8GA1UdIwQYMBaAFElv+F66JtNinfmGM1cttCjILv/hMA0GCSqG
SIb3DQEBCwUAA4IBAQDOrqBCHRfVrTC/mfIIXcFn3lB+3kGmAmBVxH5UILljPdl9
ADjW9iiJtaEYxCOjrnFzpcOvuQnWPC7dbb+cy+DntLy/g6x95kBlAPdp02nYoS42
mDHmYUx+rIvnAceSTr72R+Vu9LNVzdbvnULT1o/4kW6uwRnrskisoFkAzeMd/4DT
tY71Dkz9faJt4VIE0wF3/jYXbqVhffyu6xXl+mS9mmCw/u9pFXMys2i/5tF90qIx
hpcVLhqFq4+dTnXaohC2DRpd+sCH4wRHMIRpi7gWI+6nXwLg95VSSwRNd+C+tyyh
GXlSB7/9WOGRGv74M5W9im3VFn5Ot3zMruEtl/WA
-----END CERTIFICATE-----
@@ -1,27 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAszcr/n7Jfof0O+rxOsq6TQq0UGqYMM/eUpcykyRaMOfg60oa
rhC1o88l8YGOK1h5zIctZuoZmVZTYfy6D+Qv8+0AWC1OCIW85t49s/hVRU6UgKK0
BYJIyjvGy+39dIYs4Xd1XW0KgRyMr0a0kQw7Kiocw6Bu5n3zrAhHguSBQvPcDa4L
lptc/kTFrqmEwK/cyiONpWA4UQi4LjfvVl4tT9heNr2yxDQGzw/M4iMI/uKlx73i
FhhKAAfdRrVlxZVlURsLK2ho4ZZeSuE1NVn6cBquUVjh+A3fIKL5iAWKkpTUf2g2
vg+AuzGG0zd/X3DC71c1jVEXvZx9E9L+Y/LzqwIDAQABAoIBAELDuAkMdMZFodA8
m3e6lKMk7L3UqDPvDLUaDMZSUaNMjzc4mS3lnbWT81/AUxWE1YNDjL99UOIWDeRA
QZSv/slRrsIqxppYMGKVwsjsJ+A1AQ/XDVfMDJACqvHIDJc/cTLhzQBsIfCtkR+v
KI+szdHMdIDQoOAPZhrdzr5NoHYvQM7B8HYe5G9dyw5GinRnTNqNUIhFM1HW5Gki
dhLAiqUGj2drSsbRoIWIOIzBbM3+hWZK1mO3q+QhdBEPcwzrOgMaj2722Dea57Hb
duCpdpKH43JfSmQ+f0V8OS/zYNUcyQikQg+Euak6dOuMhFN1ma7bNEug3slJMQ0M
JVG55IECgYEAxNgUXU+ORxCVZjMLxq2Uk2qJxbZspRIQ0ElsvsUpVpw0q0KV7V8K
qnxL4c6khOqWZQ9M7PWG4nJgjNXhYW9PpYdTXkmOZzAq+XU8nUYGHR0ZAlDj0oAd
lC9m9hBZPovxRozjMcRpnJinkZRLB0KEuTBECB6ZKZscLqbMIH81kWsCgYEA6RLd
b1Kk6xUjmUcGnq6bZN4a0spEGLayzgFOA2o/Ma1d94c3NsWsz97KGpCISExBOoPd
e/vryCrgvY50U4989z3mOVlcW9IJxaX5jyLmyG1POMkzwpWSST5u1DqnHpZ1xhzo
qjdd+F9E05PG8YM/2JYUDoCgL+BWvSYUsW/bdsECgYA2LZr9S8ZHPQNBy87z8haw
tGQTLPCeRmimS29I2o9ULU45zOvjF4OiBPAFyJBznPWj/yAXIETt0rlMShnsbWyo
jKSfkPNG53UMj/4M85b/MGEPyB/MckKx5JIcK8fEdVQFLQXjTsIavdFxOjWkW+SX
6/btnS5eyzhohrQsRZcC3QKBgEuzauSLbTFFjmhsX0QO5j3evcuVEoUMYgry9Ym6
aogSDSEmc9KAZd6mN/Jk2z7QNadxyPBKJIzBEHnA2RuC0U3kdvBNi+fu0mm1vNa2
uUqD5mVFRGCBACB1/L1Fx53xtJMCNLeEgCr5lns51jX/MS+Bn0YOlPi33rRUuAfh
kuCBAoGAPvxUmDXFnYyt8/3t5dpKt1GEpqDdQfhUDqE6zOPulsv0IkMKCvbyHdKI
iR1EbSvCMP9aVO7BeVRnr9FSrdL10TWNLP4JveSI4Ee1bzy0vvTj5l8CC4MwSdhN
04I8F7UqPhSbdVjsTxw16XrHSkvB5JRZsIAz/K0jVMwZs7fS8Lk=
-----END RSA PRIVATE KEY-----
@@ -1,70 +0,0 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2024 ImmortalWrt
. /lib/functions.sh
. /lib/functions/procd.sh
USE_PROCD=1
START=90
STOP=10
init_conf() {
config_load "gecoosac"
config_get "db_dir" "config" "db_dir" "/etc/gecoosac/"
config_get "upload_dir" "config" "upload_dir" "/tmp/gecoosac/upload/"
config_get "enabled" "config" "enabled" "0"
config_get "port" "config" "port" "60650"
config_get "isonlyoneprot" "config" "isonlyoneprot" "1"
config_get "m_port" "config" "m_port" "8080"
config_get "https" "config" "https" "0"
config_get "crt_file" "config" "crt_file" "/etc/gecoosac/tls/1.crt"
config_get "key_file" "config" "key_file" "/etc/gecoosac/tls/1.key"
config_get "log" "config" "log" "0"
}
start_service() {
init_conf
[ "${enabled}" = "1" ] || return 0
procd_open_instance gecoosac
procd_set_param command "/usr/bin/gecoosac"
procd_append_param command -f "${upload_dir}"
procd_append_param command -p "${port}"
procd_append_param command -debug "0"
procd_append_param command -dbpath "${db_dir}"
procd_append_param command -token "1"
if [ "${isonlyoneprot}" = "0" ]; then
procd_append_param command -isonlyoneprot "0"
procd_append_param command -mp "${m_port}"
if [ "${https}" = "1" ]; then
procd_append_param command -https "1"
procd_append_param command -crt "${crt_file}"
procd_append_param command -key "${key_file}"
else
procd_append_param command -https "0"
fi
else
procd_append_param command -isonlyoneprot "1"
fi
procd_append_param command -showtip "0"
procd_set_param env GIN_MODE=release
procd_set_param pidfile /var/run/gecoosac.pid
procd_set_param stdout $log
procd_set_param stderr $log
procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
procd_close_instance
}
stop_service(){
init_conf
}
reload_service()
{
stop
start
}
service_triggers() {
procd_add_reload_trigger "gecoosac"
}
@@ -15,5 +15,6 @@ uci -q batch <<-EOF >/dev/null
commit ucitrack
EOF
rm -rf /tmp/luci-*
rm -f /tmp/luci-indexcache
rm -rf /tmp/luci-modulecache
exit 0
+2 -2
View File
@@ -11,8 +11,8 @@ LUCI_DESCRIPTION:=LuCI JS interface for the modemband. The package allows set LT
LUCI_DEPENDS:=+modemband
PKG_NAME:=luci-app-modemband
PKG_VERSION:=1.0.24
PKG_RELEASE:=2
PKG_VERSION:=1.0.25.20240519
PKG_RELEASE:=3
PKG_MAINTAINER:=Rafał Wabik <4Rafal@gmail.com>
include $(TOPDIR)/feeds/luci/luci.mk
@@ -12,29 +12,29 @@
Copyright 2022-2024 Rafał Wabik - IceG - From eko.one.pl forum
*/
var CBISelectswitch = form.DummyValue.extend({
renderWidget: function(section_id, option_id, cfgvalue) {
var section = this.section;
return E([], [
E('span', { 'class': 'control-group' }, [
E('button', {
'class': 'cbi-button cbi-button-apply',
'click': ui.createHandlerFn(this, function() {
var dropdown = section.getUIElement(section_id, 'set_5gnsabands');
dropdown.setValue([]);
}),
}, _('Deselect all')),
' ',
E('button', {
'class': 'cbi-button cbi-button-action important',
'click': ui.createHandlerFn(this, function() {
var dropdown = section.getUIElement(section_id, 'set_5gnsabands');
dropdown.setValue(Object.keys(dropdown.choices));
})
}, _('Select all'))
])
]);
},
var CBISelectswitch = form.DummyValue.extend({
renderWidget: function(section_id, option_id, cfgvalue) {
var section = this.section;
return E([], [
E('span', { 'class': 'control-group' }, [
E('button', {
'class': 'cbi-button cbi-button-apply',
'click': ui.createHandlerFn(this, function() {
var dropdown = section.getUIElement(section_id, 'set_5gnsabands');
dropdown.setValue([]);
}),
}, _('Deselect all')),
' ',
E('button', {
'class': 'cbi-button cbi-button-action important',
'click': ui.createHandlerFn(this, function() {
var dropdown = section.getUIElement(section_id, 'set_5gnsabands');
dropdown.setValue(Object.keys(dropdown.choices));
})
}, _('Select all'))
])
]);
},
});
var BANDmagic = form.DummyValue.extend({
@@ -176,14 +176,14 @@ function handleAction(ev) {
if (ev === 'reload') {
location.reload();
}
if (ev === 'resetbandz') {
if (ev === 'resetbandz') {
if (confirm(_('Do you really want to set up all possible bands for the modem?')))
{
fs.exec_direct('/usr/bin/modemband.sh', [ 'setbands5gnsa', 'default' ]);
return uci.load('modemband').then(function() {
var nuser = (uci.get('modemband', '@modemband[0]', 'notify'));
if ( nuser != '1' || nuser == null ) {
ui.addNotification(null, E('p', _('The new bands settings have been sent to the modem. If the changes are not visible, a restart of the connection, modem or router may be required.')), 'info');
}
@@ -202,7 +202,7 @@ function handleAction(ev) {
if (ev === 'restartwan') {
return uci.load('modemband').then(function() {
var wname = (uci.get('modemband', '@modemband[0]', 'iface'));
if (wname.includes('@')) {
wname = wname.replace(/@/g, '')
};
@@ -251,7 +251,7 @@ return view.extend({
modemen = modemen.includes('n0') == true ? modemen = _('Bands are disabled...') : modemen.trim();
for (var i = 0; i < json.supported5gnsa.length; i++)
for (var i = 0; i < json.supported5gnsa.length; i++)
{
var txtband = json.supported5gnsa[i].band.toString();
var numb = txtband.match(/\d+$/);
@@ -259,18 +259,18 @@ return view.extend({
sbands = sbands.replace('undefined', '');
}
sbands = sbands.trim();
pollData: poll.add(function() {
return L.resolveDefault(fs.exec_direct('/usr/bin/modemband.sh', [ 'json' ]))
.then(function(res) {
var json = JSON.parse(res);
//modemen = _('Waiting for device...');
if ( json != null ) {
if ( json != null ) {
var renderHTML = "";
var view = document.getElementById("modemlteb");
for (var i = 0; i < json.enabled5gnsa.length; i++)
for (var i = 0; i < json.enabled5gnsa.length; i++)
{
var txtband = json.enabled5gnsa[i].toString();
var numb = txtband.match(/\d+$/);
@@ -288,7 +288,7 @@ return view.extend({
});
});
}
}
}
else {
if (json.error.includes('No supported') == true) {
modemen = '-';
@@ -305,7 +305,7 @@ return view.extend({
} catch (err) {
console.log('Error: ', err.message);
}
}
}
var info = _('Configuration modem frequency bands. More information about the modemband application on the %seko.one.pl forum%s.').format('<a href="https://eko.one.pl/?p=openwrt-modemband" target="_blank">', '</a>');
@@ -347,21 +347,21 @@ return view.extend({
else {
s.tab('bandset', _('Preferred bands settings'));
o = s.taboption('bandset', cbiRichListValue, 'set_5gnsabands',
_('Modification of the bands'),
_('Modification of the bands'),
_("Select the preferred band(s) for the modem."));
for (var i = 0; i < json.supported5gnsa.length; i++)
for (var i = 0; i < json.supported5gnsa.length; i++)
{
o.value(json.supported5gnsa[i].band, _('n')+json.supported5gnsa[i].band,json.supported5gnsa[i].txt);
}
o.multiple = true;
o.placeholder = _('Please select a band(s)');
o.cfgvalue = function(section_id) {
return L.toArray((json.enabled5gnsa).join(' '));
};
o = s.taboption('bandset', CBISelectswitch, '_switch', _('Band selection switch'));
s = m.section(form.TypedSection);
@@ -383,7 +383,7 @@ return view.extend({
o = s.taboption('opt1', SYSTmagic);
}
return m.render();
},
@@ -396,7 +396,7 @@ return view.extend({
args.push(data.modemband.set_5gnsabands);
var ax = args.toString();
ax = ax.replace(/,/g, ' ')
ax.length >= 1 ? fs.exec_direct('/usr/bin/modemband.sh', [ 'setbands5gnsa', ax ]) : ui.addNotification(null, E('p', _('Check if you have selected the bands correctly.')), 'info');
return uci.load('modemband').then(function() {
@@ -404,20 +404,20 @@ return view.extend({
var mrestart = (uci.get('modemband', '@modemband[0]', 'modemrestart'));
var cmdrestart = (uci.get('modemband', '@modemband[0]', 'restartcmd'));
var wname = (uci.get('modemband', '@modemband[0]', 'iface'));
if (wname.includes('@')) {
wname = wname.replace(/@/g, '')
};
var sport = (uci.get('modemband', '@modemband[0]', 'set_port'));
var nuser = (uci.get('modemband', '@modemband[0]', 'notify'));
if ( ax.length >= 1 ) {
if ( nuser != '1' || nuser == null ) {
ui.addNotification(null, E('p', _('The new bands settings have been sent to the modem. If the changes are not visible, a restart of the connection, modem or router may be required.')), 'info');
}
}
if (wrestart == '1') {
fs.exec('/sbin/ifdown', [ wname ]);
fs.exec('sleep 3');
@@ -13,29 +13,29 @@
*/
var CBISelectswitch = form.DummyValue.extend({
renderWidget: function(section_id, option_id, cfgvalue) {
var section = this.section;
return E([], [
E('span', { 'class': 'control-group' }, [
E('button', {
'class': 'cbi-button cbi-button-apply',
'click': ui.createHandlerFn(this, function() {
var dropdown = section.getUIElement(section_id, 'set_5gsabands');
dropdown.setValue([]);
}),
}, _('Deselect all')),
' ',
E('button', {
'class': 'cbi-button cbi-button-action important',
'click': ui.createHandlerFn(this, function() {
var dropdown = section.getUIElement(section_id, 'set_5gsabands');
dropdown.setValue(Object.keys(dropdown.choices));
})
}, _('Select all'))
])
]);
},
var CBISelectswitch = form.DummyValue.extend({
renderWidget: function(section_id, option_id, cfgvalue) {
var section = this.section;
return E([], [
E('span', { 'class': 'control-group' }, [
E('button', {
'class': 'cbi-button cbi-button-apply',
'click': ui.createHandlerFn(this, function() {
var dropdown = section.getUIElement(section_id, 'set_5gsabands');
dropdown.setValue([]);
}),
}, _('Deselect all')),
' ',
E('button', {
'class': 'cbi-button cbi-button-action important',
'click': ui.createHandlerFn(this, function() {
var dropdown = section.getUIElement(section_id, 'set_5gsabands');
dropdown.setValue(Object.keys(dropdown.choices));
})
}, _('Select all'))
])
]);
},
});
@@ -178,14 +178,14 @@ function handleAction(ev) {
if (ev === 'reload') {
location.reload();
}
if (ev === 'resetbandz') {
if (ev === 'resetbandz') {
if (confirm(_('Do you really want to set up all possible bands for the modem?')))
{
fs.exec_direct('/usr/bin/modemband.sh', [ 'setbands5gsa', 'default' ]);
return uci.load('modemband').then(function() {
var nuser = (uci.get('modemband', '@modemband[0]', 'notify'));
if ( nuser != '1' || nuser == null ) {
ui.addNotification(null, E('p', _('The new bands settings have been sent to the modem. If the changes are not visible, a restart of the connection, modem or router may be required.')), 'info');
}
@@ -204,7 +204,7 @@ function handleAction(ev) {
if (ev === 'restartwan') {
return uci.load('modemband').then(function() {
var wname = (uci.get('modemband', '@modemband[0]', 'iface'));
if (wname.includes('@')) {
wname = wname.replace(/@/g, '')
};
@@ -243,7 +243,7 @@ return view.extend({
else {
var modem = json.modem;
for (var i = 0; i < json.enabled5gsa.length; i++)
for (var i = 0; i < json.enabled5gsa.length; i++)
{
var txtband = json.enabled5gsa[i].toString();
var numb = txtband.match(/\d+$/);
@@ -252,7 +252,7 @@ return view.extend({
}
modemen = modemen.includes('n0') == true ? modemen = _('Bands are disabled...') : modemen = modemen.trim();
for (var i = 0; i < json.supported5gsa.length; i++)
for (var i = 0; i < json.supported5gsa.length; i++)
{
var txtband = json.supported5gsa[i].band.toString();
var numb = txtband.match(/\d+$/);
@@ -260,17 +260,17 @@ return view.extend({
sbands = sbands.replace('undefined', '');
}
sbands = sbands.trim();
pollData: poll.add(function() {
return L.resolveDefault(fs.exec_direct('/usr/bin/modemband.sh', [ 'json' ]))
.then(function(res) {
var json = JSON.parse(res);
//modemen = _('Waiting for device...');
if ( json != null ) {
if ( json != null ) {
var renderHTML = "";
var view = document.getElementById("modemlteb");
for (var i = 0; i < json.enabled5gsa.length; i++)
for (var i = 0; i < json.enabled5gsa.length; i++)
{
var txtband = json.enabled5gsa[i].toString();
var numb = txtband.match(/\d+$/);
@@ -288,7 +288,7 @@ return view.extend({
});
});
}
}
}
else {
if (json.error.includes('No supported') == true) {
modemen = '-';
@@ -305,7 +305,7 @@ return view.extend({
} catch (err) {
console.log('Error: ', err.message);
}
}
}
var info = _('Configuration modem frequency bands. More information about the modemband application on the %seko.one.pl forum%s.').format('<a href="https://eko.one.pl/?p=openwrt-modemband" target="_blank">', '</a>');
@@ -347,15 +347,15 @@ return view.extend({
else {
s.tab('bandset', _('Preferred bands settings'));
o = s.taboption('bandset', cbiRichListValue, 'set_5gsabands',
_('Modification of the bands'),
_('Modification of the bands'),
_("Select the preferred band(s) for the modem."));
for (var i = 0; i < json.supported5gsa.length; i++)
for (var i = 0; i < json.supported5gsa.length; i++)
{
o.value(json.supported5gsa[i].band, _('n')+json.supported5gsa[i].band,json.supported5gsa[i].txt);
}
o.multiple = true;
o.placeholder = _('Please select a band(s)');
o.cfgvalue = function(section_id) {
@@ -383,7 +383,7 @@ return view.extend({
o = s.taboption('opt1', SYSTmagic);
}
return m.render();
},
@@ -396,7 +396,7 @@ return view.extend({
args.push(data.modemband.set_5gsabands);
var ax = args.toString();
ax = ax.replace(/,/g, ' ')
ax.length >= 1 ? fs.exec_direct('/usr/bin/modemband.sh', [ 'setbands5gsa', ax ]) : ui.addNotification(null, E('p', _('Check if you have selected the bands correctly.')), 'info');
return uci.load('modemband').then(function() {
@@ -404,20 +404,20 @@ return view.extend({
var mrestart = (uci.get('modemband', '@modemband[0]', 'modemrestart'));
var cmdrestart = (uci.get('modemband', '@modemband[0]', 'restartcmd'));
var wname = (uci.get('modemband', '@modemband[0]', 'iface'));
if (wname.includes('@')) {
wname = wname.replace(/@/g, '')
};
var sport = (uci.get('modemband', '@modemband[0]', 'set_port'));
var nuser = (uci.get('modemband', '@modemband[0]', 'notify'));
if ( ax.length >= 1 ) {
if ( nuser != '1' || nuser == null ) {
ui.addNotification(null, E('p', _('The new bands settings have been sent to the modem. If the changes are not visible, a restart of the connection, modem or router may be required.')), 'info');
}
}
if (wrestart == '1') {
fs.exec('/sbin/ifdown', [ wname ]);
fs.exec('sleep 3');
@@ -12,29 +12,29 @@
Copyright 2022-2024 Rafał Wabik - IceG - From eko.one.pl forum
*/
var CBISelectswitch = form.DummyValue.extend({
renderWidget: function(section_id, option_id, cfgvalue) {
var section = this.section;
return E([], [
E('span', { 'class': 'control-group' }, [
E('button', {
'class': 'cbi-button cbi-button-apply',
'click': ui.createHandlerFn(this, function() {
var dropdown = section.getUIElement(section_id, 'set_bands');
dropdown.setValue([]);
}),
}, _('Deselect all')),
' ',
E('button', {
'class': 'cbi-button cbi-button-action important',
'click': ui.createHandlerFn(this, function() {
var dropdown = section.getUIElement(section_id, 'set_bands');
dropdown.setValue(Object.keys(dropdown.choices));
})
}, _('Select all'))
])
]);
},
var CBISelectswitch = form.DummyValue.extend({
renderWidget: function(section_id, option_id, cfgvalue) {
var section = this.section;
return E([], [
E('span', { 'class': 'control-group' }, [
E('button', {
'class': 'cbi-button cbi-button-apply',
'click': ui.createHandlerFn(this, function() {
var dropdown = section.getUIElement(section_id, 'set_bands');
dropdown.setValue([]);
}),
}, _('Deselect all')),
' ',
E('button', {
'class': 'cbi-button cbi-button-action important',
'click': ui.createHandlerFn(this, function() {
var dropdown = section.getUIElement(section_id, 'set_bands');
dropdown.setValue(Object.keys(dropdown.choices));
})
}, _('Select all'))
])
]);
},
});
var BANDmagic = form.DummyValue.extend({
@@ -224,14 +224,14 @@ function handleAction(ev) {
if (ev === 'reload') {
location.reload();
}
if (ev === 'resetbandz') {
if (ev === 'resetbandz') {
if (confirm(_('Do you really want to set up all possible bands for the modem?')))
{
fs.exec_direct('/usr/bin/modemband.sh', [ 'setbands', 'default' ]);
return uci.load('modemband').then(function() {
var nuser = (uci.get('modemband', '@modemband[0]', 'notify'));
if ( nuser != '1' || nuser == null ) {
ui.addNotification(null, E('p', _('The new bands settings have been sent to the modem. If the changes are not visible, a restart of the connection, modem or router may be required.')), 'info');
}
@@ -250,7 +250,7 @@ function handleAction(ev) {
if (ev === 'restartwan') {
return uci.load('modemband').then(function() {
var wname = (uci.get('modemband', '@modemband[0]', 'iface'));
if (wname.includes('@')) {
wname = wname.replace(/@/g, '')
};
@@ -265,7 +265,7 @@ function handleAction(ev) {
//var sport = (uci.get('modemband', '@modemband[0]', 'set_port'));
fs.exec_direct('/usr/bin/sms_tool', [ '-d' , '/dev/ttyUSB1' , 'at' , 'AT+ZULCA=1' ]);
});
}
if (ev === 'offupload') {
return uci.load('modemband').then(function() {
@@ -304,7 +304,7 @@ return view.extend({
else {
var modem = json.modem;
for (var i = 0; i < json.enabled.length; i++)
for (var i = 0; i < json.enabled.length; i++)
{
var txtband = json.enabled[i].toString();
var numb = txtband.match(/\d+$/);
@@ -313,7 +313,7 @@ return view.extend({
}
modemen = modemen.trim();
for (var i = 0; i < json.supported.length; i++)
for (var i = 0; i < json.supported.length; i++)
{
var txtband = json.supported[i].band.toString();
var numb = txtband.match(/\d+$/);
@@ -321,17 +321,17 @@ return view.extend({
sbands = sbands.replace('undefined', '');
}
sbands = sbands.trim();
pollData: poll.add(function() {
return L.resolveDefault(fs.exec_direct('/usr/bin/modemband.sh', [ 'json' ]))
.then(function(res) {
var json = JSON.parse(res);
//modemen = _('Waiting for device...');
if ( json != null ) {
if ( json != null ) {
var renderHTML = "";
var view = document.getElementById("modemlteb");
for (var i = 0; i < json.enabled.length; i++)
for (var i = 0; i < json.enabled.length; i++)
{
var txtband = json.enabled[i].toString();
var numb = txtband.match(/\d+$/);
@@ -349,7 +349,7 @@ return view.extend({
});
});
}
}
}
else {
if (json.error.includes('No supported') == true) {
modemen = '-';
@@ -365,7 +365,7 @@ return view.extend({
} catch (err) {
console.log('Error: ', err.message);
}
}
}
var info = _('Configuration modem frequency bands. More information about the modemband application on the %seko.one.pl forum%s.').format('<a href="https://eko.one.pl/?p=openwrt-modemband" target="_blank">', '</a>');
@@ -408,23 +408,23 @@ return view.extend({
}
else {
s.tab('bandset', _('Preferred bands settings'));
o = s.taboption('bandset', cbiRichListValue, 'set_bands',
_('Modification of the bands'),
_('Modification of the bands'),
_("Select the preferred band(s) for the modem."));
for (var i = 0; i < json.supported.length; i++)
for (var i = 0; i < json.supported.length; i++)
{
o.value(json.supported[i].band, _('B')+json.supported[i].band,json.supported[i].txt);
}
o.multiple = true;
o.placeholder = _('Please select a band(s)');
o.cfgvalue = function(section_id) {
return L.toArray((json.enabled).join(' '));
};
o = s.taboption('bandset', CBISelectswitch, '_switch', _('Band selection switch'));
s = m.section(form.TypedSection);
@@ -466,7 +466,7 @@ return view.extend({
'</em></div>';
};
}
return m.render();
},
@@ -479,7 +479,7 @@ return view.extend({
args.push(data.modemband.set_bands);
var ax = args.toString();
ax = ax.replace(/,/g, ' ')
ax.length >= 1 ? fs.exec_direct('/usr/bin/modemband.sh', [ 'setbands', ax ]) : ui.addNotification(null, E('p', _('Check if you have selected the bands correctly.')), 'info');
return uci.load('modemband').then(function() {
@@ -487,20 +487,20 @@ return view.extend({
var mrestart = (uci.get('modemband', '@modemband[0]', 'modemrestart'));
var cmdrestart = (uci.get('modemband', '@modemband[0]', 'restartcmd'));
var wname = (uci.get('modemband', '@modemband[0]', 'iface'));
if (wname.includes('@')) {
wname = wname.replace(/@/g, '')
};
var sport = (uci.get('modemband', '@modemband[0]', 'set_port'));
var nuser = (uci.get('modemband', '@modemband[0]', 'notify'));
if ( ax.length >= 1 ) {
if ( nuser != '1' || nuser == null ) {
ui.addNotification(null, E('p', _('The new bands settings have been sent to the modem. If the changes are not visible, a restart of the connection, modem or router may be required.')), 'info');
}
}
if (wrestart == '1') {
fs.exec('/sbin/ifdown', [ wname ]);
fs.exec('sleep 3');
@@ -33,7 +33,7 @@ return view.extend({
o.noaliases = false;
o.default = 'wan';
*/
o = s.option(widgets.NetworkSelect, 'iface', _('Interface'),
_('Network interface for Internet access.')
);
@@ -42,11 +42,11 @@ return view.extend({
o.rmempty = false;
o.default = 'wan';
o = s.option(form.Value, 'set_port', _('Port for communication with the modem'),
o = s.option(form.Value, 'set_port', _('Port for communication with the modem'),
_("Select one of the available ttyUSBX ports."));
devs.sort((a, b) => a.name > b.name);
devs.forEach(dev => o.value('/dev/' + dev.name));
o.placeholder = _('Please select a port');
o.rmempty = false;
@@ -8,7 +8,7 @@
/*
Copyright 2022-2024 Rafał Wabik - IceG - From eko.one.pl forum
MIT License
*/
@@ -3,14 +3,14 @@
'require form';
'require network';
var callFileList = rpc.declare({
const 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++)
let rv = [];
for (let i = 0; i < list.length; i++)
if (list[i].name.match(/^cdc-wdm/))
rv.push(params.path + list[i].name);
return rv.sort();
@@ -31,7 +31,7 @@ return network.registerProtocol('quectel', {
return this._ubus('l3_device') || 'quectel-%s'.format(this.sid);
},
getOpkgPackage: function() {
getPackageName: function() {
return 'quectel-cm';
},
@@ -52,14 +52,14 @@ return network.registerProtocol('quectel', {
},
renderFormOptions: function(s) {
var dev = this.getL3Device() || this.getDevice(), o;
let dev = this.getL3Device() || this.getDevice(), o;
o = s.taboption('general', form.Value, '_modem_device', _('Modem device'));
o.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++)
for (let i = 0; i < devices.length; i++)
this.value(devices[i]);
return form.Value.prototype.load.apply(this, [section_id]);
}, this));
@@ -99,7 +99,7 @@ return network.registerProtocol('quectel', {
o = s.taboption('advanced', form.Value, 'delay', _('Modem init timeout'),
_('Maximum amount of seconds to wait for the modem to become ready'));
o.placeholder = '20';
o.placeholder = '10';
o.datatype = 'min(1)';
o = s.taboption('advanced', form.Value, 'mtu', _('Override MTU'));
-28
View File
@@ -1,28 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=modemband
PKG_VERSION:=20240616
PKG_RELEASE:=1
PKG_LICENSE:=MIT
PKG_MAINTAINER:=Cezary Jackiewicz <cezary@eko.one.pl>
include $(INCLUDE_DIR)/package.mk
define Package/modemband
SECTION:=net
CATEGORY:=Network
SUBMENU:=WWAN
TITLE:=Setting LTE/5G bands for selected modems
DEPENDS:=+sms-tool
PKGARCH:=all
endef
define Build/Compile
endef
define Package/modemband/install
$(CP) ./files/* $(1)
endef
$(eval $(call BuildPackage,modemband))
-135
View File
@@ -1,135 +0,0 @@
Setting LTE/5G NSA/5G SA bands for selected modems.
Supported devices:
- BroadMobi BM806U
- Dell DW5821e Snapdragon X20 LTE (Foxconn T77W968)
- Fibocom FM350-GL
- Fibocom L850-GL
- Fibocom L850-GL in mbim mode
- Fibocom L860-GL
- Fibocom L860-GL-16
- HP lt4112 (Huawei ME906E)
- HP lt4132 LTE/HSPA+ 4G Module (Huawei ME906s-158)
- HP lt4220 (Foxconn T77W676)
- HP lt4220 (Foxconn T77W676) in mbim mode
- Huawei (various models) in serial mode
- Quectel EC20
- Quectel EC25
- Quectel EG06-E
- Quectel EG18-EA
- Quectel EM12-G
- Quectel EM160R-GL
- Quectel EP06-E
- Quectel RG500Q-EA
- Quectel RG502Q-EA
- Quectel RM500Q-GL
- Quectel RM500U-CNV
- Quectel RM502Q-AE
- Quectel RM502Q-GL
- Quectel RM505Q-AE
- Quectel RM520N-GL
- Sierra Wireless EM7455/MC7455/DW5811e
- SIMCOM SIM8200EA-M2
- Telit LM940
- Telit LN940 (Foxconn T77W676)
- Telit LN940 (Foxconn T77W676) in mbim mode
- Telit LN960 (Foxconn T77W968)
- Telit LN960
- Yuge CLM920 NC_5
- ZTE MF286 (router)
- ZTE MF286A (router)
- ZTE MF286D (router)
- ZTE MF286R (router)
- ZTE MF289R (router)
```
root@MiFi:~# modemband.sh help
Available commands:
/usr/bin/modemband.sh getinfo
/usr/bin/modemband.sh json
/usr/bin/modemband.sh help
for LTE modem
/usr/bin/modemband.sh getsupportedbands
/usr/bin/modemband.sh getsupportedbandsext
/usr/bin/modemband.sh getbands
/usr/bin/modemband.sh getbandsext
/usr/bin/modemband.sh setbands "<band list>"
for 5G NSA modem
/usr/bin/modemband.sh getsupportedbands5gnsa
/usr/bin/modemband.sh getsupportedbandsext5gnsa
/usr/bin/modemband.sh getbands5gnsa
/usr/bin/modemband.sh getbandsext5gnsa
/usr/bin/modemband.sh setbands5gnsa "<band list>"
for 5G SA modem
/usr/bin/modemband.sh getsupportedbands5gsa
/usr/bin/modemband.sh getsupportedbandsext5gsa
/usr/bin/modemband.sh getbands5gsa
/usr/bin/modemband.sh getbandsext5gsa
/usr/bin/modemband.sh setbands5gsa "<band list>"
root@MiFi:~# # modemband.sh
Modem: Quectel EC25
Supported LTE bands: 1 3 5 7 8 20 38 40 41
LTE bands: 1 3 5 7 8 20 38 40 41
1: FDD 2100 MHz
3: FDD 1800 MHz
5: FDD 850 MHz
7: FDD 2600 MHz
8: FDD 900 MHz
20: FDD 800 MHz
38: TDD 2600 MHz
40: TDD 2300 MHz
41: TDD 2500 MHz
root@MiFi:~# modemband.sh json
{ "modem": "Quectel EC25", "supported": [ { "band": 1, "txt": "FDD 2100 MHz" }, { "band": 3, "txt": "FDD 1800 MHz" }, { "band": 5, "txt": "FDD 850 MHz" }, { "band": 7, "txt": "FDD 2600 MHz" }, { "band": 8, "txt": "FDD 900 MHz" }, { "band": 20, "txt": "FDD 800 MHz" }, { "band": 38, "txt": "TDD 2600 MHz" }, { "band": 40, "txt": "TDD 2300 MHz" }, { "band": 41, "txt": "TDD 2500 MHz" } ], "enabled": [ 1, 3, 5, 7, 8, 20, 38, 40, 41 ] }
root@MiFi:~# modemband.sh getinfo
Quectel EC25
root@MiFi:~# modemband.sh getsupportedbands
1 3 5 7 8 20 38 40 41
root@MiFi:~# modemband.sh getsupportedbandsext
1: FDD 2100 MHz
3: FDD 1800 MHz
5: FDD 850 MHz
7: FDD 2600 MHz
8: FDD 900 MHz
20: FDD 800 MHz
38: TDD 2600 MHz
40: TDD 2300 MHz
41: TDD 2500 MHz
root@MiFi:~# modemband.sh getbands
1 3 5 7 8 20 38 40 41
root@MiFi:~# modemband.sh getbandsext
1: FDD 2100 MHz
3: FDD 1800 MHz
5: FDD 850 MHz
7: FDD 2600 MHz
8: FDD 900 MHz
20: FDD 800 MHz
38: TDD 2600 MHz
40: TDD 2300 MHz
41: TDD 2500 MHz
root@MiFi:~# modemband.sh setbands "1 3 5 40"
at+qcfg="band",0,8000000015,0,1
root@MiFi:~# modemband.sh getbands
1 3 5 40
root@MiFi:~# modemband.sh setbands default
at+qcfg="band",0,1a0000800d5,0,1
root@MiFi:~# modemband.sh getbands
1 3 5 7 8 20 38 40 41
```
See also [description in Polish](https://eko.one.pl/?p=openwrt-modemband).
-518
View File
@@ -1,518 +0,0 @@
#!/bin/sh
#
# (c) 2022-2024 Cezary Jackiewicz <cezary@eko.one.pl>
#
# (c) 2022-2024 modified by Rafał Wabik - IceG - From eko.one.pl forum
#
hextobands() {
BANDS=""
HEX="$1"
LEN=${#HEX}
if [ $LEN -gt 18 ]; then
CNT=$((LEN - 16))
HHEX=${HEX:0:CNT}
HEX="0x"${HEX:CNT}
fi
for B in $(seq 0 63); do
POW=$((2 ** $B))
T=$((HEX&$POW))
[ "x$T" = "x$POW" ] && BANDS="${BANDS}$((B + 1)) "
done
if [ -n "$HHEX" ]; then
for B in $(seq 0 63); do
POW=$((2 ** $B))
T=$((HHEX&$POW))
[ "x$T" = "x$POW" ] && BANDS="${BANDS}$((B + 1 + 64)) "
done
fi
echo "$BANDS"
}
bandstohex() {
BANDS="$1"
SUM=0
HSUM=0
for BAND in $BANDS; do
case $BAND in
''|*[!0-9]*) continue ;;
esac
if [ $BAND -gt 64 ]; then
B=$((BAND - 1 - 64))
POW=$((2 ** $B))
HSUM=$((HSUM + POW))
else
B=$((BAND - 1))
POW=$((2 ** $B))
SUM=$((SUM + POW))
fi
done
if [ $HSUM -eq 0 ]; then
HEX=$(printf '%x' $SUM)
else
HEX=$(printf '%x%016x' $HSUM $SUM)
fi
echo "$HEX"
}
bandtxt() {
BAND=$1
# see https://en.wikipedia.org/wiki/LTE_frequency_bands
case "$BAND" in
"1") echo " $BAND: FDD 2100 MHz";;
"2") echo " $BAND: FDD 1900 MHz";;
"3") echo " $BAND: FDD 1800 MHz";;
"4") echo " $BAND: FDD 1700 MHz";;
"5") echo " $BAND: FDD 850 MHz";;
"7") echo " $BAND: FDD 2600 MHz";;
"8") echo " $BAND: FDD 900 MHz";;
"11") echo "$BAND: FDD 1500 MHz";;
"12") echo "$BAND: FDD 700 MHz";;
"13") echo "$BAND: FDD 700 MHz";;
"14") echo "$BAND: FDD 700 MHz";;
"17") echo "$BAND: FDD 700 MHz";;
"18") echo "$BAND: FDD 850 MHz";;
"19") echo "$BAND: FDD 850 MHz";;
"20") echo "$BAND: FDD 800 MHz";;
"21") echo "$BAND: FDD 1500 MHz";;
"24") echo "$BAND: FDD 1600 MHz";;
"25") echo "$BAND: FDD 1900 MHz";;
"26") echo "$BAND: FDD 850 MHz";;
"28") echo "$BAND: FDD 700 MHz";;
"29") echo "$BAND: SDL 700 MHz";;
"30") echo "$BAND: FDD 2300 MHz";;
"31") echo "$BAND: FDD 450 MHz";;
"32") echo "$BAND: SDL 1500 MHz";;
"34") echo "$BAND: TDD 2000 MHz";;
"37") echo "$BAND: TDD 1900 MHz";;
"38") echo "$BAND: TDD 2600 MHz";;
"39") echo "$BAND: TDD 1900 MHz";;
"40") echo "$BAND: TDD 2300 MHz";;
"41") echo "$BAND: TDD 2500 MHz";;
"42") echo "$BAND: TDD 3500 MHz";;
"43") echo "$BAND: TDD 3700 MHz";;
"46") echo "$BAND: TDD 5200 MHz";;
"47") echo "$BAND: TDD 5900 MHz";;
"48") echo "$BAND: TDD 3500 MHz";;
"50") echo "$BAND: TDD 1500 MHz";;
"51") echo "$BAND: TDD 1500 MHz";;
"53") echo "$BAND: TDD 2400 MHz";;
"54") echo "$BAND: TDD 1600 MHz";;
"65") echo "$BAND: FDD 2100 MHz";;
"66") echo "$BAND: FDD 1700 MHz";;
"67") echo "$BAND: SDL 700 MHz";;
"69") echo "$BAND: SDL 2600 MHz";;
"70") echo "$BAND: FDD 1700 MHz";;
"71") echo "$BAND: FDD 600 MHz";;
"72") echo "$BAND: FDD 450 MHz";;
"73") echo "$BAND: FDD 450 MHz";;
"74") echo "$BAND: FDD 1500 MHz";;
"75") echo "$BAND: SDL 1500 MHz";;
"76") echo "$BAND: SDL 1500 MHz";;
"85") echo "$BAND: FDD 700 MHz";;
"87") echo "$BAND: FDD 410 MHz";;
"88") echo "$BAND: FDD 410 MHz";;
"103") echo "$BAND: FDD 700 MHz";;
"106") echo "$BAND: FDD 900 MHz";;
esac
}
bandtxt5g() {
BAND=$1
# see https://en.wikipedia.org/wiki/5G_NR_frequency_bands
case "$BAND" in
"1") echo " $BAND: FDD 2100 MHz";;
"2") echo " $BAND: FDD 1900 MHz";;
"3") echo " $BAND: FDD 1800 MHz";;
"5") echo " $BAND: FDD 850 MHz";;
"7") echo " $BAND: FDD 2600 MHz";;
"8") echo " $BAND: FDD 900 MHz";;
"12") echo "$BAND: FDD 700 MHz";;
"13") echo "$BAND: FDD 700 MHz";;
"14") echo "$BAND: FDD 700 MHz";;
"18") echo "$BAND: FDD 850 MHz";;
"20") echo "$BAND: FDD 800 MHz";;
"24") echo "$BAND: FDD 1600 MHz";;
"25") echo "$BAND: FDD 1900 MHz";;
"26") echo "$BAND: FDD 850 MHz";;
"28") echo "$BAND: FDD 700 MHz";;
"29") echo "$BAND: SDL 700 MHz";;
"30") echo "$BAND: TDD 2300 MHz";;
"34") echo "$BAND: TDD 2100 MHz";;
"38") echo "$BAND: TDD 2600 MHz";;
"39") echo "$BAND: TDD 1900 MHz";;
"40") echo "$BAND: TDD 2300 MHz";;
"41") echo "$BAND: TDD 2500 MHz";;
"46") echo "$BAND: TDD 5200 MHz";;
"47") echo "$BAND: TDD 5900 MHz";;
"48") echo "$BAND: TDD 3500 MHz";;
"50") echo "$BAND: TDD 1500 MHz";;
"51") echo "$BAND: TDD 1500 MHz";;
"53") echo "$BAND: TDD 2400 MHz";;
"54") echo "$BAND: TDD 1600 MHz";;
"65") echo "$BAND: FDD 2100 MHz";;
"66") echo "$BAND: FDD 1700/2100 MHz";;
"67") echo "$BAND: SDL 700 MHz";;
"70") echo "$BAND: FDD 2000 MHz";;
"71") echo "$BAND: FDD 600 MHz";;
"74") echo "$BAND: FDD 1500 MHz";;
"75") echo "$BAND: SDL 1500 MHz";;
"76") echo "$BAND: SDL 1500 MHz";;
"77") echo "$BAND: TDD 3700 MHz";;
"78") echo "$BAND: TDD 3500 MHz";;
"79") echo "$BAND: TDD 4700 MHz";;
"80") echo "$BAND: SUL 1800 MHz";;
"81") echo "$BAND: SUL 900 MHz";;
"82") echo "$BAND: SUL 800 MHz";;
"83") echo "$BAND: SUL 700 MHz";;
"84") echo "$BAND: SUL 2100 MHz";;
"85") echo "$BAND: FDD 700 MHz";;
"86") echo "$BAND: SUL 1700 MHz";;
"89") echo "$BAND: SUL 850 MHz";;
"90") echo "$BAND: TDD 2500 MHz";;
"91") echo "$BAND: FDD 800/1500 MHz";;
"92") echo "$BAND: FDD 800/1500 MHz";;
"93") echo "$BAND: FDD 900/1500 MHz";;
"94") echo "$BAND: FDD 900/1500 MHz";;
"95") echo "$BAND: SUL 2100 MHz";;
"96") echo "$BAND: TDD 6000 MHz";;
"97") echo "$BAND: SUL 2300 MHz";;
"98") echo "$BAND: SUL 1900 MHz";;
"99") echo "$BAND: SUL 1600 MHz)";;
"100") echo "$BAND: FDD 900 MHz";;
"101") echo "$BAND: TDD 1900 MHz";;
"102") echo "$BAND: TDD 6200 MHz";;
"104") echo "$BAND: TDD 6700 MHz";;
"105") echo "$BAND: FDD 600 MHz";;
"257") echo "$BAND: 28 GHz";;
"258") echo "$BAND: 26 GHz";;
"259") echo "$BAND: 41 GHz";;
"260") echo "$BAND: 39 GHz";;
"261") echo "$BAND: 28 GHz";;
"262") echo "$BAND: 47 GHz";;
"263") echo "$BAND: 60 GHz";;
esac
}
_DEVICE=""
_DEFAULT_LTE_BANDS=""
_DEFAULT_5GNSA_BANDS=""
_DEFAULT_5GSA_BANDS=""
# default templates
# modem name/type
getinfo() {
echo "Unsupported"
}
# get supported band - 4G
getsupportedbands() {
echo "Unsupported"
}
getsupportedbandsext() {
T=$(getsupportedbands)
[ "x$T" = "xUnsupported" ] && return
for BAND in $T; do
bandtxt "$BAND"
done
}
# get current configured bands - 4G
getbands() {
echo "Unsupported"
}
getbandsext() {
T=$(getbands)
[ "x$T" = "xUnsupported" ] && return
for BAND in $T; do
bandtxt "$BAND"
done
}
# set bands - 4G
setbands() {
echo "Unsupported"
}
# get supported band - 5G NSA
getsupportedbands5gnsa() {
echo "Unsupported"
}
getsupportedbandsext5gnsa() {
T=$(getsupportedbands5gnsa)
[ "x$T" = "xUnsupported" ] && return
for BAND in $T; do
bandtxt5g "$BAND"
done
}
# get current configured bands - 5G NSA
getbands5gnsa() {
echo "Unsupported"
}
getbandsext5gnsa() {
T=$(getbands5gnsa)
[ "x$T" = "xUnsupported" ] && return
for BAND in $T; do
bandtxt5g "$BAND"
done
}
# set bands - 5G NSA
setbands5gnsa() {
echo "Unsupported"
}
# get supported band - 5G SA
getsupportedbands5gsa() {
echo "Unsupported"
}
getsupportedbandsext5gsa() {
T=$(getsupportedbands5gsa)
[ "x$T" = "xUnsupported" ] && return
for BAND in $T; do
bandtxt5g "$BAND"
done
}
# get current configured bands - 5G SA
getbands5gsa() {
echo "Unsupported"
}
getbandsext5gsa() {
T=$(getbands5gsa)
[ "x$T" = "xUnsupported" ] && return
for BAND in $T; do
bandtxt5g "$BAND"
done
}
# set bands - 5G SA
setbands5gsa() {
echo "Unsupported"
}
RES="/usr/share/modemband"
_DEVS=$(awk '{gsub("="," ");
if ($0 ~ /Bus.*Lev.*Prnt.*Port.*/) {T=$0}
if ($0 ~ /Vendor.*ProdID/) {idvendor[T]=$3; idproduct[T]=$5}
if ($0 ~ /Product/) {product[T]=$3}}
END {for (idx in idvendor) {printf "%s%s\n%s%s%s\n", idvendor[idx], idproduct[idx], idvendor[idx], idproduct[idx], product[idx]}}' /sys/kernel/debug/usb/devices)
for _DEV in $_DEVS; do
if [ -e "$RES/$_DEV" ]; then
. "$RES/$_DEV"
break
fi
done
if [ -z "$_DEVICE" ]; then
if [ "x$1" = "xjson" ]; then
echo '{"error":"No supported modem was found, quitting..."}'
else
echo "No supported modem was found, quitting..."
fi
exit 0
else
_DEVICE1=$(uci -q get modemband.@modemband[0].set_port)
if [ -n "$_DEVICE1" ]; then
_DEVICE=$_DEVICE1
fi
fi
if [ ! -e "$_DEVICE" ]; then
if [ "x$1" = "xjson" ]; then
echo '{"error":"Port not found, quitting..."}'
else
echo "Port not found, quitting..."
fi
exit 0
fi
case $1 in
"getinfo")
getinfo
;;
"getsupportedbands")
getsupportedbands
;;
"getsupportedbandsext")
getsupportedbandsext
;;
"getbands")
getbands
;;
"getbandsext")
getbandsext
;;
"setbands")
[ -n "$2" ] && setbands "$2"
;;
"getsupportedbands5gnsa")
getsupportedbands5gnsa
;;
"getsupportedbandsext5gnsa")
getsupportedbandsext5gnsa
;;
"getbands5gnsa")
getbands5gnsa
;;
"getbandsext5gnsa")
getbandsext5gnsa
;;
"setbands5gnsa")
[ -n "$2" ] && setbands5gnsa "$2"
;;
"getsupportedbands5gsa")
getsupportedbands5gsa
;;
"getsupportedbandsext5gsa")
getsupportedbandsext5gsa
;;
"getbands5gsa")
getbands5gsa
;;
"getbandsext5gsa")
getbandsext5gsa
;;
"setbands5gsa")
[ -n "$2" ] && setbands5gsa "$2"
;;
"json")
. /usr/share/libubox/jshn.sh
json_init
json_add_string modem "$(getinfo)"
json_add_array supported
T=$(getsupportedbands)
if [ "x$T" != "xUnsupported" ]; then
for BAND in $T; do
json_add_object ""
json_add_int band $BAND
TXT="$(bandtxt $BAND)"
json_add_string txt "${TXT##*: }"
json_close_object
done
fi
json_close_array
json_add_array enabled
T=$(getbands)
if [ "x$T" != "xUnsupported" ]; then
for BAND in $T; do
json_add_int "" $BAND
done
fi
json_close_array
T=$(getsupportedbands5gnsa)
if [ "x$T" != "xUnsupported" ]; then
json_add_array supported5gnsa
for BAND in $T; do
json_add_object ""
json_add_int band $BAND
TXT="$(bandtxt5g $BAND)"
json_add_string txt "${TXT##*: }"
json_close_object
done
json_close_array
json_add_array enabled5gnsa
T=$(getbands5gnsa)
if [ "x$T" != "xUnsupported" ]; then
for BAND in $T; do
json_add_int "" $BAND
done
fi
json_close_array
fi
T=$(getsupportedbands5gsa)
if [ "x$T" != "xUnsupported" ]; then
json_add_array supported5gsa
for BAND in $T; do
json_add_object ""
json_add_int band $BAND
TXT="$(bandtxt5g $BAND)"
json_add_string txt "${TXT##*: }"
json_close_object
done
json_close_array
json_add_array enabled5gsa
T=$(getbands5gsa)
if [ "x$T" != "xUnsupported" ]; then
for BAND in $T; do
json_add_int "" $BAND
done
fi
json_close_array
fi
json_dump
;;
"help")
echo "Available commands:"
echo " $0 getinfo"
echo " $0 json"
echo " $0 help"
echo ""
echo "for LTE modem"
echo " $0 getsupportedbands"
echo " $0 getsupportedbandsext"
echo " $0 getbands"
echo " $0 getbandsext"
echo " $0 setbands \"<band list>\""
echo ""
echo "for 5G NSA modem"
echo " $0 getsupportedbands5gnsa"
echo " $0 getsupportedbandsext5gnsa"
echo " $0 getbands5gnsa"
echo " $0 getbandsext5gnsa"
echo " $0 setbands5gnsa \"<band list>\""
echo ""
echo "for 5G SA modem"
echo " $0 getsupportedbands5gsa"
echo " $0 getsupportedbandsext5gsa"
echo " $0 getbands5gsa"
echo " $0 getbandsext5gsa"
echo " $0 setbands5gsa \"<band list>\""
;;
*)
echo -n "Modem: "
getinfo
echo -n "Supported LTE bands: "
getsupportedbands
echo -n "Enabled LTE bands: "
getbands
echo ""
getsupportedbandsext
T=$(getsupportedbands5gnsa)
if [ "x$T" != "xUnsupported" ]; then
echo -n "Supported 5G NSA bands: "
getsupportedbands5gnsa
echo -n "Enabled 5G NSA bands: "
getbands5gnsa
echo ""
getsupportedbandsext5gnsa
fi
T=$(getsupportedbands5gsa)
if [ "x$T" != "xUnsupported" ]; then
echo -n "Supported 5G SA bands: "
getsupportedbands5gsa
echo -n "Enabled 5G SA bands: "
getbands5gsa
echo ""
getsupportedbandsext5gsa
fi
;;
esac
exit 0
@@ -1,8 +0,0 @@
_DEVICE=/dev/ttyUSB1
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 17 18 19 20 21 25 26 28 29 30 38 39 40 41 66"
getinfo() {
echo "Qualcomm Snapdragon(TM) X12 LTE-A"
}
. $RES/_foxconn_common2
@@ -1,10 +0,0 @@
_DEVICE=/dev/ttyUSB2
_DEFAULT_LTE_BANDS="1 3 5 7 8 20"
getinfo() {
echo "Quectel EC20"
}
# +QCFG: "band",0xdf,0x800d5,0x3f
. $RES/_quectel_common
@@ -1,36 +0,0 @@
_DEVICE=/dev/ttyUSB2
_DEFAULT_LTE_BANDS="1 3 5 8 38 39 40 41"
getinfo() {
echo "Yuge CLM920 NC_5"
}
getsupportedbands() {
echo "$_DEFAULT_LTE_BANDS"
}
getbands() {
O=$(sms_tool -d $_DEVICE at "as+bandcfg?")
HEXHI=$(echo "$O" | awk -F[,] '/^\+BANDCFG:3,/{print $2}' | xargs)
HEXLO=$(echo "$O" | awk -F[,] '/^\+BANDCFG:3,/{print $3}' | xargs)
hextobands $(printf "0x%x%08x" 0x${HEXHI:-0} 0x${HEXLO:-0})
}
setbands() {
BANDS="$1"
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_LTE_BANDS"
HEX=$(bandstohex "$BANDS")
LEN=${#HEX}
if [ $LEN -gt 8 ]; then
CNT=$((LEN - 8))
HEXHI=${HEX:0:CNT}
HEXLO=${HEX:CNT}
else
HEXLO=$HEX
HEXHI=0
fi
HEXHI=$(printf "%X" 0x$HEXHI)
HEXLO=$(printf "%X" 0x$HEXLO)
[ "$HEX" != "0" ] && sms_tool -d $_DEVICE at "at+bandcfg=$HEXHI,$HEXLO,3"
}
@@ -1,4 +0,0 @@
# +GTUSBMODE: 40
_DEVICE=/dev/ttyUSB2
. $RES/_fibocom_fm350_common
@@ -1,4 +0,0 @@
# +GTUSBMODE: 41
_DEVICE=/dev/ttyUSB4
. $RES/_fibocom_fm350_common
@@ -1,38 +0,0 @@
_DEVICE=/dev/ttyUSB2
getinfo() {
echo "Sierra Wireless EM7455/MC7455/DW5811e"
}
getsupportedbands() {
sms_tool -d $_DEVICE at 'AT!ENTERCND="A710"' >/dev/null 2>&1
O=$(sms_tool -d $_DEVICE at 'AT!BAND=?')
HEX=$(echo "$O" | awk '/^00, All bands/{printf "0x%s\n", $5}')
[ "$HEX" = "0x" ] || hextobands "$HEX"
}
getbands() {
sms_tool -d $_DEVICE at 'AT!ENTERCND="A710"' >/dev/null 2>&1
O=$(sms_tool -d $_DEVICE at 'AT!BAND?')
HEX=$(echo "$O" | awk -F, '/^[0-9a-fA-F][0-9a-fA-F],/{print $3}' | awk '{printf "0x%s\n", $2}')
[ "$HEX" = "0x" ] || hextobands "$HEX"
}
setbands() {
BANDS="$1"
if [ "$BANDS" = "default" ]; then
sms_tool -d $_DEVICE at 'AT!ENTERCND="A710"' >/dev/null 2>&1
sms_tool -d $_DEVICE at 'AT!BAND=00' >/dev/null 2>&1
else
HEXL=$(bandstohex "$BANDS")
if [ "$HEXL" != "0" ]; then
sms_tool -d $_DEVICE at 'AT!ENTERCND="A710"' >/dev/null 2>&1
O=$(sms_tool -d $_DEVICE at 'AT!BAND?')
HEXGW=$(echo "$O" | awk -F, '/^[0-9a-fA-F][0-9a-fA-F],/{print $3}' | awk '{print $1}')
sms_tool -d $_DEVICE at 'AT!BAND=10,"Custom bands",'$HEXGW','$HEXL
sms_tool -d $_DEVICE at 'AT!BAND=10'
sms_tool -d $_DEVICE at 'AT!RESET'
fi
fi
}
@@ -1,47 +0,0 @@
_DEVICE=/dev/ttyUSB2
getinfo() {
echo "Sierra Wireless EM7465"
}
getsupportedbands() {
sms_tool -d $_DEVICE at 'AT!ENTERCND="A710"' >/dev/null 2>&1
O=$(sms_tool -d $_DEVICE at 'AT!BAND=?')
HEX=$(echo "$O" | awk '/^00, All bands/{printf "0x%s%s\n", $6, $5}')
[ "$HEX" = "0x" ] || hextobands "$HEX"
}
getbands() {
sms_tool -d $_DEVICE at 'AT!ENTERCND="A710"' >/dev/null 2>&1
O=$(sms_tool -d $_DEVICE at 'AT!BAND?')
HEX=$(echo "$O" | awk -F, '/^[0-9a-fA-F][0-9a-fA-F],/{print $3}' | awk '{printf "0x%s%s\n", $3, $2}')
[ "$HEX" = "0x" ] || hextobands "$HEX"
}
setbands() {
BANDS="$1"
if [ "$BANDS" = "default" ]; then
sms_tool -d $_DEVICE at 'AT!ENTERCND="A710"' >/dev/null 2>&1
sms_tool -d $_DEVICE at 'AT!BAND=00' >/dev/null 2>&1
else
HEX=$(bandstohex "$BANDS")
if [ "$HEX" != "0" ]; then
sms_tool -d $_DEVICE at 'AT!ENTERCND="A710"' >/dev/null 2>&1
O=$(sms_tool -d $_DEVICE at 'AT!BAND?')
HEXGW=$(echo "$O" | awk -F, '/^[0-9a-fA-F][0-9a-fA-F],/{print $3}' | awk '{print $1}')
LEN=${#HEX}
if [ $LEN -gt 16 ]; then
CNT=$((LEN - 16))
HEXL2=${HEX:0:CNT}
HEXL1=${HEX:CNT}
else
HEXL1=$HEX
HEXL2=0
fi
sms_tool -d $_DEVICE at 'AT!BAND=10,"Custom bands",'$HEXGW','$HEXL1','$HEXL2
sms_tool -d $_DEVICE at 'AT!BAND=10'
sms_tool -d $_DEVICE at 'AT!RESET'
fi
fi
}
@@ -1,60 +0,0 @@
_DEVICE=/dev/ttyUSB1
getinfo() {
O=$(sms_tool -d $_DEVICE at "at+cgmi")
VENDOR=$(echo "$O" | awk '/^[a-zA-Z0-9]/ && !/at\+cgmi/{print $0}' | xargs)
O=$(sms_tool -d $_DEVICE at "at+cgmm")
PRODUCT=$(echo "$O" | awk '/^[a-zA-Z0-9]/ && !/at\+cgmm/{print $0}' | xargs)
echo "$(echo ${VENDOR:0:1} | tr '[a-z]' '[A-Z]')${VENDOR:1} $PRODUCT"
}
getsupportedbands() {
O=$(sms_tool -d $_DEVICE at "at+cgmm")
_NAME=$(echo "$O" | awk '/^[a-zA-Z0-9]/ && !/at\+cgmm/{print tolower($0)}' | xargs)
case "$_NAME" in
"me906e"* | \
"me909u-521")
echo "1 2 3 5 7 8 20"
;;
"me906s"*)
echo "1 2 3 5 7 8 20 28"
;;
"me909s-120")
echo "1 2 3 4 5 7 8 20"
;;
"me909s-821")
echo "1 3 8 38 39 40 41"
;;
"me909s-821a")
echo "1 3 5 8 38 39 40 41"
;;
*)
echo "1 3 7 8 20"
;;
esac
}
getbands() {
O=$(sms_tool -d $_DEVICE at "at^syscfgex?")
HEX="0x"$(echo "$O" | awk -F[:,] '/^\^SYSCFGEX:/{print $6}' | xargs)
if [ "$HEX" = "0x7FFFFFFFFFFFFFFF" ]; then
getsupportedbands
else
[ "$HEX" = "0x" ] || hextobands "$HEX"
fi
}
setbands() {
BANDS="$1"
if [ "$BANDS" = "default" ]; then
HEX="7FFFFFFFFFFFFFFF"
else
HEX=$(bandstohex "$BANDS")
fi
if [ "$HEX" != "0" ]; then
O=$(sms_tool -d $_DEVICE at "at^syscfgex?")
MODE=$(echo "$O" | awk -F[:,] '{print $2}' | xargs)
sms_tool -d $_DEVICE at "at^syscfgex=\"${MODE:-030201}\",3FFFFFFF,2,4,$HEX,,"
fi
}
@@ -1,34 +0,0 @@
_DEVICE=/dev/ttyUSB2
getinfo() {
echo "Huawei E3372h-320"
}
getsupportedbands() {
echo "1 3 7 8 20 28"
}
getbands() {
O=$(sms_tool -d $_DEVICE at "at^syscfgex?")
HEX="0x"$(echo "$O" | awk -F[:,] '/^\^SYSCFGEX:/{print $6}' | xargs)
if [ "$HEX" = "0x7FFFFFFFFFFFFFFF" ]; then
getsupportedbands
else
[ "$HEX" = "0x" ] || hextobands "$HEX"
fi
}
setbands() {
BANDS="$1"
if [ "$BANDS" = "default" ]; then
HEX="7FFFFFFFFFFFFFFF"
else
HEX=$(bandstohex "$BANDS")
fi
if [ "$HEX" != "0" ]; then
O=$(sms_tool -d $_DEVICE at "at^syscfgex?")
MODE=$(echo "$O" | awk -F[:,] '{print $2}' | xargs)
sms_tool -d $_DEVICE at "at^syscfgex=\"${MODE:-030201}\",3FFFFFFF,2,4,$HEX,,"
fi
}
@@ -1,20 +0,0 @@
_DEVICE=/dev/ttyUSB1
_DEFAULT_LTE_BANDS="1 3 7 8 20 28"
_NAME="ZTE MF286"
case $(cat /tmp/sysinfo/board_name) in
"zte,mf286a")
_DEFAULT_LTE_BANDS="1 2 3 5 7 8 20 38"
_NAME="ZTE MF286A"
;;
"zte,mf289f")
_DEFAULT_LTE_BANDS="1 3 7 8 20 28 32 38"
_NAME="ZTE MF289F"
;;
esac
getinfo() {
echo "$_NAME"
}
. $RES/_zte_common
@@ -1,15 +0,0 @@
_DEVICE=/dev/ttyUSB1
_DEFAULT_LTE_BANDS="1 3 7 8 20 28 32 38"
_NAME="ZTE MF286D"
case $(cat /tmp/sysinfo/board_name) in
"zte,mf289f")
_NAME="ZTE MF289F"
;;
esac
getinfo() {
echo "$_NAME"
}
. $RES/_zte_common
@@ -1,8 +0,0 @@
_DEVICE=/dev/ttyACM0
_DEFAULT_LTE_BANDS="1 3 7 8 20 38"
getinfo() {
echo "ZTE MF286R"
}
. $RES/_zte_common
@@ -1,31 +0,0 @@
_DEVICE=/dev/ttyUSB2
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 17 20 25 26 28 29 30 38 40 41"
getinfo() {
echo "Telit LM940"
}
getsupportedbands() {
echo "$_DEFAULT_LTE_BANDS"
}
getbands() {
# #BND: 0,11,1A03B0918DF
O=$(sms_tool -d $_DEVICE at "at#bnd?")
HEX="0x"$(echo "$O" | awk -F[:,] '{print $4}' | xargs)
hextobands "$HEX"
}
setbands() {
BANDS="$1"
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_LTE_BANDS"
HEX=$(bandstohex "$BANDS")
if [ "$HEX" != "0" ]; then
O=$(sms_tool -d $_DEVICE at "at#bnd?")
GSM=$(echo "$O" | awk -F[:,] '{print $2}' | xargs)
UMTS=$(echo "$O" | awk -F[:,] '{print $3}' | xargs)
sms_tool -d $_DEVICE at "at#bnd=${GSM},${UMTS},${HEX}"
fi
}
@@ -1,8 +0,0 @@
_DEVICE=/dev/ttyUSB1
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 17 18 19 20 21 25 26 28 29 30 38 39 40 41 66"
getinfo() {
echo "Telit LN940 Mobile Broadband"
}
. $RES/_foxconn_common2
@@ -1,8 +0,0 @@
_DEVICE=/dev/ttyUSB1
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 17 18 19 20 25 26 28 29 30 32 38 39 40 41 42 43 46 66"
getinfo() {
echo "Telit LN960 Mobile Broadband"
}
. $RES/_foxconn_common1
@@ -1,83 +0,0 @@
_DEVICE=/dev/ttyUSB2
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 17 18 19 20 25 26 28 29 30 32 34 38 39 40 41 42 43 48 66 71"
_DEFAULT_5GNSA_BANDS="1 2 3 5 7 8 12 14 20 28 38 40 41 48 66 71 77 78"
_DEFAULT_5GSA_BANDS="1 2 3 5 7 8 12 14 20 28 38 40 41 48 66 71 77 78"
getinfo() {
echo "SIMCOM SIM8200EA-M2"
}
getsupportedbands() {
echo "$_DEFAULT_LTE_BANDS"
}
getbands() {
O=$(sms_tool -d $_DEVICE at "AT+CSYSSEL=\"lte_band\"")
echo "$O" | awk -F, '/^\+CSYSSEL: "lte_band",/{gsub(":"," ");print $2}' | xargs
}
setbands() {
BANDS="$1"
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_LTE_BANDS"
T=""
for BAND in $BANDS; do
case $BAND in
''|*[!0-9]*) continue ;;
esac
[ -n "$T" ] && T="${T}:"
T="${T}${BAND}"
done
[ -n "$T" ] && sms_tool -d $_DEVICE at "AT+CSYSSEL=\"lte_band\",$T"
}
getsupportedbands5gnsa() {
echo "$_DEFAULT_5GNSA_BANDS"
}
getbands5gnsa() {
O=$(sms_tool -d $_DEVICE at "AT+CSYSSEL=\"nsa_nr5g_band\"")
echo "$O" | awk -F, '/^\+CSYSSEL: "nsa_nr5g_band",/{gsub(":"," ");print $2}' | xargs
}
setbands5gnsa() {
BANDS="$1"
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_5GNSA_BANDS"
T=""
for BAND in $BANDS; do
case $BAND in
''|*[!0-9]*) continue ;;
esac
[ -n "$T" ] && T="${T}:"
T="${T}${BAND}"
done
[ -n "$T" ] && sms_tool -d $_DEVICE at "AT+CSYSSEL=\"nsa_nr5g_band\",$T"
}
getsupportedbands5gsa() {
echo "$_DEFAULT_5GSA_BANDS"
}
getbands5gsa() {
O=$(sms_tool -d $_DEVICE at "AT+CSYSSEL=\"nr5g_band\"")
echo "$O" | awk -F, '/^\+CSYSSEL: "nr5g_band",/{gsub(":"," ");print $2}' | xargs
}
setbands5gsa() {
BANDS="$1"
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_5GSA_BANDS"
T=""
for BAND in $BANDS; do
case $BAND in
''|*[!0-9]*) continue ;;
esac
[ -n "$T" ] && T="${T}:"
T="${T}${BAND}"
done
[ -n "$T" ] && sms_tool -d $_DEVICE at "AT+CSYSSEL=\"nr5g_band\",$T"
}
@@ -1,24 +0,0 @@
_DEVICE=/dev/ttyUSB2
_DEFAULT_LTE_BANDS="1 2 3 5 7 8 12 17 20 38 40"
getinfo() {
echo "BroadMobi BM806U"
}
getsupportedbands() {
echo "$_DEFAULT_LTE_BANDS"
}
getbands() {
O=$(sms_tool -d $_DEVICE at "at+bmbandpref?")
HEX=$(echo "$O" | awk -F[:,] '{print $3}' | xargs)
hextobands "$HEX"
}
setbands() {
BANDS="$1"
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_LTE_BANDS"
HEX=$(bandstohex "$BANDS")
[ "$HEX" != "0" ] && sms_tool -d $_DEVICE at "at+bmbandpref=,$HEX,"
}
@@ -1,8 +0,0 @@
_DEVICE=/dev/ttyUSB2
_DEFAULT_LTE_BANDS="1 3 5 7 8 20 38 40 41"
getinfo() {
echo "Quectel EC25"
}
. $RES/_quectel_common
@@ -1,10 +0,0 @@
_DEVICE=/dev/ttyUSB2
_DEFAULT_LTE_BANDS="1 3 5 7 8 20 28 32 38 40 41"
getinfo() {
echo "Quectel EG06-E"
}
# +QCFG: "band",0x8df,0x1a0880800d5,0x0
. $RES/_quectel_common
@@ -1,10 +0,0 @@
_DEVICE=/dev/ttyUSB2
_DEFAULT_LTE_BANDS="1 3 5 7 8 20 28 38 40 41"
getinfo() {
echo "Quectel EP06-E"
}
# +QCFG: "band",0x8d0,0x1a0080800d5,0x1
. $RES/_quectel_common
@@ -1,8 +0,0 @@
_DEVICE=/dev/ttyUSB2
_DEFAULT_LTE_BANDS="1 3 5 7 8 20 28 38 40 41"
getinfo() {
echo "Quectel EG18-EA"
}
. $RES/_quectel_common
@@ -1,26 +0,0 @@
_DEVICE=/dev/ttyUSB2
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 9 12 13 14 17 18 19 20 21 25 26 28 29 30 32 38 39 40 41 66"
getinfo() {
echo "Quectel EM12-G"
}
getsupportedbands() {
echo "$_DEFAULT_LTE_BANDS"
}
getbands() {
# +QCFG: "band",0x5af0,0x42000000003300185a,0x1
O=$(sms_tool -d $_DEVICE at "AT+QCFG=\"band\"")
HEX=$(echo "$O" | awk -F[:,] '{print $4}' | xargs)
hextobands "$HEX"
}
setbands() {
BANDS="$1"
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_LTE_BANDS"
HEX=$(bandstohex "$BANDS")
[ "$HEX" != "0" ] && sms_tool -d $_DEVICE at "AT+QCFG=\"band\",0,$HEX,1"
}
@@ -1,33 +0,0 @@
_DEVICE=/dev/ttyUSB2
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 18 19 20 25 26 28 29 30 32 38 39 40 41 42 46 48 66"
getinfo() {
echo "Quectel EM160R-GL"
}
getsupportedbands() {
echo "$_DEFAULT_LTE_BANDS"
}
getbands() {
# +QNWPREFCFG: "lte_band",1:3:7:8:20:28:38
O=$(sms_tool -d $_DEVICE at "at+qnwprefcfg=\"lte_band\"?")
echo "$O" | awk -F, '/^\+QNWPREFCFG:/{gsub(":"," ");print $2}'
}
setbands() {
BANDS="$1"
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_LTE_BANDS"
T=""
for BAND in $BANDS; do
case $BAND in
''|*[!0-9]*) continue ;;
esac
[ -n "$T" ] && T="${T}:"
T="${T}${BAND}"
done
[ -n "$T" ] && sms_tool -d $_DEVICE at "at+qnwprefcfg=\"lte_band\",$T"
}
@@ -1,12 +0,0 @@
_DEVICE=/dev/ttyUSB2
_DEFAULT_LTE_BANDS="1 3 5 7 8 18 19 20 26 28 32 34 38 39 40 41 42 43"
_DEFAULT_5GNSA_BANDS="1 3 5 7 8 20 28 38 40 41 77 78 79"
_DEFAULT_5GSA_BANDS="1 3 5 7 8 20 28 38 40 41 77 78 79"
getinfo() {
echo "Quectel RG500Q-EA"
}
# +QNWPREFCFG: "lte_band",1:3:7:8:20:28:38
. $RES/_quectel_common2
@@ -1,12 +0,0 @@
_DEVICE=/dev/ttyUSB2
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 17 18 19 20 25 26 28 29 30 32 34 38 39 40 41 42 43 46 48 66 71"
_DEFAULT_5GNSA_BANDS="1 3 5 7 8 20 28 38 40 41 77 78 79"
_DEFAULT_5GSA_BANDS="1 3 5 7 8 20 28 38 40 41 77 78 79"
getinfo() {
echo "Quectel RG502Q-EA"
}
# +QNWPREFCFG: "lte_band",1:3:7:8:20:28:38
. $RES/_quectel_common2
@@ -1,12 +0,0 @@
_DEVICE=/dev/ttyUSB2
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 17 18 19 20 25 26 28 29 30 32 34 38 39 40 41 42 43 46 48 66 71"
_DEFAULT_5GNSA_BANDS="1 2 3 5 7 8 12 20 25 28 38 40 41 48 66 71 77 78 79"
_DEFAULT_5GSA_BANDS="1 2 3 5 7 8 12 20 25 28 38 40 41 48 66 71 77 78 79"
getinfo() {
echo "Quectel RM500Q-GL"
}
# +QNWPREFCFG: "lte_band",1:3:7:8:20:28:38
. $RES/_quectel_common2
@@ -1,12 +0,0 @@
_DEVICE=/dev/ttyUSB2
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 18 19 20 25 26 28 29 30 32 34 38 39 40 41 42 43 46 48 66 71"
_DEFAULT_5GNSA_BANDS="1 2 3 5 7 8 12 20 25 28 38 40 41 48 66 71 77 78 79"
_DEFAULT_5GSA_BANDS="1 2 3 5 7 8 12 20 25 28 38 40 41 48 66 71 77 78 79"
getinfo() {
echo "Quectel RM502Q-AE"
}
# +QNWPREFCFG: "lte_band",1:3:7:8:20:28:38
. $RES/_quectel_common2
@@ -1,12 +0,0 @@
_DEVICE=/dev/ttyUSB2
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 17 18 19 20 25 26 28 29 30 32 34 38/39 40 41 42 43 48 66 71"
_DEFAULT_5GNSA_BANDS="38 41 77 78"
_DEFAULT_5GSA_BANDS="1 2 3 5 7 8 12 20 25 28 38 40 41 48 66 71 77 78"
getinfo() {
echo "Quectel RM502Q-GL"
}
# +QNWPREFCFG: "lte_band",1:3:7:8:20:28:38
. $RES/_quectel_common2
@@ -1,12 +0,0 @@
_DEVICE=/dev/ttyUSB2
_DEFAULT_LTE_BANDS="1 2 3 4 5 8 12 13 14 17 18 19 20 25 26 28 29 30 32 34 39 40 41 42 43 46 48 66 71"
_DEFAULT_5GNSA_BANDS="1 2 3 5 7 8 12 14 20 25 28 38 40 41 48 66 71 77 78 79"
_DEFAULT_5GSA_BANDS="1 2 3 5 7 8 12 14 20 25 28 38 40 41 48 66 71 77 78 79"
getinfo() {
echo "Quectel RM505Q-AE"
}
# +QNWPREFCFG: "lte_band",1:3:7:8:20:28:38
. $RES/_quectel_common2
@@ -1,15 +0,0 @@
_DEVICE=/dev/ttyUSB3
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 17 18 19 20 25 26 28 29 30 32 34 38 39 40 41 42 43 46 48 66 71"
_DEFAULT_5GNSA_BANDS="1 2 3 5 7 8 12 13 14 18 20 25 26 28 29 30 38 40 41 48 66 70 71 75 76 77 78 79"
_DEFAULT_5GSA_BANDS="1 2 3 5 7 8 12 13 14 18 20 25 26 28 29 30 38 40 41 48 66 70 71 75 76 77 78 79"
getinfo() {
VENDOR=$(sms_tool -d /dev/ttyUSB3 at AT+CGMI | tr -s '\n' | xargs)
DEVICE=$(sms_tool -d /dev/ttyUSB3 at AT+CGMM | tr -s '\n' | xargs)
echo "$VENDOR $DEVICE"
}
# +QNWPREFCFG: "lte_band",1:2:3:4:5:7:8:12:13:14:17:18:19:20:25:26:28:29:30:32:34:38:39:40:41:42:43:46:48:66:71
# +QNWPREFCFG: "nsa_nr5g_band",1:2:3:5:7:8:12:13:14:18:20:25:26:28:29:30:38:40:41:48:66:70:71:75:76:77:78:79
. $RES/_quectel_common2
@@ -1,12 +0,0 @@
_DEVICE=/dev/ttyUSB2
_DEFAULT_LTE_BANDS="1 2 3 5 8 34 38 39 40 41"
_DEFAULT_5GNSA_BANDS="41 78 79"
_DEFAULT_5GSA_BANDS="1 2 3 5 8 28 41 77 78 79"
getinfo() {
echo "Quectel RM500U-CNV"
}
# +QNWPREFCFG: "lte_band",1:3:7:8:20:28:38
. $RES/_quectel_common2
@@ -1,8 +0,0 @@
_DEVICE=/dev/ttyUSB1
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 17 18 19 20 25 26 28 29 30 32 38 39 40 41 42 43 46 66"
getinfo() {
echo "Dell DW5821e Snapdragon X20 LTE"
}
. $RES/_foxconn_common1
@@ -1,57 +0,0 @@
_DEVICE=/dev/ttyACM2
getinfo() {
O=$(sms_tool -d $_DEVICE at "at+gmm")
_NAME="Fibocom $(echo "$O" | awk -F, '{print $2}')"
echo "$_NAME"
}
getsupportedbands() {
O=$(sms_tool -d $_DEVICE at "at+gmm")
if echo "$O" | grep -q "L850"; then
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 11 12 13 17 18 19 20 21 26 28 29 30 38 39 40 41 66"
fi
if echo "$O" | grep -q "L860"; then
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 17 18 19 20 25 26 28 29 30 32 38 39 40 41 42 46 66"
fi
if echo "$O" | grep -q "L860-GL-16"; then
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 17 18 19 20 25 26 28 29 30 32 34 38 39 40 41 42 43 46 48 66 71"
fi
echo "$_DEFAULT_LTE_BANDS"
}
getbands() {
# +XACT: 4,2,1,1,2,4,5,8,101,102,103,104,105,107,108,112,113,114,117,118,119,120,125,126,128,129,130,132,138,139,140,141,142,146,166
O=$(sms_tool -d $_DEVICE at "at+xact?")
BANDS=$(echo "$O" | awk -F: '/^\+XACT:/{gsub(","," ");print $2}')
for BAND in $BANDS; do
if [ $BAND -gt 100 ] && [ $BAND -lt 200 ]; then
echo -n "$((BAND - 100)) "
fi
done
echo ""
}
setbands() {
BANDS="$1"
T=""
if [ "$BANDS" = "default" ]; then
T="0"
else
for BAND in $BANDS; do
case $BAND in
''|*[!0-9]*) continue ;;
esac
[ -n "$T" ] && T="${T},"
T="${T}$((BAND + 100))"
done
fi
if [ -n "$T" ]; then
O=$(sms_tool -d $_DEVICE at "at+xact?")
MODE=$(echo "$O" | awk -F[:,] '{print $2}' | xargs)
sms_tool -d $_DEVICE at "at+xact=$MODE,,,$T"
fi
}
@@ -1,131 +0,0 @@
# Unified for NSA/SA
_DEFAULT_5G_BANDS="1 2 3 5 7 8 20 25 28 30 38 40 41 48 66 71 77 78 79"
getinfo() {
O=$(sms_tool -d $_DEVICE at "AT+CGMM?")
_NAME="Fibocom $(echo "$O" | awk -F[:,] '/^\+CGMM:/{gsub("\"","");print $2}' | xargs)"
echo "$_NAME"
}
getsupportedbands() {
_DEFAULT_LTE_BANDS="1 2 3 4 5 7 8 12 13 14 17 18 19 20 25 26 28 29 30 32 34 38 39 40 41 42 43 46 48 66 71"
echo "$_DEFAULT_LTE_BANDS"
}
getbands() {
# +GTACT: 20,6,3,101,102,103,104,105,107,108,112,113,114,117,118,119,120,125,126,128,129,130,132,134,138,139,140,141,142,143,146,148,166,171
O=$(sms_tool -d $_DEVICE at "AT+GTACT?")
BANDS=$(echo "$O" | awk -F: '/^\+GTACT:/{gsub(","," ");print $2}')
for BAND in $BANDS; do
if [ $BAND -gt 100 ] && [ $BAND -lt 200 ]; then
echo -n "$((BAND - 100)) "
fi
done
echo ""
}
setbands() {
BANDS="$1"
T=""
if [ "$BANDS" = "default" ]; then
T="0"
else
for BAND in $BANDS; do
case $BAND in
''|*[!0-9]*) continue ;;
esac
[ -n "$T" ] && T="${T},"
T="${T}$((BAND + 100))"
done
fi
if [ -n "$T" ]; then
O=$(sms_tool -d $_DEVICE at "AT+GTACT?")
MODE=$(echo "$O" | awk -F[:,] '/\+GTACT:/{print $2","$3","$4}'| xargs)
sms_tool -d $_DEVICE at "AT+GTACT=$MODE,$T"
fi
}
getsupportedbands5gsa() {
echo "$_DEFAULT_5G_BANDS"
}
getsupportedbands5gnsa() {
echo "$_DEFAULT_5G_BANDS"
}
getbands5gsa() {
# +GTACT: 20,6,3,501,502,503,505,507,508,5020,5025,5028,5030,5038,5040,5041,5048,5066,5071,5077,5078,5079
O=$(sms_tool -d $_DEVICE at "AT+GTACT?")
BANDS=$(echo "$O" | awk -F: '/^\+GTACT:/{gsub(","," ");print $2}')
for BAND in $BANDS; do
if [ $BAND -gt 500 ] && [ $BAND -lt 5100 ]; then
echo -n "$(echo "$BAND" | sed 's/^50//g') "
fi
done
echo ""
}
getbands5gnsa() {
# +GTACT: 20,6,3,501,502,503,505,507,508,5020,5025,5028,5030,5038,5040,5041,5048,5066,5071,5077,5078,5079
O=$(sms_tool -d $_DEVICE at "AT+GTACT?")
BANDS=$(echo "$O" | awk -F: '/^\+GTACT:/{gsub(","," ");print $2}')
for BAND in $BANDS; do
if [ $BAND -gt 500 ] && [ $BAND -lt 5100 ]; then
echo -n "$(echo "$BAND" | sed 's/^50//g') "
fi
done
echo ""
}
setbands5gsa() {
BANDS="$1"
T=""
if [ "$BANDS" = "default" ]; then
T="0"
else
for BAND in $BANDS; do
case $BAND in
''|*[!0-9]*) continue ;;
esac
[ -n "$T" ] && T="${T},"
T="${T}50${BAND}"
done
fi
if [ -n "$T" ]; then
O=$(sms_tool -d $_DEVICE at "AT+GTACT?")
MODE=$(echo "$O" | awk -F[:,] '/\+GTACT:/{print $2","$3","$4}'| xargs)
sms_tool -d $_DEVICE at "AT+GTACT=$MODE,$T"
fi
}
setbands5gnsa() {
BANDS="$1"
T=""
if [ "$BANDS" = "default" ]; then
T="0"
else
for BAND in $BANDS; do
case $BAND in
''|*[!0-9]*) continue ;;
esac
[ -n "$T" ] && T="${T},"
T="${T}50${BAND}"
done
fi
if [ -n "$T" ]; then
O=$(sms_tool -d $_DEVICE at "AT+GTACT?")
MODE=$(echo "$O" | awk -F[:,] '/\+GTACT:/{print $2","$3","$4}'| xargs)
sms_tool -d $_DEVICE at "AT+GTACT=$MODE,$T"
fi
}
@@ -1,27 +0,0 @@
getsupportedbands() {
echo "$_DEFAULT_LTE_BANDS"
}
getbands() {
# ^SLBAND: WCDMA,Enabled,1,2,4,5,6,8,9,19
# ^SLBAND: LTE,Enabled,1,2,3,4,5,7,8,12,13,14,17,18,19,20,25,26,28,29,30,32,38,39,40,41,42,43,46,66
O=$(sms_tool -d $_DEVICE at "at^slband?")
echo "$O" | awk -F: '/LTE/{gsub("LTE,Enabled,","");gsub(","," ");print $2}' | xargs
}
setbands() {
BANDS="$1"
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_LTE_BANDS"
T=""
for BAND in $BANDS; do
case $BAND in
''|*[!0-9]*) continue ;;
esac
[ -n "$T" ] && T="${T},"
T="${T}${BAND}"
done
[ -n "$T" ] && sms_tool -d $_DEVICE at "at^slband=lte,2,$T"
}
@@ -1,27 +0,0 @@
getsupportedbands() {
echo "$_DEFAULT_LTE_BANDS"
}
getbands() {
# ^SLBAND: WCDMA,1,2,4,5,6,8,9,19
# ^SLBAND: LTE,1,2,3,4,5,7,8,12,13,17,18,19,20,21,25,26,28,29,30,38,39,40,41,66
O=$(sms_tool -d $_DEVICE at "at^slband?")
echo "$O" | awk -F: '/^\^SLBAND:.*LTE,/{gsub("LTE,","");gsub(","," ");print $2}' | xargs
}
setbands() {
BANDS="$1"
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_LTE_BANDS"
T=""
for BAND in $BANDS; do
case $BAND in
''|*[!0-9]*) continue ;;
esac
[ -n "$T" ] && T="${T},"
T="${T}${BAND}"
done
[ -n "$T" ] && sms_tool -d $_DEVICE at "at^slband=lte,$T"
}
@@ -1,17 +0,0 @@
getsupportedbands() {
echo "${_DEFAULT_LTE_BANDS:-Unsupported}"
}
getbands() {
O=$(sms_tool -d $_DEVICE at "at+qcfg=\"band\"")
HEX=$(echo "$O" | awk -F[:,] '{print $4}' | xargs)
hextobands "$HEX"
}
setbands() {
BANDS="$1"
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_LTE_BANDS"
HEX=$(bandstohex "$BANDS")
[ "$HEX" != "0" ] && sms_tool -d $_DEVICE at "at+qcfg=\"band\",0,$HEX,0,1"
}
@@ -1,80 +0,0 @@
getsupportedbands() {
echo "$_DEFAULT_LTE_BANDS"
}
getbands() {
# +QNWPREFCFG: "lte_band",1:3:7:8:20:28:38
O=$(sms_tool -d $_DEVICE at "at+qnwprefcfg=\"lte_band\"")
echo "$O" | awk -F, '/^\+QNWPREFCFG:/{gsub(":"," ");print $2}'
}
setbands() {
BANDS="$1"
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_LTE_BANDS"
T=""
for BAND in $BANDS; do
case $BAND in
''|*[!0-9]*) continue ;;
esac
[ -n "$T" ] && T="${T}:"
T="${T}${BAND}"
done
[ -n "$T" ] && sms_tool -d $_DEVICE at "at+qnwprefcfg=\"lte_band\",$T"
}
getsupportedbands5gnsa() {
echo "$_DEFAULT_5GNSA_BANDS"
}
getbands5gnsa() {
# +QNWPREFCFG: "nsa_nr5g_band",1:2:3:5:7:8:12:20:25:28:38:40:41:48:66:71:77:78:79
O=$(sms_tool -d $_DEVICE at "at+qnwprefcfg=\"nsa_nr5g_band\"")
echo "$O" | awk -F, '/^\+QNWPREFCFG:/{gsub(":"," ");print $2}' | xargs
}
setbands5gnsa() {
BANDS="$1"
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_5GNSA_BANDS"
T=""
for BAND in $BANDS; do
case $BAND in
''|*[!0-9]*) continue ;;
esac
[ -n "$T" ] && T="${T}:"
T="${T}${BAND}"
done
[ -n "$T" ] && sms_tool -d $_DEVICE at "at+qnwprefcfg=\"nsa_nr5g_band\",$T"
}
getsupportedbands5gsa() {
echo "$_DEFAULT_5GSA_BANDS"
}
getbands5gsa() {
# +QNWPREFCFG: "nr5g_band",1:2:3:5:7:8:12:20:25:28:38:40:41:48:66:71:77:78:79
O=$(sms_tool -d $_DEVICE at "at+qnwprefcfg=\"nr5g_band\"")
echo "$O" | awk -F, '/^\+QNWPREFCFG:/{gsub(":"," ");print $2}' | xargs
}
setbands5gsa() {
BANDS="$1"
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_5GSA_BANDS"
T=""
for BAND in $BANDS; do
case $BAND in
''|*[!0-9]*) continue ;;
esac
[ -n "$T" ] && T="${T}:"
T="${T}${BAND}"
done
[ -n "$T" ] && sms_tool -d $_DEVICE at "at+qnwprefcfg=\"nr5g_band\",$T"
}
@@ -1,19 +0,0 @@
getsupportedbands() {
echo "$_DEFAULT_LTE_BANDS"
}
getbands() {
# +ZNLOCKBAND: 80800c5,2000000680380
O=$(sms_tool -d $_DEVICE at "at+znlockband?")
HEX="0x"$(echo "$O" | awk -F[:,] '{print $2}' | xargs)
hextobands "$HEX"
}
setbands() {
BANDS="$1"
[ "$BANDS" = "default" ] && BANDS="$_DEFAULT_LTE_BANDS"
HEX=$(bandstohex "$BANDS")
[ "$HEX" != "0" ] && sms_tool -d $_DEVICE at "at+znlockband=1,0,$HEX,0"
}
+10 -20
View File
@@ -1,36 +1,26 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=quectel-cm
PKG_VERSION:=1.6.8
PKG_RELEASE:=3
PKG_VERSION:=1.6.7
PKG_RELEASE:=4
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/quectel-open-source/Quectel_QConnectManager_Linux
PKG_SOURCE_VERSION:=170ed7177cc3beb831bc85571aad956492ff7e7e
PKG_MIRROR_HASH:=skip
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk
define Package/quectel-cm
SECTION:=net
CATEGORY:=Network
SUBMENU:=WWAN
TITLE:=Qconnector Manager for Quectel WWAN modules
DEPENDS:= \
+kmod-usb-net-cdc-mbim \
+kmod-usb-net-qmi-wwan \
+kmod-usb-net-qmi-wwan-fibocom \
+kmod-usb-net-qmi-wwan-quectel \
+kmod-usb-serial-option
TITLE:=Quectel dial program
DEPENDS:=+libpthread
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
$(INSTALL_BIN) $(PKG_BUILD_DIR)/quectel-CM $(1)/usr/bin
endef
$(eval $(call BuildPackage,quectel-cm))
-138
View File
@@ -1,138 +0,0 @@
#!/bin/sh
[ -n "$INCLUDE_ONLY" ] || {
. /lib/functions.sh
. ../netifd-proto.sh
init_proto "$@"
}
proto_quectel_init_config() {
available=1
no_device=1
proto_config_add_string "device:device"
proto_config_add_string "apn"
proto_config_add_string "auth"
proto_config_add_string "username"
proto_config_add_string "password"
proto_config_add_string "pincode"
proto_config_add_int "delay"
proto_config_add_string "pdptype"
proto_config_add_boolean "dhcp"
proto_config_add_boolean "dhcpv6"
proto_config_add_boolean "sourcefilter"
proto_config_add_boolean "delegate"
proto_config_add_int "mtu"
proto_config_add_defaults
}
proto_quectel_setup() {
local interface="$1"
local device apn auth username password pincode delay pdptype
local dhcp dhcpv6 sourcefilter delegate mtu $PROTO_DEFAULT_OPTIONS
local ip4table ip6table
local pid zone
json_get_vars device apn auth username password pincode delay
json_get_vars pdptype dhcp dhcpv6 sourcefilter delegate ip4table
json_get_vars ip6table mtu $PROTO_DEFAULT_OPTIONS
[ -n "$delay" ] && sleep "$delay"
[ -n "$metric" ] || metric="0"
[ -z "$ctl_device" ] || device="$ctl_device"
[ -n "$device" ] || {
echo "No control device specified"
proto_notify_error "$interface" NO_DEVICE
proto_set_available "$interface" 0
return 1
}
device="$(readlink -f "$device")"
[ -c "$device" ] || {
echo "The specified control device does not exist"
proto_notify_error "$interface" NO_DEVICE
proto_set_available "$interface" 0
return 1
}
devname="$(basename "$device")"
devpath="$(readlink -f "/sys/class/usbmisc/$devname/device/")"
ifname="$(ls "$devpath/net" 2>"/dev/null")"
[ -n "$ifname" ] || {
echo "The interface could not be found."
proto_notify_error "$interface" NO_IFACE
proto_set_available "$interface" 0
return 1
}
[ "$pdptype" = "ipv4" -o "$pdptype" = "ipv4v6" ] && ipv4opt="-4"
[ "$pdptype" = "ipv6" -o "$pdptype" = "ipv4v6" ] && ipv6opt="-6"
[ -n "$auth" ] || auth="none"
eval "proto_run_command '$interface' /usr/bin/quectel-cm -i '$ifname' $ipv4opt $ipv6opt ${pincode:+-p $pincode} -s '$apn' '$username' '$password' '$auth'"
sleep 5
ifconfig "$ifname" up
ifconfig "${ifname}_1" &>"/dev/null" && ifname="${ifname}_1"
if [ -n "$mtu" ]; then
echo "Setting MTU to $mtu"
/sbin/ip link set dev "$ifname" mtu "$mtu"
fi
echo "Setting up $ifname"
proto_init_update "$ifname" 1
proto_set_keep 1
proto_send_update "$interface"
zone="$(fw3 -q network "$interface" 2>/dev/null)"
if [ "$pdptype" = "ipv6" ] || [ "$pdptype" = "ipv4v6" ]; then
json_init
json_add_string name "${interface}_6"
json_add_string ifname "@$interface"
[ "$pdptype" = "ipv4v6" ] && json_add_string iface_464xlat "0"
json_add_string proto "dhcpv6"
proto_add_dynamic_defaults
[ -z "$ip6table" ] || json_add_string ip6table "$ip6table"
# RFC 7278: Extend an IPv6 /64 Prefix to LAN
json_add_string extendprefix 1
[ "$delegate" = "0" ] && json_add_boolean delegate "0"
[ "$sourcefilter" = "0" ] && json_add_boolean sourcefilter "0"
[ -z "$zone" ] || json_add_string zone "$zone"
json_close_object
ubus call network add_dynamic "$(json_dump)"
fi
if [ "$pdptype" = "ipv4" ] || [ "$pdptype" = "ipv4v6" ]; then
json_init
json_add_string name "${interface}_4"
json_add_string ifname "@$interface"
json_add_string proto "dhcp"
[ -z "$ip4table" ] || json_add_string ip4table "$ip4table"
proto_add_dynamic_defaults
[ -z "$zone" ] || json_add_string zone "$zone"
json_close_object
ubus call network add_dynamic "$(json_dump)"
fi
}
proto_quectel_teardown() {
local interface="$1"
local device
json_get_vars device
[ -z "$ctl_device" ] || device="$ctl_device"
echo "Stopping network $interface"
proto_kill_command "$interface"
proto_init_update "*" 0
proto_send_update "$interface"
}
[ -n "$INCLUDE_ONLY" ] || {
add_protocol quectel
}
-24
View File
@@ -1,24 +0,0 @@
#!/bin/sh
[ "$ACTION" = add ] || exit
echo "$INTERFACE" | grep -q "rmnet_mhi" || exit
core_count="$(grep -c "processor" "/proc/cpuinfo")"
irq_path="/sys/class/net/$INTERFACE/queues"
devnum="$(echo "${INTERFACE%.*}" | grep -Eo "[0-9]+")"
core="$(( devnum % (core_count - 1) + 1))"
if [ "$INTERFACE" != "${INTERFACE%.*}" ]; then
if [ "$core" -lt "$(( core_count - 1 ))" ]; then
let core++
else
core="1"
fi
fi
irq="$(printf "%x" "$((1 << core))")"
echo "$irq" > "$irq_path/rx-0/rps_cpus"
echo "4096" > "$irq_path/rx-0/rps_flow_cnt"
echo "2000" > "/proc/sys/net/core/netdev_max_backlog"
exit 0
-24
View File
@@ -1,24 +0,0 @@
#!/bin/sh
[ "$ACTION" = add ] || exit
echo "$INTERFACE" | grep -q "wwan" || exit
core_count="$(grep -c "processor" "/proc/cpuinfo")"
irq_path="/sys/class/net/$INTERFACE/queues"
devnum="$(echo "${INTERFACE%_*}" | grep -Eo "[0-9]+")"
core="$(( devnum % (core_count - 1) + 1))"
if [ "$INTERFACE" != "${INTERFACE%_*}" ]; then
if [ "$core" -lt "$(( core_count - 1 ))" ]; then
let core++
else
core="1"
fi
fi
irq="$(printf "%x" "$((1 << core))")"
echo "$irq" > "$irq_path/rx-0/rps_cpus"
echo "4096" > "$irq_path/rx-0/rps_flow_cnt"
echo "2000" > "/proc/sys/net/core/netdev_max_backlog"
exit 0
-29
View File
@@ -1,29 +0,0 @@
--- a/quectel-qrtr-proxy.c
+++ b/quectel-qrtr-proxy.c
@@ -555,7 +555,7 @@ static int recv_qmi_from_client(PQCQMIMS
}
else if (le16toh(pQMI->CTLMsg.QMICTLMsgHdr.QMICTLType) == QMICTL_GET_CLIENT_ID_REQ) {
uint8_t QMIType = pQMI->CTLMsg.GetClientIdReq.QMIType;
- PQCQMIMSG pRsp = (PQCQMIMSG)malloc(256);
+ PQCQMIMSG pRsp = (PQCQMIMSG)malloc(sizeof(*pRsp));
if (pRsp) {
uint8_t ClientId = 0;
@@ -589,7 +589,7 @@ static int recv_qmi_from_client(PQCQMIMS
}
}
else if (le16toh(pQMI->CTLMsg.QMICTLMsgHdr.QMICTLType) == QMICTL_RELEASE_CLIENT_ID_REQ) {
- PQCQMIMSG pRsp = (PQCQMIMSG)malloc(256);
+ PQCQMIMSG pRsp = (PQCQMIMSG)malloc(sizeof(*pRsp));
release_qrtr_client_id(qrtr_con, pQMI->CTLMsg.ReleaseClientIdReq.QMIType, pQMI->CTLMsg.ReleaseClientIdReq.ClientId);
if (pRsp) {
@@ -618,7 +618,7 @@ static int recv_qmi_from_client(PQCQMIMS
}
}
else if (le16toh(pQMI->CTLMsg.QMICTLMsgHdr.QMICTLType) == QMICTL_GET_VERSION_REQ) {
- PQCQMIMSG pRsp = (PQCQMIMSG)malloc(256);
+ PQCQMIMSG pRsp = (PQCQMIMSG)malloc(sizeof(*pRsp));
if (pRsp) {
pRsp->QMIHdr.IFType = USB_CTL_MSG_TYPE_QMI;
-8
View File
@@ -1,8 +0,0 @@
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.4)
+cmake_minimum_required(VERSION 3.10)
project(quectel-CM)
add_definitions(-Wall -Wextra -Werror -O1)
@@ -1,15 +0,0 @@
--- a/device.c
+++ b/device.c
@@ -342,10 +342,12 @@ BOOL qmidevice_detect(char *qmichannel,
switch (profile->usb_dev.idProduct) { //EC200U
case 0x0901: //EC200U
case 0x0902: //EC200D
+ case 0x0904: //EC200G
case 0x8101: //RG801H
atIntf = 2;
break;
case 0x0900: //RG500U
+ case 0x0903: //EC600
atIntf = 4;
break;
case 0x6026: //EC200T
-36
View File
@@ -1,36 +0,0 @@
cmake_minimum_required(VERSION 2.4)
project(quectel-CM)
add_definitions(-Wall -Wextra -Werror -O1)
option(USE_QRTR "Enable QRTR" OFF)
set( QL_CM_SRC
QmiWwanCM.c GobiNetCM.c main.c QCQMUX.c QMIThread.c util.c qmap_bridge_mode.c mbim-cm.c device.c
atc.c atchannel.c at_tok.c
udhcpc.c
)
if(USE_QRTR)
add_definitions(-DCONFIG_QRTR)
set( QRTR_SRC qrtr.c rmnetctl.c)
endif()
add_executable(quectel-CM ${QL_CM_SRC} ${QRTR_SRC})
target_link_libraries(quectel-CM PUBLIC pthread)
install (TARGETS quectel-CM DESTINATION bin)
add_executable(quectel-qmi-proxy quectel-qmi-proxy.c)
target_link_libraries(quectel-qmi-proxy PUBLIC pthread)
install (TARGETS quectel-qmi-proxy DESTINATION bin)
add_executable(quectel-mbim-proxy quectel-mbim-proxy.c)
target_link_libraries(quectel-mbim-proxy PUBLIC pthread)
install (TARGETS quectel-mbim-proxy DESTINATION bin)
add_executable(quectel-atc-proxy quectel-atc-proxy.c atchannel.c at_tok.c util.c)
target_link_libraries(quectel-atc-proxy PUBLIC pthread)
install (TARGETS quectel-atc-proxy DESTINATION bin)
add_executable(quectel-qrtr-proxy quectel-qrtr-proxy.c)
target_link_libraries(quectel-qrtr-proxy PUBLIC pthread)
install (TARGETS quectel-qrtr-proxy DESTINATION bin)
-242
View File
@@ -1,242 +0,0 @@
/*
Copyright 2025 Quectel Wireless Solutions Co.,Ltd
Quectel hereby grants customers of Quectel a license to use, modify,
distribute and publish the Software in binary form provided that
customers shall have no right to reverse engineer, reverse assemble,
decompile or reduce to source code form any portion of the Software.
Under no circumstances may customers modify, demonstrate, use, deliver
or disclose any portion of the Software in source code form.
*/
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <stdio.h>
#include <ctype.h>
#include "QMIThread.h"
#ifdef CONFIG_GOBINET
static int qmiclientId[QMUX_TYPE_ALL];
// IOCTL to generate a client ID for this service type
#define IOCTL_QMI_GET_SERVICE_FILE 0x8BE0 + 1
// IOCTL to get the VIDPID of the device
#define IOCTL_QMI_GET_DEVICE_VIDPID 0x8BE0 + 2
// IOCTL to get the MEID of the device
#define IOCTL_QMI_GET_DEVICE_MEID 0x8BE0 + 3
static int GobiNetSendQMI(PQCQMIMSG pRequest) {
int ret, fd;
fd = qmiclientId[pRequest->QMIHdr.QMIType];
pRequest->QMIHdr.ClientId = (fd&0xFF) ? fd&0xFF : pRequest->QMIHdr.QMIType;
if (fd <= 0) {
dbg_time("%s QMIType: %d has no clientID", __func__, pRequest->QMIHdr.QMIType);
return -ENODEV;
}
// Always ready to write
if (1 == 1) {
ssize_t nwrites = le16_to_cpu(pRequest->QMIHdr.Length) + 1 - sizeof(QCQMI_HDR);
ret = write(fd, &pRequest->MUXMsg, nwrites);
if (ret == nwrites) {
ret = 0;
} else {
dbg_time("%s write=%d, errno: %d (%s)", __func__, ret, errno, strerror(errno));
}
} else {
dbg_time("%s poll=%d, errno: %d (%s)", __func__, ret, errno, strerror(errno));
}
return ret;
}
static int GobiNetGetClientID(const char *qcqmi, UCHAR QMIType) {
int ClientId;
ClientId = cm_open_dev(qcqmi);
if (ClientId == -1) {
dbg_time("failed to open %s, errno: %d (%s)", qcqmi, errno, strerror(errno));
return 0;
}
if (ioctl(ClientId, IOCTL_QMI_GET_SERVICE_FILE, QMIType) != 0) {
dbg_time("failed to get ClientID for 0x%02x errno: %d (%s)", QMIType, errno, strerror(errno));
close(ClientId);
ClientId = 0;
}
switch (QMIType) {
case QMUX_TYPE_WDS: dbg_time("Get clientWDS = %d", ClientId); break;
case QMUX_TYPE_DMS: dbg_time("Get clientDMS = %d", ClientId); break;
case QMUX_TYPE_NAS: dbg_time("Get clientNAS = %d", ClientId); break;
case QMUX_TYPE_QOS: dbg_time("Get clientQOS = %d", ClientId); break;
case QMUX_TYPE_WMS: dbg_time("Get clientWMS = %d", ClientId); break;
case QMUX_TYPE_PDS: dbg_time("Get clientPDS = %d", ClientId); break;
case QMUX_TYPE_UIM: dbg_time("Get clientUIM = %d", ClientId); break;
case QMUX_TYPE_COEX: dbg_time("Get clientCOEX = %d", ClientId); break;
case QMUX_TYPE_WDS_ADMIN: dbg_time("Get clientWDA = %d", ClientId);
break;
default: break;
}
return ClientId;
}
static int GobiNetDeInit(void) {
unsigned int i;
for (i = 0; i < sizeof(qmiclientId)/sizeof(qmiclientId[0]); i++)
{
if (qmiclientId[i] != 0)
{
close(qmiclientId[i]);
qmiclientId[i] = 0;
}
}
return 0;
}
static void * GobiNetThread(void *pData) {
PROFILE_T *profile = (PROFILE_T *)pData;
const char *qcqmi = (const char *)profile->qmichannel;
int wait_for_request_quit = 0;
qmiclientId[QMUX_TYPE_WDS] = GobiNetGetClientID(qcqmi, QMUX_TYPE_WDS);
if (profile->enable_ipv6)
qmiclientId[QMUX_TYPE_WDS_IPV6] = GobiNetGetClientID(qcqmi, QMUX_TYPE_WDS);
qmiclientId[QMUX_TYPE_DMS] = GobiNetGetClientID(qcqmi, QMUX_TYPE_DMS);
qmiclientId[QMUX_TYPE_NAS] = GobiNetGetClientID(qcqmi, QMUX_TYPE_NAS);
qmiclientId[QMUX_TYPE_UIM] = GobiNetGetClientID(qcqmi, QMUX_TYPE_UIM);
#ifdef CONFIG_COEX_WWAN_STATE
qmiclientId[QMUX_TYPE_COEX] = GobiNetGetClientID(qcqmi, QMUX_TYPE_COEX);
#endif
if (profile->qmap_mode == 0 || profile->loopback_state) {//when QMAP enabled, set data format in GobiNet Driver
qmiclientId[QMUX_TYPE_WDS_ADMIN] = GobiNetGetClientID(qcqmi, QMUX_TYPE_WDS_ADMIN);
profile->wda_client = qmiclientId[QMUX_TYPE_WDS_ADMIN];
}
//donot check clientWDA, there is only one client for WDA, if quectel-CM is killed by SIGKILL, i cannot get client ID for WDA again!
if (qmiclientId[QMUX_TYPE_WDS] == 0) /*|| (clientWDA == -1)*/ {
GobiNetDeInit();
dbg_time("%s Failed to open %s, errno: %d (%s)", __func__, qcqmi, errno, strerror(errno));
qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_DISCONNECTED);
pthread_exit(NULL);
return NULL;
}
qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_CONNECTED);
while (1) {
struct pollfd pollfds[16] = {{qmidevice_control_fd[1], POLLIN, 0}};
int ne, ret, nevents = 1;
unsigned int i;
for (i = 0; i < sizeof(qmiclientId)/sizeof(qmiclientId[0]); i++)
{
if (qmiclientId[i] != 0)
{
pollfds[nevents].fd = qmiclientId[i];
pollfds[nevents].events = POLLIN;
pollfds[nevents].revents = 0;
nevents++;
}
}
do {
ret = poll(pollfds, nevents, wait_for_request_quit ? 1000: -1);
} while ((ret < 0) && (errno == EINTR));
if (ret == 0 && wait_for_request_quit) {
QmiThreadRecvQMI(NULL); //main thread may pending on QmiThreadSendQMI()
continue;
}
if (ret <= 0) {
dbg_time("%s poll=%d, errno: %d (%s)", __func__, ret, errno, strerror(errno));
break;
}
for (ne = 0; ne < nevents; ne++) {
int fd = pollfds[ne].fd;
short revents = pollfds[ne].revents;
if (revents & (POLLERR | POLLHUP | POLLNVAL)) {
dbg_time("%s poll err/hup/inval", __func__);
dbg_time("epoll fd = %d, events = 0x%04x", fd, revents);
if (fd == qmidevice_control_fd[1]) {
} else {
}
if (revents & (POLLERR | POLLHUP | POLLNVAL))
goto __GobiNetThread_quit;
}
if ((revents & POLLIN) == 0)
continue;
if (fd == qmidevice_control_fd[1]) {
int triger_event;
if (read(fd, &triger_event, sizeof(triger_event)) == sizeof(triger_event)) {
//DBG("triger_event = 0x%x", triger_event);
switch (triger_event) {
case RIL_REQUEST_QUIT:
goto __GobiNetThread_quit;
break;
case SIG_EVENT_STOP:
wait_for_request_quit = 1;
break;
default:
break;
}
}
continue;
}
{
ssize_t nreads;
PQCQMIMSG pResponse = (PQCQMIMSG)cm_recv_buf;
nreads = read(fd, &pResponse->MUXMsg, sizeof(cm_recv_buf) - sizeof(QCQMI_HDR));
if (nreads <= 0)
{
dbg_time("%s read=%d errno: %d (%s)", __func__, (int)nreads, errno, strerror(errno));
break;
}
for (i = 0; i < sizeof(qmiclientId)/sizeof(qmiclientId[0]); i++)
{
if (qmiclientId[i] == fd)
{
pResponse->QMIHdr.QMIType = i;
}
}
pResponse->QMIHdr.IFType = USB_CTL_MSG_TYPE_QMI;
pResponse->QMIHdr.Length = cpu_to_le16(nreads + sizeof(QCQMI_HDR) - 1);
pResponse->QMIHdr.CtlFlags = 0x00;
pResponse->QMIHdr.ClientId = (fd&0xFF) ? fd&0xFF : pResponse->QMIHdr.QMIType;;
QmiThreadRecvQMI(pResponse);
}
}
}
__GobiNetThread_quit:
GobiNetDeInit();
qmidevice_send_event_to_main(RIL_INDICATE_DEVICE_DISCONNECTED);
QmiThreadRecvQMI(NULL); //main thread may pending on QmiThreadSendQMI()
dbg_time("%s exit", __func__);
pthread_exit(NULL);
return NULL;
}
const struct qmi_device_ops gobi_qmidev_ops = {
.deinit = GobiNetDeInit,
.send = GobiNetSendQMI,
.read = GobiNetThread,
};
#endif
-46
View File
@@ -1,46 +0,0 @@
ifneq ($(CROSS_COMPILE),)
CROSS-COMPILE:=$(CROSS_COMPILE)
endif
#CROSS-COMPILE:=/workspace/buildroot/buildroot-qemu_mips_malta_defconfig/output/host/usr/bin/mips-buildroot-linux-uclibc-
#CROSS-COMPILE:=/workspace/buildroot/buildroot-qemu_arm_vexpress_defconfig/output/host/usr/bin/arm-buildroot-linux-uclibcgnueabi-
#CROSS-COMPILE:=/workspace/buildroot-git/qemu_mips64_malta/output/host/usr/bin/mips-gnu-linux-
ifeq ($(CC),cc)
CC:=$(CROSS-COMPILE)gcc
endif
LD:=$(CROSS-COMPILE)ld
QL_CM_SRC=QmiWwanCM.c GobiNetCM.c main.c QCQMUX.c QMIThread.c util.c qmap_bridge_mode.c mbim-cm.c device.c
QL_CM_SRC+=atc.c atchannel.c at_tok.c
#QL_CM_SRC+=qrtr.c rmnetctl.c
ifeq (1,1)
QL_CM_DHCP=udhcpc.c
else
LIBMNL=libmnl/ifutils.c libmnl/attr.c libmnl/callback.c libmnl/nlmsg.c libmnl/socket.c
DHCP=libmnl/dhcp/dhcpclient.c libmnl/dhcp/dhcpmsg.c libmnl/dhcp/packet.c
QL_CM_DHCP=udhcpc_netlink.c
QL_CM_DHCP+=${LIBMNL}
endif
CFLAGS += -Wall -Wextra -Werror -O1 #-s
LDFLAGS += -lpthread -ldl -lrt
release: clean qmi-proxy mbim-proxy atc-proxy #qrtr-proxy
$(CC) ${CFLAGS} ${QL_CM_SRC} ${QL_CM_DHCP} -o quectel-CM ${LDFLAGS}
debug: clean
$(CC) ${CFLAGS} -g -DCM_DEBUG ${QL_CM_SRC} ${QL_CM_DHCP} -o quectel-CM -lpthread -ldl -lrt
qmi-proxy:
$(CC) ${CFLAGS} quectel-qmi-proxy.c -o quectel-qmi-proxy ${LDFLAGS}
mbim-proxy:
$(CC) ${CFLAGS} quectel-mbim-proxy.c -o quectel-mbim-proxy ${LDFLAGS}
qrtr-proxy:
$(CC) ${CFLAGS} quectel-qrtr-proxy.c -o quectel-qrtr-proxy ${LDFLAGS}
atc-proxy:
$(CC) ${CFLAGS} quectel-atc-proxy.c atchannel.c at_tok.c util.c -o quectel-atc-proxy ${LDFLAGS}
clean:
rm -rf *.o libmnl/*.o quectel-CM quectel-qmi-proxy quectel-mbim-proxy quectel-atc-proxy
-22
View File
@@ -1,22 +0,0 @@
bin_PROGRAMS = quectel-CM
QL_CM_SRC=QmiWwanCM.c GobiNetCM.c main.c QCQMUX.c QMIThread.c util.c qmap_bridge_mode.c mbim-cm.c device.c
QL_CM_SRC+=atc.c atchannel.c at_tok.c
#QL_CM_SRC+=qrtr.c rmnetctl.c
QL_CM_DHCP=udhcpc.c
if USE_QRTR
quectel_CM_CFLAGS = -DCONFIG_QRTR
QL_CM_SRC += qrtr.c rmnetctl.c
if USE_MSM_IPC
quectel_CM_CFLAGS += -DUSE_LINUX_MSM_IPC
endif
endif
quectel_CM_SOURCES = ${QL_CM_SRC} ${QL_CM_DHCP}
bin_PROGRAMS += quectel-qmi-proxy
quectel_qmi_proxy_SOURCES = quectel-qmi-proxy.c
bin_PROGRAMS += quectel-mbim-proxy
quectel_mbim_proxy_SOURCES = quectel-mbim-proxy.c
LIBS = -l pthread
CFLAGS = -Wall -Wextra -Werror -O1
-7
View File
@@ -1,7 +0,0 @@
This program is totally open souce code, and public domain software for customers of Quectel company.
The APIs of QMI WWAMN interfaces are defined by Qualcomm. And this program complies with Qualcomm QMI WWAN interfaces specification.
Customers are free to modify the source codes and redistribute them.
For those who is not Quectel's customer, all rights are closed, and any copying and commercial development over this progrma is not allowed.
Loaded 100 of 307 files, more files were not shown because too many files have changed in this diff. Show more