Added ModemManager
This commit is contained in:
		
							
								
								
									
										1
									
								
								net-misc/modemmanager/Manifest
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								net-misc/modemmanager/Manifest
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
DIST ModemManager-1.16.2.tar.xz 2447936 BLAKE2B aafd2bde9fe72ec837a34987a698d82f4ba2aedf778c350263f8fe937ccd4b5b9b78fc66c58a39a8729c371788ab7b7782073726dc132b8f08bd2df0a9bc2da4 SHA512 c0b095972eba6e0f3a1ad22e425b412f17d8b60f0af4d423a92fdebcb6d2801f87e6af98758f8c2dc4db3586a3a15530a318805fda312443fa6abe2265ebd6b6
 | 
			
		||||
@@ -0,0 +1,25 @@
 | 
			
		||||
From 2091ac5f75a6e025be896c21179b04bc53ce4bb0 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Arnaud Ferraris <arnaud.ferraris@gmail.com>
 | 
			
		||||
Date: Sat, 23 May 2020 17:14:36 +0200
 | 
			
		||||
Subject: [PATCH] mm-broadband-modem: improve voice capabilities detection
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 src/mm-broadband-modem.c | 2 +-
 | 
			
		||||
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
 | 
			
		||||
index fdbd13b0..6dadb90e 100644
 | 
			
		||||
--- a/src/mm-broadband-modem.c
 | 
			
		||||
+++ b/src/mm-broadband-modem.c
 | 
			
		||||
