modem-manager: Copy the AT retry behaviour in ModemManager

Fixes https://github.com/fwupd/fwupd/issues/4319
This commit is contained in:
Richard Hughes 2022-02-22 10:24:39 +00:00
parent 6ec0646380
commit ccc897e574

View File

@ -32,6 +32,9 @@
* required (e.g. if switching from the default (DF) to generic (GC).*/
#define FU_MM_DEVICE_REMOVE_DELAY_REPROBE 120000 /* ms */
#define FU_MM_DEVICE_AT_RETRIES 3
#define FU_MM_DEVICE_AT_DELAY 3000 /* ms */
/* Amount of time for the modem to get firmware version */
#define MAX_WAIT_TIME_SECS 150 /* s */
@ -616,14 +619,21 @@ fu_mm_device_qcdm_cmd(FuMmDevice *self, const guint8 *cmd, gsize cmd_len, GError
}
#endif /* MM_CHECK_VERSION(1,17,2) */
typedef struct {
const gchar *cmd;
gboolean has_response;
} FuMmDeviceAtCmdHelper;
static gboolean
fu_mm_device_at_cmd(FuMmDevice *self, const gchar *cmd, gboolean has_response, GError **error)
fu_mm_device_at_cmd_cb(FuDevice *device, gpointer user_data, GError **error)
{
FuMmDevice *self = FU_MM_DEVICE(device);
FuMmDeviceAtCmdHelper *helper = (FuMmDeviceAtCmdHelper *)user_data;
const gchar *buf;
gsize bufsz = 0;
g_autoptr(GBytes) at_req = NULL;
g_autoptr(GBytes) at_res = NULL;
g_autofree gchar *cmd_cr = g_strdup_printf("%s\r\n", cmd);
g_autofree gchar *cmd_cr = g_strdup_printf("%s\r\n", helper->cmd);
/* command */
at_req = g_bytes_new(cmd_cr, strlen(cmd_cr));
@ -634,13 +644,13 @@ fu_mm_device_at_cmd(FuMmDevice *self, const gchar *cmd, gboolean has_response, G
1500,
FU_IO_CHANNEL_FLAG_FLUSH_INPUT,
error)) {
g_prefix_error(error, "failed to write %s: ", cmd);
g_prefix_error(error, "failed to write %s: ", helper->cmd);
return FALSE;
}
/* AT command has no response, return TRUE */
if (!has_response) {
g_debug("No response expected for AT command: '%s', assuming succeed", cmd);
if (!helper->has_response) {
g_debug("No response expected for AT command: '%s', assuming succeed", helper->cmd);
return TRUE;
}
@ -651,7 +661,7 @@ fu_mm_device_at_cmd(FuMmDevice *self, const gchar *cmd, gboolean has_response, G
FU_IO_CHANNEL_FLAG_SINGLE_SHOT,
error);
if (at_res == NULL) {
g_prefix_error(error, "failed to read response for %s: ", cmd);
g_prefix_error(error, "failed to read response for %s: ", helper->cmd);
return FALSE;
}
if (g_getenv("FWUPD_MODEM_MANAGER_VERBOSE") != NULL)
@ -662,7 +672,7 @@ fu_mm_device_at_cmd(FuMmDevice *self, const gchar *cmd, gboolean has_response, G
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
"failed to read valid response for %s",
cmd);
helper->cmd);
return FALSE;
}
@ -673,13 +683,13 @@ fu_mm_device_at_cmd(FuMmDevice *self, const gchar *cmd, gboolean has_response, G
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
"failed to read valid response for %s: %s",
cmd,
helper->cmd,
tmp);
return FALSE;
}
/* set firmware branch if returned */
if (self->branch_at != NULL && g_strcmp0(cmd, self->branch_at) == 0) {
if (self->branch_at != NULL && g_strcmp0(helper->cmd, self->branch_at) == 0) {
/*
* example AT+GETFWBRANCH response:
*
@ -700,9 +710,22 @@ fu_mm_device_at_cmd(FuMmDevice *self, const gchar *cmd, gboolean has_response, G
}
}
/* success */
return TRUE;
}
static gboolean
fu_mm_device_at_cmd(FuMmDevice *self, const gchar *cmd, gboolean has_response, GError **error)
{
FuMmDeviceAtCmdHelper helper = {.cmd = cmd, .has_response = has_response};
return fu_device_retry_full(FU_DEVICE(self),
fu_mm_device_at_cmd_cb,
FU_MM_DEVICE_AT_RETRIES,
FU_MM_DEVICE_AT_DELAY,
&helper,
error);
}
static gboolean
fu_mm_device_io_open(FuMmDevice *self, GError **error)
{