diff --git a/temp/libqmi/0001-data-qmi-service-ssc-add-SSC-service.patch b/temp/libqmi/0001-data-qmi-service-ssc-add-SSC-service.patch new file mode 100644 index 0000000000000000000000000000000000000000..626085cc5d5eaf83c3d28026a74c84d30e2c78b2 --- /dev/null +++ b/temp/libqmi/0001-data-qmi-service-ssc-add-SSC-service.patch @@ -0,0 +1,377 @@ +From 508dbb40b9cb2970759909c97b46698336f0ce37 Mon Sep 17 00:00:00 2001 +From: Dylan Van Assche <me@dylanvanassche.be> +Date: Wed, 21 Dec 2022 19:45:54 +0100 +Subject: [PATCH 1/7] data: qmi-service-ssc: add SSC service + +The SSC service is the Qualcomm Snapdragon Sensor Core (SSC) which is a +remoteproc exposing the sensor devices in the latest Qualcomm SoCs. +The SSC manages the power to the sensors, sample rates, etc. which +can be used over QMI. In contrast to other QMI services, the SSC uses +QMI only as a transport mechamism. The actual messages are Protobuf +messages encoded in the QMI messages and indications. +Therefore, only 1 QMI message is used and 2 QMI indications. +The SSC may emit QMI indications with a small data size or much bigger, +they are indentical besides the data size and ID. +--- + data/qmi-collection-basic.json | 6 +- + data/qmi-service-ssc.json | 87 +++++++++++++++++++ + .../libqmi-glib/libqmi-glib-common.sections | 6 ++ + .../libqmi-glib/libqmi-glib-docs.xml | 14 +++ + meson.build | 2 +- + src/libqmi-glib/generated/meson.build | 3 +- + src/libqmi-glib/libqmi-glib.h | 2 + + src/libqmi-glib/meson.build | 1 + + src/libqmi-glib/qmi-device.c | 6 ++ + src/libqmi-glib/qmi-enums-ssc.h | 40 +++++++++ + src/libqmi-glib/qmi-enums.h | 2 + + src/libqmi-glib/qmi-message.c | 6 ++ + src/qmicli/qmicli.c | 1 + + 13 files changed, 173 insertions(+), 3 deletions(-) + create mode 100644 data/qmi-service-ssc.json + create mode 100644 src/libqmi-glib/qmi-enums-ssc.h + +diff --git a/data/qmi-collection-basic.json b/data/qmi-collection-basic.json +index ba0e33e0..a16d1f16 100644 +--- a/data/qmi-collection-basic.json ++++ b/data/qmi-collection-basic.json +@@ -211,5 +211,9 @@ + + "QMI_MESSAGE_DSD_GET_SYSTEM_STATUS", + "QMI_MESSAGE_DSD_SYSTEM_STATUS_CHANGE", +- "QMI_INDICATION_DSD_SYSTEM_STATUS" ++ "QMI_INDICATION_DSD_SYSTEM_STATUS", ++ ++ "QMI_MESSAGE_SSC_MESSAGE", ++ "QMI_INDICATION_SSC_REPORT_SMALL", ++ "QMI_INDICATION_SSC_REPORT_LARGE" + ] +diff --git a/data/qmi-service-ssc.json b/data/qmi-service-ssc.json +new file mode 100644 +index 00000000..9ef4d9ad +--- /dev/null ++++ b/data/qmi-service-ssc.json +@@ -0,0 +1,87 @@ ++[ ++ // ********************************************************************************* ++ { "name" : "SSC", ++ "type" : "Service" }, ++ ++ // ********************************************************************************* ++ { "name" : "QMI Client SSC", ++ "type" : "Client", ++ "since" : "1.34" }, ++ ++ // ********************************************************************************* ++ { "name" : "QMI Message SSC", ++ "type" : "Message-ID-Enum" }, ++ ++ // ********************************************************************************* ++ { "name" : "QMI Indication SSC", ++ "type" : "Indication-ID-Enum" }, ++ ++ // ********************************************************************************* ++ { "name" : "Control", ++ "type" : "Message", ++ "service" : "SSC", ++ "id" : "0x0020", ++ "since" : "1.34", ++ "input" : [ { "name" : "Protobuf Data", ++ "id" : "0x01", ++ "type" : "TLV", ++ "since" : "1.34", ++ "format" : "array", ++ "size-prefix-format" : "guint16", ++ "array-element" : { "format" : "guint8" } ++ }, ++ { "name" : "Unknown Value", ++ "id" : "0x10", ++ "type" : "TLV", ++ "since" : "1.34", ++ "format" : "guint8" } ], ++ "output" : [ { "common-ref" : "Operation Result" }, ++ { "name" : "Client ID", ++ "id" : "0x10", ++ "type" : "TLV", ++ "since" : "1.34", ++ "format" : "guint64", ++ "prerequisites": [ { "common-ref" : "Success" } ] }, ++ { "name" : "Response", ++ "id" : "0x11", ++ "type" : "TLV", ++ "since" : "1.34", ++ "format" : "guint32", ++ "prerequisites": [ { "common-ref" : "Success" } ] } ] }, ++ // ********************************************************************************* ++ { "name" : "Report Small", ++ "type" : "Indication", ++ "service" : "SSC", ++ "id" : "0x0021", ++ "since" : "1.34", ++ "output" : [ { "name" : "Client ID", ++ "id" : "0x01", ++ "type" : "TLV", ++ "since" : "1.34", ++ "format" : "guint64" }, ++ { "name" : "Protobuf Data", ++ "id" : "0x02", ++ "type" : "TLV", ++ "since" : "1.34", ++ "format" : "array", ++ "size-prefix-format" : "guint16", ++ "array-element" : { "format" : "guint8" } } ] }, ++ // ********************************************************************************* ++ { "name" : "Report Large", ++ "type" : "Indication", ++ "service" : "SSC", ++ "id" : "0x0022", ++ "since" : "1.34", ++ "output" : [ { "name" : "Client ID", ++ "id" : "0x01", ++ "type" : "TLV", ++ "since" : "1.34", ++ "format" : "guint64" }, ++ { "name" : "Protobuf Data", ++ "id" : "0x02", ++ "type" : "TLV", ++ "since" : "1.34", ++ "format" : "array", ++ "size-prefix-format" : "guint16", ++ "array-element" : { "format" : "guint8" } } ] } ++] +diff --git a/docs/reference/libqmi-glib/libqmi-glib-common.sections b/docs/reference/libqmi-glib/libqmi-glib-common.sections +index c812dcf6..f9cc6a67 100644 +--- a/docs/reference/libqmi-glib/libqmi-glib-common.sections ++++ b/docs/reference/libqmi-glib/libqmi-glib-common.sections +@@ -30,6 +30,7 @@ HAVE_QMI_SERVICE_WDS + HAVE_QMI_SERVICE_WMS + HAVE_QMI_SERVICE_DPM + HAVE_QMI_SERVICE_FOX ++HAVE_QMI_SERVICE_SSC + </SECTION> + + <SECTION> +@@ -1602,6 +1603,11 @@ QMI_TYPE_FOX_FIRMWARE_VERSION_TYPE + qmi_fox_firmware_version_type_get_type + </SECTION> + ++<SECTION> ++<FILE>qmi-enums-ssc</FILE> ++<TITLE>SSC enumerations and flags</TITLE> ++</SECTION> ++ + <SECTION> + <FILE>qmi-errors</FILE> + <TITLE>Errors</TITLE> +diff --git a/docs/reference/libqmi-glib/libqmi-glib-docs.xml b/docs/reference/libqmi-glib/libqmi-glib-docs.xml +index f20b2049..604f5213 100644 +--- a/docs/reference/libqmi-glib/libqmi-glib-docs.xml ++++ b/docs/reference/libqmi-glib/libqmi-glib-docs.xml +@@ -573,6 +573,20 @@ + </section> + </chapter> + ++ <chapter> ++ <title>Snapdragon Sensor Core Service (SSC)</title> ++ <xi:include href="xml/qmi-client-ssc.xml"/> ++ <section> ++ <title>SSC Indications</title> ++ <xi:include href="xml/qmi-indication-ssc-report-small.xml"/> ++ <xi:include href="xml/qmi-indication-ssc-report-large.xml"/> ++ </section> ++ <section> ++ <title>SSC Requests</title> ++ <xi:include href="xml/qmi-message-ssc-control.xml"/> ++ </section> ++ </chapter> ++ + <chapter> + <title>Compatibility with older versions</title> + <xi:include href="xml/qmi-compat.xml"/> +diff --git a/meson.build b/meson.build +index 8711e0a0..898a2475 100644 +--- a/meson.build ++++ b/meson.build +@@ -3,7 +3,7 @@ + + project( + 'libqmi', 'c', +- version: '1.33.5', ++ version: '1.33.6', + license: 'GPL2', + default_options: [ + 'buildtype=debugoptimized', +diff --git a/src/libqmi-glib/generated/meson.build b/src/libqmi-glib/generated/meson.build +index a41acc0e..6fe8e10b 100644 +--- a/src/libqmi-glib/generated/meson.build ++++ b/src/libqmi-glib/generated/meson.build +@@ -67,7 +67,7 @@ gen_headers += custom_target( + command: [ + python, + qmi_mkenums, +- '--fhead', '#ifndef __LIBQMI_GLIB_ENUM_TYPES_H__\n#define __LIBQMI_GLIB_ENUM_TYPES_H__\n#include "qmi-enums.h"\n#include "qmi-enums-wds.h"\n#include "qmi-enums-dms.h"\n#include "qmi-enums-nas.h"\n#include "qmi-enums-wms.h"\n#include "qmi-enums-pds.h"\n#include "qmi-enums-pdc.h"\n#include "qmi-enums-pbm.h"\n#include "qmi-enums-uim.h"\n#include "qmi-enums-sar.h"\n#include "qmi-enums-oma.h"\n#include "qmi-enums-wda.h"\n#include "qmi-enums-voice.h"\n#include "qmi-enums-loc.h"\n#include "qmi-enums-qos.h"\n#include "qmi-enums-gas.h"\n#include "qmi-enums-dsd.h"\n#include "qmi-enums-fox.h"\n#include "qmi-device.h"\n', ++ '--fhead', '#ifndef __LIBQMI_GLIB_ENUM_TYPES_H__\n#define __LIBQMI_GLIB_ENUM_TYPES_H__\n#include "qmi-enums.h"\n#include "qmi-enums-wds.h"\n#include "qmi-enums-dms.h"\n#include "qmi-enums-nas.h"\n#include "qmi-enums-wms.h"\n#include "qmi-enums-pds.h"\n#include "qmi-enums-pdc.h"\n#include "qmi-enums-pbm.h"\n#include "qmi-enums-uim.h"\n#include "qmi-enums-sar.h"\n#include "qmi-enums-oma.h"\n#include "qmi-enums-wda.h"\n#include "qmi-enums-voice.h"\n#include "qmi-enums-loc.h"\n#include "qmi-enums-qos.h"\n#include "qmi-enums-gas.h"\n#include "qmi-enums-dsd.h"\n#include "qmi-enums-fox.h"\n#include "qmi-enums-ssc.h"\n#include "qmi-device.h"\n', + '--template', files(templates_dir / enum_types + '.h.template'), + '--ftail', '#endif /* __LIBQMI_GLIB_ENUM_TYPES_H__ */\n', + '@INPUT@'], +@@ -180,6 +180,7 @@ services = [ + 'pds', + 'qos', + 'sar', ++ 'ssc', + 'uim', + 'voice', + 'wda', +diff --git a/src/libqmi-glib/libqmi-glib.h b/src/libqmi-glib/libqmi-glib.h +index 867429f7..5f88684d 100644 +--- a/src/libqmi-glib/libqmi-glib.h ++++ b/src/libqmi-glib/libqmi-glib.h +@@ -99,6 +99,8 @@ + #include "qmi-enums-fox.h" + #include "qmi-fox.h" + ++#include "qmi-ssc.h" ++ + /* generated */ + #include "qmi-error-types.h" + #include "qmi-enum-types.h" +diff --git a/src/libqmi-glib/meson.build b/src/libqmi-glib/meson.build +index 84c8e636..39e5454b 100644 +--- a/src/libqmi-glib/meson.build ++++ b/src/libqmi-glib/meson.build +@@ -20,6 +20,7 @@ qmi_enums_headers = files( + 'qmi-enums-pds.h', + 'qmi-enums-qos.h', + 'qmi-enums-sar.h', ++ 'qmi-enums-ssc.h', + 'qmi-enums-uim.h', + 'qmi-enums-voice.h', + 'qmi-enums-wda.h', +diff --git a/src/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c +index 01e7ba13..f119d5fe 100644 +--- a/src/libqmi-glib/qmi-device.c ++++ b/src/libqmi-glib/qmi-device.c +@@ -57,6 +57,7 @@ + #include "qmi-dsd.h" + #include "qmi-dpm.h" + #include "qmi-fox.h" ++#include "qmi-ssc.h" + #include "qmi-utils.h" + #include "qmi-helpers.h" + #include "qmi-error-types.h" +@@ -1310,6 +1311,11 @@ qmi_device_allocate_client (QmiDevice *self, + case QMI_SERVICE_FOX: + #if defined HAVE_QMI_SERVICE_FOX + ctx->client_type = QMI_TYPE_CLIENT_FOX; ++#endif ++ break; ++ case QMI_SERVICE_SSC: ++#if defined HAVE_QMI_SERVICE_SSC ++ ctx->client_type = QMI_TYPE_CLIENT_SSC; + #endif + break; + +diff --git a/src/libqmi-glib/qmi-enums-ssc.h b/src/libqmi-glib/qmi-enums-ssc.h +new file mode 100644 +index 00000000..7b3b619c +--- /dev/null ++++ b/src/libqmi-glib/qmi-enums-ssc.h +@@ -0,0 +1,40 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ ++/* ++ * libqmi-glib -- GLib/GIO based library to control QMI devices ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the ++ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ++ * Boston, MA 02110-1301 USA. ++ * ++ * Copyright (C) 2022 Dylan Van Assche <me@dylanvanassche.be> ++ */ ++ ++#ifndef _LIBQMI_GLIB_QMI_ENUMS_SSC_H_ ++#define _LIBQMI_GLIB_QMI_ENUMS_SSC_H_ ++ ++#if !defined (__LIBQMI_GLIB_H_INSIDE__) && !defined (LIBQMI_GLIB_COMPILATION) ++#error "Only <libqmi-glib.h> can be included directly." ++#endif ++ ++/** ++ * SECTION: qmi-enums-ssc ++ * @title: SSC enumerations and flags ++ * @short_description: Enumerations and flags in the SSC service. ++ * ++ * This section defines enumerations and flags used in the SSC service ++ * interface. ++ */ ++ ++#endif /* _LIBQMI_GLIB_QMI_ENUMS_SSC_H_ */ ++ +diff --git a/src/libqmi-glib/qmi-enums.h b/src/libqmi-glib/qmi-enums.h +index b50841c2..4f77097c 100644 +--- a/src/libqmi-glib/qmi-enums.h ++++ b/src/libqmi-glib/qmi-enums.h +@@ -86,6 +86,7 @@ + * @QMI_SERVICE_RMS: Remote Management Service. + * @QMI_SERVICE_OMA: Open Mobile Alliance device management service. + * @QMI_SERVICE_FOX: Foxconn General Modem Service. Since: 1.32. ++ * @QMI_SERVICE_SSC: Snapdragon Sensore Core Service. Since: 1.34. + * @QMI_SERVICE_FOTA: Firmware Over The Air service. Since: 1.24. + * @QMI_SERVICE_GMS: Telit General Modem Service. Since: 1.24. + * @QMI_SERVICE_GAS: Telit General Application Service. Since: 1.24. +@@ -148,6 +149,7 @@ typedef enum { /*< since=1.0 >*/ + QMI_SERVICE_FOTA = 0xE6, + QMI_SERVICE_GMS = 0xE7, + QMI_SERVICE_GAS = 0xE8, ++ QMI_SERVICE_SSC = 0x190, + } QmiService; + + /** +diff --git a/src/libqmi-glib/qmi-message.c b/src/libqmi-glib/qmi-message.c +index a51b77e1..dff0be39 100644 +--- a/src/libqmi-glib/qmi-message.c ++++ b/src/libqmi-glib/qmi-message.c +@@ -1728,6 +1728,11 @@ qmi_message_get_printable_full (QmiMessage *self, + case QMI_SERVICE_FOX: + #if defined HAVE_QMI_SERVICE_FOX + contents = __qmi_message_fox_get_printable (self, context, line_prefix); ++#endif ++ break; ++ case QMI_SERVICE_SSC: ++#if defined HAVE_QMI_SERVICE_SSC ++ contents = __qmi_message_ssc_get_printable (self, context, line_prefix); + #endif + break; + +@@ -1846,6 +1851,7 @@ __qmi_message_is_abortable (QmiMessage *self, + case QMI_SERVICE_DSD: + case QMI_SERVICE_QOS: + case QMI_SERVICE_FOX: ++ case QMI_SERVICE_SSC: + default: + return FALSE; + } +diff --git a/src/qmicli/qmicli.c b/src/qmicli/qmicli.c +index a37eaab6..d2834450 100644 +--- a/src/qmicli/qmicli.c ++++ b/src/qmicli/qmicli.c +@@ -510,6 +510,7 @@ allocate_client_ready (QmiDevice *dev, + case QMI_SERVICE_FOTA: + case QMI_SERVICE_PDS: + case QMI_SERVICE_OMA: ++ case QMI_SERVICE_SSC: + default: + break; + } +-- +2.39.2 + diff --git a/temp/libqmi/0002-libqmi-glib-message-handle-QMUX-and-QRTR-messages.patch b/temp/libqmi/0002-libqmi-glib-message-handle-QMUX-and-QRTR-messages.patch new file mode 100644 index 0000000000000000000000000000000000000000..74cf3e3fe0c75560c6c23d7a54769b1c6298ef9c --- /dev/null +++ b/temp/libqmi/0002-libqmi-glib-message-handle-QMUX-and-QRTR-messages.patch @@ -0,0 +1,369 @@ +From 34e99dad0623d7ad4fc14b36dd77fb345da5d5f5 Mon Sep 17 00:00:00 2001 +From: Dylan Van Assche <me@dylanvanassche.be> +Date: Tue, 28 Mar 2023 20:19:58 +0200 +Subject: [PATCH 2/7] libqmi-glib,message: handle QMUX and QRTR messages + +Handle QMUX and QRTR messages in QMI Message: + +- Set a different marker for services > G_MAXUINT8 +- Handle different markers in helper methods +- Print QMI Messages differently depending on marker +--- + src/libqmi-glib/qmi-message.c | 157 +++++++++++++++++++++++++--------- + src/libqmi-glib/qmi-message.h | 23 ++++- + 2 files changed, 139 insertions(+), 41 deletions(-) + +diff --git a/src/libqmi-glib/qmi-message.c b/src/libqmi-glib/qmi-message.c +index dff0be39..812c8b92 100644 +--- a/src/libqmi-glib/qmi-message.c ++++ b/src/libqmi-glib/qmi-message.c +@@ -64,13 +64,19 @@ + + #define PACKED __attribute__((packed)) + +-struct qmux { ++struct qmux_header { + guint16 length; + guint8 flags; + guint8 service; + guint8 client; + } PACKED; + ++struct qrtr_header { ++ guint16 length; ++ guint16 service; ++ guint8 client; ++} PACKED; ++ + struct control_header { + guint8 flags; + guint8 transaction; +@@ -103,7 +109,10 @@ struct service_message { + + struct full_message { + guint8 marker; +- struct qmux qmux; ++ union { ++ struct qmux_header qmux; ++ struct qrtr_header qrtr; ++ } header; + union { + struct control_message control; + struct service_message service; +@@ -113,26 +122,39 @@ struct full_message { + static inline gboolean + message_is_control (QmiMessage *self) + { +- return ((struct full_message *)(self->data))->qmux.service == QMI_SERVICE_CTL; ++ if (((struct full_message *)(self->data))->marker == QMI_MESSAGE_QMUX_MARKER) ++ return ((struct full_message *)(self->data))->header.qmux.service == QMI_SERVICE_CTL; ++ ++ return ((struct full_message *)(self->data))->header.qrtr.service == QMI_SERVICE_CTL; + } + + static inline guint16 + get_qmux_length (QmiMessage *self) + { +- return GUINT16_FROM_LE (((struct full_message *)(self->data))->qmux.length); ++ if (((struct full_message *)(self->data))->marker == QMI_MESSAGE_QMUX_MARKER) ++ return GUINT16_FROM_LE (((struct full_message *)(self->data))->header.qmux.length); ++ ++ return GUINT16_FROM_LE (((struct full_message *)(self->data))->header.qrtr.length); + } + + static inline void + set_qmux_length (QmiMessage *self, + guint16 length) + { +- ((struct full_message *)(self->data))->qmux.length = GUINT16_TO_LE (length); ++ if (((struct full_message *)(self->data))->marker == QMI_MESSAGE_QMUX_MARKER) ++ ((struct full_message *)(self->data))->header.qmux.length = GUINT16_TO_LE (length); ++ else ++ ((struct full_message *)(self->data))->header.qrtr.length = GUINT16_TO_LE (length); + } + + static inline guint8 + get_qmux_flags (QmiMessage *self) + { +- return ((struct full_message *)(self->data))->qmux.flags; ++ if (((struct full_message *)(self->data))->marker == QMI_MESSAGE_QMUX_MARKER) ++ return ((struct full_message *)(self->data))->header.qmux.flags; ++ ++ /* QMI_MESSAGE_QRTR_MARKER does not support flags */ ++ return 0x00; + } + + static inline guint8 +@@ -183,7 +205,10 @@ qmi_message_get_service (QmiMessage *self) + { + g_return_val_if_fail (self != NULL, QMI_SERVICE_UNKNOWN); + +- return (QmiService)((struct full_message *)(self->data))->qmux.service; ++ if (((struct full_message *)(self->data))->marker == QMI_MESSAGE_QMUX_MARKER) ++ return (QmiService)((struct full_message *)(self->data))->header.qmux.service; ++ else ++ return (QmiService)((struct full_message *)(self->data))->header.qrtr.service; + } + + guint8 +@@ -191,7 +216,10 @@ qmi_message_get_client_id (QmiMessage *self) + { + g_return_val_if_fail (self != NULL, 0); + +- return ((struct full_message *)(self->data))->qmux.client; ++ if (((struct full_message *)(self->data))->marker == QMI_MESSAGE_QMUX_MARKER) ++ return ((struct full_message *)(self->data))->header.qmux.client; ++ ++ return ((struct full_message *)(self->data))->header.qrtr.client; + } + + guint16 +@@ -319,16 +347,17 @@ message_check (QmiMessage *self, + guint8 *end; + struct tlv *tlv; + +- if (self->len < (1 + sizeof (struct qmux))) { ++ if (self->len < (1 + sizeof (struct qmux_header))) { + g_set_error (error, + QMI_CORE_ERROR, + QMI_CORE_ERROR_INVALID_MESSAGE, + "QMUX length too short for QMUX header (%u < %" G_GSIZE_FORMAT ")", +- self->len, 1 + sizeof (struct qmux)); ++ self->len, 1 + sizeof (struct qmux_header)); + return FALSE; + } + +- if (((struct full_message *)(self->data))->marker != QMI_MESSAGE_QMUX_MARKER) { ++ if (((struct full_message *)(self->data))->marker != QMI_MESSAGE_QMUX_MARKER && ++ ((struct full_message *)(self->data))->marker != QMI_MESSAGE_QRTR_MARKER) { + g_set_error (error, + QMI_CORE_ERROR, + QMI_CORE_ERROR_INVALID_MESSAGE, +@@ -352,9 +381,9 @@ message_check (QmiMessage *self, + return FALSE; + } + +- header_length = sizeof (struct qmux) + (message_is_control (self) ? +- sizeof (struct control_header) : +- sizeof (struct service_header)); ++ header_length = sizeof (struct qmux_header) + (message_is_control (self) ? ++ sizeof (struct control_header) : ++ sizeof (struct service_header)); + + if (qmux_length < header_length) { + g_set_error (error, +@@ -418,9 +447,10 @@ qmi_message_new (QmiService service, + NULL); + + /* Create array with enough size for the QMUX marker, the QMUX header and +- * the QMI header */ ++ * the QMI header. Use the qmux_header size for both QMUX and QRTR messages ++ * as they are the same size. */ + buffer_len = (1 + +- sizeof (struct qmux) + ++ sizeof (struct qmux_header) + + (service == QMI_SERVICE_CTL ? sizeof (struct control_header) : sizeof (struct service_header))); + + /* NOTE: +@@ -435,10 +465,17 @@ qmi_message_new (QmiService service, + g_byte_array_set_size (self, buffer_len); + + buffer = (struct full_message *)(self->data); +- buffer->marker = QMI_MESSAGE_QMUX_MARKER; +- buffer->qmux.flags = 0; +- buffer->qmux.service = service; +- buffer->qmux.client = client_id; ++ /* QMI messages of services up to 255 are QMUX compatible */ ++ if (service <= G_MAXUINT8) { ++ buffer->marker = QMI_MESSAGE_QMUX_MARKER; ++ buffer->header.qmux.flags = 0; ++ buffer->header.qmux.service = service; ++ buffer->header.qmux.client = client_id; ++ } else { ++ buffer->marker = QMI_MESSAGE_QRTR_MARKER; ++ buffer->header.qrtr.service = service; ++ buffer->header.qrtr.client = client_id; ++ } + + if (service == QMI_SERVICE_CTL) { + buffer->qmi.control.header.flags = 0; +@@ -480,18 +517,28 @@ qmi_message_new_from_data (QmiService service, + message_len = sizeof (struct service_header) + + ((struct service_message *)(qmi_data->data))->header.tlv_length; + } +- buffer_len = (1 + sizeof (struct qmux) + message_len); ++ ++ /* Use the size of qmux_header for both QMUX and QRTR as they are the same */ ++ buffer_len = (1 + sizeof (struct qmux_header) + message_len); ++ + /* Create the GByteArray with buffer_len bytes preallocated */ + self = g_byte_array_sized_new (buffer_len); + g_byte_array_set_size (self, buffer_len); + + /* Set up fake QMUX header */ + buffer = (struct full_message *)(self->data); +- buffer->marker = QMI_MESSAGE_QMUX_MARKER; +- buffer->qmux.length = GUINT16_TO_LE (buffer_len - 1); +- buffer->qmux.flags = 0; +- buffer->qmux.service = service; +- buffer->qmux.client = client_id; ++ if (service <= G_MAXUINT8) { ++ buffer->marker = QMI_MESSAGE_QMUX_MARKER; ++ buffer->header.qmux.length = GUINT16_TO_LE (buffer_len - 1); ++ buffer->header.qmux.flags = 0; ++ buffer->header.qmux.service = service; ++ buffer->header.qmux.client = client_id; ++ } else { ++ buffer->marker = QMI_MESSAGE_QRTR_MARKER; ++ buffer->header.qrtr.length = GUINT16_TO_LE (buffer_len - 1); ++ buffer->header.qrtr.service = service; ++ buffer->header.qrtr.client = client_id; ++ } + + /* Move bytes from the qmi_data array to the newly created message */ + memcpy (&buffer->qmi, qmi_data->data, message_len); +@@ -520,7 +567,8 @@ qmi_message_response_new (QmiMessage *request, + qmi_message_get_message_id (request)); + + /* Set sender type flag */ +- ((struct full_message *)(((GByteArray *)response)->data))->qmux.flags = 0x80; ++ if (qmi_message_get_service (request) <= G_MAXUINT8) ++ ((struct full_message *)(((GByteArray *)response)->data))->header.qmux.flags = 0x80; + + /* Set the response flag */ + if (message_is_control (request)) +@@ -556,6 +604,15 @@ qmi_message_unref (QmiMessage *self) + g_byte_array_unref (self); + } + ++guint8 ++qmi_message_get_marker (QmiMessage *self) ++{ ++ if (self == NULL) ++ return 0x00; ++ ++ return ((struct full_message *)(self->data))->marker; ++} ++ + const guint8 * + qmi_message_get_raw (QmiMessage *self, + gsize *length, +@@ -1503,18 +1560,26 @@ qmi_message_new_from_raw (GByteArray *raw, + GError **error) + { + GByteArray *self; ++ gsize header_len; + gsize message_len; + + g_return_val_if_fail (raw != NULL, NULL); + ++ if (((struct full_message *)raw->data)->marker == QMI_MESSAGE_QMUX_MARKER) { ++ header_len = sizeof (struct qmux_header); ++ message_len = GUINT16_FROM_LE (((struct full_message *)raw->data)->header.qmux.length); ++ } else { ++ header_len = sizeof (struct qrtr_header); ++ message_len = GUINT16_FROM_LE (((struct full_message *)raw->data)->header.qrtr.length); ++ } ++ + /* If we didn't even read the QMUX header (comes after the 1-byte marker), + * leave */ +- if (raw->len < (sizeof (struct qmux) + 1)) ++ if (raw->len < (header_len + 1)) + return NULL; + + /* We need to have read the length reported by the QMUX header (plus the + * initial 1-byte marker) */ +- message_len = GUINT16_FROM_LE (((struct full_message *)raw->data)->qmux.length); + if (raw->len < (message_len + 1)) + return NULL; + +@@ -1605,17 +1670,29 @@ qmi_message_get_printable_full (QmiMessage *self, + line_prefix = ""; + + printable = g_string_new (""); +- g_string_append_printf (printable, +- "%sQMUX:\n" +- "%s length = %u\n" +- "%s flags = 0x%02x\n" +- "%s service = \"%s\"\n" +- "%s client = %u\n", +- line_prefix, +- line_prefix, get_qmux_length (self), +- line_prefix, get_qmux_flags (self), +- line_prefix, qmi_service_get_string (qmi_message_get_service (self)), +- line_prefix, qmi_message_get_client_id (self)); ++ if (qmi_message_get_marker(self) == QMI_MESSAGE_QMUX_MARKER) { ++ g_string_append_printf (printable, ++ "%sQMUX:\n" ++ "%s length = %u\n" ++ "%s flags = 0x%02x\n" ++ "%s service = \"%s\"\n" ++ "%s client = %u\n", ++ line_prefix, ++ line_prefix, get_qmux_length (self), ++ line_prefix, get_qmux_flags (self), ++ line_prefix, qmi_service_get_string (qmi_message_get_service (self)), ++ line_prefix, qmi_message_get_client_id (self)); ++ } else { ++ g_string_append_printf (printable, ++ "%sQRTR:\n" ++ "%s length = %u\n" ++ "%s service = \"%s\"\n" ++ "%s client = %u\n", ++ line_prefix, ++ line_prefix, get_qmux_length (self), ++ line_prefix, qmi_service_get_string (qmi_message_get_service (self)), ++ line_prefix, qmi_message_get_client_id (self)); ++ } + + if (qmi_message_get_service (self) == QMI_SERVICE_CTL) + qmi_flags_str = qmi_ctl_flag_build_string_from_mask (get_qmi_flags (self)); +diff --git a/src/libqmi-glib/qmi-message.h b/src/libqmi-glib/qmi-message.h +index 7cf6ee74..cf2b0e54 100644 +--- a/src/libqmi-glib/qmi-message.h ++++ b/src/libqmi-glib/qmi-message.h +@@ -57,12 +57,21 @@ G_BEGIN_DECLS + /** + * QMI_MESSAGE_QMUX_MARKER: + * +- * First byte of every QMI message. ++ * First byte of every QMI QMUX message. + * + * Since: 1.0 + */ + #define QMI_MESSAGE_QMUX_MARKER (guint8) 0x01 + ++/** ++ * QMI_MESSAGE_QRTR_MARKER: ++ * ++ * First byte of every QRTR QMI message. ++ * ++ * Since: 1.34 ++ */ ++#define QMI_MESSAGE_QRTR_MARKER (guint8) 0x02 ++ + /** + * QmiMessage: + * +@@ -304,6 +313,18 @@ const guint8 *qmi_message_get_data (QmiMessage *self, + gsize *length, + GError **error); + ++/** ++ * qmi_message_get_marker: ++ * @self: a #QmiMessage. ++ * ++ * Gets the marker of the #QmiMessage. ++ * ++ * Returns: The message marker, or 0x00 if message is NULL. ++ * ++ * Since: 1.34 ++ */ ++guint8 qmi_message_get_marker (QmiMessage *self); ++ + /*****************************************************************************/ + /* TLV builder & writer */ + +-- +2.39.2 + diff --git a/temp/libqmi/0003-libqmi-glib-proxy-handle-QMUX-and-QRTR-messages.patch b/temp/libqmi/0003-libqmi-glib-proxy-handle-QMUX-and-QRTR-messages.patch new file mode 100644 index 0000000000000000000000000000000000000000..5a262222ba0d3da9e41899d9e952b417691ff1af --- /dev/null +++ b/temp/libqmi/0003-libqmi-glib-proxy-handle-QMUX-and-QRTR-messages.patch @@ -0,0 +1,83 @@ +From 929894825c0caa1876e73bd30190e093af2a5022 Mon Sep 17 00:00:00 2001 +From: Dylan Van Assche <me@dylanvanassche.be> +Date: Wed, 29 Mar 2023 16:43:12 +0200 +Subject: [PATCH 3/7] libqmi-glib,proxy: handle QMUX and QRTR messages + +Handle QMUX and QRTR messages in QMI Message: + +- Use QmiService enum instead of guint8 +- Handle service ID extraction from QMI message based on marker +- Allow messages with QMUX and QRTR marker +--- + src/libqmi-glib/qmi-proxy.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/src/libqmi-glib/qmi-proxy.c b/src/libqmi-glib/qmi-proxy.c +index eeff4bf0..8fc49071 100644 +--- a/src/libqmi-glib/qmi-proxy.c ++++ b/src/libqmi-glib/qmi-proxy.c +@@ -596,7 +596,7 @@ track_cid (Client *client, + guint16 error_status; + guint16 error_code; + GError *error = NULL; +- guint8 service_tmp; ++ QmiService service_tmp; + QmiClientInfo info; + gint i; + +@@ -616,13 +616,14 @@ track_cid (Client *client, + + offset = 0; + if (((init_offset = qmi_message_tlv_read_init (message, QMI_MESSAGE_OUTPUT_TLV_ALLOCATION_INFO, NULL, &error)) == 0) || +- !qmi_message_tlv_read_guint8 (message, init_offset, &offset, &service_tmp, &error) || ++ (qmi_message_get_marker (message) == QMI_MESSAGE_QMUX_MARKER && !qmi_message_tlv_read_guint8 (message, init_offset, &offset, (guint8 *) &service_tmp, &error)) || ++ (qmi_message_get_marker (message) == QMI_MESSAGE_QRTR_MARKER && !qmi_message_tlv_read_guint16 (message, init_offset, &offset, QMI_ENDIAN_LITTLE, (guint16 *) &service_tmp, &error)) || + !qmi_message_tlv_read_guint8 (message, init_offset, &offset, &(info.cid), &error)) { + g_warning ("invalid 'CTL allocate CID' response: missing or invalid allocation info TLV: %s", error->message); + g_error_free (error); + return; + } +- info.service = (QmiService)service_tmp; ++ info.service = service_tmp; + + /* Check if it already exists */ + i = qmi_client_info_array_lookup_cid (client->qmi_client_info_array, info.service, info.cid); +@@ -643,7 +644,7 @@ untrack_cid (QmiProxy *self, + gsize offset = 0; + gsize init_offset; + GError *error = NULL; +- guint8 service_tmp; ++ QmiService service_tmp; + QmiClientInfo info; + gint i; + +@@ -651,13 +652,14 @@ untrack_cid (QmiProxy *self, + g_assert (qmi_message_is_request (message)); + + if (((init_offset = qmi_message_tlv_read_init (message, QMI_MESSAGE_INPUT_TLV_RELEASE_INFO, NULL, &error)) == 0) || +- !qmi_message_tlv_read_guint8 (message, init_offset, &offset, &service_tmp, &error) || ++ (qmi_message_get_marker (message) == QMI_MESSAGE_QMUX_MARKER && !qmi_message_tlv_read_guint8 (message, init_offset, &offset, (guint8 *) &service_tmp, &error)) || ++ (qmi_message_get_marker (message) == QMI_MESSAGE_QRTR_MARKER && !qmi_message_tlv_read_guint16 (message, init_offset, &offset, QMI_ENDIAN_LITTLE, (guint16 *) &service_tmp, &error)) || + !qmi_message_tlv_read_guint8 (message, init_offset, &offset, &(info.cid), &error)) { + g_warning ("invalid 'CTL release CID' request: missing or invalid release info TLV: %s", error->message); + g_error_free (error); + return; + } +- info.service = (QmiService)service_tmp; ++ info.service = service_tmp; + + /* Check if it already exists in the client */ + i = qmi_client_info_array_lookup_cid (client->qmi_client_info_array, info.service, info.cid); +@@ -918,7 +920,8 @@ parse_request (QmiProxy *self, + * If we broke framing, an error should be reported and the device + * should get closed */ + if (client->buffer->len > 0 && +- client->buffer->data[0] != QMI_MESSAGE_QMUX_MARKER) { ++ client->buffer->data[0] != QMI_MESSAGE_QMUX_MARKER && ++ client->buffer->data[0] != QMI_MESSAGE_QRTR_MARKER) { + /* TODO: Report fatal error */ + g_warning ("QMI framing error detected"); + return; +-- +2.39.2 + diff --git a/temp/libqmi/0004-libqmi-glib-endpoint-handle-QMUX-and-QRTR-messages.patch b/temp/libqmi/0004-libqmi-glib-endpoint-handle-QMUX-and-QRTR-messages.patch new file mode 100644 index 0000000000000000000000000000000000000000..b7d2759eba32d2337d9bcc4816cd144c938fb68a --- /dev/null +++ b/temp/libqmi/0004-libqmi-glib-endpoint-handle-QMUX-and-QRTR-messages.patch @@ -0,0 +1,29 @@ +From 141f9627bb1ba36dcfba166d8823daa541416432 Mon Sep 17 00:00:00 2001 +From: Dylan Van Assche <me@dylanvanassche.be> +Date: Thu, 30 Mar 2023 19:55:02 +0200 +Subject: [PATCH 4/7] libqmi-glib,endpoint: handle QMUX and QRTR messages + +Handle QMUX and QRTR messages in QMI Message: + +- Allow QMI messages with both QMUX and QRTR markers +--- + src/libqmi-glib/qmi-endpoint.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/libqmi-glib/qmi-endpoint.c b/src/libqmi-glib/qmi-endpoint.c +index 4743e253..97503b29 100644 +--- a/src/libqmi-glib/qmi-endpoint.c ++++ b/src/libqmi-glib/qmi-endpoint.c +@@ -67,7 +67,8 @@ qmi_endpoint_parse_buffer (QmiEndpoint *self, + * If we broke framing, an error should be reported and the device + * should get closed */ + if (self->priv->buffer->len > 0 && +- self->priv->buffer->data[0] != QMI_MESSAGE_QMUX_MARKER) { ++ self->priv->buffer->data[0] != QMI_MESSAGE_QMUX_MARKER && ++ self->priv->buffer->data[0] != QMI_MESSAGE_QRTR_MARKER) { + g_set_error (error, + QMI_PROTOCOL_ERROR, + QMI_PROTOCOL_ERROR_MALFORMED_MESSAGE, +-- +2.39.2 + diff --git a/temp/libqmi/0005-libqmi-glib-device-handle-QMUX-and-QRTR-messages.patch b/temp/libqmi/0005-libqmi-glib-device-handle-QMUX-and-QRTR-messages.patch new file mode 100644 index 0000000000000000000000000000000000000000..50a5ab7aa26aa3f5d2207b6a93d7cfe3a1f169a2 --- /dev/null +++ b/temp/libqmi/0005-libqmi-glib-device-handle-QMUX-and-QRTR-messages.patch @@ -0,0 +1,298 @@ +From 4284ca2fb0ac4e73f05e659739c6b24aed2a3405 Mon Sep 17 00:00:00 2001 +From: Dylan Van Assche <me@dylanvanassche.be> +Date: Thu, 30 Mar 2023 20:38:43 +0200 +Subject: [PATCH 5/7] libqmi-glib,device: handle QMUX and QRTR messages + +Handle QMUX and QRTR messages in QMI Message: + +- Add internal calls for CTL service which is handled by QRTR endpoint +- Adjust QMI Device to send internal CTL service messages when services + are out of reach of QMUX compatible endpoints. +--- + data/qmi-service-ctl.json | 57 ++++++++++++- + src/libqmi-glib/qmi-device.c | 152 +++++++++++++++++++++++++++++++---- + 2 files changed, 192 insertions(+), 17 deletions(-) + +diff --git a/data/qmi-service-ctl.json b/data/qmi-service-ctl.json +index 63f2a142..2c567ec3 100644 +--- a/data/qmi-service-ctl.json ++++ b/data/qmi-service-ctl.json +@@ -168,6 +168,61 @@ + "type" : "TLV", + "since" : "1.8", + "format" : "string" } ], +- "output" : [ { "common-ref" : "Operation Result" } ] } ++ "output" : [ { "common-ref" : "Operation Result" } ] }, + ++ // ********************************************************************************* ++ // Internal ++ { "name" : "Allocate CID QRTR", ++ "type" : "Message", ++ "service" : "CTL", ++ "id" : "0xFF22", ++ "since" : "1.0", ++ "input" : [ { "name" : "Service", ++ "id" : "0x01", ++ "type" : "TLV", ++ "since" : "1.0", ++ "format" : "guint16" , ++ "public-format" : "QmiService" } ], ++ "output" : [ { "common-ref" : "Operation Result" }, ++ { "name" : "Allocation Info", ++ "id" : "0x01", ++ "type" : "TLV", ++ "since" : "1.0", ++ "format" : "sequence", ++ "contents" : [ { "name" : "Service", ++ "format" : "guint16", ++ "public-format" : "QmiService" }, ++ { "name" : "Cid", ++ "format" : "guint8" } ], ++ "prerequisites": [ { "common-ref" : "Success" } ] } ] }, ++ ++ // ********************************************************************************* ++ // Internal ++ { "name" : "Release CID QRTR", ++ "type" : "Message", ++ "service" : "CTL", ++ "id" : "0xFF23", ++ "since" : "1.0", ++ "input" : [ { "name" : "Release Info", ++ "id" : "0x01", ++ "type" : "TLV", ++ "since" : "1.0", ++ "format" : "sequence", ++ "contents" : [ { "name" : "Service", ++ "format" : "guint16", ++ "public-format" : "QmiService" }, ++ { "name" : "Cid", ++ "format" : "guint8" } ] } ], ++ "output" : [ { "common-ref" : "Operation Result" }, ++ { "name" : "Release Info", ++ "id" : "0x01", ++ "type" : "TLV", ++ "since" : "1.0", ++ "format" : "sequence", ++ "contents" : [ { "name" : "Service", ++ "format" : "guint16", ++ "public-format" : "QmiService" }, ++ { "name" : "Cid", ++ "format" : "guint8" } ], ++ "prerequisites": [ { "common-ref" : "Success" } ] } ] } + ] +diff --git a/src/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c +index f119d5fe..75ab3419 100644 +--- a/src/libqmi-glib/qmi-device.c ++++ b/src/libqmi-glib/qmi-device.c +@@ -1137,7 +1137,7 @@ allocate_cid_ready (QmiClientCtl *client_ctl, + /* Check result of the async operation */ + output = qmi_client_ctl_allocate_cid_finish (client_ctl, res, &error); + if (!output) { +- g_prefix_error (&error, "CID allocation failed in the CTL client: "); ++ g_prefix_error (&error, "CID allocation failed in the CTL client (QMUX): "); + g_task_return_error (task, error); + g_object_unref (task); + return; +@@ -1161,7 +1161,7 @@ allocate_cid_ready (QmiClientCtl *client_ctl, + task, + QMI_CORE_ERROR, + QMI_CORE_ERROR_FAILED, +- "CID allocation failed in the CTL client: " ++ "CID allocation failed in the CTL client (QMUX): " + "Service mismatch (requested '%s', got '%s')", + qmi_service_get_string (ctx->service), + qmi_service_get_string (service)); +@@ -1175,6 +1175,58 @@ allocate_cid_ready (QmiClientCtl *client_ctl, + qmi_message_ctl_allocate_cid_output_unref (output); + } + ++static void ++allocate_cid_qrtr_ready (QmiClientCtl *client_ctl, ++ GAsyncResult *res, ++ GTask *task) ++{ ++ QmiMessageCtlAllocateCidQrtrOutput *output; ++ QmiService service; ++ guint8 cid; ++ GError *error = NULL; ++ AllocateClientContext *ctx; ++ ++ /* Check result of the async operation */ ++ output = qmi_client_ctl_allocate_cid_qrtr_finish (client_ctl, res, &error); ++ if (!output) { ++ g_prefix_error (&error, "CID allocation failed in the CTL client (QRTR): "); ++ g_task_return_error (task, error); ++ g_object_unref (task); ++ return; ++ } ++ ++ /* Check result of the QMI operation */ ++ if (!qmi_message_ctl_allocate_cid_qrtr_output_get_result (output, &error)) { ++ g_task_return_error (task, error); ++ g_object_unref (task); ++ qmi_message_ctl_allocate_cid_qrtr_output_unref (output); ++ return; ++ } ++ ++ /* Allocation info is mandatory when result is success */ ++ g_assert (qmi_message_ctl_allocate_cid_qrtr_output_get_allocation_info (output, &service, &cid, NULL)); ++ ++ ctx = g_task_get_task_data (task); ++ ++ if (service != ctx->service) { ++ g_task_return_new_error ( ++ task, ++ QMI_CORE_ERROR, ++ QMI_CORE_ERROR_FAILED, ++ "CID allocation failed in the CTL client (QRTR): " ++ "Service mismatch (requested '%s', got '%s')", ++ qmi_service_get_string (ctx->service), ++ qmi_service_get_string (service)); ++ g_object_unref (task); ++ qmi_message_ctl_allocate_cid_qrtr_output_unref (output); ++ return; ++ } ++ ++ ctx->cid = cid; ++ build_client_object (task); ++ qmi_message_ctl_allocate_cid_qrtr_output_unref (output); ++} ++ + void + qmi_device_allocate_client (QmiDevice *self, + QmiService service, +@@ -1365,13 +1417,13 @@ qmi_device_allocate_client (QmiDevice *self, + } + + /* Allocate a new CID for the client to be created */ +- if (cid == QMI_CID_NONE) { ++ if (cid == QMI_CID_NONE && ctx->service <= G_MAXUINT8) { + QmiMessageCtlAllocateCidInput *input; + + input = qmi_message_ctl_allocate_cid_input_new (); + qmi_message_ctl_allocate_cid_input_set_service (input, ctx->service, NULL); + +- g_debug ("[%s] allocating new client ID...", ++ g_debug ("[%s] allocating new client ID (QMUX)...", + qmi_file_get_path_display (self->priv->file)); + qmi_client_ctl_allocate_cid (self->priv->client_ctl, + input, +@@ -1382,6 +1434,23 @@ qmi_device_allocate_client (QmiDevice *self, + + qmi_message_ctl_allocate_cid_input_unref (input); + return; ++ } else if (cid == QMI_CID_NONE) { ++ QmiMessageCtlAllocateCidQrtrInput *input; ++ ++ input = qmi_message_ctl_allocate_cid_qrtr_input_new (); ++ qmi_message_ctl_allocate_cid_qrtr_input_set_service (input, ctx->service, NULL); ++ ++ g_debug ("[%s] allocating new client ID (QRTR)...", ++ qmi_file_get_path_display (self->priv->file)); ++ qmi_client_ctl_allocate_cid_qrtr (self->priv->client_ctl, ++ input, ++ timeout, ++ cancellable, ++ (GAsyncReadyCallback)allocate_cid_qrtr_ready, ++ task); ++ ++ qmi_message_ctl_allocate_cid_qrtr_input_unref (input); ++ return; + } + + /* Reuse the given CID */ +@@ -1435,6 +1504,38 @@ client_ctl_release_cid_ready (QmiClientCtl *client_ctl, + qmi_message_ctl_release_cid_output_unref (output); + } + ++static void ++client_ctl_release_cid_qrtr_ready (QmiClientCtl *client_ctl, ++ GAsyncResult *res, ++ GTask *task) ++{ ++ GError *error = NULL; ++ QmiMessageCtlReleaseCidQrtrOutput *output; ++ ++ /* Note: even if we return an error, the client is to be considered ++ * released! (so shouldn't be used) */ ++ ++ /* Check result of the async operation */ ++ output = qmi_client_ctl_release_cid_qrtr_finish (client_ctl, res, &error); ++ if (!output) { ++ g_task_return_error (task, error); ++ g_object_unref (task); ++ return; ++ } ++ ++ /* Check result of the QMI operation */ ++ if (!qmi_message_ctl_release_cid_qrtr_output_get_result (output, &error)) { ++ g_task_return_error (task, error); ++ g_object_unref (task); ++ qmi_message_ctl_release_cid_qrtr_output_unref (output); ++ return; ++ } ++ ++ g_task_return_boolean (task, TRUE); ++ g_object_unref (task); ++ qmi_message_ctl_release_cid_qrtr_output_unref (output); ++} ++ + void + qmi_device_release_client (QmiDevice *self, + QmiClient *client, +@@ -1498,21 +1599,40 @@ qmi_device_release_client (QmiDevice *self, + g_object_unref (client); + + if (flags & QMI_DEVICE_RELEASE_CLIENT_FLAGS_RELEASE_CID) { +- QmiMessageCtlReleaseCidInput *input; ++ if (service <= G_MAXUINT8) { ++ QmiMessageCtlReleaseCidInput *input; + +- /* And now, really try to release the CID */ +- input = qmi_message_ctl_release_cid_input_new (); +- qmi_message_ctl_release_cid_input_set_release_info (input, service, cid, NULL); ++ /* And now, really try to release the CID */ ++ input = qmi_message_ctl_release_cid_input_new (); ++ qmi_message_ctl_release_cid_input_set_release_info (input, service, cid, NULL); + +- qmi_client_ctl_release_cid (self->priv->client_ctl, +- input, +- timeout, +- cancellable, +- (GAsyncReadyCallback)client_ctl_release_cid_ready, +- task); ++ qmi_client_ctl_release_cid (self->priv->client_ctl, ++ input, ++ timeout, ++ cancellable, ++ (GAsyncReadyCallback)client_ctl_release_cid_ready, ++ task); + +- qmi_message_ctl_release_cid_input_unref (input); +- return; ++ qmi_message_ctl_release_cid_input_unref (input); ++ return; ++ } else { ++ QmiMessageCtlReleaseCidQrtrInput *input; ++ ++ /* And now, really try to release the CID */ ++ input = qmi_message_ctl_release_cid_qrtr_input_new (); ++ qmi_message_ctl_release_cid_qrtr_input_set_release_info (input, service, cid, NULL); ++ ++ qmi_client_ctl_release_cid_qrtr (self->priv->client_ctl, ++ input, ++ timeout, ++ cancellable, ++ (GAsyncReadyCallback)client_ctl_release_cid_qrtr_ready, ++ task); ++ ++ qmi_message_ctl_release_cid_qrtr_input_unref (input); ++ return; ++ ++ } + } + + /* No need to release the CID, so just done */ +-- +2.39.2 + diff --git a/temp/libqmi/0006-libqmi-glib-endpoint-qrtr-handle-QMUX-and-QRTR-messa.patch b/temp/libqmi/0006-libqmi-glib-endpoint-qrtr-handle-QMUX-and-QRTR-messa.patch new file mode 100644 index 0000000000000000000000000000000000000000..a30138fea3e342744d3607ff57cd8354d02978c8 --- /dev/null +++ b/temp/libqmi/0006-libqmi-glib-endpoint-qrtr-handle-QMUX-and-QRTR-messa.patch @@ -0,0 +1,119 @@ +From d70669657d1c475ff2127528a26f71fed71d257f Mon Sep 17 00:00:00 2001 +From: Dylan Van Assche <me@dylanvanassche.be> +Date: Wed, 29 Mar 2023 16:37:26 +0200 +Subject: [PATCH 6/7] libqmi-glib,endpoint-qrtr: handle QMUX and QRTR messages + +Handle QMUX and QRTR messages in QMI Message: + +- Use QmiService enum instead of guint where possible +- Bump service ID size from guint8 to guint6 when constructing TLVs +- Extract service IDs from QMI messages depending on marker +--- + src/libqmi-glib/qmi-endpoint-qrtr.c | 28 +++++++++++++++++++++------- + 1 file changed, 21 insertions(+), 7 deletions(-) + +diff --git a/src/libqmi-glib/qmi-endpoint-qrtr.c b/src/libqmi-glib/qmi-endpoint-qrtr.c +index 8c4007a1..7ab84afa 100644 +--- a/src/libqmi-glib/qmi-endpoint-qrtr.c ++++ b/src/libqmi-glib/qmi-endpoint-qrtr.c +@@ -43,6 +43,8 @@ + /* Constants for allocating/releasing clients */ + #define QMI_MESSAGE_CTL_ALLOCATE_CID 0x0022 + #define QMI_MESSAGE_CTL_RELEASE_CID 0x0023 ++#define QMI_MESSAGE_CTL_ALLOCATE_CID_QRTR 0xFF22 ++#define QMI_MESSAGE_CTL_RELEASE_CID_QRTR 0xFF23 + #define QMI_MESSAGE_TLV_ALLOCATION_INFO 0x01 + #define QMI_MESSAGE_INPUT_TLV_SERVICE 0x01 + +@@ -137,7 +139,7 @@ client_message_cb (QrtrClient *qrtr_client, + QmiEndpointQrtr *self) + { + QmiMessage *message; +- guint service; ++ QmiService service; + guint cid; + g_autoptr(GError) error = NULL; + +@@ -262,7 +264,7 @@ release_client (QmiEndpointQrtr *self, + + static gboolean + construct_alloc_tlv (QmiMessage *message, +- guint8 service, ++ guint16 service, + guint8 client) + { + gsize init_offset; +@@ -270,8 +272,14 @@ construct_alloc_tlv (QmiMessage *message, + init_offset = qmi_message_tlv_write_init (message, + QMI_MESSAGE_TLV_ALLOCATION_INFO, + NULL); ++ if (service > G_MAXUINT8) ++ return init_offset && ++ qmi_message_tlv_write_guint16 (message, QMI_ENDIAN_LITTLE, service, NULL) && ++ qmi_message_tlv_write_guint8 (message, client, NULL) && ++ qmi_message_tlv_write_complete (message, init_offset, NULL); ++ + return init_offset && +- qmi_message_tlv_write_guint8 (message, service, NULL) && ++ qmi_message_tlv_write_guint8 (message, (guint8) service, NULL) && + qmi_message_tlv_write_guint8 (message, client, NULL) && + qmi_message_tlv_write_complete (message, init_offset, NULL); + } +@@ -282,13 +290,14 @@ handle_alloc_cid (QmiEndpointQrtr *self, + { + gsize offset = 0; + gsize init_offset; +- guint8 service; ++ QmiService service; + guint cid; + g_autoptr(QmiMessage) response = NULL; + g_autoptr(GError) error = NULL; + + if (((init_offset = qmi_message_tlv_read_init (message, QMI_MESSAGE_TLV_ALLOCATION_INFO, NULL, &error)) == 0) || +- !qmi_message_tlv_read_guint8 (message, init_offset, &offset, &service, &error)) { ++ (qmi_message_get_message_id (message) == QMI_MESSAGE_CTL_ALLOCATE_CID && !qmi_message_tlv_read_guint8 (message, init_offset, &offset, (guint8 *) &service, &error)) || ++ (qmi_message_get_message_id (message) == QMI_MESSAGE_CTL_ALLOCATE_CID_QRTR && !qmi_message_tlv_read_guint16 (message, init_offset, &offset, QMI_ENDIAN_LITTLE, (guint16 *) &service, &error))) { + g_debug ("[%s] error allocating CID: could not parse message: %s", + qmi_endpoint_get_name (QMI_ENDPOINT (self)), error->message); + response = qmi_message_response_new (message, QMI_PROTOCOL_ERROR_MALFORMED_MESSAGE); +@@ -299,6 +308,8 @@ handle_alloc_cid (QmiEndpointQrtr *self, + return; + } + ++ g_debug("Extracted service: %d", service); ++ + cid = allocate_client (self, service, &error); + if (!cid) { + g_debug ("[%s] error allocating CID: %s", +@@ -327,13 +338,14 @@ handle_release_cid (QmiEndpointQrtr *self, + { + gsize offset = 0; + gsize init_offset; +- guint8 service; ++ QmiService service; + guint8 cid; + g_autoptr(QmiMessage) response = NULL; + g_autoptr(GError) error = NULL; + + if (((init_offset = qmi_message_tlv_read_init (message, QMI_MESSAGE_TLV_ALLOCATION_INFO, NULL, &error)) == 0) || +- !qmi_message_tlv_read_guint8 (message, init_offset, &offset, &service, &error) || ++ (qmi_message_get_message_id (message) == QMI_MESSAGE_CTL_RELEASE_CID && !qmi_message_tlv_read_guint8 (message, init_offset, &offset, (guint8 *) &service, &error)) || ++ (qmi_message_get_message_id (message) == QMI_MESSAGE_CTL_RELEASE_CID_QRTR && !qmi_message_tlv_read_guint16 (message, init_offset, &offset, QMI_ENDIAN_LITTLE, (guint16 *) &service, &error)) || + !qmi_message_tlv_read_guint8 (message, init_offset, &offset, &cid, &error)) { + g_debug ("[%s] error releasing CID: could not parse message: %s", + qmi_endpoint_get_name (QMI_ENDPOINT (self)), error->message); +@@ -389,9 +401,11 @@ handle_ctl_message (QmiEndpointQrtr *self, + { + switch (qmi_message_get_message_id (message)) { + case QMI_MESSAGE_CTL_ALLOCATE_CID: ++ case QMI_MESSAGE_CTL_ALLOCATE_CID_QRTR: + handle_alloc_cid (self, message); + break; + case QMI_MESSAGE_CTL_RELEASE_CID: ++ case QMI_MESSAGE_CTL_RELEASE_CID_QRTR: + handle_release_cid (self, message); + break; + case QMI_MESSAGE_CTL_SYNC: +-- +2.39.2 + diff --git a/temp/libqmi/0007-libqmi-glib-port-context-handle-QMUX-and-QRTR-messag.patch b/temp/libqmi/0007-libqmi-glib-port-context-handle-QMUX-and-QRTR-messag.patch new file mode 100644 index 0000000000000000000000000000000000000000..898e55a43e351265c409398297576c53d178e56a --- /dev/null +++ b/temp/libqmi/0007-libqmi-glib-port-context-handle-QMUX-and-QRTR-messag.patch @@ -0,0 +1,35 @@ +From cf67304f5bae53a2ca7624351c9056f61fc28650 Mon Sep 17 00:00:00 2001 +From: Dylan Van Assche <me@dylanvanassche.be> +Date: Fri, 31 Mar 2023 14:32:30 +0200 +Subject: [PATCH 7/7] libqmi-glib,port-context: handle QMUX and QRTR messages + +Handle QMUX and QRTR messages in QMI Message: + +- Allow QMI messages with both QMUX and QRTR markers +--- + src/libqmi-glib/test/test-port-context.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/libqmi-glib/test/test-port-context.c b/src/libqmi-glib/test/test-port-context.c +index 72407c2f..c647e8a3 100644 +--- a/src/libqmi-glib/test/test-port-context.c ++++ b/src/libqmi-glib/test/test-port-context.c +@@ -114,11 +114,13 @@ process_next_command (TestPortContext *ctx, + gchar *received; + GByteArray *response; + +- /* Every message received must start with the QMUX marker. ++ /* Every message received must start with the QMUX or QRTR marker. + * If it doesn't, we broke framing :-/ + * If we broke framing, an error should be reported and the device + * should get closed */ +- if (buffer->len > 0 && buffer->data[0] != QMI_MESSAGE_QMUX_MARKER) ++ if (buffer->len > 0 && ++ buffer->data[0] != QMI_MESSAGE_QMUX_MARKER && ++ buffer->data[0] != QMI_MESSAGE_QRTR_MARKER) + g_assert_not_reached (); + + message = qmi_message_new_from_raw (buffer, &error); +-- +2.39.2 + diff --git a/temp/libqmi/APKBUILD b/temp/libqmi/APKBUILD new file mode 100644 index 0000000000000000000000000000000000000000..e8ef866c21ba76a5d0707294b058f72e3c17fbb3 --- /dev/null +++ b/temp/libqmi/APKBUILD @@ -0,0 +1,71 @@ +# Forked from Alpine to support QRTR-only services + +pkgname=libqmi +pkgver=9999_git20230324 +pkgrel=0 +pkgdesc="QMI modem protocol helper library" +url="https://www.freedesktop.org/wiki/Software/libqmi" +arch="all" +license="GPL-2.0-or-later AND LGPL-2.1-or-later" +makedepends=" + bash-completion + glib-dev + gobject-introspection-dev + help2man + libgudev-dev + libmbim-dev + libqrtr-glib-dev + linux-headers + meson + python3 + " +subpackages=" + $pkgname-dev + $pkgname-doc + $pkgname-bash-completion + qmi-utils + " +_commit="0d1980eef16cc0f1357d555b70606f852db2dc97" +source="https://gitlab.freedesktop.org/mobile-broadband/libqmi/-/archive/$_commit/libqmi-$_commit.tar.gz + 0001-data-qmi-service-ssc-add-SSC-service.patch + 0002-libqmi-glib-message-handle-QMUX-and-QRTR-messages.patch + 0003-libqmi-glib-proxy-handle-QMUX-and-QRTR-messages.patch + 0004-libqmi-glib-endpoint-handle-QMUX-and-QRTR-messages.patch + 0005-libqmi-glib-device-handle-QMUX-and-QRTR-messages.patch + 0006-libqmi-glib-endpoint-qrtr-handle-QMUX-and-QRTR-messa.patch + 0007-libqmi-glib-port-context-handle-QMUX-and-QRTR-messag.patch + " +builddir="$srcdir/$pkgname-$_commit" + +build() { + abuild-meson \ + -Db_lto=true \ + . output + meson compile -C output +} + +check() { + meson test --no-rebuild --print-errorlogs -C output +} + +package() { + DESTDIR="$pkgdir" meson install --no-rebuild -C output +} + +utils() { + pkgdesc="$pkgdesc (CLI utilities)" + + amove usr/bin +} + + +sha512sums=" +c1faffbb8d26023c06e3ab3aab8e0b394232da13eaa84bedc7c9e30f95cffe6116160c6fd943c9dad4114dfd73a48e9e586991080fb077bc0b216d1d9f89e5bf libqmi-0d1980eef16cc0f1357d555b70606f852db2dc97.tar.gz +3cc7e723119905d01d47852334c4a4cb6523a9f027b5524cddb8d9b7433522c49978ff7a2b1172517585e5576beeae7ab3f835d72a26ca41f16721b791b0859b 0001-data-qmi-service-ssc-add-SSC-service.patch +88bf3673bea0906beecbfea93a577b8bf80019b9c53ba95c8e8a0242a085271f695100032624a38ec82be43796bc3bf90d16fed34cd10691ca45a8b9d59aac04 0002-libqmi-glib-message-handle-QMUX-and-QRTR-messages.patch +b320d9d28d862c486104cf91b4fef45bb0e3931551af0603f7e1823f4884a0b3a9095b33449fed11b4637883b731ebf949129a46a79f98925031ebbf034217dc 0003-libqmi-glib-proxy-handle-QMUX-and-QRTR-messages.patch +f217c49925fd7206ffc6767ae106b3e52a59c563f63e1512dfe374087013d7ab4aa128d834e9ca69e6d0b6e4c544fa3ff991275f3b05191a0af4c9de9ec78a21 0004-libqmi-glib-endpoint-handle-QMUX-and-QRTR-messages.patch +8e82a9f029aebb48cced514d2760cfca9d7afdb3bb8e9d1bafa24b1af20a9f41c7dacee8892c99cdb4d92b74997557681fad4d78367bd969fdaed5026b753b9a 0005-libqmi-glib-device-handle-QMUX-and-QRTR-messages.patch +b6cf531de814d2cf0c9c6039978f5ba5f904fe09252da7724d1f018cdbe8793a99634818ec9ec68041d8b4bccfa47397d2cb59bbbb2ad7518be55366e2a5f211 0006-libqmi-glib-endpoint-qrtr-handle-QMUX-and-QRTR-messa.patch +e85f547291c38cf8cf457b72049f6dd5809b9f1f7429572c8440465f762e8461dff96ed72a92d02f0ae155a476e74f9da94997a3d2cddaa58f6773803ac1ecc3 0007-libqmi-glib-port-context-handle-QMUX-and-QRTR-messag.patch +"