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.
This commit is contained in:
Martin Hundebøll 2019-08-12 22:38:31 +02:00 committed by Denis Kenzior
parent e3d5ac1f16
commit e69a30f1df
2 changed files with 38 additions and 0 deletions

View File

@ -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 */

View File

@ -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);