From d1bd0a297103b426e3ec3afe310f1471c6c6dbae Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Sun, 16 May 2021 22:03:10 +0200 Subject: core: improve error helpers First, simplify the logic that attempts to find the correct error code associated to an error text string. This logic is very flaky, as it relies on knowing what the modems report as text string for the different error codes, and obviously that is not always the same. Instead of supporting all error codes in this logic, we now limit them to a small subset with common error codes and hopefully common error strings. Second, in order to quickly get the error description string for a given error code, we rework the array of supported errors so that the index of the array is the error code itself. For mobile equipment errors the logic is straightforward, as they're always in the [0,255] range, but for the message errors we create an array where the index of the array is equal to the code plus 300 as they're always in the [300,500] range. By doing this, we avoid having an array with 300 NULL items before the actual values we want to support. --- src/mm-error-helpers.c | 500 +++++++++++++++++++++++++++---------------------- 1 file changed, 271 insertions(+), 229 deletions(-) (limited to 'src/mm-error-helpers.c') diff --git a/src/mm-error-helpers.c b/src/mm-error-helpers.c index 57486d8b..47d27028 100644 --- a/src/mm-error-helpers.c +++ b/src/mm-error-helpers.c @@ -20,281 +20,323 @@ #include -typedef struct { - guint code; - const gchar *error; /* lowercase, and stripped of special chars and whitespace */ - const gchar *message; -} ErrorTable; +/******************************************************************************/ + +static gchar * +normalize_error_string (const gchar *str) +{ + gchar *buf = NULL; + guint i; + guint j; + + /* Normalize the error code by stripping whitespace and odd characters */ + buf = g_strdup (str); + for (i = 0, j = 0; str[i]; i++) { + if (isalnum (str[i])) + buf[j++] = tolower (str[i]); + } + buf[j] = '\0'; + + return buf; +} -/* --- Connection errors --- */ +/******************************************************************************/ +/* Connection errors */ + +/* Human friendly messages for each error type */ +static const gchar *connection_error_messages[] = { + [MM_CONNECTION_ERROR_UNKNOWN] = "Unknown", + [MM_CONNECTION_ERROR_NO_CARRIER] = "No carrier", + [MM_CONNECTION_ERROR_NO_DIALTONE] = "No dialtone", + [MM_CONNECTION_ERROR_BUSY] = "Busy", + [MM_CONNECTION_ERROR_NO_ANSWER] = "No answer", +}; GError * mm_connection_error_for_code (MMConnectionError code, gpointer log_object) { - const gchar *msg; - - switch (code) { - case MM_CONNECTION_ERROR_UNKNOWN: - msg = "Unknown"; - break; - case MM_CONNECTION_ERROR_NO_CARRIER: - msg = "No carrier"; - break; - case MM_CONNECTION_ERROR_NO_DIALTONE: - msg = "No dialtone"; - break; - case MM_CONNECTION_ERROR_BUSY: - msg = "Busy"; - break; - case MM_CONNECTION_ERROR_NO_ANSWER: - msg = "No answer"; - break; - - default: - mm_obj_dbg (log_object, "invalid connection error code: %u", code); - /* uhm... make something up (yes, ok, lie!). */ - code = MM_CONNECTION_ERROR_NO_CARRIER; - msg = "No carrier"; + if (code < G_N_ELEMENTS (connection_error_messages)) { + const gchar *error_message; + + error_message = connection_error_messages[code]; + if (error_message) + return g_error_new_literal (MM_CONNECTION_ERROR, code, error_message); } - return g_error_new_literal (MM_CONNECTION_ERROR, code, msg); + /* Not found? Then, default to 'no carrier' */ + mm_obj_dbg (log_object, "unknown connection error: %u", code); + return g_error_new (MM_CONNECTION_ERROR, + MM_CONNECTION_ERROR_NO_CARRIER, + "Unknown connection error: %u", code); } -/* --- Mobile equipment errors --- */ - -static ErrorTable me_errors[] = { - { MM_MOBILE_EQUIPMENT_ERROR_PHONE_FAILURE, "phonefailure", "Phone failure" }, - { MM_MOBILE_EQUIPMENT_ERROR_NO_CONNECTION, "noconnectiontophone", "No connection to phone" }, - { MM_MOBILE_EQUIPMENT_ERROR_LINK_RESERVED, "phoneadapterlinkreserved", "Phone-adaptor link reserved" }, - { MM_MOBILE_EQUIPMENT_ERROR_NOT_ALLOWED, "operationnotallowed", "Operation not allowed" }, - { MM_MOBILE_EQUIPMENT_ERROR_NOT_SUPPORTED, "operationnotsupported", "Operation not supported" }, - { MM_MOBILE_EQUIPMENT_ERROR_PH_SIM_PIN, "phsimpinrequired", "PH-SIM PIN required" }, - { MM_MOBILE_EQUIPMENT_ERROR_PH_FSIM_PIN, "phfsimpinrequired", "PH-FSIM PIN required" }, - { MM_MOBILE_EQUIPMENT_ERROR_PH_FSIM_PUK, "phfsimpukrequired", "PH-FSIM PUK required" }, - { MM_MOBILE_EQUIPMENT_ERROR_SIM_NOT_INSERTED, "simnotinserted", "SIM not inserted" }, - { MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN, "simpinrequired", "SIM PIN required" }, - { MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK, "simpukrequired", "SIM PUK required" }, - { MM_MOBILE_EQUIPMENT_ERROR_SIM_FAILURE, "simfailure", "SIM failure" }, - { MM_MOBILE_EQUIPMENT_ERROR_SIM_BUSY, "simbusy", "SIM busy" }, - { MM_MOBILE_EQUIPMENT_ERROR_SIM_WRONG, "simwrong", "SIM wrong" }, - { MM_MOBILE_EQUIPMENT_ERROR_INCORRECT_PASSWORD, "incorrectpassword", "Incorrect password" }, - { MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN2, "simpin2required", "SIM PIN2 required" }, - { MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK2, "simpuk2required", "SIM PUK2 required" }, - { MM_MOBILE_EQUIPMENT_ERROR_MEMORY_FULL, "memoryfull", "Memory full" }, - { MM_MOBILE_EQUIPMENT_ERROR_INVALID_INDEX, "invalidindex", "Invalid index" }, - { MM_MOBILE_EQUIPMENT_ERROR_NOT_FOUND, "notfound", "Not found" }, - { MM_MOBILE_EQUIPMENT_ERROR_MEMORY_FAILURE, "memoryfailure", "Memory failure" }, - { MM_MOBILE_EQUIPMENT_ERROR_TEXT_TOO_LONG, "textstringtoolong", "Text string too long" }, - { MM_MOBILE_EQUIPMENT_ERROR_INVALID_CHARS, "invalidcharactersintextstring", "Invalid characters in text string" }, - { MM_MOBILE_EQUIPMENT_ERROR_DIAL_STRING_TOO_LONG, "dialstringtoolong", "Dial string too long" }, - { MM_MOBILE_EQUIPMENT_ERROR_DIAL_STRING_INVALID, "invalidcharactersindialstring", "Invalid characters in dial string" }, - { MM_MOBILE_EQUIPMENT_ERROR_NO_NETWORK, "nonetworkservice", "No network service" }, - { MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT, "networktimeout", "Network timeout" }, - { MM_MOBILE_EQUIPMENT_ERROR_NETWORK_NOT_ALLOWED, "networknotallowedemergencycallsonly", "Network not allowed - emergency calls only" }, - { MM_MOBILE_EQUIPMENT_ERROR_NETWORK_PIN, "networkpersonalizationpinrequired", "Network personalization PIN required" }, - { MM_MOBILE_EQUIPMENT_ERROR_NETWORK_PUK, "networkpersonalizationpukrequired", "Network personalization PUK required" }, - { MM_MOBILE_EQUIPMENT_ERROR_NETWORK_SUBSET_PIN, "networksubsetpersonalizationpinrequired", "Network subset personalization PIN required" }, - { MM_MOBILE_EQUIPMENT_ERROR_NETWORK_SUBSET_PUK, "networksubsetpersonalizationpukrequired", "Network subset personalization PUK required" }, - { MM_MOBILE_EQUIPMENT_ERROR_SERVICE_PIN, "serviceproviderpersonalizationpinrequired", "Service provider personalization PIN required" }, - { MM_MOBILE_EQUIPMENT_ERROR_SERVICE_PUK, "serviceproviderpersonalizationpukrequired", "Service provider personalization PUK required" }, - { MM_MOBILE_EQUIPMENT_ERROR_CORP_PIN, "corporatepersonalizationpinrequired", "Corporate personalization PIN required" }, - { MM_MOBILE_EQUIPMENT_ERROR_CORP_PUK, "corporatepersonalizationpukrequired", "Corporate personalization PUK required" }, - { MM_MOBILE_EQUIPMENT_ERROR_HIDDEN_KEY_REQUIRED, "hiddenkeyrequired", "Hidden key required" }, - { MM_MOBILE_EQUIPMENT_ERROR_EAP_METHOD_NOT_SUPPORTED, "eapmethodnotsupported", "EAP method not supported" }, - { MM_MOBILE_EQUIPMENT_ERROR_INCORRECT_PARAMETERS, "incorrectparameters", "Incorrect parameters" }, - { MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN, "unknownerror", "Unknown error" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_IMSI_UNKNOWN_IN_HLR, "imsiunknowninhlr", "IMSI unknown in HLR" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_ILLEGAL_MS, "illegalms", "Illegal MS" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_IMSI_UNKNOWN_IN_VLR, "imsiunknowninvlr", "IMSI unknown in VLR" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_ILLEGAL_ME, "illegalme", "Illegal ME" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_SERVICE_NOT_ALLOWED, "gprsservicesnotallowed", "GPRS services not allowed" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_AND_NON_GPRS_SERVICES_NOT_ALLOWED, "gprsandnongprsservicesnotallowed", "GPRS and non-GPRS services not allowed" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_PLMN_NOT_ALLOWED, "plmnnotallowed", "PLMN not allowed" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_LOCATION_NOT_ALLOWED, "locationareanotallowed", "Location area not allowed" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_ROAMING_NOT_ALLOWED, "roamingnotallowedinthislocationarea", "Roaming not allowed in this location area" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_NO_CELLS_IN_LOCATION_AREA, "nocellsinlocationarea", "No cells in location area" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_NETWORK_FAILURE, "networkfailure", "Network failure" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_CONGESTION, "congestion", "Congestion" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_NOT_AUTHORIZED_FOR_CSG, "notauthorizedforcsg", "Not authorized for CSG" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_INSUFFICIENT_RESOURCES, "insufficientresources", "Insufficient resources" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_MISSING_OR_UNKNOWN_APN, "missingorunknownapn", "Missing or unknown APN" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_UNKNOWN_PDP_ADDRESS_OR_TYPE, "unknownpdpaddressortype", "Unknown PDP address or type" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_USER_AUTHENTICATION_FAILED, "userauthenticationfailed", "User authentication failed" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_ACTIVATION_REJECTED_BY_GGSN_OR_GW, "activationrejectedbyggsnorgw", "Activation rejected by GGSN or GW" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_ACTIVATION_REJECTED_UNSPECIFIED, "actovationrejectedunspecified", "Activation rejected (unspecified)" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_SERVICE_OPTION_NOT_SUPPORTED, "serviceoperationnotsupported", "Service option not supported" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_SERVICE_OPTION_NOT_SUBSCRIBED, "requestedserviceoptionnotsubscribed", "Requested service option not subscribed" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_SERVICE_OPTION_OUT_OF_ORDER, "serviceoptiontemporarilyoutoforder", "Service option temporarily out of order" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_FEATURE_NOT_SUPPORTED, "featurenotsupported", "Feature not supported" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_SEMANTIC_ERROR_IN_TFT_OPERATION, "semanticerrorintftoperation", "Semantic error in TFT operation" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_SYNTACTICAL_ERROR_IN_TFT_OPERATION, "syntacticalerrorintftoperation", "Syntactical error in TFT operation" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_UNKNOWN_PDP_CONTEXT, "unknownpdpcontext", "Unknown PDP context" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_SEMANTIC_ERRORS_IN_PACKET_FILTER, "semanticerrorsinpacketfilter", "Semantic error in packet filter" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_SYNTACTICAL_ERROR_IN_PACKET_FILTER, "syntacticalerrorinpacketfilter", "Syntactical error in packet filter" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_PDP_CONTEXT_WITHOUT_TFT_ALREADY_ACTIVATED, "pdpcontextwithouttftalreadyactivated", "PDP context without TFT already activated" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_UNKNOWN, "unspecifiedgprserror", "Unspecified GPRS error" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_PDP_AUTH_FAILURE, "pdpauthenticationfailure", "PDP authentication failure" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_INVALID_MOBILE_CLASS, "invalidmobileclass", "Invalid mobile class" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_LAST_PDN_DISCONNECTION_NOT_ALLOWED_LEGACY, "lastpdndisconnectionnotallowedlegacy", "Last PDN disconnection not allowed (legacy)" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_LAST_PDN_DISCONNECTION_NOT_ALLOWED, "lastpdndisconnectionnotallowed", "Last PDN disconnection not allowed" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_SEMANTICALLY_INCORRECT_MESSAGE, "semanticallyincorrectmessage", "Semantically incorrect message" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_MANDATORY_IE_ERROR, "mandatoryieerror", "Mandatory IE error" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_IE_NOT_IMPLEMENTED, "ienotimplemented", "IE not implemented" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_CONDITIONAL_IE_ERROR, "conditionalieerror", "Conditional IE error" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_UNSPECIFIED_PROTOCOL_ERROR, "unspecifiedprotocolerror", "Unspecified protocol error" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_OPERATOR_DETERMINED_BARRING, "operatordeterminedbarring", "Operator determined barring" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_MAXIMUM_NUMBER_OF_PDP_CONTEXTS_REACHED, "maximumnumberofpdpcontextsreached", "Maximum number of PDP contexts reached" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_REQUESTED_APN_NOT_SUPPORTED, "requestedapnnotsupported", "Requested APN not supported" }, - { MM_MOBILE_EQUIPMENT_ERROR_GPRS_REQUEST_REJECTED_BCM_VIOLATION, "rejectedbcmviolation", "Rejected BCM violation" }, +/******************************************************************************/ +/* Mobile equipment errors */ + +/* Human friendly messages for each error type */ +static const gchar *me_error_messages[] = { + [MM_MOBILE_EQUIPMENT_ERROR_PHONE_FAILURE] = "Phone failure", + [MM_MOBILE_EQUIPMENT_ERROR_NO_CONNECTION] = "No connection to phone", + [MM_MOBILE_EQUIPMENT_ERROR_LINK_RESERVED] = "Phone-adaptor link reserved", + [MM_MOBILE_EQUIPMENT_ERROR_NOT_ALLOWED] = "Operation not allowed", + [MM_MOBILE_EQUIPMENT_ERROR_NOT_SUPPORTED] = "Operation not supported", + [MM_MOBILE_EQUIPMENT_ERROR_PH_SIM_PIN] = "PH-SIM PIN required", + [MM_MOBILE_EQUIPMENT_ERROR_PH_FSIM_PIN] = "PH-FSIM PIN required", + [MM_MOBILE_EQUIPMENT_ERROR_PH_FSIM_PUK] = "PH-FSIM PUK required", + [MM_MOBILE_EQUIPMENT_ERROR_SIM_NOT_INSERTED] = "SIM not inserted", + [MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN] = "SIM PIN required", + [MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK] = "SIM PUK required", + [MM_MOBILE_EQUIPMENT_ERROR_SIM_FAILURE] = "SIM failure", + [MM_MOBILE_EQUIPMENT_ERROR_SIM_BUSY] = "SIM busy", + [MM_MOBILE_EQUIPMENT_ERROR_SIM_WRONG] = "SIM wrong", + [MM_MOBILE_EQUIPMENT_ERROR_INCORRECT_PASSWORD] = "Incorrect password", + [MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN2] = "SIM PIN2 required", + [MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK2] = "SIM PUK2 required", + [MM_MOBILE_EQUIPMENT_ERROR_MEMORY_FULL] = "Memory full", + [MM_MOBILE_EQUIPMENT_ERROR_INVALID_INDEX] = "Invalid index", + [MM_MOBILE_EQUIPMENT_ERROR_NOT_FOUND] = "Not found", + [MM_MOBILE_EQUIPMENT_ERROR_MEMORY_FAILURE] = "Memory failure", + [MM_MOBILE_EQUIPMENT_ERROR_TEXT_TOO_LONG] = "Text string too long", + [MM_MOBILE_EQUIPMENT_ERROR_INVALID_CHARS] = "Invalid characters in text string", + [MM_MOBILE_EQUIPMENT_ERROR_DIAL_STRING_TOO_LONG] = "Dial string too long", + [MM_MOBILE_EQUIPMENT_ERROR_DIAL_STRING_INVALID] = "Invalid characters in dial string", + [MM_MOBILE_EQUIPMENT_ERROR_NO_NETWORK] = "No network service", + [MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT] = "Network timeout", + [MM_MOBILE_EQUIPMENT_ERROR_NETWORK_NOT_ALLOWED] = "Network not allowed - emergency calls only", + [MM_MOBILE_EQUIPMENT_ERROR_NETWORK_PIN] = "Network personalization PIN required", + [MM_MOBILE_EQUIPMENT_ERROR_NETWORK_PUK] = "Network personalization PUK required", + [MM_MOBILE_EQUIPMENT_ERROR_NETWORK_SUBSET_PIN] = "Network subset personalization PIN required", + [MM_MOBILE_EQUIPMENT_ERROR_NETWORK_SUBSET_PUK] = "Network subset personalization PUK required", + [MM_MOBILE_EQUIPMENT_ERROR_SERVICE_PIN] = "Service provider personalization PIN required", + [MM_MOBILE_EQUIPMENT_ERROR_SERVICE_PUK] = "Service provider personalization PUK required", + [MM_MOBILE_EQUIPMENT_ERROR_CORP_PIN] = "Corporate personalization PIN required", + [MM_MOBILE_EQUIPMENT_ERROR_CORP_PUK] = "Corporate personalization PUK required", + [MM_MOBILE_EQUIPMENT_ERROR_HIDDEN_KEY_REQUIRED] = "Hidden key required", + [MM_MOBILE_EQUIPMENT_ERROR_EAP_METHOD_NOT_SUPPORTED] = "EAP method not supported", + [MM_MOBILE_EQUIPMENT_ERROR_INCORRECT_PARAMETERS] = "Incorrect parameters", + [MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN] = "Unknown error", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_IMSI_UNKNOWN_IN_HLR] = "IMSI unknown in HLR", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_ILLEGAL_MS] = "Illegal MS", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_IMSI_UNKNOWN_IN_VLR] = "IMSI unknown in VLR", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_ILLEGAL_ME] = "Illegal ME", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_SERVICE_NOT_ALLOWED] = "GPRS services not allowed", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_AND_NON_GPRS_SERVICES_NOT_ALLOWED] = "GPRS and non-GPRS services not allowed", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_PLMN_NOT_ALLOWED] = "PLMN not allowed", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_LOCATION_NOT_ALLOWED] = "Location area not allowed", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_ROAMING_NOT_ALLOWED] = "Roaming not allowed in this location area", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_NO_CELLS_IN_LOCATION_AREA] = "No cells in location area", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_NETWORK_FAILURE] = "Network failure", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_CONGESTION] = "Congestion", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_NOT_AUTHORIZED_FOR_CSG] = "Not authorized for CSG", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_INSUFFICIENT_RESOURCES] = "Insufficient resources", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_MISSING_OR_UNKNOWN_APN] = "Missing or unknown APN", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_UNKNOWN_PDP_ADDRESS_OR_TYPE] = "Unknown PDP address or type", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_USER_AUTHENTICATION_FAILED] = "User authentication failed", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_ACTIVATION_REJECTED_BY_GGSN_OR_GW] = "Activation rejected by GGSN or GW", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_ACTIVATION_REJECTED_UNSPECIFIED] = "Activation rejected (unspecified)", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_SERVICE_OPTION_NOT_SUPPORTED] = "Service option not supported", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_SERVICE_OPTION_NOT_SUBSCRIBED] = "Requested service option not subscribed", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_SERVICE_OPTION_OUT_OF_ORDER] = "Service option temporarily out of order", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_FEATURE_NOT_SUPPORTED] = "Feature not supported", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_SEMANTIC_ERROR_IN_TFT_OPERATION] = "Semantic error in TFT operation", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_SYNTACTICAL_ERROR_IN_TFT_OPERATION] = "Syntactical error in TFT operation", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_UNKNOWN_PDP_CONTEXT] = "Unknown PDP context", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_SEMANTIC_ERRORS_IN_PACKET_FILTER] = "Semantic error in packet filter", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_SYNTACTICAL_ERROR_IN_PACKET_FILTER] = "Syntactical error in packet filter", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_PDP_CONTEXT_WITHOUT_TFT_ALREADY_ACTIVATED] = "PDP context without TFT already activated", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_UNKNOWN] = "Unspecified GPRS error", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_PDP_AUTH_FAILURE] = "PDP authentication failure", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_INVALID_MOBILE_CLASS] = "Invalid mobile class", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_LAST_PDN_DISCONNECTION_NOT_ALLOWED_LEGACY] = "Last PDN disconnection not allowed (legacy)", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_LAST_PDN_DISCONNECTION_NOT_ALLOWED] = "Last PDN disconnection not allowed", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_SEMANTICALLY_INCORRECT_MESSAGE] = "Semantically incorrect message", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_MANDATORY_IE_ERROR] = "Mandatory IE error", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_IE_NOT_IMPLEMENTED] = "IE not implemented", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_CONDITIONAL_IE_ERROR] = "Conditional IE error", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_UNSPECIFIED_PROTOCOL_ERROR] = "Unspecified protocol error", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_OPERATOR_DETERMINED_BARRING] = "Operator determined barring", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_MAXIMUM_NUMBER_OF_PDP_CONTEXTS_REACHED] = "Maximum number of PDP contexts reached", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_REQUESTED_APN_NOT_SUPPORTED] = "Requested APN not supported", + [MM_MOBILE_EQUIPMENT_ERROR_GPRS_REQUEST_REJECTED_BCM_VIOLATION] = "Rejected BCM violation", }; +/* All generic ME errors should be < 255, as those are the only reserved ones in the 3GPP spec */ +G_STATIC_ASSERT (G_N_ELEMENTS (me_error_messages) <= 256); + GError * mm_mobile_equipment_error_for_code (MMMobileEquipmentError code, gpointer log_object) { - guint i; - - /* Look for the code */ - for (i = 0; i < G_N_ELEMENTS (me_errors); i++) { - if (me_errors[i].code == code) - return g_error_new_literal (MM_MOBILE_EQUIPMENT_ERROR, - code, - me_errors[i].message); + if (code < G_N_ELEMENTS (me_error_messages)) { + const gchar *error_message; + + error_message = me_error_messages[code]; + if (error_message) + return g_error_new_literal (MM_MOBILE_EQUIPMENT_ERROR, code, error_message); } /* Not found? Then, default */ - mm_obj_dbg (log_object, "invalid mobile equipment error code: %u", (guint)code); + mm_obj_dbg (log_object, "unknown mobile equipment error: %u", code); return g_error_new (MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN, - "Unknown error"); + "Unknown mobile equipment error: %u", code); } -GError * -mm_mobile_equipment_error_for_string (const gchar *str, - gpointer log_object) -{ - MMMobileEquipmentError code = MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN; - const gchar *msg = NULL; - gchar *buf; - guint i; - guint j; +/******************************************************************************/ +/* Message errors + * + * The message errors are all >300, so we define a common offset for all error + * types. + */ - g_return_val_if_fail (str != NULL, NULL); +#define MM_MESSAGE_ERROR_COMMON_OFFSET 300 - /* Normalize the error code by stripping whitespace and odd characters */ - buf = g_strdup (str); - for (i = 0, j = 0; str[i]; i++) { - if (isalnum (str[i])) - buf[j++] = tolower (str[i]); - } - buf[j] = '\0'; +/* Human friendly messages for each error type */ +static const gchar *msg_error_messages[] = { + [MM_MESSAGE_ERROR_ME_FAILURE - MM_MESSAGE_ERROR_COMMON_OFFSET] = "ME failure", + [MM_MESSAGE_ERROR_SMS_SERVICE_RESERVED - MM_MESSAGE_ERROR_COMMON_OFFSET] = "SMS service reserved", + [MM_MESSAGE_ERROR_NOT_ALLOWED - MM_MESSAGE_ERROR_COMMON_OFFSET] = "Operation not allowed", + [MM_MESSAGE_ERROR_NOT_SUPPORTED - MM_MESSAGE_ERROR_COMMON_OFFSET] = "Operation not supported", + [MM_MESSAGE_ERROR_INVALID_PDU_PARAMETER - MM_MESSAGE_ERROR_COMMON_OFFSET] = "Invalid PDU mode parameter", + [MM_MESSAGE_ERROR_INVALID_TEXT_PARAMETER - MM_MESSAGE_ERROR_COMMON_OFFSET] = "Invalid text mode parameter", + [MM_MESSAGE_ERROR_SIM_NOT_INSERTED - MM_MESSAGE_ERROR_COMMON_OFFSET] = "SIM not inserted", + [MM_MESSAGE_ERROR_SIM_PIN - MM_MESSAGE_ERROR_COMMON_OFFSET] = "SIM PIN required", + [MM_MESSAGE_ERROR_PH_SIM_PIN - MM_MESSAGE_ERROR_COMMON_OFFSET] = "PH-SIM PIN required", + [MM_MESSAGE_ERROR_SIM_FAILURE - MM_MESSAGE_ERROR_COMMON_OFFSET] = "SIM failure", + [MM_MESSAGE_ERROR_SIM_BUSY - MM_MESSAGE_ERROR_COMMON_OFFSET] = "SIM busy", + [MM_MESSAGE_ERROR_SIM_WRONG - MM_MESSAGE_ERROR_COMMON_OFFSET] = "SIM wrong", + [MM_MESSAGE_ERROR_SIM_PUK - MM_MESSAGE_ERROR_COMMON_OFFSET] = "SIM PUK required", + [MM_MESSAGE_ERROR_SIM_PIN2 - MM_MESSAGE_ERROR_COMMON_OFFSET] = "SIM PIN2 required", + [MM_MESSAGE_ERROR_SIM_PUK2 - MM_MESSAGE_ERROR_COMMON_OFFSET] = "SIM PUK2 required", + [MM_MESSAGE_ERROR_MEMORY_FAILURE - MM_MESSAGE_ERROR_COMMON_OFFSET] = "Memory failure", + [MM_MESSAGE_ERROR_INVALID_INDEX - MM_MESSAGE_ERROR_COMMON_OFFSET] = "Invalid index", + [MM_MESSAGE_ERROR_MEMORY_FULL - MM_MESSAGE_ERROR_COMMON_OFFSET] = "Memory full", + [MM_MESSAGE_ERROR_SMSC_ADDRESS_UNKNOWN - MM_MESSAGE_ERROR_COMMON_OFFSET] = "SMSC address unknown", + [MM_MESSAGE_ERROR_NO_NETWORK - MM_MESSAGE_ERROR_COMMON_OFFSET] = "No network", + [MM_MESSAGE_ERROR_NETWORK_TIMEOUT - MM_MESSAGE_ERROR_COMMON_OFFSET] = "Network timeout", + [MM_MESSAGE_ERROR_NO_CNMA_ACK_EXPECTED - MM_MESSAGE_ERROR_COMMON_OFFSET] = "No CNMA acknowledgement expected", + [MM_MESSAGE_ERROR_UNKNOWN - MM_MESSAGE_ERROR_COMMON_OFFSET] = "Unknown", +}; - /* Look for the string */ - for (i = 0; i < G_N_ELEMENTS (me_errors); i++) { - if (g_str_equal (me_errors[i].error, buf)) { - code = me_errors[i].code; - msg = me_errors[i].message; - break; - } - } +/* All generic message errors should be <= 500 (500-common=200), as those are the only reserved ones in the 3GPP spec */ +G_STATIC_ASSERT (G_N_ELEMENTS (msg_error_messages) <= 201); - /* Not found? Then, default */ - if (!msg) { - mm_obj_dbg (log_object, "invalid mobile equipment error string: '%s' (%s)", str, buf); - code = MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN; - msg = "Unknown error"; +GError * +mm_message_error_for_code (MMMessageError code, + gpointer log_object) +{ + if ((code >= MM_MESSAGE_ERROR_COMMON_OFFSET) && ((code - MM_MESSAGE_ERROR_COMMON_OFFSET) < G_N_ELEMENTS (msg_error_messages))) { + const gchar *error_message; + + error_message = msg_error_messages[code - MM_MESSAGE_ERROR_COMMON_OFFSET]; + if (error_message) + return g_error_new_literal (MM_MESSAGE_ERROR, code, error_message); } - g_free (buf); - return g_error_new_literal (MM_MOBILE_EQUIPMENT_ERROR, code, msg); + /* Not found? Then, default */ + mm_obj_dbg (log_object, "unknown message error: %u", code); + return g_error_new (MM_MESSAGE_ERROR, + MM_MESSAGE_ERROR_UNKNOWN, + "Unknown message error: %u", code); } -/* --- Message errors --- */ - -static ErrorTable msg_errors[] = { - { MM_MESSAGE_ERROR_ME_FAILURE, "mefailure", "ME failure" }, - { MM_MESSAGE_ERROR_SMS_SERVICE_RESERVED, "smsservicereserved", "SMS service reserved" }, - { MM_MESSAGE_ERROR_NOT_ALLOWED, "operationnotallowed", "Operation not allowed" }, - { MM_MESSAGE_ERROR_NOT_SUPPORTED, "operationnotsupported", "Operation not supported" }, - { MM_MESSAGE_ERROR_INVALID_PDU_PARAMETER, "invalidpduparameter", "Invalid PDU mode parameter" }, - { MM_MESSAGE_ERROR_INVALID_TEXT_PARAMETER, "invalidtextparameter", "Invalid text mode parameter" }, - { MM_MESSAGE_ERROR_SIM_NOT_INSERTED, "simnotinserted", "SIM not inserted" }, - { MM_MESSAGE_ERROR_SIM_PIN, "simpinrequired", "SIM PIN required" }, - { MM_MESSAGE_ERROR_PH_SIM_PIN, "phsimpinrequired", "PH-SIM PIN required" }, - { MM_MESSAGE_ERROR_SIM_FAILURE, "simfailure", "SIM failure" }, - { MM_MESSAGE_ERROR_SIM_BUSY, "simbusy", "SIM busy" }, - { MM_MESSAGE_ERROR_SIM_WRONG, "simwrong", "SIM wrong" }, - { MM_MESSAGE_ERROR_SIM_PUK, "simpukrequired", "SIM PUK required" }, - { MM_MESSAGE_ERROR_SIM_PIN2, "simpin2required", "SIM PIN2 required" }, - { MM_MESSAGE_ERROR_SIM_PUK2, "simpuk2required", "SIM PUK2 required" }, - { MM_MESSAGE_ERROR_MEMORY_FAILURE, "memoryfailure", "Memory failure" }, - { MM_MESSAGE_ERROR_INVALID_INDEX, "invalidindex", "Invalid index" }, - { MM_MESSAGE_ERROR_MEMORY_FULL, "memoryfull", "Memory full" }, - { MM_MESSAGE_ERROR_SMSC_ADDRESS_UNKNOWN, "smscaddressunknown", "SMSC address unknown" }, - { MM_MESSAGE_ERROR_NO_NETWORK, "nonetwork", "No network" }, - { MM_MESSAGE_ERROR_NETWORK_TIMEOUT, "networktimeout", "Network timeout" }, - { MM_MESSAGE_ERROR_NO_CNMA_ACK_EXPECTED, "nocnmaackexpected", "No CNMA acknowledgement expected" }, - { MM_MESSAGE_ERROR_UNKNOWN, "unknown", "Unknown" } +/******************************************************************************/ +/* Mobile equipment and message errors as string + * + * The strings given here must be all lowercase, and stripped of special chars + * and whitespaces. + * + * Not all errors are included, only the most generic ones. + */ + +typedef struct { + guint error_code; + const gchar *error_string; +} MeErrorString; + +static const MeErrorString me_error_strings[] = { + { MM_MOBILE_EQUIPMENT_ERROR_PHONE_FAILURE, "phonefailure" }, + { MM_MOBILE_EQUIPMENT_ERROR_NO_CONNECTION, "noconnection" }, + { MM_MOBILE_EQUIPMENT_ERROR_LINK_RESERVED, "linkreserved" }, + { MM_MOBILE_EQUIPMENT_ERROR_NOT_ALLOWED, "operationnotallowed" }, + { MM_MOBILE_EQUIPMENT_ERROR_NOT_SUPPORTED, "operationnotsupported" }, + { MM_MOBILE_EQUIPMENT_ERROR_SIM_NOT_INSERTED, "simnotinserted" }, + { MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN, "simpinrequired" }, + { MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK, "simpukrequired" }, + { MM_MOBILE_EQUIPMENT_ERROR_SIM_FAILURE, "simfailure" }, + { MM_MOBILE_EQUIPMENT_ERROR_SIM_BUSY, "simbusy" }, + { MM_MOBILE_EQUIPMENT_ERROR_SIM_WRONG, "simwrong" }, + { MM_MOBILE_EQUIPMENT_ERROR_INCORRECT_PASSWORD, "incorrectpassword" }, + { MM_MOBILE_EQUIPMENT_ERROR_NOT_FOUND, "notfound" }, + { MM_MOBILE_EQUIPMENT_ERROR_NO_NETWORK, "nonetwork" }, + { MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT, "timeout" }, + { MM_MOBILE_EQUIPMENT_ERROR_INCORRECT_PARAMETERS, "incorrectparameters" }, }; GError * -mm_message_error_for_code (MMMessageError code, - gpointer log_object) +mm_mobile_equipment_error_for_string (const gchar *str, + gpointer log_object) { - guint i; - - /* Look for the code */ - for (i = 0; i < G_N_ELEMENTS (msg_errors); i++) { - if (msg_errors[i].code == code) - return g_error_new_literal (MM_MESSAGE_ERROR, - code, - msg_errors[i].message); + g_autofree gchar *buf = NULL; + guint i; + + g_assert (str != NULL); + + /* Look for the string */ + buf = normalize_error_string (str); + for (i = 0; i < G_N_ELEMENTS (me_error_strings); i++) { + if (g_str_equal (me_error_strings[i].error_string, buf)) + return mm_mobile_equipment_error_for_code ((MMMobileEquipmentError)me_error_strings[i].error_code, log_object); } - /* Not found? Then, default */ - mm_obj_dbg (log_object, "invalid message error code: %u", (guint)code); - return g_error_new (MM_MESSAGE_ERROR, - MM_MESSAGE_ERROR_UNKNOWN, - "Unknown error"); + /* Not found? then, default */ + mm_obj_dbg (log_object, "unknown mobile equipment error string: '%s' (%s)", str, buf); + return g_error_new (MM_MOBILE_EQUIPMENT_ERROR, + MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN, + "Unknown mobile equipment error string: %s", str); } +static const MeErrorString msg_error_strings[] = { + { MM_MESSAGE_ERROR_ME_FAILURE, "mefailure" }, + { MM_MESSAGE_ERROR_SMS_SERVICE_RESERVED, "smsservicereserved" }, + { MM_MESSAGE_ERROR_NOT_ALLOWED, "operationnotallowed" }, + { MM_MESSAGE_ERROR_NOT_SUPPORTED, "operationnotsupported" }, + { MM_MESSAGE_ERROR_INVALID_PDU_PARAMETER, "invalidpduparameter" }, + { MM_MESSAGE_ERROR_INVALID_TEXT_PARAMETER, "invalidtextparameter" }, + { MM_MESSAGE_ERROR_SIM_NOT_INSERTED, "simnotinserted" }, + { MM_MESSAGE_ERROR_SIM_PIN, "simpinrequired" }, + { MM_MESSAGE_ERROR_SIM_FAILURE, "simfailure" }, + { MM_MESSAGE_ERROR_SIM_BUSY, "simbusy" }, + { MM_MESSAGE_ERROR_SIM_WRONG, "simwrong" }, + { MM_MESSAGE_ERROR_SIM_PUK, "simpukrequired" }, + { MM_MESSAGE_ERROR_MEMORY_FAILURE, "memoryfailure" }, + { MM_MESSAGE_ERROR_INVALID_INDEX, "invalidindex" }, + { MM_MESSAGE_ERROR_MEMORY_FULL, "memoryfull" }, + { MM_MESSAGE_ERROR_SMSC_ADDRESS_UNKNOWN, "smscaddressunknown" }, + { MM_MESSAGE_ERROR_NO_NETWORK, "nonetwork" }, + { MM_MESSAGE_ERROR_NETWORK_TIMEOUT, "networktimeout" }, +}; + GError * mm_message_error_for_string (const gchar *str, gpointer log_object) { - MMMessageError code = MM_MESSAGE_ERROR_UNKNOWN; - const gchar *msg = NULL; - gchar *buf; - guint i; - guint j; + g_autofree gchar *buf = NULL; + guint i; - g_return_val_if_fail (str != NULL, NULL); - - /* Normalize the error code by stripping whitespace and odd characters */ - buf = g_strdup (str); - for (i = 0, j = 0; str[i]; i++) { - if (isalnum (str[i])) - buf[j++] = tolower (str[i]); - } - buf[j] = '\0'; + g_assert (str != NULL); /* Look for the string */ - for (i = 0; i < G_N_ELEMENTS (msg_errors); i++) { - if (g_str_equal (msg_errors[i].error, buf)) { - code = msg_errors[i].code; - msg = msg_errors[i].message; - break; - } + buf = normalize_error_string (str); + for (i = 0; i < G_N_ELEMENTS (msg_error_strings); i++) { + if (g_str_equal (msg_error_strings[i].error_string, buf)) + return mm_message_error_for_code ((MMMessageError)msg_error_strings[i].error_code, log_object); } - /* Not found? Then, default */ - if (!msg) { - mm_obj_dbg (log_object, "invalid message error string: '%s' (%s)", str, buf); - code = MM_MESSAGE_ERROR_UNKNOWN; - msg = "Unknown error"; - } - - g_free (buf); - return g_error_new_literal (MM_MESSAGE_ERROR, code, msg); + /* Not found? then, default */ + mm_obj_dbg (log_object, "unknown message error string: '%s' (%s)", str, buf); + return g_error_new (MM_MESSAGE_ERROR, + MM_MESSAGE_ERROR_UNKNOWN, + "Unknown message error string: %s", str); } -- cgit v1.2.3-70-g09d2