temp/eg25-manager: build master branch, drop merged patches (MR 2443)
I believe everything here has been merged in master, so let's build that for now (since it includes at least 1 additional fix not in the patches that were dropped here)
This commit is contained in:
parent
2283190a93
commit
c4fc7c9ed0
9 changed files with 6 additions and 1439 deletions
|
@ -1,28 +0,0 @@
|
||||||
From 705950bb399781a291a3998014f916fc1effce16 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Bhushan Shah <bhush94@gmail.com>
|
|
||||||
Date: Thu, 15 Apr 2021 09:29:36 +0530
|
|
||||||
Subject: [PATCH 1/8] mm-iface: clean out modem_iface if mm disappears
|
|
||||||
|
|
||||||
otherwise we will be stuck in state where restarting of mm will not
|
|
||||||
reset the modem_iface and it will loop through hard resetting modem
|
|
||||||
---
|
|
||||||
src/mm-iface.c | 3 +++
|
|
||||||
1 file changed, 3 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/mm-iface.c b/src/mm-iface.c
|
|
||||||
index d6a74f8..0409236 100644
|
|
||||||
--- a/src/mm-iface.c
|
|
||||||
+++ b/src/mm-iface.c
|
|
||||||
@@ -183,6 +183,9 @@ static void mm_iface_clean(struct EG25Manager *manager)
|
|
||||||
g_free(manager->modem_usb_id);
|
|
||||||
manager->modem_usb_id = NULL;
|
|
||||||
}
|
|
||||||
+ if (manager->modem_iface == MODEM_IFACE_MODEMMANAGER) {
|
|
||||||
+ manager->modem_iface = MODEM_IFACE_NONE;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mm_vanished_cb(GDBusConnection *connection,
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
|
@ -1,97 +0,0 @@
|
||||||
From a046b539418958eeb2ee26ec5ef273835c98d0d2 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dylan Van Assche <me@dylanvanassche.be>
|
|
||||||
Date: Thu, 15 Apr 2021 20:11:03 +0200
|
|
||||||
Subject: [PATCH 2/8] config: synchronize with modem-power
|
|
||||||
|
|
||||||
We cannot assume default factory values if other drivers change them
|
|
||||||
---
|
|
||||||
data/pine64,pinephone-1.0.toml | 13 +++++++++++--
|
|
||||||
data/pine64,pinephone-1.1.toml | 13 +++++++++++--
|
|
||||||
data/pine64,pinephone-1.2.toml | 12 ++++++++++++
|
|
||||||
3 files changed, 34 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/data/pine64,pinephone-1.0.toml b/data/pine64,pinephone-1.0.toml
|
|
||||||
index e1f5b24..6e21bda 100644
|
|
||||||
--- a/data/pine64,pinephone-1.0.toml
|
|
||||||
+++ b/data/pine64,pinephone-1.0.toml
|
|
||||||
@@ -39,12 +39,21 @@ configure = [
|
|
||||||
{ cmd = "QCFG", subcmd = "risignaltype", expect = "\"physical\"" },
|
|
||||||
{ cmd = "QCFG", subcmd = "ims", expect = "1" },
|
|
||||||
{ cmd = "QCFG", subcmd = "urc/ri/ring", expect = "\"pulse\",2000,1000,5000,\"off\",1" },
|
|
||||||
- { cmd = "QCFG", subcmd = "urc/ri/smsincoming", expect = "\"pulse\",2000" },
|
|
||||||
- { cmd = "QCFG", subcmd = "urc/ri/other", expect = "\"off\",1" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "urc/ri/smsincoming", expect = "\"pulse\",2000,1" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "urc/ri/other", expect = "\"off\",1,1" },
|
|
||||||
{ cmd = "QCFG", subcmd = "urc/delay", expect = "1" },
|
|
||||||
{ cmd = "QURCCFG", subcmd = "urcport", expect = "\"all\"" },
|
|
||||||
{ cmd = "QGPS", value = "1" },
|
|
||||||
{ cmd = "QSCLK", value = "1" },
|
|
||||||
+# Reset modem-power configurations to what we expect
|
|
||||||
+ { cmd = "QCFG", subcmd = "urc/cache", expect = "0" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "fast/poweroff", expect = "1" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "apready", expect = "0,0,500" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "sleepind/level", expect = "0" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "wakeupin/level", expect = "0,0" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "ApRstLevel", expect = "0" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "ModemRstLevel", expect = "0" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "urc/ri/pin", expect = "uart_ri" },
|
|
||||||
]
|
|
||||||
suspend = [
|
|
||||||
{ cmd = "QGPSEND" },
|
|
||||||
diff --git a/data/pine64,pinephone-1.1.toml b/data/pine64,pinephone-1.1.toml
|
|
||||||
index e1f5b24..6e21bda 100644
|
|
||||||
--- a/data/pine64,pinephone-1.1.toml
|
|
||||||
+++ b/data/pine64,pinephone-1.1.toml
|
|
||||||
@@ -39,12 +39,21 @@ configure = [
|
|
||||||
{ cmd = "QCFG", subcmd = "risignaltype", expect = "\"physical\"" },
|
|
||||||
{ cmd = "QCFG", subcmd = "ims", expect = "1" },
|
|
||||||
{ cmd = "QCFG", subcmd = "urc/ri/ring", expect = "\"pulse\",2000,1000,5000,\"off\",1" },
|
|
||||||
- { cmd = "QCFG", subcmd = "urc/ri/smsincoming", expect = "\"pulse\",2000" },
|
|
||||||
- { cmd = "QCFG", subcmd = "urc/ri/other", expect = "\"off\",1" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "urc/ri/smsincoming", expect = "\"pulse\",2000,1" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "urc/ri/other", expect = "\"off\",1,1" },
|
|
||||||
{ cmd = "QCFG", subcmd = "urc/delay", expect = "1" },
|
|
||||||
{ cmd = "QURCCFG", subcmd = "urcport", expect = "\"all\"" },
|
|
||||||
{ cmd = "QGPS", value = "1" },
|
|
||||||
{ cmd = "QSCLK", value = "1" },
|
|
||||||
+# Reset modem-power configurations to what we expect
|
|
||||||
+ { cmd = "QCFG", subcmd = "urc/cache", expect = "0" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "fast/poweroff", expect = "1" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "apready", expect = "0,0,500" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "sleepind/level", expect = "0" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "wakeupin/level", expect = "0,0" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "ApRstLevel", expect = "0" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "ModemRstLevel", expect = "0" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "urc/ri/pin", expect = "uart_ri" },
|
|
||||||
]
|
|
||||||
suspend = [
|
|
||||||
{ cmd = "QGPSEND" },
|
|
||||||
diff --git a/data/pine64,pinephone-1.2.toml b/data/pine64,pinephone-1.2.toml
|
|
||||||
index 4ca1274..598ebaf 100644
|
|
||||||
--- a/data/pine64,pinephone-1.2.toml
|
|
||||||
+++ b/data/pine64,pinephone-1.2.toml
|
|
||||||
@@ -36,9 +36,21 @@ configure = [
|
|
||||||
{ cmd = "QCFG", subcmd = "risignaltype", expect = "\"physical\"" },
|
|
||||||
{ cmd = "QCFG", subcmd = "ims", expect = "1" },
|
|
||||||
{ cmd = "QCFG", subcmd = "apready", expect = "1,0,500" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "urc/ri/ring", expect = "\"pulse\",120,1000,5000,\"off\",1" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "urc/ri/smsincoming", expect = "\"pulse\",120,1" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "urc/ri/other", expect = "\"off\",1,1" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "urc/delay", expect = "0" },
|
|
||||||
{ cmd = "QURCCFG", subcmd = "urcport", expect = "\"all\"" },
|
|
||||||
{ cmd = "QGPS", value = "1" },
|
|
||||||
{ cmd = "QSCLK", value = "1" },
|
|
||||||
+# Reset modem-power configurations to what we expect
|
|
||||||
+ { cmd = "QCFG", subcmd = "urc/cache", expect = "0" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "fast/poweroff", expect = "1" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "sleepind/level", expect = "0" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "wakeupin/level", expect = "0,0" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "ApRstLevel", expect = "0" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "ModemRstLevel", expect = "0" },
|
|
||||||
+ { cmd = "QCFG", subcmd = "urc/ri/pin", expect = "uart_ri" },
|
|
||||||
]
|
|
||||||
suspend = [
|
|
||||||
{ cmd = "QGPSEND" },
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
From 0094dea49d8bc5a60c044da1e01417c29397c7b0 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dylan Van Assche <me@dylanvanassche.be>
|
|
||||||
Date: Sat, 17 Apr 2021 15:50:07 +0200
|
|
||||||
Subject: [PATCH 3/8] at: fast/poweroff is only available in newer firmware
|
|
||||||
versions
|
|
||||||
|
|
||||||
Do not retry the AT command of the fast/poweroff setting as it may not be supported by the firmware
|
|
||||||
---
|
|
||||||
src/at.c | 6 +++++-
|
|
||||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/at.c b/src/at.c
|
|
||||||
index a34025f..4469d26 100644
|
|
||||||
--- a/src/at.c
|
|
||||||
+++ b/src/at.c
|
|
||||||
@@ -215,7 +215,11 @@ static gboolean modem_response(gint fd,
|
|
||||||
suspend_inhibit(manager, TRUE, TRUE);
|
|
||||||
manager->modem_state = EG25_STATE_STARTED;
|
|
||||||
}
|
|
||||||
- else if (strstr(response, "ERROR"))
|
|
||||||
+ /*
|
|
||||||
+ * QCFG="fast/poweroff" configuration is only available in
|
|
||||||
+ * newer firmware versions
|
|
||||||
+ */
|
|
||||||
+ else if (strstr(response, "ERROR") && !strstr(response, "fast/poweroff"))
|
|
||||||
retry_at_command(manager);
|
|
||||||
else if (strstr(response, "OK"))
|
|
||||||
process_at_result(manager, response);
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
From a74d2c58babd2e85a4d1920e0144b5c7ee2231d0 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dylan Van Assche <me@dylanvanassche.be>
|
|
||||||
Date: Wed, 12 May 2021 16:41:48 +0200
|
|
||||||
Subject: [PATCH 4/8] at: g_free doesn't require NULL checking
|
|
||||||
|
|
||||||
From the docs: If mem is NULL it simply returns, so there is no need to check mem against NULL before calling this function.
|
|
||||||
---
|
|
||||||
src/at.c | 15 +++++----------
|
|
||||||
1 file changed, 5 insertions(+), 10 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/at.c b/src/at.c
|
|
||||||
index 4469d26..3ccc5d6 100644
|
|
||||||
--- a/src/at.c
|
|
||||||
+++ b/src/at.c
|
|
||||||
@@ -104,14 +104,10 @@ static void next_at_command(struct EG25Manager *manager)
|
|
||||||
if (!at_cmd)
|
|
||||||
return;
|
|
||||||
|
|
||||||
- if (at_cmd->cmd)
|
|
||||||
- g_free(at_cmd->cmd);
|
|
||||||
- if (at_cmd->subcmd)
|
|
||||||
- g_free(at_cmd->subcmd);
|
|
||||||
- if (at_cmd->value)
|
|
||||||
- g_free(at_cmd->value);
|
|
||||||
- if (at_cmd->expected)
|
|
||||||
- g_free(at_cmd->expected);
|
|
||||||
+ g_free(at_cmd->cmd);
|
|
||||||
+ g_free(at_cmd->subcmd);
|
|
||||||
+ g_free(at_cmd->value);
|
|
||||||
+ g_free(at_cmd->expected);
|
|
||||||
g_free(at_cmd);
|
|
||||||
manager->at_cmds = g_list_remove(manager->at_cmds, at_cmd);
|
|
||||||
|
|
||||||
@@ -142,8 +138,7 @@ static void process_at_result(struct EG25Manager *manager, char *response)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (at_cmd->expected && !strstr(response, at_cmd->expected)) {
|
|
||||||
- if (at_cmd->value)
|
|
||||||
- g_free(at_cmd->value);
|
|
||||||
+ g_free(at_cmd->value);
|
|
||||||
at_cmd->value = at_cmd->expected;
|
|
||||||
at_cmd->expected = NULL;
|
|
||||||
g_message("Got a different result than expected, changing value...");
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
|
@ -1,176 +0,0 @@
|
||||||
From 3a205f7e9baf702dccc572ae2342990052c23155 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dylan Van Assche <me@dylanvanassche.be>
|
|
||||||
Date: Wed, 12 May 2021 18:21:29 +0200
|
|
||||||
Subject: [PATCH 5/8] at: make next_at_command, send_at_command,
|
|
||||||
process_at_result, and append_at_command public methods
|
|
||||||
|
|
||||||
Allows other modules to send AT commands as well
|
|
||||||
---
|
|
||||||
src/at.c | 47 ++++++++++++++++++++++++-----------------------
|
|
||||||
src/at.h | 22 ++++++++++++++++------
|
|
||||||
2 files changed, 40 insertions(+), 29 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/at.c b/src/at.c
|
|
||||||
index 3ccc5d6..1e605a1 100644
|
|
||||||
--- a/src/at.c
|
|
||||||
+++ b/src/at.c
|
|
||||||
@@ -52,7 +52,7 @@ static int configure_serial(const char *tty)
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static gboolean send_at_command(struct EG25Manager *manager)
|
|
||||||
+gboolean at_send_command(struct EG25Manager *manager)
|
|
||||||
{
|
|
||||||
char command[256];
|
|
||||||
struct AtCommand *at_cmd = manager->at_cmds ? g_list_nth_data(manager->at_cmds, 0) : NULL;
|
|
||||||
@@ -97,7 +97,7 @@ static gboolean send_at_command(struct EG25Manager *manager)
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void next_at_command(struct EG25Manager *manager)
|
|
||||||
+void at_next_command(struct EG25Manager *manager)
|
|
||||||
{
|
|
||||||
struct AtCommand *at_cmd = manager->at_cmds ? g_list_nth_data(manager->at_cmds, 0) : NULL;
|
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ static void next_at_command(struct EG25Manager *manager)
|
|
||||||
g_free(at_cmd);
|
|
||||||
manager->at_cmds = g_list_remove(manager->at_cmds, at_cmd);
|
|
||||||
|
|
||||||
- send_at_command(manager);
|
|
||||||
+ at_send_command(manager);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void retry_at_command(struct EG25Manager *manager)
|
|
||||||
@@ -124,13 +124,14 @@ static void retry_at_command(struct EG25Manager *manager)
|
|
||||||
at_cmd->retries++;
|
|
||||||
if (at_cmd->retries > 3) {
|
|
||||||
g_critical("Command %s retried %d times, aborting...", at_cmd->cmd, at_cmd->retries);
|
|
||||||
- next_at_command(manager);
|
|
||||||
+ at_next_command(manager);
|
|
||||||
} else {
|
|
||||||
- g_timeout_add(500, G_SOURCE_FUNC(send_at_command), manager);
|
|
||||||
+ g_timeout_add(500, G_SOURCE_FUNC(at_send_command), manager);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void process_at_result(struct EG25Manager *manager, char *response)
|
|
||||||
+void at_process_result(struct EG25Manager *manager,
|
|
||||||
+ const char *response)
|
|
||||||
{
|
|
||||||
struct AtCommand *at_cmd = manager->at_cmds ? g_list_nth_data(manager->at_cmds, 0) : NULL;
|
|
||||||
|
|
||||||
@@ -143,17 +144,17 @@ static void process_at_result(struct EG25Manager *manager, char *response)
|
|
||||||
at_cmd->expected = NULL;
|
|
||||||
g_message("Got a different result than expected, changing value...");
|
|
||||||
g_message("\t%s\n\t%s", at_cmd->expected, response);
|
|
||||||
- send_at_command(manager);
|
|
||||||
+ at_send_command(manager);
|
|
||||||
} else {
|
|
||||||
- next_at_command(manager);
|
|
||||||
+ at_next_command(manager);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int append_at_command(struct EG25Manager *manager,
|
|
||||||
- const char *cmd,
|
|
||||||
- const char *subcmd,
|
|
||||||
- const char *value,
|
|
||||||
- const char *expected)
|
|
||||||
+int at_append_command(struct EG25Manager *manager,
|
|
||||||
+ const char *cmd,
|
|
||||||
+ const char *subcmd,
|
|
||||||
+ const char *value,
|
|
||||||
+ const char *expected)
|
|
||||||
{
|
|
||||||
struct AtCommand *at_cmd = calloc(1, sizeof(struct AtCommand));
|
|
||||||
|
|
||||||
@@ -217,10 +218,10 @@ static gboolean modem_response(gint fd,
|
|
||||||
else if (strstr(response, "ERROR") && !strstr(response, "fast/poweroff"))
|
|
||||||
retry_at_command(manager);
|
|
||||||
else if (strstr(response, "OK"))
|
|
||||||
- process_at_result(manager, response);
|
|
||||||
+ at_process_result(manager, response);
|
|
||||||
else
|
|
||||||
// Not a recognized response, try running next command, just in case
|
|
||||||
- next_at_command(manager);
|
|
||||||
+ at_next_command(manager);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
@@ -325,34 +326,34 @@ void at_sequence_configure(struct EG25Manager *manager)
|
|
||||||
{
|
|
||||||
for (guint i = 0; i < configure_commands->len; i++) {
|
|
||||||
struct AtCommand *cmd = &g_array_index(configure_commands, struct AtCommand, i);
|
|
||||||
- append_at_command(manager, cmd->cmd, cmd->subcmd, cmd->value, cmd->expected);
|
|
||||||
+ at_append_command(manager, cmd->cmd, cmd->subcmd, cmd->value, cmd->expected);
|
|
||||||
}
|
|
||||||
- send_at_command(manager);
|
|
||||||
+ at_send_command(manager);
|
|
||||||
}
|
|
||||||
|
|
||||||
void at_sequence_suspend(struct EG25Manager *manager)
|
|
||||||
{
|
|
||||||
for (guint i = 0; i < suspend_commands->len; i++) {
|
|
||||||
struct AtCommand *cmd = &g_array_index(suspend_commands, struct AtCommand, i);
|
|
||||||
- append_at_command(manager, cmd->cmd, cmd->subcmd, cmd->value, cmd->expected);
|
|
||||||
+ at_append_command(manager, cmd->cmd, cmd->subcmd, cmd->value, cmd->expected);
|
|
||||||
}
|
|
||||||
- send_at_command(manager);
|
|
||||||
+ at_send_command(manager);
|
|
||||||
}
|
|
||||||
|
|
||||||
void at_sequence_resume(struct EG25Manager *manager)
|
|
||||||
{
|
|
||||||
for (guint i = 0; i < resume_commands->len; i++) {
|
|
||||||
struct AtCommand *cmd = &g_array_index(resume_commands, struct AtCommand, i);
|
|
||||||
- append_at_command(manager, cmd->cmd, cmd->subcmd, cmd->value, cmd->expected);
|
|
||||||
+ at_append_command(manager, cmd->cmd, cmd->subcmd, cmd->value, cmd->expected);
|
|
||||||
}
|
|
||||||
- send_at_command(manager);
|
|
||||||
+ at_send_command(manager);
|
|
||||||
}
|
|
||||||
|
|
||||||
void at_sequence_reset(struct EG25Manager *manager)
|
|
||||||
{
|
|
||||||
for (guint i = 0; i < reset_commands->len; i++) {
|
|
||||||
struct AtCommand *cmd = &g_array_index(reset_commands, struct AtCommand, i);
|
|
||||||
- append_at_command(manager, cmd->cmd, cmd->subcmd, cmd->value, cmd->expected);
|
|
||||||
+ at_append_command(manager, cmd->cmd, cmd->subcmd, cmd->value, cmd->expected);
|
|
||||||
}
|
|
||||||
- send_at_command(manager);
|
|
||||||
+ at_send_command(manager);
|
|
||||||
}
|
|
||||||
diff --git a/src/at.h b/src/at.h
|
|
||||||
index ba294a4..e0445af 100644
|
|
||||||
--- a/src/at.h
|
|
||||||
+++ b/src/at.h
|
|
||||||
@@ -8,10 +8,20 @@
|
|
||||||
|
|
||||||
#include "manager.h"
|
|
||||||
|
|
||||||
-int at_init(struct EG25Manager *data, toml_table_t *config);
|
|
||||||
-void at_destroy(struct EG25Manager *data);
|
|
||||||
+int at_init(struct EG25Manager *manager, toml_table_t *config);
|
|
||||||
+void at_destroy(struct EG25Manager *manager);
|
|
||||||
|
|
||||||
-void at_sequence_configure(struct EG25Manager *data);
|
|
||||||
-void at_sequence_suspend(struct EG25Manager *data);
|
|
||||||
-void at_sequence_resume(struct EG25Manager *data);
|
|
||||||
-void at_sequence_reset(struct EG25Manager *data);
|
|
||||||
+void at_process_result(struct EG25Manager *manager,
|
|
||||||
+ const char *response);
|
|
||||||
+void at_next_command(struct EG25Manager *manager);
|
|
||||||
+gboolean at_send_command(struct EG25Manager *manager);
|
|
||||||
+int at_append_command(struct EG25Manager *manager,
|
|
||||||
+ const char *cmd,
|
|
||||||
+ const char *subcmd,
|
|
||||||
+ const char *value,
|
|
||||||
+ const char *expected);
|
|
||||||
+
|
|
||||||
+void at_sequence_configure(struct EG25Manager *manager);
|
|
||||||
+void at_sequence_suspend(struct EG25Manager *manager);
|
|
||||||
+void at_sequence_resume(struct EG25Manager *manager);
|
|
||||||
+void at_sequence_reset(struct EG25Manager *manager);
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
From 47a7069c143c0f6a1219a1cef78a51d0f31f0710 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dylan Van Assche <me@dylanvanassche.be>
|
|
||||||
Date: Wed, 12 May 2021 18:25:40 +0200
|
|
||||||
Subject: [PATCH 6/8] at: log expected result before setting it to NULL
|
|
||||||
|
|
||||||
Otherwise the log contains NULL instead of the expected value, making it hard to debug
|
|
||||||
---
|
|
||||||
src/at.c | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/at.c b/src/at.c
|
|
||||||
index 1e605a1..533ed1c 100644
|
|
||||||
--- a/src/at.c
|
|
||||||
+++ b/src/at.c
|
|
||||||
@@ -141,9 +141,9 @@ void at_process_result(struct EG25Manager *manager,
|
|
||||||
if (at_cmd->expected && !strstr(response, at_cmd->expected)) {
|
|
||||||
g_free(at_cmd->value);
|
|
||||||
at_cmd->value = at_cmd->expected;
|
|
||||||
- at_cmd->expected = NULL;
|
|
||||||
g_message("Got a different result than expected, changing value...");
|
|
||||||
- g_message("\t%s\n\t%s", at_cmd->expected, response);
|
|
||||||
+ g_message("Expected: [%s]\nResponse: [%s]", at_cmd->expected, response);
|
|
||||||
+ at_cmd->expected = NULL;
|
|
||||||
at_send_command(manager);
|
|
||||||
} else {
|
|
||||||
at_next_command(manager);
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
|
@ -1,158 +0,0 @@
|
||||||
From 427944b75e0a4abc4cc2af2f16858739a8833e6e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dylan Van Assche <me@dylanvanassche.be>
|
|
||||||
Date: Wed, 12 May 2021 18:34:03 +0200
|
|
||||||
Subject: [PATCH 7/8] at: allow custom callbacks for AT command response
|
|
||||||
processing
|
|
||||||
|
|
||||||
---
|
|
||||||
src/at.c | 32 +++++++++++++++++---------------
|
|
||||||
src/at.h | 14 +++++++++++++-
|
|
||||||
src/manager.h | 1 +
|
|
||||||
3 files changed, 31 insertions(+), 16 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/at.c b/src/at.c
|
|
||||||
index 533ed1c..35b7042 100644
|
|
||||||
--- a/src/at.c
|
|
||||||
+++ b/src/at.c
|
|
||||||
@@ -16,14 +16,6 @@
|
|
||||||
|
|
||||||
#include <glib-unix.h>
|
|
||||||
|
|
||||||
-struct AtCommand {
|
|
||||||
- char *cmd;
|
|
||||||
- char *subcmd;
|
|
||||||
- char *value;
|
|
||||||
- char *expected;
|
|
||||||
- int retries;
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
static GArray *configure_commands = NULL;
|
|
||||||
static GArray *suspend_commands = NULL;
|
|
||||||
static GArray *resume_commands = NULL;
|
|
||||||
@@ -69,6 +61,7 @@ gboolean at_send_command(struct EG25Manager *manager)
|
|
||||||
len = sprintf(command, "AT+%s=\"%s\"\r\n", at_cmd->cmd, at_cmd->subcmd);
|
|
||||||
else if (at_cmd->subcmd && at_cmd->value)
|
|
||||||
len = sprintf(command, "AT+%s=\"%s\",%s\r\n", at_cmd->cmd, at_cmd->subcmd, at_cmd->value);
|
|
||||||
+ manager->at_callback = at_cmd->callback;
|
|
||||||
|
|
||||||
ret = write(manager->at_fd, command, len);
|
|
||||||
if (ret < len)
|
|
||||||
@@ -154,7 +147,10 @@ int at_append_command(struct EG25Manager *manager,
|
|
||||||
const char *cmd,
|
|
||||||
const char *subcmd,
|
|
||||||
const char *value,
|
|
||||||
- const char *expected)
|
|
||||||
+ const char *expected,
|
|
||||||
+ void (*callback)
|
|
||||||
+ (struct EG25Manager *manager,
|
|
||||||
+ const char *response))
|
|
||||||
{
|
|
||||||
struct AtCommand *at_cmd = calloc(1, sizeof(struct AtCommand));
|
|
||||||
|
|
||||||
@@ -168,6 +164,8 @@ int at_append_command(struct EG25Manager *manager,
|
|
||||||
at_cmd->value = g_strdup(value);
|
|
||||||
if (expected)
|
|
||||||
at_cmd->expected = g_strdup(expected);
|
|
||||||
+ if (callback)
|
|
||||||
+ at_cmd->callback = callback;
|
|
||||||
|
|
||||||
manager->at_cmds = g_list_append(manager->at_cmds, at_cmd);
|
|
||||||
|
|
||||||
@@ -217,8 +215,12 @@ static gboolean modem_response(gint fd,
|
|
||||||
*/
|
|
||||||
else if (strstr(response, "ERROR") && !strstr(response, "fast/poweroff"))
|
|
||||||
retry_at_command(manager);
|
|
||||||
- else if (strstr(response, "OK"))
|
|
||||||
- at_process_result(manager, response);
|
|
||||||
+ else if (strstr(response, "OK")) {
|
|
||||||
+ if (manager->at_callback != NULL)
|
|
||||||
+ manager->at_callback(manager, response);
|
|
||||||
+ else
|
|
||||||
+ g_warning("AT command succesfull but no callback registered");
|
|
||||||
+ }
|
|
||||||
else
|
|
||||||
// Not a recognized response, try running next command, just in case
|
|
||||||
at_next_command(manager);
|
|
||||||
@@ -326,7 +328,7 @@ void at_sequence_configure(struct EG25Manager *manager)
|
|
||||||
{
|
|
||||||
for (guint i = 0; i < configure_commands->len; i++) {
|
|
||||||
struct AtCommand *cmd = &g_array_index(configure_commands, struct AtCommand, i);
|
|
||||||
- at_append_command(manager, cmd->cmd, cmd->subcmd, cmd->value, cmd->expected);
|
|
||||||
+ at_append_command(manager, cmd->cmd, cmd->subcmd, cmd->value, cmd->expected, at_process_result);
|
|
||||||
}
|
|
||||||
at_send_command(manager);
|
|
||||||
}
|
|
||||||
@@ -335,7 +337,7 @@ void at_sequence_suspend(struct EG25Manager *manager)
|
|
||||||
{
|
|
||||||
for (guint i = 0; i < suspend_commands->len; i++) {
|
|
||||||
struct AtCommand *cmd = &g_array_index(suspend_commands, struct AtCommand, i);
|
|
||||||
- at_append_command(manager, cmd->cmd, cmd->subcmd, cmd->value, cmd->expected);
|
|
||||||
+ at_append_command(manager, cmd->cmd, cmd->subcmd, cmd->value, cmd->expected, at_process_result);
|
|
||||||
}
|
|
||||||
at_send_command(manager);
|
|
||||||
}
|
|
||||||
@@ -344,7 +346,7 @@ void at_sequence_resume(struct EG25Manager *manager)
|
|
||||||
{
|
|
||||||
for (guint i = 0; i < resume_commands->len; i++) {
|
|
||||||
struct AtCommand *cmd = &g_array_index(resume_commands, struct AtCommand, i);
|
|
||||||
- at_append_command(manager, cmd->cmd, cmd->subcmd, cmd->value, cmd->expected);
|
|
||||||
+ at_append_command(manager, cmd->cmd, cmd->subcmd, cmd->value, cmd->expected, at_process_result);
|
|
||||||
}
|
|
||||||
at_send_command(manager);
|
|
||||||
}
|
|
||||||
@@ -353,7 +355,7 @@ void at_sequence_reset(struct EG25Manager *manager)
|
|
||||||
{
|
|
||||||
for (guint i = 0; i < reset_commands->len; i++) {
|
|
||||||
struct AtCommand *cmd = &g_array_index(reset_commands, struct AtCommand, i);
|
|
||||||
- at_append_command(manager, cmd->cmd, cmd->subcmd, cmd->value, cmd->expected);
|
|
||||||
+ at_append_command(manager, cmd->cmd, cmd->subcmd, cmd->value, cmd->expected, at_process_result);
|
|
||||||
}
|
|
||||||
at_send_command(manager);
|
|
||||||
}
|
|
||||||
diff --git a/src/at.h b/src/at.h
|
|
||||||
index e0445af..0364e2c 100644
|
|
||||||
--- a/src/at.h
|
|
||||||
+++ b/src/at.h
|
|
||||||
@@ -8,6 +8,15 @@
|
|
||||||
|
|
||||||
#include "manager.h"
|
|
||||||
|
|
||||||
+typedef struct AtCommand {
|
|
||||||
+ char *cmd;
|
|
||||||
+ char *subcmd;
|
|
||||||
+ char *value;
|
|
||||||
+ char *expected;
|
|
||||||
+ void (*callback)(struct EG25Manager *manager, const char *response);
|
|
||||||
+ int retries;
|
|
||||||
+} AtCommand;
|
|
||||||
+
|
|
||||||
int at_init(struct EG25Manager *manager, toml_table_t *config);
|
|
||||||
void at_destroy(struct EG25Manager *manager);
|
|
||||||
|
|
||||||
@@ -19,7 +28,10 @@ int at_append_command(struct EG25Manager *manager,
|
|
||||||
const char *cmd,
|
|
||||||
const char *subcmd,
|
|
||||||
const char *value,
|
|
||||||
- const char *expected);
|
|
||||||
+ const char *expected,
|
|
||||||
+ void (*callback)
|
|
||||||
+ (struct EG25Manager *manager,
|
|
||||||
+ const char *response));
|
|
||||||
|
|
||||||
void at_sequence_configure(struct EG25Manager *manager);
|
|
||||||
void at_sequence_suspend(struct EG25Manager *manager);
|
|
||||||
diff --git a/src/manager.h b/src/manager.h
|
|
||||||
index 30028e6..3cc0118 100644
|
|
||||||
--- a/src/manager.h
|
|
||||||
+++ b/src/manager.h
|
|
||||||
@@ -47,6 +47,7 @@ struct EG25Manager {
|
|
||||||
int at_fd;
|
|
||||||
guint at_source;
|
|
||||||
GList *at_cmds;
|
|
||||||
+ void (*at_callback)(struct EG25Manager *manager, const char *response);
|
|
||||||
|
|
||||||
enum EG25State modem_state;
|
|
||||||
gchar *modem_usb_id;
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
|
@ -1,852 +0,0 @@
|
||||||
From b5578250c1f2c00972e8c7215458160b04871c5e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dylan Van Assche <me@dylanvanassche.be>
|
|
||||||
Date: Wed, 12 May 2021 19:37:21 +0200
|
|
||||||
Subject: [PATCH 8/8] gnss: add GNSS assistance support
|
|
||||||
|
|
||||||
Automatically fetch the GNSS assistance data from the Web
|
|
||||||
to heavily reduce the time to acquire a GNSS lock by uploading
|
|
||||||
the assistance data to the modem.
|
|
||||||
This feature is optional and can be disabled in the configuration
|
|
||||||
as people may prefer to not download the assistance data from
|
|
||||||
the Quectel/Qualcomm servers.
|
|
||||||
Also configure the GNSS engine to optimize the performance
|
|
||||||
and power consumption.
|
|
||||||
---
|
|
||||||
data/pine64,pinephone-1.0.toml | 26 +-
|
|
||||||
data/pine64,pinephone-1.1.toml | 26 +-
|
|
||||||
data/pine64,pinephone-1.2.toml | 26 +-
|
|
||||||
meson.build | 1 +
|
|
||||||
src/at.c | 22 +-
|
|
||||||
src/gnss.c | 478 +++++++++++++++++++++++++++++++++
|
|
||||||
src/gnss.h | 16 ++
|
|
||||||
src/manager.c | 2 +
|
|
||||||
src/manager.h | 34 +++
|
|
||||||
src/meson.build | 1 +
|
|
||||||
src/mm-iface.c | 5 +-
|
|
||||||
11 files changed, 625 insertions(+), 12 deletions(-)
|
|
||||||
create mode 100644 src/gnss.c
|
|
||||||
create mode 100644 src/gnss.h
|
|
||||||
|
|
||||||
diff --git a/data/pine64,pinephone-1.0.toml b/data/pine64,pinephone-1.0.toml
|
|
||||||
index 6e21bda..c2ee8bd 100644
|
|
||||||
--- a/data/pine64,pinephone-1.0.toml
|
|
||||||
+++ b/data/pine64,pinephone-1.0.toml
|
|
||||||
@@ -43,7 +43,6 @@ configure = [
|
|
||||||
{ cmd = "QCFG", subcmd = "urc/ri/other", expect = "\"off\",1,1" },
|
|
||||||
{ cmd = "QCFG", subcmd = "urc/delay", expect = "1" },
|
|
||||||
{ cmd = "QURCCFG", subcmd = "urcport", expect = "\"all\"" },
|
|
||||||
- { cmd = "QGPS", value = "1" },
|
|
||||||
{ cmd = "QSCLK", value = "1" },
|
|
||||||
# Reset modem-power configurations to what we expect
|
|
||||||
{ cmd = "QCFG", subcmd = "urc/cache", expect = "0" },
|
|
||||||
@@ -54,11 +53,32 @@ configure = [
|
|
||||||
{ cmd = "QCFG", subcmd = "ApRstLevel", expect = "0" },
|
|
||||||
{ cmd = "QCFG", subcmd = "ModemRstLevel", expect = "0" },
|
|
||||||
{ cmd = "QCFG", subcmd = "urc/ri/pin", expect = "uart_ri" },
|
|
||||||
+# GNSS configuration:
|
|
||||||
+# * Enable A-GPS data upload support (XTRA)
|
|
||||||
+# * Disable On-Demand-Positioning (ODP) mode
|
|
||||||
+# to avoid running the GNSS system in the background, even when not enabled.
|
|
||||||
+# * Enable Dynamic Power Optimizations (DPO) mode to turn off GNSS RF radios
|
|
||||||
+# when they are not in use.
|
|
||||||
+# * Only enable GPS and GLONASS, disable other GNSS systems.
|
|
||||||
+# A-GPS data upload doesn't work for Galileo anyway.
|
|
||||||
+# * Avoid turning on GNSS support automatically when the modem boots.
|
|
||||||
+ { cmd = "QGPSXTRA", expect = "1" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "gnssconfig", expect = "4" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "odpcontrol", expect = "0" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "dpoenable", expect = "1" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "gpsnmeatype", expect = "31" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "glonassnmeatype", expect = "7" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "galileonmeatype", expect = "0" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "beidounmeatype", expect = "0" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "autogps", expect = "0" },
|
|
||||||
]
|
|
||||||
suspend = [
|
|
||||||
- { cmd = "QGPSEND" },
|
|
||||||
]
|
|
||||||
resume = [
|
|
||||||
- { cmd = "QGPS", value = "1" }
|
|
||||||
]
|
|
||||||
reset = [ { cmd = "CFUN", value = "1,1" } ]
|
|
||||||
+
|
|
||||||
+[gnss]
|
|
||||||
+enabled = true
|
|
||||||
+url = "https://proxy.postmarketos.org"
|
|
||||||
+file = "xtra2.bin"
|
|
||||||
diff --git a/data/pine64,pinephone-1.1.toml b/data/pine64,pinephone-1.1.toml
|
|
||||||
index 6e21bda..c2ee8bd 100644
|
|
||||||
--- a/data/pine64,pinephone-1.1.toml
|
|
||||||
+++ b/data/pine64,pinephone-1.1.toml
|
|
||||||
@@ -43,7 +43,6 @@ configure = [
|
|
||||||
{ cmd = "QCFG", subcmd = "urc/ri/other", expect = "\"off\",1,1" },
|
|
||||||
{ cmd = "QCFG", subcmd = "urc/delay", expect = "1" },
|
|
||||||
{ cmd = "QURCCFG", subcmd = "urcport", expect = "\"all\"" },
|
|
||||||
- { cmd = "QGPS", value = "1" },
|
|
||||||
{ cmd = "QSCLK", value = "1" },
|
|
||||||
# Reset modem-power configurations to what we expect
|
|
||||||
{ cmd = "QCFG", subcmd = "urc/cache", expect = "0" },
|
|
||||||
@@ -54,11 +53,32 @@ configure = [
|
|
||||||
{ cmd = "QCFG", subcmd = "ApRstLevel", expect = "0" },
|
|
||||||
{ cmd = "QCFG", subcmd = "ModemRstLevel", expect = "0" },
|
|
||||||
{ cmd = "QCFG", subcmd = "urc/ri/pin", expect = "uart_ri" },
|
|
||||||
+# GNSS configuration:
|
|
||||||
+# * Enable A-GPS data upload support (XTRA)
|
|
||||||
+# * Disable On-Demand-Positioning (ODP) mode
|
|
||||||
+# to avoid running the GNSS system in the background, even when not enabled.
|
|
||||||
+# * Enable Dynamic Power Optimizations (DPO) mode to turn off GNSS RF radios
|
|
||||||
+# when they are not in use.
|
|
||||||
+# * Only enable GPS and GLONASS, disable other GNSS systems.
|
|
||||||
+# A-GPS data upload doesn't work for Galileo anyway.
|
|
||||||
+# * Avoid turning on GNSS support automatically when the modem boots.
|
|
||||||
+ { cmd = "QGPSXTRA", expect = "1" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "gnssconfig", expect = "4" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "odpcontrol", expect = "0" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "dpoenable", expect = "1" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "gpsnmeatype", expect = "31" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "glonassnmeatype", expect = "7" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "galileonmeatype", expect = "0" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "beidounmeatype", expect = "0" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "autogps", expect = "0" },
|
|
||||||
]
|
|
||||||
suspend = [
|
|
||||||
- { cmd = "QGPSEND" },
|
|
||||||
]
|
|
||||||
resume = [
|
|
||||||
- { cmd = "QGPS", value = "1" }
|
|
||||||
]
|
|
||||||
reset = [ { cmd = "CFUN", value = "1,1" } ]
|
|
||||||
+
|
|
||||||
+[gnss]
|
|
||||||
+enabled = true
|
|
||||||
+url = "https://proxy.postmarketos.org"
|
|
||||||
+file = "xtra2.bin"
|
|
||||||
diff --git a/data/pine64,pinephone-1.2.toml b/data/pine64,pinephone-1.2.toml
|
|
||||||
index 598ebaf..a45c7ec 100644
|
|
||||||
--- a/data/pine64,pinephone-1.2.toml
|
|
||||||
+++ b/data/pine64,pinephone-1.2.toml
|
|
||||||
@@ -41,7 +41,6 @@ configure = [
|
|
||||||
{ cmd = "QCFG", subcmd = "urc/ri/other", expect = "\"off\",1,1" },
|
|
||||||
{ cmd = "QCFG", subcmd = "urc/delay", expect = "0" },
|
|
||||||
{ cmd = "QURCCFG", subcmd = "urcport", expect = "\"all\"" },
|
|
||||||
- { cmd = "QGPS", value = "1" },
|
|
||||||
{ cmd = "QSCLK", value = "1" },
|
|
||||||
# Reset modem-power configurations to what we expect
|
|
||||||
{ cmd = "QCFG", subcmd = "urc/cache", expect = "0" },
|
|
||||||
@@ -51,11 +50,32 @@ configure = [
|
|
||||||
{ cmd = "QCFG", subcmd = "ApRstLevel", expect = "0" },
|
|
||||||
{ cmd = "QCFG", subcmd = "ModemRstLevel", expect = "0" },
|
|
||||||
{ cmd = "QCFG", subcmd = "urc/ri/pin", expect = "uart_ri" },
|
|
||||||
+# GNSS configuration:
|
|
||||||
+# * Enable A-GPS data upload support (XTRA)
|
|
||||||
+# * Disable On-Demand-Positioning (ODP) mode
|
|
||||||
+# to avoid running the GNSS system in the background, even when not enabled.
|
|
||||||
+# * Enable Dynamic Power Optimizations (DPO) mode to turn off GNSS RF radios
|
|
||||||
+# when they are not in use.
|
|
||||||
+# * Only enable GPS and GLONASS, disable other GNSS systems.
|
|
||||||
+# A-GPS data upload doesn't work for Galileo anyway.
|
|
||||||
+# * Avoid turning on GNSS support automatically when the modem boots.
|
|
||||||
+ { cmd = "QGPSXTRA", expect = "1" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "gnssconfig", expect = "4" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "odpcontrol", expect = "0" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "dpoenable", expect = "1" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "gpsnmeatype", expect = "31" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "glonassnmeatype", expect = "7" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "galileonmeatype", expect = "0" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "beidounmeatype", expect = "0" },
|
|
||||||
+ { cmd = "QGPSCFG", subcmd = "autogps", expect = "0" },
|
|
||||||
]
|
|
||||||
suspend = [
|
|
||||||
- { cmd = "QGPSEND" },
|
|
||||||
]
|
|
||||||
resume = [
|
|
||||||
- { cmd = "QGPS", value = "1" }
|
|
||||||
]
|
|
||||||
reset = [ { cmd = "CFUN", value = "1,1" } ]
|
|
||||||
+
|
|
||||||
+[gnss]
|
|
||||||
+enabled = true
|
|
||||||
+url = "https://proxy.postmarketos.org"
|
|
||||||
+file = "xtra2.bin"
|
|
||||||
diff --git a/meson.build b/meson.build
|
|
||||||
index d57d2cb..2852778 100644
|
|
||||||
--- a/meson.build
|
|
||||||
+++ b/meson.build
|
|
||||||
@@ -58,6 +58,7 @@ mgr_deps = [
|
|
||||||
dependency('gudev-1.0'),
|
|
||||||
dependency('libgpiod'),
|
|
||||||
dependency('libusb-1.0'),
|
|
||||||
+ dependency('libcurl'),
|
|
||||||
mmglib_dep,
|
|
||||||
]
|
|
||||||
|
|
||||||
diff --git a/src/at.c b/src/at.c
|
|
||||||
index 35b7042..3e0f531 100644
|
|
||||||
--- a/src/at.c
|
|
||||||
+++ b/src/at.c
|
|
||||||
@@ -6,6 +6,7 @@
|
|
||||||
|
|
||||||
#include "at.h"
|
|
||||||
#include "suspend.h"
|
|
||||||
+#include "gnss.h"
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
@@ -205,24 +206,41 @@ static gboolean modem_response(gint fd,
|
|
||||||
|
|
||||||
g_message("Response: [%s]", response);
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * When the modem is started, it outputs 'RDY' to indicate that
|
|
||||||
+ * it is ready to receive AT commands.
|
|
||||||
+ */
|
|
||||||
if (strcmp(response, "RDY") == 0) {
|
|
||||||
suspend_inhibit(manager, TRUE, TRUE);
|
|
||||||
manager->modem_state = EG25_STATE_STARTED;
|
|
||||||
}
|
|
||||||
+ /*
|
|
||||||
+ * Search for 'QGPSURC: "xtradataexpire"' in response to detect
|
|
||||||
+ * if GNSS assistance data must be re-uploaded.
|
|
||||||
+ * If that's the case, check if no AT commands are being processed
|
|
||||||
+ * to avoid deadlocks and start upload.
|
|
||||||
+ */
|
|
||||||
+ else if (strstr(response, "QGPSURC: \"xtradataexpire\"") && manager->at_cmds == NULL)
|
|
||||||
+ gnss_upload_assistance_data(manager);
|
|
||||||
/*
|
|
||||||
+ * AT command failed, retry
|
|
||||||
* QCFG="fast/poweroff" configuration is only available in
|
|
||||||
* newer firmware versions
|
|
||||||
*/
|
|
||||||
else if (strstr(response, "ERROR") && !strstr(response, "fast/poweroff"))
|
|
||||||
retry_at_command(manager);
|
|
||||||
- else if (strstr(response, "OK")) {
|
|
||||||
+ /*
|
|
||||||
+ * Successfull AT responses contain 'OK', except for AT+QFUPL which also
|
|
||||||
+ * returns 'CONNECT' when the modem is ready to receive data over serial
|
|
||||||
+ */
|
|
||||||
+ else if (strstr(response, "OK") || strstr(response, "CONNECT")) {
|
|
||||||
if (manager->at_callback != NULL)
|
|
||||||
manager->at_callback(manager, response);
|
|
||||||
else
|
|
||||||
g_warning("AT command succesfull but no callback registered");
|
|
||||||
}
|
|
||||||
+ /* Not a recognized response, try running next command, just in case */
|
|
||||||
else
|
|
||||||
- // Not a recognized response, try running next command, just in case
|
|
||||||
at_next_command(manager);
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/src/gnss.c b/src/gnss.c
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..15814e9
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/src/gnss.c
|
|
||||||
@@ -0,0 +1,478 @@
|
|
||||||
+/*
|
|
||||||
+ * Copyright (C) 2021 Dylan Van Assche <me@dylanvanassche.be>
|
|
||||||
+ *
|
|
||||||
+ * SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#include "gnss.h"
|
|
||||||
+#include "manager.h"
|
|
||||||
+#include "at.h"
|
|
||||||
+
|
|
||||||
+#define BUFFER_SIZE 256
|
|
||||||
+#define UPLOAD_DELAY 100000
|
|
||||||
+#define RESCHEDULE_IN_SECS 30
|
|
||||||
+
|
|
||||||
+static void gnss_step(struct EG25Manager *manager);
|
|
||||||
+
|
|
||||||
+void gnss_upload_assistance_data(struct EG25Manager *manager)
|
|
||||||
+{
|
|
||||||
+ if (!manager->gnss_assistance_enabled) {
|
|
||||||
+ g_message("GNSS assistance is disabled!");
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (manager->gnss_assistance_step < EG25_GNSS_STEP_LAST) {
|
|
||||||
+ g_warning("GNSS assistance data upload already in process (%d/%d)",
|
|
||||||
+ manager->gnss_assistance_step, EG25_GNSS_STEP_LAST);
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+ manager->gnss_assistance_step = EG25_GNSS_STEP_FIRST;
|
|
||||||
+ gnss_step(manager);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void gnss_init(struct EG25Manager *manager, toml_table_t *config)
|
|
||||||
+{
|
|
||||||
+ toml_datum_t enabled;
|
|
||||||
+ toml_datum_t url;
|
|
||||||
+ toml_datum_t file;
|
|
||||||
+ g_autoptr (GError) error = NULL;
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * GNSS assistance is an optional feature, you can disable it
|
|
||||||
+ * if you want in the configuration file.
|
|
||||||
+ * In case the configuration is missing, we assume GNSS assistance
|
|
||||||
+ * to be disabled.
|
|
||||||
+ */
|
|
||||||
+ enabled = toml_bool_in(config, "enabled");
|
|
||||||
+ manager->gnss_assistance_enabled = FALSE;
|
|
||||||
+ if (enabled.ok)
|
|
||||||
+ manager->gnss_assistance_enabled = enabled.u.b;
|
|
||||||
+
|
|
||||||
+ if (!manager->gnss_assistance_enabled) {
|
|
||||||
+ g_message("GNSS assistance is disabled!");
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ url = toml_string_in(config, "url");
|
|
||||||
+ if (url.ok)
|
|
||||||
+ manager->gnss_assistance_url = url.u.s;
|
|
||||||
+ else
|
|
||||||
+ g_error("GNSS assistance server URL is missing from config file");
|
|
||||||
+ file = toml_string_in(config, "file");
|
|
||||||
+ if (file.ok)
|
|
||||||
+ manager->gnss_assistance_file = file.u.s;
|
|
||||||
+ else
|
|
||||||
+ g_error("GNSS assistance file name is missing from config file");
|
|
||||||
+
|
|
||||||
+ /* Create temporary file to store assistance data */
|
|
||||||
+ manager->gnss_assistance_fd = g_file_open_tmp(NULL, NULL, &error);
|
|
||||||
+ if (error != NULL)
|
|
||||||
+ g_error ("Unable to create temporary file: %s", error->message);
|
|
||||||
+
|
|
||||||
+ /* Initialize state and schedule upload */
|
|
||||||
+ manager->gnss_assistance_step = EG25_GNSS_STEP_LAST;
|
|
||||||
+ g_timeout_add_seconds(RESCHEDULE_IN_SECS,
|
|
||||||
+ G_SOURCE_FUNC(gnss_upload_assistance_data), manager);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void gnss_destroy(struct EG25Manager *manager)
|
|
||||||
+{
|
|
||||||
+ close(manager->gnss_assistance_fd);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/******************************************************************************/
|
|
||||||
+
|
|
||||||
+#ifdef HAVE_MMGLIB
|
|
||||||
+static void disable_mm_gnss(struct EG25Manager *manager)
|
|
||||||
+{
|
|
||||||
+ MMModemLocationSource sources;
|
|
||||||
+ gboolean signals_location;
|
|
||||||
+ g_autoptr (GError) error = NULL;
|
|
||||||
+
|
|
||||||
+ sources = mm_modem_location_get_enabled(manager->mm_location);
|
|
||||||
+ signals_location = mm_modem_location_signals_location(manager->mm_location);
|
|
||||||
+ manager->gnss_sources = EG25_GNSS_SOURCE_NONE;
|
|
||||||
+
|
|
||||||
+ /* Save GNSS engine state */
|
|
||||||
+ if (sources & MM_MODEM_LOCATION_SOURCE_GPS_NMEA)
|
|
||||||
+ manager->gnss_sources |= EG25_GNSS_SOURCE_NMEA;
|
|
||||||
+ else
|
|
||||||
+ manager->gnss_sources &= ~EG25_GNSS_SOURCE_NMEA;
|
|
||||||
+
|
|
||||||
+ if (sources & MM_MODEM_LOCATION_SOURCE_GPS_RAW)
|
|
||||||
+ manager->gnss_sources |= EG25_GNSS_SOURCE_RAW;
|
|
||||||
+ else
|
|
||||||
+ manager->gnss_sources &= ~EG25_GNSS_SOURCE_RAW;
|
|
||||||
+
|
|
||||||
+ if (sources & MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED)
|
|
||||||
+ manager->gnss_sources |= EG25_GNSS_SOURCE_UNMANAGED;
|
|
||||||
+ else
|
|
||||||
+ manager->gnss_sources &= ~EG25_GNSS_SOURCE_UNMANAGED;
|
|
||||||
+
|
|
||||||
+ /* Disable GNSS engine */
|
|
||||||
+ sources &= ~MM_MODEM_LOCATION_SOURCE_GPS_RAW;
|
|
||||||
+ sources &= ~MM_MODEM_LOCATION_SOURCE_GPS_NMEA;
|
|
||||||
+ sources &= ~MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED;
|
|
||||||
+ mm_modem_location_setup_sync(manager->mm_location, sources,
|
|
||||||
+ signals_location, NULL, &error);
|
|
||||||
+ if (error != NULL) {
|
|
||||||
+ g_warning("Unable to disable GNSS engine through ModemManager: %s",
|
|
||||||
+ error->message);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+static void disable_at_gnss_cb(struct EG25Manager *manager,
|
|
||||||
+ const char *response)
|
|
||||||
+{
|
|
||||||
+ /* Clear QGPSEND AT command and process next */
|
|
||||||
+ at_next_command(manager);
|
|
||||||
+
|
|
||||||
+ /* Go to the next step */
|
|
||||||
+ manager->gnss_assistance_step++;
|
|
||||||
+ gnss_step(manager);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void state_at_gnss_cb(struct EG25Manager *manager, const char *response)
|
|
||||||
+{
|
|
||||||
+ struct AtCommand *at_cmd = manager->at_cmds ? g_list_nth_data(manager->at_cmds, 0) : NULL;
|
|
||||||
+
|
|
||||||
+ if (!at_cmd)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ /* Parse GNSS engine status and disable it if needed */
|
|
||||||
+ if (strstr(response, "QGPS: 1")) {
|
|
||||||
+ manager->gnss_sources |= EG25_GNSS_SOURCE_QGPS;
|
|
||||||
+ g_free(at_cmd->value);
|
|
||||||
+ g_free(at_cmd->cmd);
|
|
||||||
+ at_cmd->expected = NULL;
|
|
||||||
+ at_cmd->subcmd = NULL;
|
|
||||||
+ at_cmd->value = NULL;
|
|
||||||
+ at_cmd->cmd = g_strdup("QGPSEND");
|
|
||||||
+ at_cmd->callback = disable_at_gnss_cb;
|
|
||||||
+ at_send_command(manager);
|
|
||||||
+ }
|
|
||||||
+ /* QGPS is already disabled, move on to next step */
|
|
||||||
+ else {
|
|
||||||
+ at_next_command(manager);
|
|
||||||
+ manager->gnss_sources &= ~EG25_GNSS_SOURCE_QGPS;
|
|
||||||
+ manager->gnss_assistance_step++;
|
|
||||||
+ gnss_step(manager);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void state_at_gnss(struct EG25Manager *manager)
|
|
||||||
+{
|
|
||||||
+ /* Asynchronously send AT command to query status of GNSS engine */
|
|
||||||
+ at_append_command(manager, "QGPS?", NULL, NULL, NULL, state_at_gnss_cb);
|
|
||||||
+ at_send_command(manager);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/******************************************************************************/
|
|
||||||
+
|
|
||||||
+static void fetch_assistance_data(struct EG25Manager *manager)
|
|
||||||
+{
|
|
||||||
+ CURL *curl;
|
|
||||||
+ CURLcode response;
|
|
||||||
+ long status_code;
|
|
||||||
+ gchar *url = NULL;
|
|
||||||
+ FILE *tmp_file = NULL;
|
|
||||||
+ long int size;
|
|
||||||
+
|
|
||||||
+ /* Fetch assistance data with curl */
|
|
||||||
+ tmp_file = fdopen(manager->gnss_assistance_fd, "wb");
|
|
||||||
+ url = g_strconcat(manager->gnss_assistance_url, "/",
|
|
||||||
+ manager->gnss_assistance_file, NULL);
|
|
||||||
+ curl = curl_easy_init();
|
|
||||||
+ if (!curl)
|
|
||||||
+ g_error ("Unable to initialize curl");
|
|
||||||
+ curl_easy_setopt(curl, CURLOPT_URL, url);
|
|
||||||
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);
|
|
||||||
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, tmp_file);
|
|
||||||
+ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
|
||||||
+ curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
|
|
||||||
+ response = curl_easy_perform(curl);
|
|
||||||
+ if (response == CURLE_HTTP_RETURNED_ERROR) {
|
|
||||||
+ curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status_code);
|
|
||||||
+ curl_easy_cleanup(curl);
|
|
||||||
+ g_warning ("Unable to fetch GNSS assistance data from %s (HTTP %ld)",
|
|
||||||
+ url, status_code);
|
|
||||||
+
|
|
||||||
+ /* Restart upload on HTTP error status code */
|
|
||||||
+ g_message ("Rescheduling upload because of failure in %ds",
|
|
||||||
+ RESCHEDULE_IN_SECS);
|
|
||||||
+ manager->gnss_assistance_step = EG25_GNSS_STEP_LAST;
|
|
||||||
+ g_timeout_add_seconds(RESCHEDULE_IN_SECS,
|
|
||||||
+ G_SOURCE_FUNC(gnss_upload_assistance_data),
|
|
||||||
+ manager);
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Get file size in bytes */
|
|
||||||
+ size = (long int)lseek(manager->gnss_assistance_fd, 0, SEEK_END);
|
|
||||||
+ lseek(manager->gnss_assistance_fd, 0, SEEK_SET);
|
|
||||||
+
|
|
||||||
+ if (size <= 0) {
|
|
||||||
+ g_warning ("GNSS assistance data contains 0 bytes,"
|
|
||||||
+ "check network connection.");
|
|
||||||
+ /*
|
|
||||||
+ * Restart upload when file does not contain any data,
|
|
||||||
+ * mostly because of no network connection.
|
|
||||||
+ */
|
|
||||||
+ g_message ("Rescheduling upload because of failure in %ds",
|
|
||||||
+ RESCHEDULE_IN_SECS);
|
|
||||||
+ manager->gnss_assistance_step = EG25_GNSS_STEP_LAST;
|
|
||||||
+ g_timeout_add_seconds(RESCHEDULE_IN_SECS,
|
|
||||||
+ G_SOURCE_FUNC(gnss_upload_assistance_data),
|
|
||||||
+ manager);
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ g_message("Fetching GNSS assistance data from %s was successfull", url);
|
|
||||||
+ curl_easy_cleanup(curl);
|
|
||||||
+ g_free(url);
|
|
||||||
+
|
|
||||||
+ /* Go to the next step */
|
|
||||||
+ manager->gnss_assistance_step++;
|
|
||||||
+ gnss_step(manager);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/******************************************************************************/
|
|
||||||
+
|
|
||||||
+static void init_assistance_data_upload_step2(struct EG25Manager *manager,
|
|
||||||
+ const char *response)
|
|
||||||
+{
|
|
||||||
+ /* Search for 'CONNECT' in response to start upload */
|
|
||||||
+ if (strstr(response, "CONNECT")) {
|
|
||||||
+ g_message("Modem ready for GNSS assistance data upload");
|
|
||||||
+ manager->gnss_assistance_step++;
|
|
||||||
+ gnss_step(manager);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void init_assistance_data_upload_step1(struct EG25Manager *manager,
|
|
||||||
+ const char *response)
|
|
||||||
+{
|
|
||||||
+ gchar value[BUFFER_SIZE];
|
|
||||||
+ long int size;
|
|
||||||
+
|
|
||||||
+ /* Process AT response */
|
|
||||||
+ at_process_result(manager, response);
|
|
||||||
+
|
|
||||||
+ /* Get file size in bytes */
|
|
||||||
+ size = (long int)lseek(manager->gnss_assistance_fd, 0, SEEK_END);
|
|
||||||
+ lseek(manager->gnss_assistance_fd, 0, SEEK_SET);
|
|
||||||
+
|
|
||||||
+ /* Start upload */
|
|
||||||
+ g_snprintf(value, BUFFER_SIZE, "\"RAM:%s\",%ld\r\n",
|
|
||||||
+ manager->gnss_assistance_file, size);
|
|
||||||
+ g_message("Initiate GNSS assistance data upload: %s", value);
|
|
||||||
+ at_append_command(manager, "QFUPL", NULL, value, NULL,
|
|
||||||
+ init_assistance_data_upload_step2);
|
|
||||||
+ at_send_command(manager);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void init_assistance_data_upload(struct EG25Manager *manager)
|
|
||||||
+{
|
|
||||||
+ /*
|
|
||||||
+ * Delete all previous GNSS assistance data files in RAM
|
|
||||||
+ * and start uploading the latest one to RAM.
|
|
||||||
+ */
|
|
||||||
+ at_append_command(manager, "QFDEL", NULL, "\"RAM:*\"\r\n",
|
|
||||||
+ NULL, init_assistance_data_upload_step1);
|
|
||||||
+ at_send_command(manager);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void upload_assistance_data(struct EG25Manager *manager)
|
|
||||||
+{
|
|
||||||
+ char buffer[2*BUFFER_SIZE];
|
|
||||||
+ gint len;
|
|
||||||
+ gboolean success = TRUE;
|
|
||||||
+
|
|
||||||
+ /* Copy downloaded XTRA assistance data to the modem over serial */
|
|
||||||
+ while((len = read(manager->gnss_assistance_fd, buffer, 2*BUFFER_SIZE)) > 0)
|
|
||||||
+ {
|
|
||||||
+ len = write(manager->at_fd, buffer, len);
|
|
||||||
+ if (len < 0) {
|
|
||||||
+ success = FALSE;
|
|
||||||
+ g_error("Writing GNSS assistance data failed: %d", len);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ usleep(UPLOAD_DELAY);
|
|
||||||
+ g_message("Uploaded %d bytes", len);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Clear QFUPL AT command and process next */
|
|
||||||
+ at_next_command(manager);
|
|
||||||
+
|
|
||||||
+ /* Go to the next step if successful */
|
|
||||||
+ if (success) {
|
|
||||||
+ manager->gnss_assistance_step++;
|
|
||||||
+ gnss_step(manager);
|
|
||||||
+ }
|
|
||||||
+ /* Restart upload */
|
|
||||||
+ else {
|
|
||||||
+ g_message ("Rescheduling upload because of failure in %ds",
|
|
||||||
+ RESCHEDULE_IN_SECS);
|
|
||||||
+ manager->gnss_assistance_step = EG25_GNSS_STEP_LAST;
|
|
||||||
+ g_timeout_add_seconds(RESCHEDULE_IN_SECS,
|
|
||||||
+ G_SOURCE_FUNC(gnss_upload_assistance_data),
|
|
||||||
+ manager);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void finish_assistance_data_upload_cb(struct EG25Manager *manager,
|
|
||||||
+ const char *response)
|
|
||||||
+{
|
|
||||||
+ /* Process response */
|
|
||||||
+ at_process_result(manager, response);
|
|
||||||
+ g_message("GNSS assistance data upload finished");
|
|
||||||
+
|
|
||||||
+ /* Go to the next step */
|
|
||||||
+ manager->gnss_assistance_step++;
|
|
||||||
+ gnss_step(manager);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void finish_assistance_data_upload(struct EG25Manager *manager)
|
|
||||||
+{
|
|
||||||
+ gchar value[BUFFER_SIZE];
|
|
||||||
+ GDateTime *datetime;
|
|
||||||
+ gchar *timestring;
|
|
||||||
+
|
|
||||||
+ /* Configure GNSS assistance clock to current system time (UTC) */
|
|
||||||
+ datetime = g_date_time_new_now_utc();
|
|
||||||
+ timestring = g_date_time_format(datetime, "0,\"%Y/%m/%d,%H:%M:%S\"\r\n");
|
|
||||||
+ g_message("Setting GNSS assistance UTC clock to: %s", timestring);
|
|
||||||
+ at_append_command(manager, "QGPSXTRATIME", NULL, timestring, NULL,
|
|
||||||
+ at_process_result);
|
|
||||||
+
|
|
||||||
+ /* Configure GNSS engine to use uploaded GNSS assistance data */
|
|
||||||
+ g_snprintf(value, BUFFER_SIZE, "\"RAM:%s\"\r\n",
|
|
||||||
+ manager->gnss_assistance_file);
|
|
||||||
+ g_message("Setting GNSS assistance file to: %s", value);
|
|
||||||
+ at_append_command(manager, "QGPSXTRADATA", NULL, value, NULL,
|
|
||||||
+ finish_assistance_data_upload_cb);
|
|
||||||
+ at_send_command(manager);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/******************************************************************************/
|
|
||||||
+
|
|
||||||
+#ifdef HAVE_MMGLIB
|
|
||||||
+static void enable_mm_gnss(struct EG25Manager *manager)
|
|
||||||
+{
|
|
||||||
+ MMModemLocationSource sources;
|
|
||||||
+ gboolean signal_location;
|
|
||||||
+ g_autoptr (GError) error = NULL;
|
|
||||||
+
|
|
||||||
+ if (manager->gnss_sources & EG25_GNSS_SOURCE_UNMANAGED)
|
|
||||||
+ sources |= MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED;
|
|
||||||
+ if (manager->gnss_sources & EG25_GNSS_SOURCE_NMEA)
|
|
||||||
+ sources |= MM_MODEM_LOCATION_SOURCE_GPS_NMEA;
|
|
||||||
+ if (manager->gnss_sources & EG25_GNSS_SOURCE_RAW)
|
|
||||||
+ sources |= MM_MODEM_LOCATION_SOURCE_GPS_RAW;
|
|
||||||
+
|
|
||||||
+ sources = mm_modem_location_get_enabled(manager->mm_location);
|
|
||||||
+ signal_location = mm_modem_location_signals_location(manager->mm_location);
|
|
||||||
+ mm_modem_location_setup_sync(manager->mm_location, sources,
|
|
||||||
+ signal_location, NULL, &error);
|
|
||||||
+ if (error != NULL)
|
|
||||||
+ g_warning("Unable to enable GNSS engine through ModemManager: %s",
|
|
||||||
+ error->message);
|
|
||||||
+}
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+static void enable_at_gnss_cb(struct EG25Manager *manager, const char *response)
|
|
||||||
+{
|
|
||||||
+ manager->gnss_assistance_step++;
|
|
||||||
+ gnss_step(manager);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void enable_at_gnss(struct EG25Manager *manager)
|
|
||||||
+{
|
|
||||||
+ if (manager->gnss_sources & EG25_GNSS_SOURCE_QGPS) {
|
|
||||||
+ at_append_command(manager, "QGPS", NULL, "1", NULL,
|
|
||||||
+ enable_at_gnss_cb);
|
|
||||||
+ at_send_command(manager);
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+ manager->gnss_assistance_step++;
|
|
||||||
+ gnss_step(manager);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/******************************************************************************/
|
|
||||||
+
|
|
||||||
+void gnss_step(struct EG25Manager *manager)
|
|
||||||
+{
|
|
||||||
+ switch(manager->gnss_assistance_step) {
|
|
||||||
+ case EG25_GNSS_STEP_FIRST:
|
|
||||||
+ manager->gnss_assistance_step++;
|
|
||||||
+ g_message("GNSS assistance upload started...");
|
|
||||||
+ /* fall-through */
|
|
||||||
+
|
|
||||||
+#ifdef HAVE_MMGLIB
|
|
||||||
+ case EG25_GNSS_STEP_MM_GNSS_DISABLE:
|
|
||||||
+ g_message("GNSS assistance upload step (%d/%d): "
|
|
||||||
+ "disabling GNSS engine through ModemManager",
|
|
||||||
+ manager->gnss_assistance_step, EG25_GNSS_STEP_LAST);
|
|
||||||
+ disable_mm_gnss(manager);
|
|
||||||
+ manager->gnss_assistance_step++;
|
|
||||||
+ /* fall-through */
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ case EG25_GNSS_STEP_AT_GNSS_DISABLE:
|
|
||||||
+ g_message("GNSS assistance upload step (%d/%d): "
|
|
||||||
+ "disabling GNSS engine through AT+QGPS",
|
|
||||||
+ manager->gnss_assistance_step, EG25_GNSS_STEP_LAST);
|
|
||||||
+ state_at_gnss(manager);
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ case EG25_GNSS_STEP_FETCH_ASSISTANCE_DATA:
|
|
||||||
+ g_message("GNSS assistance upload step (%d/%d): "
|
|
||||||
+ "fetching assistance data",
|
|
||||||
+ manager->gnss_assistance_step, EG25_GNSS_STEP_LAST);
|
|
||||||
+ fetch_assistance_data(manager);
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ case EG25_GNSS_STEP_INIT_UPLOAD:
|
|
||||||
+ g_message("GNSS assistance upload step (%d/%d): initiating upload",
|
|
||||||
+ manager->gnss_assistance_step, EG25_GNSS_STEP_LAST);
|
|
||||||
+ init_assistance_data_upload(manager);
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ case EG25_GNSS_STEP_UPLOAD:
|
|
||||||
+ g_message("GNSS assistance upload step (%d/%d): "
|
|
||||||
+ "uploading assistance data",
|
|
||||||
+ manager->gnss_assistance_step, EG25_GNSS_STEP_LAST);
|
|
||||||
+ upload_assistance_data(manager);
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ case EG25_GNSS_STEP_FINISH_UPLOAD:
|
|
||||||
+ g_message("GNSS assistance upload step (%d/%d): finishing upload",
|
|
||||||
+ manager->gnss_assistance_step, EG25_GNSS_STEP_LAST);
|
|
||||||
+ finish_assistance_data_upload(manager);
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+#ifdef HAVE_MMGLIB
|
|
||||||
+ case EG25_GNSS_STEP_MM_GNSS_ENABLE:
|
|
||||||
+ g_message("GNSS assistance upload step (%d/%d): "
|
|
||||||
+ "re-enabling GNSS through ModemManager",
|
|
||||||
+ manager->gnss_assistance_step, EG25_GNSS_STEP_LAST);
|
|
||||||
+ enable_mm_gnss(manager);
|
|
||||||
+ manager->gnss_assistance_step++;
|
|
||||||
+ /* fall-through */
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ case EG25_GNSS_STEP_AT_QGPS_ENABLE:
|
|
||||||
+ g_message("GNSS assistance upload step (%d/%d): "
|
|
||||||
+ "re-enabling GNSS through AT+QGPS",
|
|
||||||
+ manager->gnss_assistance_step, EG25_GNSS_STEP_LAST);
|
|
||||||
+ enable_at_gnss(manager);
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ case EG25_GNSS_STEP_LAST:
|
|
||||||
+ g_message("GNSS assistance upload step (%d/%d): finished",
|
|
||||||
+ manager->gnss_assistance_step, EG25_GNSS_STEP_LAST);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
diff --git a/src/gnss.h b/src/gnss.h
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..931ab8b
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/src/gnss.h
|
|
||||||
@@ -0,0 +1,16 @@
|
|
||||||
+/*
|
|
||||||
+ * Copyright (C) 2021 Dylan Van Assche <me@dylanvanassche.be>
|
|
||||||
+ *
|
|
||||||
+ * SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#pragma once
|
|
||||||
+
|
|
||||||
+#include <time.h>
|
|
||||||
+#include <curl/curl.h>
|
|
||||||
+
|
|
||||||
+#include "manager.h"
|
|
||||||
+
|
|
||||||
+void gnss_init(struct EG25Manager *manager, toml_table_t *config);
|
|
||||||
+void gnss_destroy(struct EG25Manager *manager);
|
|
||||||
+void gnss_upload_assistance_data(struct EG25Manager *manager);
|
|
||||||
diff --git a/src/manager.c b/src/manager.c
|
|
||||||
index c0b8a43..d13a2a0 100644
|
|
||||||
--- a/src/manager.c
|
|
||||||
+++ b/src/manager.c
|
|
||||||
@@ -15,6 +15,7 @@
|
|
||||||
#include "ofono-iface.h"
|
|
||||||
#include "suspend.h"
|
|
||||||
#include "udev.h"
|
|
||||||
+#include "gnss.h"
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <signal.h>
|
|
||||||
@@ -342,6 +343,7 @@ int main(int argc, char *argv[])
|
|
||||||
ofono_iface_init(&manager);
|
|
||||||
suspend_init(&manager, toml_table_in(toml_config, "suspend"));
|
|
||||||
udev_init(&manager, toml_table_in(toml_config, "udev"));
|
|
||||||
+ gnss_init(&manager, toml_table_in(toml_config, "gnss"));
|
|
||||||
|
|
||||||
g_idle_add(G_SOURCE_FUNC(modem_start), &manager);
|
|
||||||
|
|
||||||
diff --git a/src/manager.h b/src/manager.h
|
|
||||||
index 3cc0118..3e097b3 100644
|
|
||||||
--- a/src/manager.h
|
|
||||||
+++ b/src/manager.h
|
|
||||||
@@ -16,6 +16,32 @@
|
|
||||||
|
|
||||||
#include "toml.h"
|
|
||||||
|
|
||||||
+typedef enum {
|
|
||||||
+ EG25_GNSS_STEP_FIRST = 0,
|
|
||||||
+#ifdef HAVE_MMGLIB
|
|
||||||
+ EG25_GNSS_STEP_MM_GNSS_DISABLE,
|
|
||||||
+#endif
|
|
||||||
+ EG25_GNSS_STEP_AT_GNSS_DISABLE,
|
|
||||||
+ EG25_GNSS_STEP_FETCH_ASSISTANCE_DATA,
|
|
||||||
+ EG25_GNSS_STEP_INIT_UPLOAD,
|
|
||||||
+ EG25_GNSS_STEP_UPLOAD,
|
|
||||||
+ EG25_GNSS_STEP_FINISH_UPLOAD,
|
|
||||||
+#ifdef HAVE_MMGLIB
|
|
||||||
+ EG25_GNSS_STEP_MM_GNSS_ENABLE,
|
|
||||||
+#endif
|
|
||||||
+ EG25_GNSS_STEP_AT_QGPS_ENABLE,
|
|
||||||
+ EG25_GNSS_STEP_LAST,
|
|
||||||
+} EG25GNSSStep;
|
|
||||||
+
|
|
||||||
+typedef enum {
|
|
||||||
+ EG25_GNSS_SOURCE_NONE = 0,
|
|
||||||
+ EG25_GNSS_SOURCE_NMEA = 1 << 0,
|
|
||||||
+ EG25_GNSS_SOURCE_RAW = 1 << 1,
|
|
||||||
+ EG25_GNSS_SOURCE_UNMANAGED = 1 << 2,
|
|
||||||
+ EG25_GNSS_SOURCE_QGPS = 1 << 3,
|
|
||||||
+} EG25GNSSSource;
|
|
||||||
+
|
|
||||||
+
|
|
||||||
enum EG25State {
|
|
||||||
EG25_STATE_INIT = 0,
|
|
||||||
EG25_STATE_POWERED, // Power-on sequence has been executed, but the modem isn't on yet
|
|
||||||
@@ -52,11 +78,19 @@ struct EG25Manager {
|
|
||||||
enum EG25State modem_state;
|
|
||||||
gchar *modem_usb_id;
|
|
||||||
|
|
||||||
+ gboolean gnss_assistance_enabled;
|
|
||||||
+ EG25GNSSSource gnss_sources;
|
|
||||||
+ EG25GNSSStep gnss_assistance_step;
|
|
||||||
+ gint gnss_assistance_fd;
|
|
||||||
+ gchar *gnss_assistance_url;
|
|
||||||
+ gchar *gnss_assistance_file;
|
|
||||||
+
|
|
||||||
enum ModemIface modem_iface;
|
|
||||||
guint mm_watch;
|
|
||||||
#ifdef HAVE_MMGLIB
|
|
||||||
MMManager *mm_manager;
|
|
||||||
MMModem *mm_modem;
|
|
||||||
+ MMModemLocation *mm_location;
|
|
||||||
#endif
|
|
||||||
guint ofono_watch;
|
|
||||||
GDBOManager *ofono_manager;
|
|
||||||
diff --git a/src/meson.build b/src/meson.build
|
|
||||||
index f9eb27f..d1127dc 100644
|
|
||||||
--- a/src/meson.build
|
|
||||||
+++ b/src/meson.build
|
|
||||||
@@ -15,6 +15,7 @@ src = [
|
|
||||||
'suspend.c', 'suspend.h',
|
|
||||||
'toml.c', 'toml.h',
|
|
||||||
'udev.c', 'udev.h',
|
|
||||||
+ 'gnss.c', 'gnss.h',
|
|
||||||
]
|
|
||||||
|
|
||||||
if mmglib_dep.found()
|
|
||||||
diff --git a/src/mm-iface.c b/src/mm-iface.c
|
|
||||||
index 0409236..2bbdfe5 100644
|
|
||||||
--- a/src/mm-iface.c
|
|
||||||
+++ b/src/mm-iface.c
|
|
||||||
@@ -32,7 +32,10 @@ static void add_modem(struct EG25Manager *manager, GDBusObject *object)
|
|
||||||
|
|
||||||
g_assert(MM_IS_OBJECT (object));
|
|
||||||
manager->mm_modem = mm_object_get_modem(MM_OBJECT(object));
|
|
||||||
- g_assert(manager->mm_modem != NULL);
|
|
||||||
+ manager->mm_location = mm_object_get_modem_location(MM_OBJECT(object));
|
|
||||||
+ g_assert_nonnull(manager->mm_modem);
|
|
||||||
+ g_assert_nonnull(manager->mm_location);
|
|
||||||
+
|
|
||||||
|
|
||||||
if (manager->modem_state == EG25_STATE_RESUMING) {
|
|
||||||
if (manager->modem_recovery_timer) {
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
# Forked from Alpine to upgrade to current git master, which has
|
# Forked from Alpine to upgrade to current git master, which has
|
||||||
# Ofono compatibility fixes needed for Plasma Mobile
|
# Ofono compatibility fixes needed for Plasma Mobile
|
||||||
|
|
||||||
pkgname=eg25-manager
|
pkgname=eg25-manager
|
||||||
pkgver=0.3.0_git20210522
|
pkgver=0.3.0_git20210812
|
||||||
_commit="73e16f76994b1d3c587796a35766cc668e30c0cd"
|
|
||||||
pkgrel=0
|
pkgrel=0
|
||||||
pkgdesc="Daemon for managing the Quectel EG25 modem"
|
pkgdesc="Daemon for managing the Quectel EG25 modem"
|
||||||
url="https://gitlab.com/mobian1/devices/eg25-manager"
|
url="https://gitlab.com/mobian1/devices/eg25-manager"
|
||||||
arch="all !s390x !mips64" # no modemmanager
|
# s390x, mips64 and riscv64 blocked by polkit -> modemmanager
|
||||||
|
arch="all !s390x !mips64 !riscv64"
|
||||||
license="GPL-3.0-or-later"
|
license="GPL-3.0-or-later"
|
||||||
makedepends="
|
makedepends="
|
||||||
glib-dev
|
glib-dev
|
||||||
|
@ -18,22 +17,15 @@ makedepends="
|
||||||
modemmanager-dev
|
modemmanager-dev
|
||||||
curl-dev
|
curl-dev
|
||||||
"
|
"
|
||||||
|
_commit="e6df81778e812ef73aa55156bea5ede2937f9a4c"
|
||||||
source="
|
source="
|
||||||
https://gitlab.com/mobian1/devices/eg25-manager/-/archive/$_commit/eg25-manager-$_commit.tar.gz
|
https://gitlab.com/mobian1/devices/eg25-manager/-/archive/$_commit/eg25-manager-$_commit.tar.gz
|
||||||
eg25-manager.confd
|
eg25-manager.confd
|
||||||
eg25-manager.initd
|
eg25-manager.initd
|
||||||
0001-mm-iface-clean-out-modem_iface-if-mm-disappears.patch
|
|
||||||
0002-config-synchronize-with-modem-power.patch
|
|
||||||
0003-at-fast-poweroff-is-only-available-in-newer-firmware.patch
|
|
||||||
0004-at-g_free-doesn-t-require-NULL-checking.patch
|
|
||||||
0005-at-make-next_at_command-send_at_command-process_at_r.patch
|
|
||||||
0006-at-log-expected-result-before-setting-it-to-NULL.patch
|
|
||||||
0007-at-allow-custom-callbacks-for-AT-command-response-pr.patch
|
|
||||||
0008-gnss-add-GNSS-assistance-support.patch
|
|
||||||
"
|
"
|
||||||
options="!check" # no tests
|
options="!check" # no tests
|
||||||
subpackages="$pkgname-openrc"
|
subpackages="$pkgname-openrc"
|
||||||
builddir="$srcdir/eg25-manager-$_commit"
|
builddir="$srcdir/$pkgname-$_commit"
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
abuild-meson . output
|
abuild-meson . output
|
||||||
|
@ -54,15 +46,7 @@ package() {
|
||||||
}
|
}
|
||||||
|
|
||||||
sha512sums="
|
sha512sums="
|
||||||
2b0d706c893744529e035e8dc70b381362e39ddd2be705e346f0fd88e4907093e59b30800ad5ecb90638338b25bb51308349fb26de2c786197aeed8c1fa9c68a eg25-manager-73e16f76994b1d3c587796a35766cc668e30c0cd.tar.gz
|
72846ea696ee9d7ec433d5dd932881931d9f1fde2a8edc23e7a8f0d9cd74f41df054ffe15a826d48224b5d1f24ce59a607a93b0da62490ffa06dd8beef2b074c eg25-manager-e6df81778e812ef73aa55156bea5ede2937f9a4c.tar.gz
|
||||||
55936830afad2968a214fb39cfe1a9db50421dc2ff4f67d04f08f6bd2b094c3ab46799cfc7743bbc5032682d98d1216203adf5264353a05134bea58524ac070b eg25-manager.confd
|
55936830afad2968a214fb39cfe1a9db50421dc2ff4f67d04f08f6bd2b094c3ab46799cfc7743bbc5032682d98d1216203adf5264353a05134bea58524ac070b eg25-manager.confd
|
||||||
0dd866ce18bac37c3832a463205402f5b34a520e1a57cc37658fb37e21a173fbba2cfab223111c68af768be1d3feeb23e41dbaf6d8dc14a2b2c0c088cf3df041 eg25-manager.initd
|
0dd866ce18bac37c3832a463205402f5b34a520e1a57cc37658fb37e21a173fbba2cfab223111c68af768be1d3feeb23e41dbaf6d8dc14a2b2c0c088cf3df041 eg25-manager.initd
|
||||||
029dce7e7d6e79faab2a63acde2fe76109e5e269bf38d72617d00ffbb89001f75b604e79290d449db7a6f960f9872eb41c2d0ab4a6d82d7563b66e954cd4ffa8 0001-mm-iface-clean-out-modem_iface-if-mm-disappears.patch
|
|
||||||
fe6c37c79ea6e89b6bcce78d015a3770347384181595e2c2ff2d42a76baa626cf430125fcefe7679570da268718039f1cce0aef90fe1a5c5ca123425006bbd03 0002-config-synchronize-with-modem-power.patch
|
|
||||||
ff263d8ce700e910d895496dc5ad0e8e75da17aaac9357b5c3a7632728daab28d2fe4700e2d7c7ba8d45d83742c60dbb581882f95847f0b22cbb09d0ae4c30a6 0003-at-fast-poweroff-is-only-available-in-newer-firmware.patch
|
|
||||||
2e6e3acde664a77dbcb67ad348e622779be1a50b8ef1b7a175fd6377e0e02511ff120b8c6e9670e914e74d9d176f6194e87bbf7742c60b4cfaf69dd26ed90f49 0004-at-g_free-doesn-t-require-NULL-checking.patch
|
|
||||||
a59cb10bf14500daaac70a4dd238133a3dfffbb365c871dc039258ee1b3f89a8a7a81f85d5b9ad8a7428b3a927cff282351a8323dfcfb1556333d04bdae14934 0005-at-make-next_at_command-send_at_command-process_at_r.patch
|
|
||||||
4726f8a8e3cb011d4f4694fc104a289340b8f04a813df9784f823aa773bcfa401fa683de0b8e3837e78b202def3c23a4946dbae31b602659add97a6a585415f2 0006-at-log-expected-result-before-setting-it-to-NULL.patch
|
|
||||||
cce1e5439783e2a88aeb88bad837d7cf09c18065f6516fb0936cb6fb9cac95034b67c87f8a42545a3e82393f2c07f9694ea668237165ec0ab566fd4159894d54 0007-at-allow-custom-callbacks-for-AT-command-response-pr.patch
|
|
||||||
7e798b4547493d6b5f7eeb848682d7e0b4d2b0c066696079e99ee777d82c5ffa04d25f15f4ef6f9197cb5187a6c9c286ffcf0cbad87122d1c36e0f67aa0ca651 0008-gnss-add-GNSS-assistance-support.patch
|
|
||||||
"
|
"
|
||||||
|
|
Loading…
Reference in a new issue