@@ -7400,7 +7400,7 @@ modem_voice_check_support (MMIfaceModemVoice *self,
 | 
			
		||||
 
 | 
			
		||||
     /* Check ATH support */
 | 
			
		||||
     mm_base_modem_at_command (MM_BASE_MODEM (self),
 | 
			
		||||
-                              "H",
 | 
			
		||||
+                              "I",
 | 
			
		||||
                               3,
 | 
			
		||||
                               FALSE,
 | 
			
		||||
                               (GAsyncReadyCallback)ath_format_check_ready,
 | 
			
		||||
-- 
 | 
			
		||||
2.26.2
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,28 @@
 | 
			
		||||
From 9a4e5a7c2da36288cd66c1500dcd0e1ba844c9cc Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dylan Van Assche <me@dylanvanassche.be>
 | 
			
		||||
Date: Wed, 25 Nov 2020 19:58:25 +0100
 | 
			
		||||
Subject: [PATCH] serial-parsers: do not fail to detect a valid response with a
 | 
			
		||||
 call or text incoming
 | 
			
		||||
 | 
			
		||||
Upstreaming at
 | 
			
		||||
https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/merge_requests/406
 | 
			
		||||
---
 | 
			
		||||
 src/mm-serial-parsers.c | 2 +-
 | 
			
		||||
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/src/mm-serial-parsers.c b/src/mm-serial-parsers.c
 | 
			
		||||
index b511302e..248cc685 100644
 | 
			
		||||
--- a/src/mm-serial-parsers.c
 | 
			
		||||
+++ b/src/mm-serial-parsers.c
 | 
			
		||||
@@ -108,7 +108,7 @@ mm_serial_parser_v1_new (void)
 | 
			
		||||
 
 | 
			
		||||
     parser = g_slice_new (MMSerialParserV1);
 | 
			
		||||
 
 | 
			
		||||
-    parser->regex_ok = g_regex_new ("\\r\\nOK(\\r\\n)+$", flags, 0, NULL);
 | 
			
		||||
+    parser->regex_ok = g_regex_new ("\\r\\nOK(\\r\\n)+", flags, 0, NULL);
 | 
			
		||||
     parser->regex_connect = g_regex_new ("\\r\\nCONNECT.*\\r\\n", flags, 0, NULL);
 | 
			
		||||
     parser->regex_sms = g_regex_new ("\\r\\n>\\s*$", flags, 0, NULL);
 | 
			
		||||
     parser->regex_cme_error = g_regex_new ("\\r\\n\\+CME ERROR:\\s*(\\d+)\\r\\n$", flags, 0, NULL);
 | 
			
		||||
-- 
 | 
			
		||||
2.25.1
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,100 @@
 | 
			
		||||
From f5ce1ae2282e6164efa6b1f9b973ff61e44a30ff Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dylan Van Assche <me@dylanvanassche.be>
 | 
			
		||||
Date: Sun, 31 Jan 2021 15:38:31 +0100
 | 
			
		||||
Subject: [PATCH 1/2] context: add test-no-suspend-resume cli parameter
 | 
			
		||||
 | 
			
		||||
Disables suspend/resume support at runtime.
 | 
			
		||||
This is useful for modems which are never turned off
 | 
			
		||||
or suspended when the host suspends.
 | 
			
		||||
---
 | 
			
		||||
 src/main.c       | 10 +++++++---
 | 
			
		||||
 src/mm-context.c | 18 ++++++++++++++++++
 | 
			
		||||
 src/mm-context.h |  9 ++++++---
 | 
			
		||||
 3 files changed, 31 insertions(+), 6 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/src/main.c b/src/main.c
 | 
			
		||||
index 9963c7cc..928078a3 100644
 | 
			
		||||
--- a/src/main.c
 | 
			
		||||
+++ b/src/main.c
 | 
			
		||||
@@ -195,9 +195,13 @@ main (int argc, char *argv[])
 | 
			
		||||
     {
 | 
			
		||||
         MMSleepMonitor *sleep_monitor;
 | 
			
		||||
 
 | 
			
		||||
-        sleep_monitor = mm_sleep_monitor_get ();
 | 
			
		||||
-        g_signal_connect (sleep_monitor, MM_SLEEP_MONITOR_SLEEPING, G_CALLBACK (sleeping_cb), NULL);
 | 
			
		||||
-        g_signal_connect (sleep_monitor, MM_SLEEP_MONITOR_RESUMING, G_CALLBACK (resuming_cb), NULL);
 | 
			
		||||
+        if (mm_context_get_test_no_suspend_resume())
 | 
			
		||||
+            mm_dbg ("Suspend/resume support disabled at runtime");
 | 
			
		||||
+        else {
 | 
			
		||||
+            sleep_monitor = mm_sleep_monitor_get ();
 | 
			
		||||
+            g_signal_connect (sleep_monitor, MM_SLEEP_MONITOR_SLEEPING, G_CALLBACK (sleeping_cb), NULL);
 | 
			
		||||
+            g_signal_connect (sleep_monitor, MM_SLEEP_MONITOR_RESUMING, G_CALLBACK (resuming_cb), NULL);
 | 
			
		||||
+        }
 | 
			
		||||
     }
 | 
			
		||||
 #endif
 | 
			
		||||
 
 | 
			
		||||
diff --git a/src/mm-context.c b/src/mm-context.c
 | 
			
		||||
index 8f20d2e8..6d25c1bd 100644
 | 
			
		||||
--- a/src/mm-context.c
 | 
			
		||||
+++ b/src/mm-context.c
 | 
			
		||||
@@ -222,6 +222,9 @@ mm_context_get_log_relative_timestamps (void)
 | 
			
		||||
 static gboolean  test_session;
 | 
			
		||||
 static gboolean  test_enable;
 | 
			
		||||
 static gchar    *test_plugin_dir;
 | 
			
		||||
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
 | 
			
		||||
+static gboolean  test_no_suspend_resume;
 | 
			
		||||
+#endif
 | 
			
		||||
 
 | 
			
		||||
 static const GOptionEntry test_entries[] = {
 | 
			
		||||
     {
 | 
			
		||||
@@ -239,6 +242,13 @@ static const GOptionEntry test_entries[] = {
 | 
			
		||||
         "Path to look for plugins",
 | 
			
		||||
         "[PATH]"
 | 
			
		||||
     },
 | 
			
		||||
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
 | 
			
		||||
+    {
 | 
			
		||||
+        "test-no-suspend-resume", 0, 0, G_OPTION_ARG_NONE, &test_no_suspend_resume,
 | 
			
		||||
+        "Disable suspend/resume support at runtime even if available",
 | 
			
		||||
+        NULL
 | 
			
		||||
+    },
 | 
			
		||||
+#endif
 | 
			
		||||
     { NULL }
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
@@ -274,6 +284,14 @@ mm_context_get_test_plugin_dir (void)
 | 
			
		||||
     return test_plugin_dir ? test_plugin_dir : PLUGINDIR;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
 | 
			
		||||
+gboolean
 | 
			
		||||
+mm_context_get_test_no_suspend_resume (void)
 | 
			
		||||
+{
 | 
			
		||||
+    return test_no_suspend_resume;
 | 
			
		||||
+}
 | 
			
		||||
+#endif
 | 
			
		||||
+
 | 
			
		||||
 /*****************************************************************************/
 | 
			
		||||
 
 | 
			
		||||
 static void
 | 
			
		||||
diff --git a/src/mm-context.h b/src/mm-context.h
 | 
			
		||||
index ff5f1343..5a9be51f 100644
 | 
			
		||||
--- a/src/mm-context.h
 | 
			
		||||
+++ b/src/mm-context.h
 | 
			
		||||
@@ -43,8 +43,11 @@ gboolean     mm_context_get_log_timestamps          (void);
 | 
			
		||||
 gboolean     mm_context_get_log_relative_timestamps (void);
 | 
			
		||||
 
 | 
			
		||||
 /* Testing support */
 | 
			
		||||
-gboolean     mm_context_get_test_session    (void);
 | 
			
		||||
-gboolean     mm_context_get_test_enable     (void);
 | 
			
		||||
-const gchar *mm_context_get_test_plugin_dir (void);
 | 
			
		||||
+gboolean     mm_context_get_test_session           (void);
 | 
			
		||||
+gboolean     mm_context_get_test_enable            (void);
 | 
			
		||||
+const gchar *mm_context_get_test_plugin_dir        (void);
 | 
			
		||||
+#if defined WITH_SYSTEMD_SUSPEND_RESUME
 | 
			
		||||
+gboolean     mm_context_get_test_no_suspend_resume (void);
 | 
			
		||||
+#endif
 | 
			
		||||
 
 | 
			
		||||
 #endif /* MM_CONTEXT_H */
 | 
			
		||||
-- 
 | 
			
		||||
2.30.0
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,167 @@
 | 
			
		||||
From f83a4b5ed428dbe412b3c9cc779bd85fc8dbe583 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dylan Van Assche <me@dylanvanassche.be>
 | 
			
		||||
Date: Sat, 30 Jan 2021 21:57:50 +0100
 | 
			
		||||
Subject: [PATCH] broadband-modem-qmi: Enable AT URCs and QMI indications
 | 
			
		||||
 | 
			
		||||
Enable both AT URCs and QMI indications for messaging events.
 | 
			
		||||
This allows to receive text messages during suspend
 | 
			
		||||
on the PinePhone with a Quectel EG25 modem.
 | 
			
		||||
---
 | 
			
		||||
 src/mm-broadband-modem-qmi.c | 109 +++++++++++++++++++++++++----------
 | 
			
		||||
 1 file changed, 80 insertions(+), 29 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/src/mm-broadband-modem-qmi.c b/src/mm-broadband-modem-qmi.c
 | 
			
		||||
index d161d96ec..bac5cf1b2 100644
 | 
			
		||||
--- a/src/mm-broadband-modem-qmi.c
 | 
			
		||||
+++ b/src/mm-broadband-modem-qmi.c
 | 
			
		||||
@@ -6115,13 +6115,6 @@ messaging_cleanup_unsolicited_events_finish (MMIfaceModemMessaging *_self,
 | 
			
		||||
                                              GAsyncResult *res,
 | 
			
		||||
                                              GError **error)
 | 
			
		||||
 {
 | 
			
		||||
-    MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (_self);
 | 
			
		||||
-
 | 
			
		||||
-    /* Handle fallback */
 | 
			
		||||
-    if (self->priv->messaging_fallback_at) {
 | 
			
		||||
-        return iface_modem_messaging_parent->cleanup_unsolicited_events_finish (_self, res, error);
 | 
			
		||||
-    }
 | 
			
		||||
-
 | 
			
		||||
     return g_task_propagate_boolean (G_TASK (res), error);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -6130,14 +6123,39 @@ messaging_setup_unsolicited_events_finish (MMIfaceModemMessaging *_self,
 | 
			
		||||
                                              GAsyncResult *res,
 | 
			
		||||
                                              GError **error)
 | 
			
		||||
 {
 | 
			
		||||
-    MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (_self);
 | 
			
		||||
+    return g_task_propagate_boolean (G_TASK (res), error);
 | 
			
		||||
+}
 | 
			
		||||
 
 | 
			
		||||
-    /* Handle fallback */
 | 
			
		||||
-    if (self->priv->messaging_fallback_at) {
 | 
			
		||||
-        return iface_modem_messaging_parent->setup_unsolicited_events_finish (_self, res, error);
 | 
			
		||||
-    }
 | 
			
		||||
+static void
 | 
			
		||||
+common_cleanup_unsolicited_events_finish (MMIfaceModemMessaging *self,
 | 
			
		||||
+                                        GAsyncResult *res,
 | 
			
		||||
+                                        GTask *task)
 | 
			
		||||
+{
 | 
			
		||||
+    GError *error = NULL;
 | 
			
		||||
 
 | 
			
		||||
-    return g_task_propagate_boolean (G_TASK (res), error);
 | 
			
		||||
+    messaging_cleanup_unsolicited_events_finish (self, res, &error);
 | 
			
		||||
+    if (error)
 | 
			
		||||
+        g_task_return_error (task, error);
 | 
			
		||||
+    else
 | 
			
		||||
+        g_task_return_boolean (task, TRUE);
 | 
			
		||||
+
 | 
			
		||||
+    g_object_unref (task);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static void
 | 
			
		||||
+common_setup_unsolicited_events_finish (MMIfaceModemMessaging *self,
 | 
			
		||||
+                                        GAsyncResult *res,
 | 
			
		||||
+                                        GTask *task)
 | 
			
		||||
+{
 | 
			
		||||
+    GError *error = NULL;
 | 
			
		||||
+
 | 
			
		||||
+    messaging_setup_unsolicited_events_finish (self, res, &error);
 | 
			
		||||
+    if (error)
 | 
			
		||||
+        g_task_return_error (task, error);
 | 
			
		||||
+    else
 | 
			
		||||
+        g_task_return_boolean (task, TRUE);
 | 
			
		||||
+
 | 
			
		||||
+    g_object_unref (task);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void
 | 
			
		||||
@@ -6185,6 +6203,26 @@ common_setup_cleanup_messaging_unsolicited_events (MMBroadbandModemQmi *self,
 | 
			
		||||
     g_object_unref (task);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static void
 | 
			
		||||
+parent_messaging_cleanup_unsolicited_events_ready (MMIfaceModemMessaging *_self,
 | 
			
		||||
+                                                   GAsyncResult *res,
 | 
			
		||||
+                                                   GTask *task)
 | 
			
		||||
+{
 | 
			
		||||
+    GError *error = NULL;
 | 
			
		||||
+
 | 
			
		||||
+    if (!iface_modem_messaging_parent->cleanup_unsolicited_events_finish (_self, res, &error)) {
 | 
			
		||||
+        g_task_return_error (task, error);
 | 
			
		||||
+        g_object_unref (task);
 | 
			
		||||
+        return;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    /* Disable QMI indications */
 | 
			
		||||
+    common_setup_cleanup_messaging_unsolicited_events (MM_BROADBAND_MODEM_QMI (_self),
 | 
			
		||||
+                                                       FALSE,
 | 
			
		||||
+                                                       (GAsyncReadyCallback)common_cleanup_unsolicited_events_finish,
 | 
			
		||||
+                                                       task);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static void
 | 
			
		||||
 messaging_cleanup_unsolicited_events (MMIfaceModemMessaging *_self,
 | 
			
		||||
                                       GAsyncReadyCallback callback,
 | 
			
		||||
@@ -6192,15 +6230,32 @@ messaging_cleanup_unsolicited_events (MMIfaceModemMessaging *_self,
 | 
			
		||||
 {
 | 
			
		||||
     MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (_self);
 | 
			
		||||
 
 | 
			
		||||
-    /* Handle fallback */
 | 
			
		||||
-    if (self->priv->messaging_fallback_at) {
 | 
			
		||||
-        return iface_modem_messaging_parent->cleanup_unsolicited_events (_self, callback, user_data);
 | 
			
		||||
+    /* Disable AT URCs parent and chain QMI indications disabling */
 | 
			
		||||
+    iface_modem_messaging_parent->cleanup_unsolicited_events (
 | 
			
		||||
+        _self,
 | 
			
		||||
+        (GAsyncReadyCallback)parent_messaging_cleanup_unsolicited_events_ready,
 | 
			
		||||
+        g_task_new (self, NULL, callback, user_data));
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static void
 | 
			
		||||
+parent_messaging_setup_unsolicited_events_ready (MMIfaceModemMessaging *_self,
 | 
			
		||||
+                                                  GAsyncResult *res,
 | 
			
		||||
+                                                  GTask *task)
 | 
			
		||||
+{
 | 
			
		||||
+    GError *error = NULL;
 | 
			
		||||
+
 | 
			
		||||
+    if (!iface_modem_messaging_parent->setup_unsolicited_events_finish (_self, res, &error)) {
 | 
			
		||||
+        g_task_return_error (task, error);
 | 
			
		||||
+        g_object_unref (task);
 | 
			
		||||
+        return;
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
-    common_setup_cleanup_messaging_unsolicited_events (MM_BROADBAND_MODEM_QMI (self),
 | 
			
		||||
-                                                       FALSE,
 | 
			
		||||
-                                                       callback,
 | 
			
		||||
-                                                       user_data);
 | 
			
		||||
+    /* Enable QMI indications */
 | 
			
		||||
+    common_setup_cleanup_messaging_unsolicited_events (MM_BROADBAND_MODEM_QMI (_self),
 | 
			
		||||
+                                                       TRUE,
 | 
			
		||||
+                                                       (GAsyncReadyCallback)common_setup_unsolicited_events_finish,
 | 
			
		||||
+                                                       task);
 | 
			
		||||
+
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void
 | 
			
		||||
@@ -6210,15 +6265,11 @@ messaging_setup_unsolicited_events (MMIfaceModemMessaging *_self,
 | 
			
		||||
 {
 | 
			
		||||
     MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (_self);
 | 
			
		||||
 
 | 
			
		||||
-    /* Handle fallback */
 | 
			
		||||
-    if (self->priv->messaging_fallback_at) {
 | 
			
		||||
-        return iface_modem_messaging_parent->setup_unsolicited_events (_self, callback, user_data);
 | 
			
		||||
-    }
 | 
			
		||||
-
 | 
			
		||||
-    common_setup_cleanup_messaging_unsolicited_events (MM_BROADBAND_MODEM_QMI (self),
 | 
			
		||||
-                                                       TRUE,
 | 
			
		||||
-                                                       callback,
 | 
			
		||||
-                                                       user_data);
 | 
			
		||||
+    /* Enable AT URCs parent and chain QMI indication enabling */
 | 
			
		||||
+    iface_modem_messaging_parent->setup_unsolicited_events (
 | 
			
		||||
+        _self,
 | 
			
		||||
+        (GAsyncReadyCallback)parent_messaging_setup_unsolicited_events_ready,
 | 
			
		||||
+        g_task_new (self, NULL, callback, user_data));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 /*****************************************************************************/
 | 
			
		||||
-- 
 | 
			
		||||
GitLab
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,109 @@
 | 
			
		||||
From deccf35a68063ddae4a51a9ec99124fce998cf4b Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dylan Van Assche <me@dylanvanassche.be>
 | 
			
		||||
Date: Sat, 30 Jan 2021 21:57:50 +0100
 | 
			
		||||
Subject: [PATCH] mm-broadband-modem-qmi: Add
 | 
			
		||||
 ID_MM_QMI_MESSAGING_AT_FALLBACK_ENABLE
 | 
			
		||||
 | 
			
		||||
Allows to force a fallback to AT URCs for detecting
 | 
			
		||||
messaging events instead of QMI indications.
 | 
			
		||||
This allows to receive text messages during suspend
 | 
			
		||||
on the PinePhone with a Quectel EG25 modem.
 | 
			
		||||
---
 | 
			
		||||
 .../quectel/77-mm-quectel-port-types.rules    |  2 ++
 | 
			
		||||
 src/mm-broadband-modem-qmi.c                  | 34 +++++++++++++++++--
 | 
			
		||||
 src/mm-broadband-modem-qmi.h                  |  1 +
 | 
			
		||||
 3 files changed, 35 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/plugins/quectel/77-mm-quectel-port-types.rules b/plugins/quectel/77-mm-quectel-port-types.rules
 | 
			
		||||
index 54778d24..fab1f6fa 100644
 | 
			
		||||
--- a/plugins/quectel/77-mm-quectel-port-types.rules
 | 
			
		||||
+++ b/plugins/quectel/77-mm-quectel-port-types.rules
 | 
			
		||||
@@ -48,10 +48,12 @@ ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0296", ENV{.MM_USBIFNUM}=="02", ENV{
 | 
			
		||||
 ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0296", ENV{.MM_USBIFNUM}=="03", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1"
 | 
			
		||||
 
 | 
			
		||||
 # Quectel EC25/EG25
 | 
			
		||||
+#  Always fallback to AT URCs for messaging notifications
 | 
			
		||||
 #  ttyUSB0 (if #0): QCDM/DIAG port
 | 
			
		||||
 #  ttyUSB1 (if #1): GPS data port
 | 
			
		||||
 #  ttyUSB2 (if #2): AT primary port
 | 
			
		||||
 #  ttyUSB3 (if #3): AT secondary port
 | 
			
		||||
+ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0125", ENV{ID_MM_QMI_MESSAGING_AT_FALLBACK_ENABLE}="1"
 | 
			
		||||
 ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0125", ENV{.MM_USBIFNUM}=="00", ENV{ID_MM_PORT_TYPE_QCDM}="1"
 | 
			
		||||
 ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0125", ENV{.MM_USBIFNUM}=="01", ENV{ID_MM_PORT_TYPE_GPS}="1"
 | 
			
		||||
 ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0125", ENV{.MM_USBIFNUM}=="02", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1"
 | 
			
		||||
diff --git a/src/mm-broadband-modem-qmi.c b/src/mm-broadband-modem-qmi.c
 | 
			
		||||
index ae27b333..4735e616 100644
 | 
			
		||||
--- a/src/mm-broadband-modem-qmi.c
 | 
			
		||||
+++ b/src/mm-broadband-modem-qmi.c
 | 
			
		||||
@@ -173,6 +173,30 @@ shared_qmi_peek_client (MMSharedQmi    *self,
 | 
			
		||||
     return client;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+/*****************************************************************************/
 | 
			
		||||
+
 | 
			
		||||
+MMPortQmi *
 | 
			
		||||
+mm_broadband_modem_qmi_peek_port_qmi (MMBroadbandModemQmi *self)
 | 
			
		||||
+{
 | 
			
		||||
+    MMPortQmi *primary_qmi_port = NULL;
 | 
			
		||||
+    GList     *qmi_ports;
 | 
			
		||||
+
 | 
			
		||||
+    g_assert (MM_IS_BROADBAND_MODEM_QMI (self));
 | 
			
		||||
+
 | 
			
		||||
+    qmi_ports = mm_base_modem_find_ports (MM_BASE_MODEM (self),
 | 
			
		||||
+                                          MM_PORT_SUBSYS_UNKNOWN,
 | 
			
		||||
+                                          MM_PORT_TYPE_QMI,
 | 
			
		||||
+                                          NULL);
 | 
			
		||||
+
 | 
			
		||||
+    /* First QMI port in the list is the primary one always */
 | 
			
		||||
+    if (qmi_ports)
 | 
			
		||||
+        primary_qmi_port = MM_PORT_QMI (qmi_ports->data);
 | 
			
		||||
+
 | 
			
		||||
+    g_list_free_full (qmi_ports, g_object_unref);
 | 
			
		||||
+
 | 
			
		||||
+    return primary_qmi_port;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 /*****************************************************************************/
 | 
			
		||||
 /* Create Bearer (Modem interface) */
 | 
			
		||||
 
 | 
			
		||||
@@ -6186,9 +6210,12 @@ messaging_cleanup_unsolicited_events (MMIfaceModemMessaging *_self,
 | 
			
		||||
                                       gpointer user_data)
 | 
			
		||||
 {
 | 
			
		||||
     MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (_self);
 | 
			
		||||
+    MMPort *port = MM_PORT (mm_broadband_modem_qmi_peek_port_qmi (self));
 | 
			
		||||
 
 | 
			
		||||
     /* Handle fallback */
 | 
			
		||||
-    if (self->priv->messaging_fallback_at) {
 | 
			
		||||
+    if (self->priv->messaging_fallback_at ||
 | 
			
		||||
+        mm_kernel_device_get_global_property_as_boolean (mm_port_peek_kernel_device (port),
 | 
			
		||||
+                                                         "ID_MM_QMI_MESSAGING_AT_FALLBACK_ENABLE")) {
 | 
			
		||||
         return iface_modem_messaging_parent->cleanup_unsolicited_events (_self, callback, user_data);
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
@@ -6204,9 +6231,12 @@ messaging_setup_unsolicited_events (MMIfaceModemMessaging *_self,
 | 
			
		||||
                                     gpointer user_data)
 | 
			
		||||
 {
 | 
			
		||||
     MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (_self);
 | 
			
		||||
+    MMPort *port = MM_PORT (mm_broadband_modem_qmi_peek_port_qmi (self));
 | 
			
		||||
 
 | 
			
		||||
     /* Handle fallback */
 | 
			
		||||
-    if (self->priv->messaging_fallback_at) {
 | 
			
		||||
+    if (self->priv->messaging_fallback_at ||
 | 
			
		||||
+        mm_kernel_device_get_global_property_as_boolean (mm_port_peek_kernel_device (port),
 | 
			
		||||
+                                                         "ID_MM_QMI_MESSAGING_AT_FALLBACK_ENABLE")) {
 | 
			
		||||
         return iface_modem_messaging_parent->setup_unsolicited_events (_self, callback, user_data);
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
diff --git a/src/mm-broadband-modem-qmi.h b/src/mm-broadband-modem-qmi.h
 | 
			
		||||
index 23825068..c9b50f15 100644
 | 
			
		||||
--- a/src/mm-broadband-modem-qmi.h
 | 
			
		||||
+++ b/src/mm-broadband-modem-qmi.h
 | 
			
		||||
@@ -46,5 +46,6 @@ MMBroadbandModemQmi *mm_broadband_modem_qmi_new (const gchar *device,
 | 
			
		||||
                                                  const gchar *plugin,
 | 
			
		||||
                                                  guint16 vendor_id,
 | 
			
		||||
                                                  guint16 product_id);
 | 
			
		||||
+MMPortQmi *mm_broadband_modem_qmi_peek_port_qmi  (MMBroadbandModemQmi  *self);
 | 
			
		||||
 
 | 
			
		||||
 #endif /* MM_BROADBAND_MODEM_QMI_H */
 | 
			
		||||
-- 
 | 
			
		||||
2.30.0
 | 
			
		||||
@@ -0,0 +1,7 @@
 | 
			
		||||
// Let users in plugdev group modify ModemManager
 | 
			
		||||
polkit.addRule(function(action, subject) {
 | 
			
		||||
    if (/^org\.freedesktop\.ModemManager1\.(Device\.Control|Contacts|Messaging|Location)$/.test(action.id) &&
 | 
			
		||||
        subject.isInGroup("plugdev") && subject.active) {
 | 
			
		||||
        return "yes";
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										11
									
								
								net-misc/modemmanager/files/modemmanager-pp.rules
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								net-misc/modemmanager/files/modemmanager-pp.rules
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
// Let users in plugdev group modify ModemManager
 | 
			
		||||
polkit.addRule(function(action, subject) {
 | 
			
		||||
    if ((action.id == "org.freedesktop.ModemManager1.Device.Control" ||
 | 
			
		||||
	action.id == "org.freedesktop.ModemManager1.Contacts" ||
 | 
			
		||||
	action.id == "org.freedesktop.ModemManager1.Messaging" ||
 | 
			
		||||
	action.id == "org.freedesktop.ModemManager1.Location") &&
 | 
			
		||||
        subject.isInGroup("plugdev") && subject.active) {
 | 
			
		||||
        return "yes";
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3
									
								
								net-misc/modemmanager/files/rpmsg-udev.rules
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								net-misc/modemmanager/files/rpmsg-udev.rules
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
SYMLINK=="modem", SUBSYSTEM=="rpmsg", ENV{ID_MM_CANDIDATE}="1", ENV{ID_MM_DEVICE_PROCESS}="1", ENV{ID_MM_PORT_TYPE_QCDM}="1", ENV{ID_MM_PHYSDEV_UID}="qcom-rpmsg"
 | 
			
		||||
SYMLINK=="modem-at", SUBSYSTEM=="rpmsg", ENV{ID_MM_CANDIDATE}="1", ENV{ID_MM_DEVICE_PROCESS}="1", ENV{ID_MM_PHYSDEV_UID}="qcom-rpmsg"
 | 
			
		||||
ENV{INTERFACE}=="rmnet0", SUBSYSTEM=="net", ENV{ID_MM_CANDIDATE}="1", ENV{ID_MM_DEVICE_PROCESS}="1", ENV{ID_MM_PHYSDEV_UID}="qcom-rpmsg"
 | 
			
		||||
@@ -0,0 +1,264 @@
 | 
			
		||||
From 6fad8948a7ba16c857b813ec532f32906055c695 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dylan Van Assche <me@dylanvanassche.be>
 | 
			
		||||
Date: Sat, 6 Feb 2021 07:52:32 +0100
 | 
			
		||||
Subject: [PATCH] suspend: add boot timer
 | 
			
		||||
 | 
			
		||||
The EG25 modem needs at least 2 minutes after indicating 'RDY'
 | 
			
		||||
to be fully operational. If the modem is suspended before that,
 | 
			
		||||
calls or texts may not be seen by the userspace.
 | 
			
		||||
This mostly occurs when a full reboot or poweroff/poweron
 | 
			
		||||
sequence of the phone is performed.
 | 
			
		||||
---
 | 
			
		||||
 src/at.c      | 19 ++++++++++-
 | 
			
		||||
 src/manager.h |  2 ++
 | 
			
		||||
 src/suspend.c | 95 +++++++++++++++++++++++++++++++++++++++++++--------
 | 
			
		||||
 src/suspend.h |  1 +
 | 
			
		||||
 4 files changed, 101 insertions(+), 16 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/src/at.c b/src/at.c
 | 
			
		||||
index 39a857a..c8fa6f5 100644
 | 
			
		||||
--- a/src/at.c
 | 
			
		||||
+++ b/src/at.c
 | 
			
		||||
@@ -17,6 +17,7 @@
 | 
			
		||||
 #include <glib-unix.h>
 | 
			
		||||
 
 | 
			
		||||
 #define MODEM_UART "/dev/ttyS2"
 | 
			
		||||
+#define FULL_BOOT_DELAY 120
 | 
			
		||||
 
 | 
			
		||||
 struct AtCommand {
 | 
			
		||||
     char *cmd;
 | 
			
		||||
@@ -26,6 +27,20 @@ struct AtCommand {
 | 
			
		||||
     int retries;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
+/*
 | 
			
		||||
+ * After the EG25 modem sends 'RDY', it takes up to 2 minutes before all
 | 
			
		||||
+ * capabilities are operational. If the modem is suspended before that,
 | 
			
		||||
+ * calls and texts may be not recognized properly.
 | 
			
		||||
+ */
 | 
			
		||||
+static gboolean modem_fully_booted(struct EG25Manager *manager)
 | 
			
		||||
+{
 | 
			
		||||
+    g_message("Modem is up for %d seconds and fully ready", FULL_BOOT_DELAY);
 | 
			
		||||
+    manager->boot_timer = 0;
 | 
			
		||||
+    boot_inhibit(manager, FALSE);
 | 
			
		||||
+
 | 
			
		||||
+    return FALSE;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static int configure_serial(const char *tty)
 | 
			
		||||
 {
 | 
			
		||||
     struct termios ttycfg;
 | 
			
		||||
@@ -202,8 +217,10 @@ static gboolean modem_response(gint fd,
 | 
			
		||||
 
 | 
			
		||||
         g_message("Response: [%s]", response);
 | 
			
		||||
 
 | 
			
		||||
-        if (strcmp(response, "RDY") == 0)
 | 
			
		||||
+        if (strcmp(response, "RDY") == 0) {
 | 
			
		||||
+            manager->boot_timer = g_timeout_add_seconds(FULL_BOOT_DELAY, G_SOURCE_FUNC(modem_fully_booted), manager);
 | 
			
		||||
             manager->modem_state = EG25_STATE_STARTED;
 | 
			
		||||
+        }
 | 
			
		||||
         else if (strstr(response, "ERROR"))
 | 
			
		||||
             retry_at_command(manager);
 | 
			
		||||
         else if (strstr(response, "OK"))
 | 
			
		||||
diff --git a/src/manager.h b/src/manager.h
 | 
			
		||||
index f6351be..d00754d 100644
 | 
			
		||||
--- a/src/manager.h
 | 
			
		||||
+++ b/src/manager.h
 | 
			
		||||
@@ -44,7 +44,9 @@ struct EG25Manager {
 | 
			
		||||
 
 | 
			
		||||
     GDBusProxy *suspend_proxy;
 | 
			
		||||
     int suspend_inhibit_fd;
 | 
			
		||||
+    int boot_inhibit_fd;
 | 
			
		||||
     guint suspend_timer;
 | 
			
		||||
+    guint boot_timer;
 | 
			
		||||
 
 | 
			
		||||
     GUdevClient *udev;
 | 
			
		||||
 
 | 
			
		||||
diff --git a/src/suspend.c b/src/suspend.c
 | 
			
		||||
index 4b1a026..93e0c84 100644
 | 
			
		||||
--- a/src/suspend.c
 | 
			
		||||
+++ b/src/suspend.c
 | 
			
		||||
@@ -26,10 +26,10 @@ static gboolean check_modem_resume(struct EG25Manager *manager)
 | 
			
		||||
     return FALSE;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static gboolean drop_inhibitor(struct EG25Manager *manager)
 | 
			
		||||
+static gboolean drop_inhibitor_suspend(struct EG25Manager *manager)
 | 
			
		||||
 {
 | 
			
		||||
     if (manager->suspend_inhibit_fd >= 0) {
 | 
			
		||||
-        g_message("dropping systemd sleep inhibitor");
 | 
			
		||||
+        g_message("dropping systemd sleep suspend inhibitor");
 | 
			
		||||
         close(manager->suspend_inhibit_fd);
 | 
			
		||||
         manager->suspend_inhibit_fd = -1;
 | 
			
		||||
         return TRUE;
 | 
			
		||||
@@ -37,7 +37,18 @@ static gboolean drop_inhibitor(struct EG25Manager *manager)
 | 
			
		||||
     return FALSE;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static void inhibit_done(GObject *source,
 | 
			
		||||
+static gboolean drop_inhibitor_boot(struct EG25Manager *manager)
 | 
			
		||||
+{
 | 
			
		||||
+    if (manager->boot_inhibit_fd >= 0) {
 | 
			
		||||
+        g_message("dropping systemd sleep boot inhibitor");
 | 
			
		||||
+        close(manager->boot_inhibit_fd);
 | 
			
		||||
+        manager->boot_inhibit_fd = -1;
 | 
			
		||||
+        return TRUE;
 | 
			
		||||
+    }
 | 
			
		||||
+    return FALSE;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static void inhibit_done_suspend(GObject *source,
 | 
			
		||||
                          GAsyncResult *result,
 | 
			
		||||
                          gpointer user_data)
 | 
			
		||||
 {
 | 
			
		||||
@@ -56,25 +67,65 @@ static void inhibit_done(GObject *source,
 | 
			
		||||
 
 | 
			
		||||
         manager->suspend_inhibit_fd = g_unix_fd_list_get(fd_list, 0, NULL);
 | 
			
		||||
 
 | 
			
		||||
-        g_message("inhibitor fd is %d", manager->suspend_inhibit_fd);
 | 
			
		||||
+        g_message("inhibitor sleep fd is %d", manager->suspend_inhibit_fd);
 | 
			
		||||
         g_object_unref(fd_list);
 | 
			
		||||
         g_variant_unref(res);
 | 
			
		||||
     }
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static void take_inhibitor(struct EG25Manager *manager)
 | 
			
		||||
+static void inhibit_done_boot(GObject *source,
 | 
			
		||||
+                         GAsyncResult *result,
 | 
			
		||||
+                         gpointer user_data)
 | 
			
		||||
+{
 | 
			
		||||
+    GDBusProxy *suspend_proxy = G_DBUS_PROXY(source);
 | 
			
		||||
+    struct EG25Manager *manager = user_data;
 | 
			
		||||
+    g_autoptr (GError) error = NULL;
 | 
			
		||||
+    GVariant *res;
 | 
			
		||||
+    GUnixFDList *fd_list;
 | 
			
		||||
+
 | 
			
		||||
+    res = g_dbus_proxy_call_with_unix_fd_list_finish(suspend_proxy, &fd_list, result, &error);
 | 
			
		||||
+    if (!res) {
 | 
			
		||||
+        g_warning("inhibit failed: %s", error->message);
 | 
			
		||||
+    } else {
 | 
			
		||||
+        if (!fd_list || g_unix_fd_list_get_length(fd_list) != 1)
 | 
			
		||||
+            g_warning("didn't get a single fd back");
 | 
			
		||||
+
 | 
			
		||||
+        manager->boot_inhibit_fd = g_unix_fd_list_get(fd_list, 0, NULL);
 | 
			
		||||
+
 | 
			
		||||
+        g_message("inhibitor boot fd is %d", manager->boot_inhibit_fd);
 | 
			
		||||
+        g_object_unref(fd_list);
 | 
			
		||||
+        g_variant_unref(res);
 | 
			
		||||
+    }
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static void take_inhibitor_suspend(struct EG25Manager *manager)
 | 
			
		||||
 {
 | 
			
		||||
     GVariant *variant_arg;
 | 
			
		||||
 
 | 
			
		||||
     if(manager->suspend_inhibit_fd != -1)
 | 
			
		||||
-        drop_inhibitor(manager);
 | 
			
		||||
+        drop_inhibitor_suspend(manager);
 | 
			
		||||
 
 | 
			
		||||
     variant_arg = g_variant_new ("(ssss)", "sleep", "eg25manager",
 | 
			
		||||
                                  "eg25manager needs to prepare modem for sleep", "delay");
 | 
			
		||||
 
 | 
			
		||||
-    g_message("taking systemd sleep inhibitor");
 | 
			
		||||
+    g_message("taking systemd sleep suspend inhibitor");
 | 
			
		||||
     g_dbus_proxy_call_with_unix_fd_list(manager->suspend_proxy, "Inhibit", variant_arg,
 | 
			
		||||
-                                        0, G_MAXINT, NULL, NULL, inhibit_done, manager);
 | 
			
		||||
+                                        0, G_MAXINT, NULL, NULL, inhibit_done_suspend, manager);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static void take_inhibitor_boot(struct EG25Manager *manager)
 | 
			
		||||
+{
 | 
			
		||||
+    GVariant *variant_arg;
 | 
			
		||||
+
 | 
			
		||||
+    if(manager->boot_inhibit_fd != -1)
 | 
			
		||||
+        drop_inhibitor_boot(manager);
 | 
			
		||||
+
 | 
			
		||||
+    variant_arg = g_variant_new ("(ssss)", "sleep", "eg25manager",
 | 
			
		||||
+                                 "eg25manager needs to wait for modem to be fully booted", "block");
 | 
			
		||||
+
 | 
			
		||||
+    g_message("taking systemd sleep boot inhibitor");
 | 
			
		||||
+    g_dbus_proxy_call_with_unix_fd_list(manager->suspend_proxy, "Inhibit", variant_arg,
 | 
			
		||||
+                                        0, G_MAXINT, NULL, NULL, inhibit_done_boot, manager);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void signal_cb(GDBusProxy *proxy,
 | 
			
		||||
@@ -97,7 +148,7 @@ static void signal_cb(GDBusProxy *proxy,
 | 
			
		||||
         modem_suspend_pre(manager);
 | 
			
		||||
     } else {
 | 
			
		||||
         g_message("system is resuming");
 | 
			
		||||
-        take_inhibitor(manager);
 | 
			
		||||
+        take_inhibitor_suspend(manager);
 | 
			
		||||
         modem_resume_pre(manager);
 | 
			
		||||
         if (manager->mm_modem) {
 | 
			
		||||
             /*
 | 
			
		||||
@@ -126,10 +177,10 @@ static void name_owner_cb(GObject *object,
 | 
			
		||||
 
 | 
			
		||||
     owner = g_dbus_proxy_get_name_owner(proxy);
 | 
			
		||||
     if (owner) {
 | 
			
		||||
-        take_inhibitor(manager);
 | 
			
		||||
+        take_inhibitor_suspend(manager);
 | 
			
		||||
         g_free(owner);
 | 
			
		||||
     } else {
 | 
			
		||||
-        drop_inhibitor(manager);
 | 
			
		||||
+        drop_inhibitor_suspend(manager);
 | 
			
		||||
     }
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -151,7 +202,8 @@ static void on_proxy_acquired(GObject *object,
 | 
			
		||||
 
 | 
			
		||||
     owner = g_dbus_proxy_get_name_owner(manager->suspend_proxy);
 | 
			
		||||
     if (owner) {
 | 
			
		||||
-        take_inhibitor(manager);
 | 
			
		||||
+        take_inhibitor_suspend(manager);
 | 
			
		||||
+        take_inhibitor_boot(manager);
 | 
			
		||||
         g_free(owner);
 | 
			
		||||
     }
 | 
			
		||||
 }
 | 
			
		||||
@@ -167,11 +219,16 @@ void suspend_init(struct EG25Manager *manager)
 | 
			
		||||
 
 | 
			
		||||
 void suspend_destroy(struct EG25Manager *manager)
 | 
			
		||||
 {
 | 
			
		||||
-    drop_inhibitor(manager);
 | 
			
		||||
+    drop_inhibitor_suspend(manager);
 | 
			
		||||
     if (manager->suspend_timer) {
 | 
			
		||||
         g_source_remove(manager->suspend_timer);
 | 
			
		||||
         manager->suspend_timer = 0;
 | 
			
		||||
     }
 | 
			
		||||
+    drop_inhibitor_boot(manager);
 | 
			
		||||
+    if (manager->boot_timer) {
 | 
			
		||||
+        g_source_remove(manager->boot_timer);
 | 
			
		||||
+        manager->boot_timer = 0;
 | 
			
		||||
+    }
 | 
			
		||||
     if (manager->suspend_proxy) {
 | 
			
		||||
         g_object_unref(manager->suspend_proxy);
 | 
			
		||||
         manager->suspend_proxy = NULL;
 | 
			
		||||
@@ -181,7 +238,15 @@ void suspend_destroy(struct EG25Manager *manager)
 | 
			
		||||
 void suspend_inhibit(struct EG25Manager *manager, gboolean inhibit)
 | 
			
		||||
 {
 | 
			
		||||
     if (inhibit)
 | 
			
		||||
-        take_inhibitor(manager);
 | 
			
		||||
+        take_inhibitor_suspend(manager);
 | 
			
		||||
+    else
 | 
			
		||||
+        drop_inhibitor_suspend(manager);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+void boot_inhibit(struct EG25Manager *manager, gboolean inhibit)
 | 
			
		||||
+{
 | 
			
		||||
+    if (inhibit)
 | 
			
		||||
+        take_inhibitor_boot(manager);
 | 
			
		||||
     else
 | 
			
		||||
-        drop_inhibitor(manager);
 | 
			
		||||
+        drop_inhibitor_boot(manager);
 | 
			
		||||
 }
 | 
			
		||||
diff --git a/src/suspend.h b/src/suspend.h
 | 
			
		||||
index 39832aa..38e591c 100644
 | 
			
		||||
--- a/src/suspend.h
 | 
			
		||||
+++ b/src/suspend.h
 | 
			
		||||
@@ -12,3 +12,4 @@ void suspend_init (struct EG25Manager *data);
 | 
			
		||||
 void suspend_destroy (struct EG25Manager *data);
 | 
			
		||||
 
 | 
			
		||||
 void suspend_inhibit (struct EG25Manager *data, gboolean inhibit);
 | 
			
		||||
+void boot_inhibit (struct EG25Manager *data, gboolean inhibit);
 | 
			
		||||
-- 
 | 
			
		||||
2.30.1
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										434
									
								
								net-misc/modemmanager/files/temp_modemmanager_rpmsg.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										434
									
								
								net-misc/modemmanager/files/temp_modemmanager_rpmsg.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,434 @@
 | 
			
		||||
From 482cfce46e1f8ec546499b782c2c2d96e6a9203e Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Stephan Gerhold <stephan@gerhold.net>
 | 
			
		||||
Date: Sat, 21 Dec 2019 18:30:13 +0100
 | 
			
		||||
Subject: [PATCH] core: Add support for Qualcomm MSM/QMI modems via rpmsg
 | 
			
		||||
 | 
			
		||||
Most older Qualcomm SoCs (e.g. MSM8916, MSM8974, ...) communicate with
 | 
			
		||||
the integrated modem via shared memory (SMD channels). This is similar
 | 
			
		||||
to QRTR on newer SoCs, but without the "network" layer. In fact, the older
 | 
			
		||||
SoCs also have QRTR, but the modem QMI services are not exposed there.
 | 
			
		||||
 | 
			
		||||
The mainline Linux kernel exposes SMD channels via the "remote processor
 | 
			
		||||
messaging bus" (rpmsg). Through special IOCTL calls it is possible to
 | 
			
		||||
create a char device for a rpmsg/SMD channel. We can then use these to
 | 
			
		||||
send QMI/AT messages to the modem, much like the ordinary serial char
 | 
			
		||||
devices when using a Qualcomm modem through USB.
 | 
			
		||||
 | 
			
		||||
The QMI/AT messages needed to use the modem seem to be pretty much
 | 
			
		||||
the same as when using QMI via USB. We have tested on a few smartphones
 | 
			
		||||
with MSM8916 which are running a (close-to) mainline kernel, e.g.:
 | 
			
		||||
 | 
			
		||||
   - BQ Aquaris X5
 | 
			
		||||
   - Motorola Moto G4 Play
 | 
			
		||||
   - Samsung Galaxy A3/A5 (2015)
 | 
			
		||||
   - Wileyfox Swift
 | 
			
		||||
   - Xiaomi Redmi 2
 | 
			
		||||
 | 
			
		||||
Most of the modem functionality seems to be working fine, without any
 | 
			
		||||
changes to the QMI/AT messages that are sent to the modem:
 | 
			
		||||
 | 
			
		||||
   - Voice calls
 | 
			
		||||
   - SMS
 | 
			
		||||
   - Mobile Internet
 | 
			
		||||
   - GPS (modem sends NMEA messages, so far we were unable to get a fix
 | 
			
		||||
          for some reason...)
 | 
			
		||||
 | 
			
		||||
However, note that the implementation of voice call audio and network
 | 
			
		||||
interface is very different from the USB modems. It is completely
 | 
			
		||||
independent of the rpmsg channels that are used to control the modem.
 | 
			
		||||
I have written special drivers for:
 | 
			
		||||
 | 
			
		||||
  - Voice call audio (q6voice) [1]
 | 
			
		||||
  - Network interface (BAM DMUX) [2]
 | 
			
		||||
    (Note: Newer SoCs use IPA (IP Accelerator) instead of BAM DMUX...)
 | 
			
		||||
 | 
			
		||||
I have plans to upstream these, but there is still some more work
 | 
			
		||||
needed (mostly fine tuning for some edge cases). This is independent of the
 | 
			
		||||
changes in ModemManager, because the additional drivers are only necessary
 | 
			
		||||
if you want to have audio/Internet actually working.
 | 
			
		||||
 | 
			
		||||
This commit adds support for probing rpmsg ports within ModemManager.
 | 
			
		||||
I think most of the changes are quite straightforward, but there are
 | 
			
		||||
some FIXME comments scattered over the code where I was not sure about
 | 
			
		||||
the best way to implement it. Those still need to be discussed :)
 | 
			
		||||
 | 
			
		||||
Note: This commit does not add the udev rules necessary to use rpmsg
 | 
			
		||||
modems with ModemManager. The reason for that is that you typically need
 | 
			
		||||
additional system services/tools and udev rules anyway for the modem to work.
 | 
			
		||||
 | 
			
		||||
Currently I'm using:
 | 
			
		||||
 | 
			
		||||
    SYMLINK=="modem", SUBSYSTEM=="rpmsg", ENV{ID_MM_CANDIDATE}="1", ENV{ID_MM_DEVICE_PROCESS}="1", ENV{ID_MM_PORT_TYPE_QCDM}="1", ENV{ID_MM_PHYSDEV_UID}="qcom-rpmsg"
 | 
			
		||||
    SYMLINK=="modem-at", SUBSYSTEM=="rpmsg", ENV{ID_MM_CANDIDATE}="1", ENV{ID_MM_DEVICE_PROCESS}="1", ENV{ID_MM_PHYSDEV_UID}="qcom-rpmsg"
 | 
			
		||||
    ENV{INTERFACE}=="rmnet0", SUBSYSTEM=="net", ENV{ID_MM_CANDIDATE}="1", ENV{ID_MM_DEVICE_PROCESS}="1", ENV{ID_MM_PHYSDEV_UID}="qcom-rpmsg"
 | 
			
		||||
 | 
			
		||||
The purpose of `ENV{ID_MM_PHYSDEV_UID}` is to link the network interface
 | 
			
		||||
to the modem in ModemManager, since it isn't related to the rpmsg ports
 | 
			
		||||
in any way. Of course this is rather naive because there could be also
 | 
			
		||||
other network interfaces called `rmnet0`...
 | 
			
		||||
 | 
			
		||||
Also, the udev rules assume that we already have set up the rpmsg
 | 
			
		||||
char devices at /dev/modem (SMD channel `DATA5_CNTL`) and /dev/modem-at
 | 
			
		||||
(SMD channel `DATA4`). Those can be set up using rpmsgexport [3].
 | 
			
		||||
In postmarketOS [4], this is handled using additional udev rules, see [5].
 | 
			
		||||
 | 
			
		||||
[1]: https://github.com/msm8916-mainline/linux/commits/q6voice
 | 
			
		||||
[2]: https://github.com/msm8916-mainline/linux/commits/bam-dmux
 | 
			
		||||
[3]: https://github.com/andersson/rpmsgexport
 | 
			
		||||
[4]: https://postmarketos.org
 | 
			
		||||
[5]: https://gitlab.com/postmarketOS/pmaports/-/blob/master/modem/msm-modem/udev-rpmsg.rules
 | 
			
		||||
---
 | 
			
		||||
 plugins/generic/mm-plugin-generic.c |  2 +-
 | 
			
		||||
 src/mm-base-manager.c               | 12 +++++--
 | 
			
		||||
 src/mm-base-modem.c                 | 55 ++++++++++++++++++++++++-----
 | 
			
		||||
 src/mm-broadband-modem-qmi.c        | 12 ++++++-
 | 
			
		||||
 src/mm-plugin.c                     | 19 ++++++++++
 | 
			
		||||
 src/mm-port-probe.c                 | 24 ++++++++++---
 | 
			
		||||
 src/mm-port-qmi.c                   |  7 ++--
 | 
			
		||||
 src/mm-port-qmi.h                   |  2 +-
 | 
			
		||||
 src/mm-port-serial-at.c             |  3 +-
 | 
			
		||||
 src/mm-port.h                       |  3 +-
 | 
			
		||||
 10 files changed, 118 insertions(+), 21 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/plugins/generic/mm-plugin-generic.c b/plugins/generic/mm-plugin-generic.c
 | 
			
		||||
index c2e3a07e..db4e3462 100644
 | 
			
		||||
--- a/plugins/generic/mm-plugin-generic.c
 | 
			
		||||
+++ b/plugins/generic/mm-plugin-generic.c
 | 
			
		||||
@@ -91,7 +91,7 @@ create_modem (MMPlugin *self,
 | 
			
		||||
 G_MODULE_EXPORT MMPlugin *
 | 
			
		||||
 mm_plugin_create (void)
 | 
			
		||||
 {
 | 
			
		||||
-    static const gchar *subsystems[] = { "tty", "net", "usb", NULL };
 | 
			
		||||
+    static const gchar *subsystems[] = { "tty", "net", "usb", "rpmsg", NULL };
 | 
			
		||||
 
 | 
			
		||||
     return MM_PLUGIN (
 | 
			
		||||
         g_object_new (MM_TYPE_PLUGIN_GENERIC,
 | 
			
		||||
diff --git a/src/mm-base-manager.c b/src/mm-base-manager.c
 | 
			
		||||
index 653adb5c..da2a3294 100644
 | 
			
		||||
--- a/src/mm-base-manager.c
 | 
			
		||||
+++ b/src/mm-base-manager.c
 | 
			
		||||
@@ -467,7 +467,8 @@ handle_uevent (GUdevClient *client,
 | 
			
		||||
     /* A bit paranoid */
 | 
			
		||||
     subsys = g_udev_device_get_subsystem (device);
 | 
			
		||||
     g_return_if_fail (subsys != NULL);
 | 
			
		||||
-    g_return_if_fail (g_str_equal (subsys, "tty") || g_str_equal (subsys, "net") || g_str_has_prefix (subsys, "usb"));
 | 
			
		||||
+    g_return_if_fail (g_str_equal (subsys, "tty") || g_str_equal (subsys, "net") ||
 | 
			
		||||
+                      g_str_has_prefix (subsys, "usb") || g_str_equal (subsys, "rpmsg"));
 | 
			
		||||
 
 | 
			
		||||
     kernel_device = mm_kernel_device_udev_new (device);
 | 
			
		||||
 
 | 
			
		||||
@@ -561,6 +562,13 @@ process_scan (MMBaseManager *self,
 | 
			
		||||
         g_object_unref (G_OBJECT (iter->data));
 | 
			
		||||
     }
 | 
			
		||||
     g_list_free (devices);
 | 
			
		||||
+
 | 
			
		||||
+    devices = g_udev_client_query_by_subsystem (self->priv->udev, "rpmsg");
 | 
			
		||||
+    for (iter = devices; iter; iter = g_list_next (iter)) {
 | 
			
		||||
+        start_device_added (self, G_UDEV_DEVICE (iter->data), manual_scan);
 | 
			
		||||
+        g_object_unref (G_OBJECT (iter->data));
 | 
			
		||||
+    }
 | 
			
		||||
+    g_list_free (devices);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 #endif
 | 
			
		||||
@@ -1448,7 +1456,7 @@ mm_base_manager_init (MMBaseManager *self)
 | 
			
		||||
 
 | 
			
		||||
 #if defined WITH_UDEV
 | 
			
		||||
     {
 | 
			
		||||
-        const gchar *subsys[5] = { "tty", "net", "usb", "usbmisc", NULL };
 | 
			
		||||
+        const gchar *subsys[] = { "tty", "net", "usb", "usbmisc", "rpmsg", NULL };
 | 
			
		||||
 
 | 
			
		||||
         /* Setup UDev client */
 | 
			
		||||
         self->priv->udev = g_udev_client_new (subsys);
 | 
			
		||||
diff --git a/src/mm-base-modem.c b/src/mm-base-modem.c
 | 
			
		||||
index 0805cedb..e4aef11a 100644
 | 
			
		||||
--- a/src/mm-base-modem.c
 | 
			
		||||
+++ b/src/mm-base-modem.c
 | 
			
		||||
@@ -175,6 +175,7 @@ mm_base_modem_grab_port (MMBaseModem         *self,
 | 
			
		||||
     if (!g_str_equal (subsys, "net") &&
 | 
			
		||||
         !g_str_equal (subsys, "tty") &&
 | 
			
		||||
         !(g_str_has_prefix (subsys, "usb") && g_str_has_prefix (name, "cdc-wdm")) &&
 | 
			
		||||
+        !g_str_equal (subsys, "rpmsg") &&
 | 
			
		||||
         !g_str_equal (subsys, "virtual")) {
 | 
			
		||||
         g_set_error (error,
 | 
			
		||||
                      MM_CORE_ERROR,
 | 
			
		||||
@@ -297,7 +298,7 @@ mm_base_modem_grab_port (MMBaseModem         *self,
 | 
			
		||||
              g_str_has_prefix (name, "cdc-wdm")) {
 | 
			
		||||
 #if defined WITH_QMI
 | 
			
		||||
         if (ptype == MM_PORT_TYPE_QMI)
 | 
			
		||||
-            port = MM_PORT (mm_port_qmi_new (name));
 | 
			
		||||
+            port = MM_PORT (mm_port_qmi_new (name, MM_PORT_SUBSYS_USB));
 | 
			
		||||
 #endif
 | 
			
		||||
 #if defined WITH_MBIM
 | 
			
		||||
         if (!port && ptype == MM_PORT_TYPE_MBIM)
 | 
			
		||||
@@ -340,6 +341,36 @@ mm_base_modem_grab_port (MMBaseModem         *self,
 | 
			
		||||
         /* Store flags already */
 | 
			
		||||
         mm_port_serial_at_set_flags (MM_PORT_SERIAL_AT (port), at_pflags);
 | 
			
		||||
     }
 | 
			
		||||
+    /* rpmsg ports... */
 | 
			
		||||
+    else if (g_str_equal (subsys, "rpmsg")) {
 | 
			
		||||
+#if defined WITH_QMI
 | 
			
		||||
+        if (ptype == MM_PORT_TYPE_QMI)
 | 
			
		||||
+            port = MM_PORT (mm_port_qmi_new (name, MM_PORT_SUBSYS_RPMSG));
 | 
			
		||||
+#endif
 | 
			
		||||
+        /* Non-serial AT port */
 | 
			
		||||
+        if (!port && ptype == MM_PORT_TYPE_AT) {
 | 
			
		||||
+            port = MM_PORT (mm_port_serial_at_new (name, MM_PORT_SUBSYS_RPMSG));
 | 
			
		||||
+
 | 
			
		||||
+            /* Set common response parser */
 | 
			
		||||
+            mm_port_serial_at_set_response_parser (MM_PORT_SERIAL_AT (port),
 | 
			
		||||
+                                                   mm_serial_parser_v1_parse,
 | 
			
		||||
+                                                   mm_serial_parser_v1_new (),
 | 
			
		||||
+                                                   mm_serial_parser_v1_destroy);
 | 
			
		||||
+            /* Store flags already */
 | 
			
		||||
+            mm_port_serial_at_set_flags (MM_PORT_SERIAL_AT (port), at_pflags);
 | 
			
		||||
+        }
 | 
			
		||||
+
 | 
			
		||||
+        if (!port) {
 | 
			
		||||
+            g_set_error (error,
 | 
			
		||||
+                         MM_CORE_ERROR,
 | 
			
		||||
+                         MM_CORE_ERROR_UNSUPPORTED,
 | 
			
		||||
+                         "Cannot add port '%s/%s', unsupported",
 | 
			
		||||
+                         subsys,
 | 
			
		||||
+                         name);
 | 
			
		||||
+            g_free (key);
 | 
			
		||||
+            return FALSE;
 | 
			
		||||
+        }
 | 
			
		||||
+    }
 | 
			
		||||
     else
 | 
			
		||||
         /* We already filter out before all non-tty, non-net, non-cdc-wdm ports */
 | 
			
		||||
         g_assert_not_reached ();
 | 
			
		||||
@@ -711,7 +742,17 @@ mm_base_modem_peek_port_qmi_for_data (MMBaseModem *self,
 | 
			
		||||
 {
 | 
			
		||||
     GList *cdc_wdm_qmi_ports, *l;
 | 
			
		||||
     const gchar *net_port_parent_path;
 | 
			
		||||
-    MMPortQmi *found = NULL;
 | 
			
		||||
+    MMPortQmi *found = NULL, *primary;
 | 
			
		||||
+
 | 
			
		||||
+    /* FIXME: For RPMSG modems the network interface is not related to the
 | 
			
		||||
+     * QMI device, they are managed through completely different subsystems.
 | 
			
		||||
+     * For now there should be just one QMI and one net port so we can just
 | 
			
		||||
+     * return the primary QMI port.
 | 
			
		||||
+     */
 | 
			
		||||
+    primary = mm_base_modem_peek_port_qmi (MM_BASE_MODEM (self));
 | 
			
		||||
+    if (primary && mm_port_get_subsys (MM_PORT (primary)) == MM_PORT_SUBSYS_RPMSG)
 | 
			
		||||
+            /* Assume there is just one QMI port */
 | 
			
		||||
+            return primary;
 | 
			
		||||
 
 | 
			
		||||
     g_warn_if_fail (mm_port_get_subsys (data) == MM_PORT_SUBSYS_NET);
 | 
			
		||||
     net_port_parent_path = mm_kernel_device_get_interface_sysfs_path (mm_port_peek_kernel_device (data));
 | 
			
		||||
@@ -1239,13 +1280,11 @@ mm_base_modem_organize_ports (MMBaseModem *self,
 | 
			
		||||
         secondary = backup_primary ? backup_primary : backup_secondary;
 | 
			
		||||
 
 | 
			
		||||
 #if defined WITH_QMI
 | 
			
		||||
-    /* On QMI-based modems, we need to have at least a net port */
 | 
			
		||||
+    /* On QMI-based modems, a net port is required for broadband.
 | 
			
		||||
+     * However, all other functionality works without so just warn about this.
 | 
			
		||||
+     */
 | 
			
		||||
     if (qmi_primary && !data_primary) {
 | 
			
		||||
-        g_set_error_literal (error,
 | 
			
		||||
-                             MM_CORE_ERROR,
 | 
			
		||||
-                             MM_CORE_ERROR_FAILED,
 | 
			
		||||
-                             "Failed to find a net port in the QMI modem");
 | 
			
		||||
-        return FALSE;
 | 
			
		||||
+        mm_obj_warn (self, "Failed to find a net port in the QMI modem");
 | 
			
		||||
     }
 | 
			
		||||
 #endif
 | 
			
		||||
 
 | 
			
		||||
diff --git a/src/mm-broadband-modem-qmi.c b/src/mm-broadband-modem-qmi.c
 | 
			
		||||
index 83e808c2..e641c401 100644
 | 
			
		||||
--- a/src/mm-broadband-modem-qmi.c
 | 
			
		||||
+++ b/src/mm-broadband-modem-qmi.c
 | 
			
		||||
@@ -9457,7 +9457,17 @@ initialization_started (MMBroadbandModem *self,
 | 
			
		||||
 
 | 
			
		||||
     /* Now open our QMI port */
 | 
			
		||||
     mm_port_qmi_open (ctx->qmi,
 | 
			
		||||
-                      TRUE,
 | 
			
		||||
+                      /* FIXME: Parts of the "data format" functionality on libqmi
 | 
			
		||||
+                       * assume that we are talking to qmi_wwan, which exposes the
 | 
			
		||||
+                       * kernel data format through sysfs.
 | 
			
		||||
+                       *
 | 
			
		||||
+                       * For RPMSG modems the driver that manages the net port
 | 
			
		||||
+                       * is a different one, and setting the kernel data format
 | 
			
		||||
+                       * therefore eventually works differently there.
 | 
			
		||||
+                       * For now skip setting the data format entirely for RPMSG
 | 
			
		||||
+                       * to avoid a Segmentation Fault.
 | 
			
		||||
+                       */
 | 
			
		||||
+                      mm_port_get_subsys (MM_PORT (ctx->qmi)) != MM_PORT_SUBSYS_RPMSG,
 | 
			
		||||
                       NULL,
 | 
			
		||||
                       (GAsyncReadyCallback)qmi_port_open_ready,
 | 
			
		||||
                       task);
 | 
			
		||||
diff --git a/src/mm-plugin.c b/src/mm-plugin.c
 | 
			
		||||
index 77bd6528..f6bee411 100644
 | 
			
		||||
--- a/src/mm-plugin.c
 | 
			
		||||
+++ b/src/mm-plugin.c
 | 
			
		||||
@@ -773,6 +773,12 @@ mm_plugin_supports_port (MMPlugin            *self,
 | 
			
		||||
 
 | 
			
		||||
     /* Build flags depending on what probing needed */
 | 
			
		||||
     probe_run_flags = MM_PORT_PROBE_NONE;
 | 
			
		||||
+    if (g_str_equal (mm_kernel_device_get_subsystem (port), "rpmsg")) {
 | 
			
		||||
+        if (self->priv->at)
 | 
			
		||||
+            probe_run_flags |= MM_PORT_PROBE_AT;
 | 
			
		||||
+        if (self->priv->qmi)
 | 
			
		||||
+            probe_run_flags |= MM_PORT_PROBE_QMI;
 | 
			
		||||
+    } else
 | 
			
		||||
     if (!g_str_has_prefix (mm_kernel_device_get_name (port), "cdc-wdm")) {
 | 
			
		||||
         /* Serial ports... */
 | 
			
		||||
         if (self->priv->at)
 | 
			
		||||
@@ -958,6 +964,18 @@ mm_plugin_create_modem (MMPlugin  *self,
 | 
			
		||||
             }
 | 
			
		||||
 
 | 
			
		||||
 #if defined WITH_QMI
 | 
			
		||||
+/* FIXME: For RPMSG modems the network interface usually won't be managed
 | 
			
		||||
+ * by the USB qmi_wwan driver so the check below prevents them from getting
 | 
			
		||||
+ * registered in ModemManager.
 | 
			
		||||
+ *
 | 
			
		||||
+ * I guess it should be just skipped in the RPMSG case. However, to detect that
 | 
			
		||||
+ * it seems like we would need to iterate another time over "port_probes"
 | 
			
		||||
+ * to see if the QMI port is provided by the RPMSG subsystem.
 | 
			
		||||
+ *
 | 
			
		||||
+ * I'm not sure if there is a simple way to detect this situation only based
 | 
			
		||||
+ * on the network device itself (which has nothing to do with RPMSG).
 | 
			
		||||
+ */
 | 
			
		||||
+#if 0
 | 
			
		||||
             if (MM_IS_BROADBAND_MODEM_QMI (modem) &&
 | 
			
		||||
                 port_type == MM_PORT_TYPE_NET &&
 | 
			
		||||
                 g_strcmp0 (driver, "qmi_wwan") != 0) {
 | 
			
		||||
@@ -966,6 +984,7 @@ mm_plugin_create_modem (MMPlugin  *self,
 | 
			
		||||
                 force_ignored = TRUE;
 | 
			
		||||
                 goto grab_port;
 | 
			
		||||
             }
 | 
			
		||||
+#endif
 | 
			
		||||
 
 | 
			
		||||
             if (!MM_IS_BROADBAND_MODEM_QMI (modem) &&
 | 
			
		||||
                 port_type == MM_PORT_TYPE_NET &&
 | 
			
		||||
diff --git a/src/mm-port-probe.c b/src/mm-port-probe.c
 | 
			
		||||
index 0c1edef1..b062f236 100644
 | 
			
		||||
--- a/src/mm-port-probe.c
 | 
			
		||||
+++ b/src/mm-port-probe.c
 | 
			
		||||
@@ -484,6 +484,9 @@ static void
 | 
			
		||||
 wdm_probe_qmi (MMPortProbe *self)
 | 
			
		||||
 {
 | 
			
		||||
     PortProbeRunContext *ctx;
 | 
			
		||||
+#if defined WITH_QMI
 | 
			
		||||
+    MMPortSubsys subsys = MM_PORT_SUBSYS_USB;
 | 
			
		||||
+#endif
 | 
			
		||||
 
 | 
			
		||||
     g_assert (self->priv->task);
 | 
			
		||||
     ctx = g_task_get_task_data (self->priv->task);
 | 
			
		||||
@@ -491,8 +494,11 @@ wdm_probe_qmi (MMPortProbe *self)
 | 
			
		||||
 #if defined WITH_QMI
 | 
			
		||||
     mm_obj_dbg (self, "probing QMI...");
 | 
			
		||||
 
 | 
			
		||||
+    if (g_str_equal (mm_kernel_device_get_subsystem (self->priv->port), "rpmsg"))
 | 
			
		||||
+        subsys = MM_PORT_SUBSYS_RPMSG;
 | 
			
		||||
+
 | 
			
		||||
     /* Create a port and try to open it */
 | 
			
		||||
-    ctx->port_qmi = mm_port_qmi_new (mm_kernel_device_get_name (self->priv->port));
 | 
			
		||||
+    ctx->port_qmi = mm_port_qmi_new (mm_kernel_device_get_name (self->priv->port), subsys);
 | 
			
		||||
     mm_port_qmi_open (ctx->port_qmi,
 | 
			
		||||
                       FALSE,
 | 
			
		||||
                       NULL,
 | 
			
		||||
@@ -1269,6 +1275,8 @@ serial_open_at (MMPortProbe *self)
 | 
			
		||||
 
 | 
			
		||||
         if (g_str_has_prefix (mm_kernel_device_get_subsystem (self->priv->port), "usb"))
 | 
			
		||||
             subsys = MM_PORT_SUBSYS_USB;
 | 
			
		||||
+        if (g_str_equal (mm_kernel_device_get_subsystem (self->priv->port), "rpmsg"))
 | 
			
		||||
+            subsys = MM_PORT_SUBSYS_RPMSG;
 | 
			
		||||
 
 | 
			
		||||
         ctx->serial = MM_PORT_SERIAL (mm_port_serial_at_new (mm_kernel_device_get_name (self->priv->port), subsys));
 | 
			
		||||
         if (!ctx->serial) {
 | 
			
		||||
@@ -1570,9 +1578,10 @@ mm_port_probe_is_qmi (MMPortProbe *self)
 | 
			
		||||
 
 | 
			
		||||
     subsys = mm_kernel_device_get_subsystem (self->priv->port);
 | 
			
		||||
     name = mm_kernel_device_get_name (self->priv->port);
 | 
			
		||||
-    if (!g_str_has_prefix (subsys, "usb") ||
 | 
			
		||||
-        !name ||
 | 
			
		||||
-        !g_str_has_prefix (name, "cdc-wdm"))
 | 
			
		||||
+    if ((!g_str_has_prefix (subsys, "usb") ||
 | 
			
		||||
+         !name ||
 | 
			
		||||
+         !g_str_has_prefix (name, "cdc-wdm")) &&
 | 
			
		||||
+        !g_str_equal (subsys, "rpmsg"))
 | 
			
		||||
         return FALSE;
 | 
			
		||||
 
 | 
			
		||||
     return self->priv->is_qmi;
 | 
			
		||||
@@ -1656,6 +1665,13 @@ mm_port_probe_get_port_type (MMPortProbe *self)
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
+    if (g_str_equal (subsys, "rpmsg")) {
 | 
			
		||||
+#if defined WITH_QMI
 | 
			
		||||
+        if (self->priv->is_qmi)
 | 
			
		||||
+            return MM_PORT_TYPE_QMI;
 | 
			
		||||
+#endif
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
     if (self->priv->flags & MM_PORT_PROBE_QCDM &&
 | 
			
		||||
         self->priv->is_qcdm)
 | 
			
		||||
         return MM_PORT_TYPE_QCDM;
 | 
			
		||||
diff --git a/src/mm-port-qmi.c b/src/mm-port-qmi.c
 | 
			
		||||
index 83d92b9d..0c4a4a98 100644
 | 
			
		||||
--- a/src/mm-port-qmi.c
 | 
			
		||||
+++ b/src/mm-port-qmi.c
 | 
			
		||||
@@ -788,11 +788,14 @@ mm_port_qmi_close (MMPortQmi           *self,
 | 
			
		||||
 /*****************************************************************************/
 | 
			
		||||
 
 | 
			
		||||
 MMPortQmi *
 | 
			
		||||
-mm_port_qmi_new (const gchar *name)
 | 
			
		||||
+mm_port_qmi_new (const gchar *name, MMPortSubsys subsys)
 | 
			
		||||
 {
 | 
			
		||||
+    g_return_val_if_fail (subsys == MM_PORT_SUBSYS_USB ||
 | 
			
		||||
+                          subsys == MM_PORT_SUBSYS_RPMSG, NULL);
 | 
			
		||||
+
 | 
			
		||||
     return MM_PORT_QMI (g_object_new (MM_TYPE_PORT_QMI,
 | 
			
		||||
                                       MM_PORT_DEVICE, name,
 | 
			
		||||
-                                      MM_PORT_SUBSYS, MM_PORT_SUBSYS_USB,
 | 
			
		||||
+                                      MM_PORT_SUBSYS, subsys,
 | 
			
		||||
                                       MM_PORT_TYPE, MM_PORT_TYPE_QMI,
 | 
			
		||||
                                       NULL));
 | 
			
		||||
 }
 | 
			
		||||
diff --git a/src/mm-port-qmi.h b/src/mm-port-qmi.h
 | 
			
		||||
index b4e8460c..6a5c298a 100644
 | 
			
		||||
--- a/src/mm-port-qmi.h
 | 
			
		||||
+++ b/src/mm-port-qmi.h
 | 
			
		||||
@@ -46,7 +46,7 @@ struct _MMPortQmiClass {
 | 
			
		||||
 
 | 
			
		||||
 GType mm_port_qmi_get_type (void);
 | 
			
		||||
 
 | 
			
		||||
-MMPortQmi *mm_port_qmi_new (const gchar *name);
 | 
			
		||||
+MMPortQmi *mm_port_qmi_new (const gchar *name, MMPortSubsys subsys);
 | 
			
		||||
 
 | 
			
		||||
 void     mm_port_qmi_open         (MMPortQmi            *self,
 | 
			
		||||
                                    gboolean              set_data_format,
 | 
			
		||||
diff --git a/src/mm-port-serial-at.c b/src/mm-port-serial-at.c
 | 
			
		||||
index c8e4782f..11a086ed 100644
 | 
			
		||||
--- a/src/mm-port-serial-at.c
 | 
			
		||||
+++ b/src/mm-port-serial-at.c
 | 
			
		||||
@@ -532,7 +532,8 @@ mm_port_serial_at_new (const char *name,
 | 
			
		||||
 {
 | 
			
		||||
     g_return_val_if_fail (subsys == MM_PORT_SUBSYS_TTY ||
 | 
			
		||||
                           subsys == MM_PORT_SUBSYS_USB ||
 | 
			
		||||
-                          subsys == MM_PORT_SUBSYS_UNIX, NULL);
 | 
			
		||||
+                          subsys == MM_PORT_SUBSYS_UNIX ||
 | 
			
		||||
+                          subsys == MM_PORT_SUBSYS_RPMSG, NULL);
 | 
			
		||||
 
 | 
			
		||||
     return MM_PORT_SERIAL_AT (g_object_new (MM_TYPE_PORT_SERIAL_AT,
 | 
			
		||||
                                             MM_PORT_DEVICE, name,
 | 
			
		||||
diff --git a/src/mm-port.h b/src/mm-port.h
 | 
			
		||||
index 33b07d97..861a086b 100644
 | 
			
		||||
--- a/src/mm-port.h
 | 
			
		||||
+++ b/src/mm-port.h
 | 
			
		||||
@@ -28,8 +28,9 @@ typedef enum { /*< underscore_name=mm_port_subsys >*/
 | 
			
		||||
     MM_PORT_SUBSYS_NET,
 | 
			
		||||
     MM_PORT_SUBSYS_USB,
 | 
			
		||||
     MM_PORT_SUBSYS_UNIX,
 | 
			
		||||
+    MM_PORT_SUBSYS_RPMSG,
 | 
			
		||||
 
 | 
			
		||||
-    MM_PORT_SUBSYS_LAST = MM_PORT_SUBSYS_UNIX /*< skip >*/
 | 
			
		||||
+    MM_PORT_SUBSYS_LAST = MM_PORT_SUBSYS_RPMSG /*< skip >*/
 | 
			
		||||
 } MMPortSubsys;
 | 
			
		||||
 
 | 
			
		||||
 typedef enum { /*< underscore_name=mm_port_type >*/
 | 
			
		||||
-- 
 | 
			
		||||
2.28.0
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										140
									
								
								net-misc/modemmanager/modemmanager-1.16.2.ebuild
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								net-misc/modemmanager/modemmanager-1.16.2.ebuild
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,140 @@
 | 
			
		||||
# Copyright 1999-2021 Gentoo Authors
 | 
			
		||||
# Distributed under the terms of the GNU General Public License v2
 | 
			
		||||
 | 
			
		||||
EAPI=7
 | 
			
		||||
VALA_USE_DEPEND="vapigen"
 | 
			
		||||
 | 
			
		||||
inherit gnome2 readme.gentoo-r1 systemd toolchain-funcs udev vala
 | 
			
		||||
 | 
			
		||||
DESCRIPTION="Modem and mobile broadband management libraries"
 | 
			
		||||
HOMEPAGE="https://www.freedesktop.org/wiki/Software/ModemManager/"
 | 
			
		||||
SRC_URI="https://www.freedesktop.org/software/ModemManager/ModemManager-${PV}.tar.xz"
 | 
			
		||||
 | 
			
		||||
LICENSE="GPL-2+"
 | 
			
		||||
SLOT="0/1" # subslot = dbus interface version, i.e. N in org.freedesktop.ModemManager${N}
 | 
			
		||||
KEYWORDS="~arm64"
 | 
			
		||||
 | 
			
		||||
IUSE="elogind +introspection mbim policykit +qmi systemd +udev vala"
 | 
			
		||||
REQUIRED_USE="
 | 
			
		||||
	?? ( elogind systemd )
 | 
			
		||||
	vala? ( introspection )
 | 
			
		||||
"
 | 
			
		||||
 | 
			
		||||
DEPEND="
 | 
			
		||||
	>=dev-libs/glib-2.48.0:2
 | 
			
		||||
	udev? ( >=dev-libs/libgudev-230:= )
 | 
			
		||||
	introspection? ( >=dev-libs/gobject-introspection-0.9.6:= )
 | 
			
		||||
	mbim? ( >=net-libs/libmbim-1.24.0 )
 | 
			
		||||
	policykit? ( >=sys-auth/polkit-0.106[introspection] )
 | 
			
		||||
	qmi? ( >=net-libs/libqmi-1.26.0:= )
 | 
			
		||||
	elogind? ( sys-auth/elogind )
 | 
			
		||||
	systemd? ( >=sys-apps/systemd-209 )
 | 
			
		||||
"
 | 
			
		||||
RDEPEND="${DEPEND}
 | 
			
		||||
	policykit? ( acct-group/plugdev )
 | 
			
		||||
"
 | 
			
		||||
BDEPEND="
 | 
			
		||||
	dev-util/gdbus-codegen
 | 
			
		||||
	dev-util/glib-utils
 | 
			
		||||
	>=dev-util/gtk-doc-am-1
 | 
			
		||||
	>=sys-devel/gettext-0.19.8
 | 
			
		||||
	virtual/pkgconfig
 | 
			
		||||
	vala? ( $(vala_depend) )
 | 
			
		||||
"
 | 
			
		||||
PATCHES="
 | 
			
		||||
	${FILESDIR}/0001-mm-broadband-modem-improve-voice-capabilities-detect.patch
 | 
			
		||||
	${FILESDIR}/0002-serial-parsers-do-not-fail-to-detect-a-valid-respons.patch
 | 
			
		||||
	${FILESDIR}/0003-context-add-test-no-suspend-resume-cli-parameter.patch
 | 
			
		||||
	${FILESDIR}/0004-broadband-modem-qmi_Enable_AT_URCs_and_QMI_indications.patch
 | 
			
		||||
	${FILESDIR}/temp_modemmanager_rpmsg.patch
 | 
			
		||||
"
 | 
			
		||||
 | 
			
		||||
S="${WORKDIR}/ModemManager-${PV}"
 | 
			
		||||
 | 
			
		||||
src_prepare() {
 | 
			
		||||
	DOC_CONTENTS="
 | 
			
		||||
		If your USB modem shows up only as a storage device when you plug it in,
 | 
			
		||||
		then you should install sys-apps/usb_modeswitch, which will automatically
 | 
			
		||||
		switch it over to USB modem mode whenever you plug it in.\n"
 | 
			
		||||
 | 
			
		||||
	if use policykit; then
 | 
			
		||||
		DOC_CONTENTS+="\nTo control your modem without needing to enter the root password,
 | 
			
		||||
			add your user account to the 'plugdev' group."
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	use vala && vala_src_prepare
 | 
			
		||||
	gnome2_src_prepare
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
src_configure() {
 | 
			
		||||
	local myconf=(
 | 
			
		||||
		--disable-Werror
 | 
			
		||||
		--disable-static
 | 
			
		||||
		--with-dist-version=${PVR}
 | 
			
		||||
		--with-udev-base-dir="$(get_udevdir)"
 | 
			
		||||
		$(use_with udev)
 | 
			
		||||
		$(use_enable introspection)
 | 
			
		||||
		$(use_with mbim)
 | 
			
		||||
		$(use_with policykit polkit)
 | 
			
		||||
		$(use_with systemd systemd-suspend-resume)
 | 
			
		||||
		$(use_with systemd systemd-journal)
 | 
			
		||||
		$(use_with qmi)
 | 
			
		||||
		$(use_enable vala)
 | 
			
		||||
	)
 | 
			
		||||
	if use elogind; then
 | 
			
		||||
		local pkgconfig="$(tc-getPKG_CONFIG)"
 | 
			
		||||
		myconf+=(
 | 
			
		||||
			--with-systemd-suspend-resume
 | 
			
		||||
			LIBSYSTEMD_LOGIN_CFLAGS="$(${pkgconfig} --cflags "libelogind")"
 | 
			
		||||
			LIBSYSTEMD_LOGIN_LIBS="$(${pkgconfig} --libs "libelogind")"
 | 
			
		||||
		)
 | 
			
		||||
	fi
 | 
			
		||||
	gnome2_src_configure "${myconf[@]}"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
src_install() {
 | 
			
		||||
	gnome2_src_install
 | 
			
		||||
 | 
			
		||||
	# Allow users in plugdev group full control over their modem
 | 
			
		||||
	if use policykit; then
 | 
			
		||||
		insinto /usr/share/polkit-1/rules.d/
 | 
			
		||||
		doins "${FILESDIR}"/01-org.freedesktop.ModemManager1.rules
 | 
			
		||||
		insinto /usr/lib/udev/rules.d/
 | 
			
		||||
		newins "${FILESDIR}"/rpmsg-udev.rules 80-modemmanager-mjr.rules 
 | 
			
		||||
	fi
 | 
			
		||||
	# Disable suspend/resume hooks for the EG25-G modem in the PinePhone
 | 
			
		||||
	sed -i -e 's|bin/ModemManager|bin/ModemManager --test-no-suspend-resume|g' \         "${D}/lib/systemd/system/ModemManager.service"
 | 
			
		||||
	readme.gentoo_create_doc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pkg_postinst() {
 | 
			
		||||
	gnome2_pkg_postinst
 | 
			
		||||
 | 
			
		||||
	# The polkit rules file moved to /usr/share
 | 
			
		||||
	old_rules="${EROOT}/etc/polkit-1/rules.d/01-org.freedesktop.ModemManager.rules"
 | 
			
		||||
	if [[ -f "${old_rules}" ]]; then
 | 
			
		||||
		case "$(md5sum ${old_rules})" in
 | 
			
		||||
		  c5ff02532cb1da2c7545c3069e5d0992* | 5c50f0dc603c0a56e2851a5ce9389335* )
 | 
			
		||||
			# Automatically delete the old rules.d file if the user did not change it
 | 
			
		||||
			elog
 | 
			
		||||
			elog "Removing old ${old_rules} ..."
 | 
			
		||||
			rm -f "${old_rules}" || eerror "Failed, please remove ${old_rules} manually"
 | 
			
		||||
			;;
 | 
			
		||||
		  * )
 | 
			
		||||
			elog "The ${old_rules}"
 | 
			
		||||
			elog "file moved to /usr/share/polkit-1/rules.d/ in >=modemmanager-0.5.2.0-r2"
 | 
			
		||||
			elog "If you edited ${old_rules}"
 | 
			
		||||
			elog "without changing its behavior, you may want to remove it."
 | 
			
		||||
			;;
 | 
			
		||||
		esac
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	if ! use udev; then
 | 
			
		||||
		ewarn "You have built ModemManager without udev support. You may have to teach it"
 | 
			
		||||
		ewarn "about your modem port manually."
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	systemd_reenable ModemManager.service
 | 
			
		||||
 | 
			
		||||
	readme.gentoo_print_elog
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user