summaryrefslogtreecommitdiff
path: root/gatchat
diff options
context:
space:
mode:
authorMartin Hundebøll <martin@geanix.com>2019-08-12 22:38:31 +0200
committerDenis Kenzior <denkenz@gmail.com>2019-08-13 02:09:09 -0500
commite69a30f1df057407987931fc4f84c0f8e4687bd1 (patch)
tree7338466323f976048d8d089a1fe6a6356bf88558 /gatchat
parente3d5ac1f166668e111d80f8a7fa0211978b5ad7d (diff)
downloadofono-e69a30f1df057407987931fc4f84c0f8e4687bd1.tar.gz
gatchat: add g_at_chat_retry()
The current API doesn't support canceling an in-progress command; instead g_at_chat_cancel() simply removes the callback. In cases where the modem doesn't respond at all to a command, a chat is simply stalled without any way to write new commands to the modem. Support that case by adding a g_at_chat_retry() function to the API. The function does nothing if the command is not yet in-progress, or if the command is finished. Otherwise, it resets the bytes-written counter to re-write the command string.
Diffstat (limited to 'gatchat')
-rw-r--r--gatchat/gatchat.c31
-rw-r--r--gatchat/gatchat.h7
2 files changed, 38 insertions, 0 deletions
diff --git a/gatchat/gatchat.c b/gatchat/gatchat.c
index 3f290ac2..9e777107 100644
--- a/gatchat/gatchat.c
+++ b/gatchat/gatchat.c
@@ -1047,6 +1047,29 @@ static guint at_chat_send_common(struct at_chat *chat, guint gid,
return c->id;
}
+static gboolean at_chat_retry(struct at_chat *chat, guint id)
+{
+ struct at_command *cmd = g_queue_peek_head(chat->command_queue);
+
+ if (!cmd)
+ return FALSE;
+
+ /* do nothing if command is not yet started, or already finished */
+ if (cmd->id != id)
+ return FALSE;
+
+ /* do nothing if command is not fully written */
+ if (chat->cmd_bytes_written != strlen(cmd->cmd))
+ return FALSE;
+
+ /* reset number of written bytes to re-write command */
+ chat->cmd_bytes_written = 0;
+
+ chat_wakeup_writer(chat);
+
+ return TRUE;
+}
+
static struct at_notify *at_notify_create(struct at_chat *chat,
const char *prefix,
gboolean pdu)
@@ -1543,6 +1566,14 @@ guint g_at_chat_send_and_expect_short_prompt(GAtChat *chat, const char *cmd,
NULL, func, user_data, notify);
}
+gboolean g_at_chat_retry(GAtChat *chat, guint id)
+{
+ if (chat == NULL || id == 0)
+ return FALSE;
+
+ return at_chat_retry(chat->parent, id);
+}
+
gboolean g_at_chat_cancel(GAtChat *chat, guint id)
{
/* We use id 0 for wakeup commands */
diff --git a/gatchat/gatchat.h b/gatchat/gatchat.h
index 7290b34f..32870318 100644
--- a/gatchat/gatchat.h
+++ b/gatchat/gatchat.h
@@ -147,6 +147,13 @@ guint g_at_chat_send_and_expect_short_prompt(GAtChat *chat, const char *cmd,
const char **valid_resp, GAtResultFunc func,
gpointer user_data, GDestroyNotify notify);
+/*!
+ * Retry an already created command. This does nothing if the command is
+ * still waiting in the queue. If the command has been written to the channel,
+ * but no response is received yet, the retry writes the command again.
+ */
+gboolean g_at_chat_retry(GAtChat *chat, guint id);
+
gboolean g_at_chat_cancel(GAtChat *chat, guint id);
gboolean g_at_chat_cancel_all(GAtChat *chat);