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.
This commit is contained in:
@@ -894,6 +894,55 @@ get_current_settings (GTask *task, QmiClientWds *client)
|
|||||||
qmi_message_wds_get_current_settings_input_unref (input);
|
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
|
static void
|
||||||
start_network_ready (QmiClientWds *client,
|
start_network_ready (QmiClientWds *client,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
@@ -911,49 +960,24 @@ start_network_ready (QmiClientWds *client,
|
|||||||
g_assert (!(ctx->running_ipv4 && ctx->running_ipv6));
|
g_assert (!(ctx->running_ipv4 && ctx->running_ipv6));
|
||||||
|
|
||||||
output = qmi_client_wds_start_network_finish (client, res, &error);
|
output = qmi_client_wds_start_network_finish (client, res, &error);
|
||||||
if (output &&
|
if (output && !qmi_message_wds_start_network_output_get_result (output, &error)) {
|
||||||
!qmi_message_wds_start_network_output_get_result (output, &error)) {
|
|
||||||
/* No-effect errors should be ignored. The modem will keep the
|
/* No-effect errors should be ignored. The modem will keep the
|
||||||
* connection active as long as there is a WDS client which requested
|
* connection active as long as there is a WDS client which requested
|
||||||
* to start the network. If ModemManager crashed while a connection was
|
* to start the network. If ModemManager crashed while a connection was
|
||||||
* active, we would be leaving an unreleased WDS client around and the
|
* active, we would be leaving an unreleased WDS client around and the
|
||||||
* modem would just keep connected. */
|
* modem would just keep connected. */
|
||||||
if (g_error_matches (error,
|
if (g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_NO_EFFECT)) {
|
||||||
QMI_PROTOCOL_ERROR,
|
g_clear_error (&error);
|
||||||
QMI_PROTOCOL_ERROR_NO_EFFECT)) {
|
|
||||||
g_error_free (error);
|
|
||||||
error = NULL;
|
|
||||||
if (ctx->running_ipv4)
|
if (ctx->running_ipv4)
|
||||||
ctx->packet_data_handle_ipv4 = GLOBAL_PACKET_DATA_HANDLE;
|
ctx->packet_data_handle_ipv4 = GLOBAL_PACKET_DATA_HANDLE;
|
||||||
else
|
else
|
||||||
ctx->packet_data_handle_ipv6 = GLOBAL_PACKET_DATA_HANDLE;
|
ctx->packet_data_handle_ipv6 = GLOBAL_PACKET_DATA_HANDLE;
|
||||||
|
|
||||||
/* Fall down to a successful connection */
|
/* Fall down to a successful connection */
|
||||||
} else {
|
} else {
|
||||||
mm_obj_info (self, "couldn't start network: %s", error->message);
|
mm_obj_info (self, "couldn't start network: %s", error->message);
|
||||||
if (g_error_matches (error,
|
if (g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_CALL_FAILED)) {
|
||||||
QMI_PROTOCOL_ERROR,
|
g_clear_error (&error);
|
||||||
QMI_PROTOCOL_ERROR_CALL_FAILED)) {
|
error = mobile_equipment_error_from_start_network_output (self, output);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "mm-modem-helpers-qmi.h"
|
#include "mm-modem-helpers-qmi.h"
|
||||||
#include "mm-modem-helpers.h"
|
#include "mm-modem-helpers.h"
|
||||||
|
#include "mm-error-helpers.h"
|
||||||
#include "mm-enums-types.h"
|
#include "mm-enums-types.h"
|
||||||
#include "mm-log-object.h"
|
#include "mm-log-object.h"
|
||||||
|
|
||||||
@@ -1616,6 +1617,78 @@ mm_bearer_apn_type_from_qmi_apn_type (QmiWdsApnTypeMask apn_type)
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static const MMMobileEquipmentError qmi_vcer_3gpp_errors[] = {
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_OPERATOR_DETERMINED_BARRING] = MM_MOBILE_EQUIPMENT_ERROR_OPERATOR_DETERMINED_BARRING,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_INSUFFICIENT_RESOURCES] = MM_MOBILE_EQUIPMENT_ERROR_INSUFFICIENT_RESOURCES,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_UNKNOWN_APN] = MM_MOBILE_EQUIPMENT_ERROR_MISSING_OR_UNKNOWN_APN,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_UNKNOWN_PDP] = MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN_PDP_ADDRESS_OR_TYPE,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_AUTHENTICATION_FAILED] = MM_MOBILE_EQUIPMENT_ERROR_USER_AUTHENTICATION_FAILED,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_GGSN_REJECT] = MM_MOBILE_EQUIPMENT_ERROR_ACTIVATION_REJECTED_BY_GGSN_OR_GW,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_ACTIVATION_REJECT] = MM_MOBILE_EQUIPMENT_ERROR_ACTIVATION_REJECTED_UNSPECIFIED,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_OPTION_NOT_SUPPORTED] = MM_MOBILE_EQUIPMENT_ERROR_SERVICE_OPTION_NOT_SUPPORTED,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_OPTION_UNSUBSCRIBED] = MM_MOBILE_EQUIPMENT_ERROR_SERVICE_OPTION_NOT_SUBSCRIBED,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_OPTION_TEMPORARILY_OUT_OF_ORDER] = MM_MOBILE_EQUIPMENT_ERROR_SERVICE_OPTION_OUT_OF_ORDER,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_NSAPI_ALREADY_USED] = MM_MOBILE_EQUIPMENT_ERROR_NSAPI_OR_PTI_ALREADY_IN_USE,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_REGULAR_DEACTIVATION] = MM_MOBILE_EQUIPMENT_ERROR_REGULAR_DEACTIVATION,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_QOS_NOT_ACCEPTED] = MM_MOBILE_EQUIPMENT_ERROR_QOS_NOT_ACCEPTED,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_NETWORK_FAILURE] = MM_MOBILE_EQUIPMENT_ERROR_NETWORK_FAILURE_ATTACH,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_REATTACH_REQUIRED] = MM_MOBILE_EQUIPMENT_ERROR_NETWORK_FAILURE_ATTACH,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_FEATURE_NOT_SUPPORTED] = MM_MOBILE_EQUIPMENT_ERROR_FEATURE_NOT_SUPPORTED,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_TFT_SEMANTIC_ERROR] = MM_MOBILE_EQUIPMENT_ERROR_SEMANTIC_ERROR_IN_TFT_OPERATION,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_TFT_SYNTAX_ERROR] = MM_MOBILE_EQUIPMENT_ERROR_SYNTACTICAL_ERROR_IN_TFT_OPERATION,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_UNKNOWN_PDP_CONTEXT] = MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN_PDP_CONTEXT,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_FILTER_SEMANTIC_ERROR] = MM_MOBILE_EQUIPMENT_ERROR_SEMANTIC_ERRORS_IN_PACKET_FILTER,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_FILTER_SYNTAX_ERROR] = MM_MOBILE_EQUIPMENT_ERROR_SYNTACTICAL_ERROR_IN_PACKET_FILTER,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_PDP_WITHOUT_ACTIVE_TFT] = MM_MOBILE_EQUIPMENT_ERROR_PDP_CONTEXT_WITHOUT_TFT_ALREADY_ACTIVATED,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_IPV4_ONLY_ALLOWED] = MM_MOBILE_EQUIPMENT_ERROR_IPV4_ONLY_ALLOWED,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_IPV6_ONLY_ALLOWED] = MM_MOBILE_EQUIPMENT_ERROR_IPV6_ONLY_ALLOWED,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_SINGLE_ADDRESS_BEARER_ONLY] = MM_MOBILE_EQUIPMENT_ERROR_SINGLE_ADDRESS_BEARERS_ONLY_ALLOWED,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_ESM_INFO_NOT_RECEIVED] = MM_MOBILE_EQUIPMENT_ERROR_ESM_INFORMATION_NOT_RECEIVED,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_PDN_CONNECTION_DOES_NOT_EXIST] = MM_MOBILE_EQUIPMENT_ERROR_PDN_CONNECTION_NONEXISTENT,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_MULTIPLE_CONNECTION_TO_SAME_PDN_NOT_ALLOWED] = MM_MOBILE_EQUIPMENT_ERROR_MULTIPLE_PDN_CONNECTION_SAME_APN_NOT_ALLOWED,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_INVALID_TRANSACTION_ID] = MM_MOBILE_EQUIPMENT_ERROR_INVALID_TRANSACTION_ID_VALUE,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_MESSAGE_INCORRECT_SEMANTIC] = MM_MOBILE_EQUIPMENT_ERROR_SEMANTICALLY_INCORRECT_MESSAGE,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_INVALID_MANDATORY_INFO] = MM_MOBILE_EQUIPMENT_ERROR_INVALID_MANDATORY_INFORMATION,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_MESSAGE_TYPE_UNSUPPORTED] = MM_MOBILE_EQUIPMENT_ERROR_MESSAGE_TYPE_NOT_IMPLEMENTED,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_MESSAGE_TYPE_NONCOMPATIBLE_STATE] = MM_MOBILE_EQUIPMENT_ERROR_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_UNKNOWN_INFO_ELEMENT] = MM_MOBILE_EQUIPMENT_ERROR_IE_NOT_IMPLEMENTED,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_CONDITIONAL_IE_ERROR] = MM_MOBILE_EQUIPMENT_ERROR_CONDITIONAL_IE_ERROR,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_MESSAGE_AND_PROTOCOL_STATE_UNCOMPATIBLE] = MM_MOBILE_EQUIPMENT_ERROR_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE,
|
||||||
|
[QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_PROTOCOL_ERROR] = MM_MOBILE_EQUIPMENT_ERROR_UNSPECIFIED_PROTOCOL_ERROR,
|
||||||
|
/* unmapped errors */
|
||||||
|
/* QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_LLC_SNDCP_FAILURE */
|
||||||
|
/* QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_APN_TYPE_CONFLICT */
|
||||||
|
/* QMI_WDS_VERBOSE_CALL_END_REASON_3GPP_INVALID_PROXY_CALL_SESSION_CONTROL_FUNCTION_ADDRESS */
|
||||||
|
};
|
||||||
|
|
||||||
|
GError *
|
||||||
|
qmi_mobile_equipment_error_from_verbose_call_end_reason_3gpp (QmiWdsVerboseCallEndReason3gpp vcer_3gpp,
|
||||||
|
gpointer log_object)
|
||||||
|
{
|
||||||
|
MMMobileEquipmentError error_code;
|
||||||
|
const gchar *msg;
|
||||||
|
|
||||||
|
/* convert to mobile equipment error */
|
||||||
|
error_code = qmi_vcer_3gpp_errors[vcer_3gpp];
|
||||||
|
if (error_code)
|
||||||
|
return mm_mobile_equipment_error_for_code (error_code, log_object);
|
||||||
|
|
||||||
|
/* provide a nicer error message on unmapped errors */
|
||||||
|
msg = qmi_wds_verbose_call_end_reason_3gpp_get_string (vcer_3gpp);
|
||||||
|
if (msg)
|
||||||
|
return g_error_new (MM_MOBILE_EQUIPMENT_ERROR,
|
||||||
|
MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN,
|
||||||
|
"Unsupported error (%u): %s",
|
||||||
|
vcer_3gpp, msg);
|
||||||
|
|
||||||
|
/* fallback */
|
||||||
|
return g_error_new_literal (MM_MOBILE_EQUIPMENT_ERROR,
|
||||||
|
MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN,
|
||||||
|
"Unknown error");
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* QMI/WDA to MM translations */
|
/* QMI/WDA to MM translations */
|
||||||
|
|
||||||
|
@@ -126,6 +126,9 @@ QmiWdsApnTypeMask mm_bearer_apn_type_to_qmi_apn_type (MMBearerApn
|
|||||||
gpointer log_object);
|
gpointer log_object);
|
||||||
MMBearerApnType mm_bearer_apn_type_from_qmi_apn_type (QmiWdsApnTypeMask apn_type);
|
MMBearerApnType mm_bearer_apn_type_from_qmi_apn_type (QmiWdsApnTypeMask apn_type);
|
||||||
|
|
||||||
|
GError *qmi_mobile_equipment_error_from_verbose_call_end_reason_3gpp (QmiWdsVerboseCallEndReason3gpp vcer_3gpp,
|
||||||
|
gpointer log_object);
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* QMI/WDA to MM translations */
|
/* QMI/WDA to MM translations */
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user