aboutsummaryrefslogtreecommitdiff
path: root/src/mm-bearer-qmi.c
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2021-05-17 00:04:45 +0200
committerAleksander Morgado <aleksander@aleksander.es>2021-05-22 22:58:37 +0000
commitb9c66e92ea71f6f46519975bda5a01ebf58fb80d (patch)
tree33308c22514adeb9d8a248c03e76e54c422f52b1 /src/mm-bearer-qmi.c
parenta878cfa0036f6c0608c3e17697edff08ccd9fab1 (diff)
bearer-qmi: rework connection failure error reporting
On a failed QMI modem connection, we won't return the generic "CallFailed" error, we'll try to convert the 3GPP verbose call end reason to a MMMobileEquipmentError. And if we cannot find a mapping, or if the reported error is not a 3GPP verbose call end reason, we'll return a Unknown MMMobileEquipmentError with a string message providing detailed error information.
Diffstat (limited to 'src/mm-bearer-qmi.c')
-rw-r--r--src/mm-bearer-qmi.c86
1 files changed, 55 insertions, 31 deletions
diff --git a/src/mm-bearer-qmi.c b/src/mm-bearer-qmi.c
index 8926918c..02059831 100644
--- a/src/mm-bearer-qmi.c
+++ b/src/mm-bearer-qmi.c
@@ -894,6 +894,55 @@ get_current_settings (GTask *task, QmiClientWds *client)
qmi_message_wds_get_current_settings_input_unref (input);
}
+static GError *
+mobile_equipment_error_from_start_network_output (MMBearerQmi *self,
+ QmiMessageWdsStartNetworkOutput *output)
+{
+ QmiWdsCallEndReason cer;
+ QmiWdsVerboseCallEndReasonType verbose_cer_type;
+ gint16 verbose_cer_reason;
+
+ if (qmi_message_wds_start_network_output_get_verbose_call_end_reason (
+ output,
+ &verbose_cer_type,
+ &verbose_cer_reason,
+ NULL)) {
+ const gchar *verbose_cer_type_str;
+ const gchar *verbose_cer_reason_str;
+
+ verbose_cer_type_str = qmi_wds_verbose_call_end_reason_type_get_string (verbose_cer_type);
+ verbose_cer_reason_str = qmi_wds_verbose_call_end_reason_get_string (verbose_cer_type, verbose_cer_reason);
+ mm_obj_info (self, "verbose call end reason (%u,%d): [%s] %s",
+ verbose_cer_type,
+ verbose_cer_reason,
+ verbose_cer_type_str,
+ verbose_cer_reason_str);
+
+ /* If we have a 3GPP verbose call end reason, we try to build an error
+ * with the exact error code and message */
+ if (verbose_cer_type == QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_3GPP)
+ return qmi_mobile_equipment_error_from_verbose_call_end_reason_3gpp ((QmiWdsVerboseCallEndReason3gpp)verbose_cer_reason, self);
+
+ return g_error_new (MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN,
+ "Call failed: %s error: %s", verbose_cer_type_str, verbose_cer_reason_str);
+ }
+
+ if (qmi_message_wds_start_network_output_get_call_end_reason (
+ output,
+ &cer,
+ NULL)) {
+ const gchar *cer_str;
+
+ cer_str = qmi_wds_call_end_reason_get_string (cer);
+ mm_obj_info (self, "call end reason (%u): %s", cer, cer_str);
+
+ return g_error_new (MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN,
+ "Call failed: %s", cer_str);
+ }
+
+ return g_error_new_literal (MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN, "Call failed");
+}
+
static void
start_network_ready (QmiClientWds *client,
GAsyncResult *res,
@@ -911,49 +960,24 @@ start_network_ready (QmiClientWds *client,
g_assert (!(ctx->running_ipv4 && ctx->running_ipv6));
output = qmi_client_wds_start_network_finish (client, res, &error);
- if (output &&
- !qmi_message_wds_start_network_output_get_result (output, &error)) {
+ if (output && !qmi_message_wds_start_network_output_get_result (output, &error)) {
/* No-effect errors should be ignored. The modem will keep the
* connection active as long as there is a WDS client which requested
* to start the network. If ModemManager crashed while a connection was
* active, we would be leaving an unreleased WDS client around and the
* modem would just keep connected. */
- if (g_error_matches (error,
- QMI_PROTOCOL_ERROR,
- QMI_PROTOCOL_ERROR_NO_EFFECT)) {
- g_error_free (error);
- error = NULL;
+ if (g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_NO_EFFECT)) {
+ g_clear_error (&error);
if (ctx->running_ipv4)
ctx->packet_data_handle_ipv4 = GLOBAL_PACKET_DATA_HANDLE;
else
ctx->packet_data_handle_ipv6 = GLOBAL_PACKET_DATA_HANDLE;
-
/* Fall down to a successful connection */
} else {
mm_obj_info (self, "couldn't start network: %s", error->message);
- if (g_error_matches (error,
- QMI_PROTOCOL_ERROR,
- QMI_PROTOCOL_ERROR_CALL_FAILED)) {
- QmiWdsCallEndReason cer;
- QmiWdsVerboseCallEndReasonType verbose_cer_type;
- gint16 verbose_cer_reason;
-
- if (qmi_message_wds_start_network_output_get_call_end_reason (
- output,
- &cer,
- NULL))
- mm_obj_info (self, "call end reason (%u): %s", cer, qmi_wds_call_end_reason_get_string (cer));
-
- if (qmi_message_wds_start_network_output_get_verbose_call_end_reason (
- output,
- &verbose_cer_type,
- &verbose_cer_reason,
- NULL))
- mm_obj_info (self, "verbose call end reason (%u,%d): [%s] %s",
- verbose_cer_type,
- verbose_cer_reason,
- qmi_wds_verbose_call_end_reason_type_get_string (verbose_cer_type),
- qmi_wds_verbose_call_end_reason_get_string (verbose_cer_type, verbose_cer_reason));
+ if (g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_CALL_FAILED)) {
+ g_clear_error (&error);
+ error = mobile_equipment_error_from_start_network_output (self, output);
}
}
}