Added ModemManager
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user