diff options
-rw-r--r-- | cli/mmcli-modem.c | 54 | ||||
-rw-r--r-- | cli/mmcli-output.c | 4 | ||||
-rw-r--r-- | cli/mmcli-output.h | 4 | ||||
-rw-r--r-- | include/ModemManager-enums.h | 155 | ||||
-rw-r--r-- | introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml | 47 | ||||
-rw-r--r-- | libmm-glib/libmm-glib.h | 1 | ||||
-rw-r--r-- | libmm-glib/meson.build | 2 | ||||
-rw-r--r-- | libmm-glib/mm-modem-3gpp.c | 49 | ||||
-rw-r--r-- | libmm-glib/mm-modem-3gpp.h | 4 | ||||
-rw-r--r-- | libmm-glib/mm-network-rejection.c | 321 | ||||
-rw-r--r-- | libmm-glib/mm-network-rejection.h | 97 | ||||
-rw-r--r-- | src/mm-iface-modem-3gpp.c | 58 | ||||
-rw-r--r-- | src/mm-iface-modem-3gpp.h | 6 |
13 files changed, 788 insertions, 14 deletions
diff --git a/cli/mmcli-modem.c b/cli/mmcli-modem.c index 1375c7b4..2c17f5b4 100644 --- a/cli/mmcli-modem.c +++ b/cli/mmcli-modem.c @@ -412,6 +412,11 @@ print_modem_info (void) const gchar *initial_eps_bearer_password = NULL; const gchar *nr5g_registration_settings_mico_mode_str = NULL; const gchar *nr5g_registration_settings_drx_cycle_str = NULL; + MMNetworkRejection *network_rejection = NULL; + const gchar *nw_rejection_operator_id = NULL; + const gchar *nw_rejection_operator_name = NULL; + g_autofree gchar *nw_rejection_access_technology = NULL; + g_autofree gchar *nw_rejection_error_str = NULL; if (ctx->modem_3gpp) { imei = mm_modem_3gpp_get_imei (ctx->modem_3gpp); @@ -445,22 +450,43 @@ print_modem_info (void) nr5g_registration_settings_drx_cycle_str = mm_modem_3gpp_drx_cycle_get_string (mm_nr5g_registration_settings_get_drx_cycle (nr5g_registration_settings)); } } + + network_rejection = mm_modem_3gpp_peek_network_rejection (ctx->modem_3gpp); + if (network_rejection) { + MMNetworkError nw_rejection_error_n; + MMModemAccessTechnology nw_rejection_access_technology_n; + const gchar *nw_rejection_error = NULL; + + nw_rejection_error_n = mm_network_rejection_get_error (network_rejection); + nw_rejection_error = mm_network_error_get_string (nw_rejection_error_n); + nw_rejection_error_str = nw_rejection_error ? g_strdup_printf ("%s", nw_rejection_error) : + g_strdup_printf ("unknown network rejection error: %u", nw_rejection_error_n); + nw_rejection_operator_id = mm_network_rejection_get_operator_id (network_rejection); + nw_rejection_operator_name = mm_network_rejection_get_operator_name (network_rejection); + nw_rejection_access_technology_n = mm_network_rejection_get_access_technology (network_rejection); + nw_rejection_access_technology = mm_modem_access_technology_build_string_from_mask (nw_rejection_access_technology_n); + + } } - mmcli_output_string (MMC_F_3GPP_IMEI, imei); - mmcli_output_string_list (MMC_F_3GPP_ENABLED_LOCKS, facility_locks); - mmcli_output_string (MMC_F_3GPP_OPERATOR_ID, operator_code); - mmcli_output_string (MMC_F_3GPP_OPERATOR_NAME, operator_name); - mmcli_output_string (MMC_F_3GPP_REGISTRATION, registration); - mmcli_output_string (MMC_F_3GPP_PACKET_SERVICE_STATE, packet_service_state); - mmcli_output_string (MMC_F_3GPP_EPS_UE_MODE, eps_ue_mode); - mmcli_output_string (MMC_F_3GPP_EPS_INITIAL_BEARER_PATH, g_strcmp0 (initial_eps_bearer_path, "/") != 0 ? initial_eps_bearer_path : NULL); - mmcli_output_string (MMC_F_3GPP_EPS_BEARER_SETTINGS_APN, initial_eps_bearer_apn); - mmcli_output_string_take (MMC_F_3GPP_EPS_BEARER_SETTINGS_IP_TYPE, initial_eps_bearer_ip_family_str); - mmcli_output_string (MMC_F_3GPP_EPS_BEARER_SETTINGS_USER, initial_eps_bearer_user); - mmcli_output_string (MMC_F_3GPP_EPS_BEARER_SETTINGS_PASSWORD, initial_eps_bearer_password); - mmcli_output_string (MMC_F_3GPP_5GNR_REGISTRATION_MICO_MODE, nr5g_registration_settings_mico_mode_str); - mmcli_output_string (MMC_F_3GPP_5GNR_REGISTRATION_DRX_CYCLE, nr5g_registration_settings_drx_cycle_str); + mmcli_output_string (MMC_F_3GPP_IMEI, imei); + mmcli_output_string_list (MMC_F_3GPP_ENABLED_LOCKS, facility_locks); + mmcli_output_string (MMC_F_3GPP_OPERATOR_ID, operator_code); + mmcli_output_string (MMC_F_3GPP_OPERATOR_NAME, operator_name); + mmcli_output_string (MMC_F_3GPP_REGISTRATION, registration); + mmcli_output_string_take (MMC_F_3GPP_NETWORK_REJECTION_ERROR, g_steal_pointer (&nw_rejection_error_str)); + mmcli_output_string (MMC_F_3GPP_NETWORK_REJECTION_OPERATOR_ID, nw_rejection_operator_id); + mmcli_output_string (MMC_F_3GPP_NETWORK_REJECTION_OPERATOR_NAME, nw_rejection_operator_name); + mmcli_output_string_take (MMC_F_3GPP_NETWORK_REJECTION_ACCESS_TECHNOLOGY, g_steal_pointer (&nw_rejection_access_technology)); + mmcli_output_string (MMC_F_3GPP_PACKET_SERVICE_STATE, packet_service_state); + mmcli_output_string (MMC_F_3GPP_EPS_UE_MODE, eps_ue_mode); + mmcli_output_string (MMC_F_3GPP_EPS_INITIAL_BEARER_PATH, g_strcmp0 (initial_eps_bearer_path, "/") != 0 ? initial_eps_bearer_path : NULL); + mmcli_output_string (MMC_F_3GPP_EPS_BEARER_SETTINGS_APN, initial_eps_bearer_apn); + mmcli_output_string_take (MMC_F_3GPP_EPS_BEARER_SETTINGS_IP_TYPE, initial_eps_bearer_ip_family_str); + mmcli_output_string (MMC_F_3GPP_EPS_BEARER_SETTINGS_USER, initial_eps_bearer_user); + mmcli_output_string (MMC_F_3GPP_EPS_BEARER_SETTINGS_PASSWORD, initial_eps_bearer_password); + mmcli_output_string (MMC_F_3GPP_5GNR_REGISTRATION_MICO_MODE, nr5g_registration_settings_mico_mode_str); + mmcli_output_string (MMC_F_3GPP_5GNR_REGISTRATION_DRX_CYCLE, nr5g_registration_settings_drx_cycle_str); mmcli_output_pco_list (pco_list); g_free (facility_locks); diff --git a/cli/mmcli-output.c b/cli/mmcli-output.c index 151778ef..c1c064da 100644 --- a/cli/mmcli-output.c +++ b/cli/mmcli-output.c @@ -136,6 +136,10 @@ static FieldInfo field_infos[] = { [MMC_F_3GPP_OPERATOR_ID] = { "modem.3gpp.operator-code", "operator id", MMC_S_MODEM_3GPP, }, [MMC_F_3GPP_OPERATOR_NAME] = { "modem.3gpp.operator-name", "operator name", MMC_S_MODEM_3GPP, }, [MMC_F_3GPP_REGISTRATION] = { "modem.3gpp.registration-state", "registration", MMC_S_MODEM_3GPP, }, + [MMC_F_3GPP_NETWORK_REJECTION_ERROR] = { "modem.3gpp.network-rejection-error", "network rejection error", MMC_S_MODEM_3GPP, }, + [MMC_F_3GPP_NETWORK_REJECTION_OPERATOR_ID] = { "modem.3gpp.network-rejection-operator-id", "network rejection operator id", MMC_S_MODEM_3GPP, }, + [MMC_F_3GPP_NETWORK_REJECTION_OPERATOR_NAME] = { "modem.3gpp.network-rejection-operator-name", "network rejection operator name", MMC_S_MODEM_3GPP, }, + [MMC_F_3GPP_NETWORK_REJECTION_ACCESS_TECHNOLOGY] = { "modem.3gpp.network-rejection-access-technology", "network rejection access technology", MMC_S_MODEM_3GPP, }, [MMC_F_3GPP_PACKET_SERVICE_STATE] = { "modem.3gpp.packet-service-state", "packet service state", MMC_S_MODEM_3GPP, }, [MMC_F_3GPP_PCO] = { "modem.3gpp.pco", "pco", MMC_S_MODEM_3GPP, }, [MMC_F_3GPP_EPS_UE_MODE] = { "modem.3gpp.eps.ue-mode-operation", "ue mode of operation", MMC_S_MODEM_3GPP_EPS, }, diff --git a/cli/mmcli-output.h b/cli/mmcli-output.h index 5e2a3071..f942f16b 100644 --- a/cli/mmcli-output.h +++ b/cli/mmcli-output.h @@ -138,6 +138,10 @@ typedef enum { MMC_F_3GPP_OPERATOR_NAME, MMC_F_3GPP_REGISTRATION, MMC_F_3GPP_PACKET_SERVICE_STATE, + MMC_F_3GPP_NETWORK_REJECTION_ERROR, + MMC_F_3GPP_NETWORK_REJECTION_OPERATOR_ID, + MMC_F_3GPP_NETWORK_REJECTION_OPERATOR_NAME, + MMC_F_3GPP_NETWORK_REJECTION_ACCESS_TECHNOLOGY, MMC_F_3GPP_PCO, /* 3GPP EPS section */ MMC_F_3GPP_EPS_UE_MODE, diff --git a/include/ModemManager-enums.h b/include/ModemManager-enums.h index 178c15f2..1217e581 100644 --- a/include/ModemManager-enums.h +++ b/include/ModemManager-enums.h @@ -1954,4 +1954,159 @@ typedef enum { /*< underscore_name=mm_serving_cell_type >*/ MM_SERVING_CELL_TYPE_INVALID = 0xFFFFFFFF } MMServingCellType; +/** + * MMNetworkError: + * @MM_NETWORK_ERROR_NONE: No error. + * @MM_NETWORK_ERROR_IMSI_UNKNOWN_IN_HLR: IMSI unknown in the HLR. + * @MM_NETWORK_ERROR_ILLEGAL_MS: Illegal MS. + * @MM_NETWORK_ERROR_IMSI_UNKNOWN_IN_VLR: IMSI unknown in the VLR. + * @MM_NETWORK_ERROR_IMEI_NOT_ACCEPTED: IMEI not accepted. + * @MM_NETWORK_ERROR_ILLEGAL_ME: Illegal ME. + * @MM_NETWORK_ERROR_GPRS_NOT_ALLOWED: GPRS not allowed. + * @MM_NETWORK_ERROR_GPRS_AND_NON_GPRS_NOT_ALLOWED: GPRS and non-GPRS not allowed. + * @MM_NETWORK_ERROR_MS_IDENTITY_NOT_DERIVED_BY_NETWORK: MS identity cannot be derived by the network. + * @MM_NETWORK_ERROR_IMPLICITLY_DETACHED: Implicitly detached. + * @MM_NETWORK_ERROR_PLMN_NOT_ALLOWED: PLMN not allowed. + * @MM_NETWORK_ERROR_LOCATION_AREA_NOT_ALLOWED: Location area not allowed. + * @MM_NETWORK_ERROR_ROAMING_NOT_ALLOWED_IN_LOCATION_AREA: Roaming not allowed in the location area. + * @MM_NETWORK_ERROR_GPRS_NOT_ALLOWED_IN_PLMN: GPRS not allowed in PLMN. + * @MM_NETWORK_ERROR_NO_CELLS_IN_LOCATION_AREA: No cells in location area. + * @MM_NETWORK_ERROR_MSC_TEMPORARILY_NOT_REACHABLE: MSC temporarily not reachable. + * @MM_NETWORK_ERROR_NETWORK_FAILURE: Network failure. + * @MM_NETWORK_ERROR_MAC_FAILURE: MAC failure. + * @MM_NETWORK_ERROR_SYNCH_FAILURE: Synch failure. + * @MM_NETWORK_ERROR_CONGESTION: Congestion. + * @MM_NETWORK_ERROR_GSM_AUTHENTICATION_UNACCEPTABLE: GSM authentication unacceptable. + * @MM_NETWORK_ERROR_NOT_AUTHORIZED_FOR_CSG: Not authorized for this CSG. + * @MM_NETWORK_ERROR_INSUFFICIENT_RESOURCES: Insufficient resources. + * @MM_NETWORK_ERROR_MISSING_OR_UNKNOWN_APN: Missing or unknown access point name. + * @MM_NETWORK_ERROR_UNKNOWN_PDP_ADDRESS_OR_TYPE: Unknown PDP address or PDP type. + * @MM_NETWORK_ERROR_USER_AUTHENTICATION_FAILED: User authentication failed. + * @MM_NETWORK_ERROR_ACTIVATION_REJECTED_BY_GGSN_OR_GW: Activation rejected by GGSN, Serving GW or PDN GW. + * @MM_NETWORK_ERROR_ACTIVATION_REJECTED_UNSPECIFIED: Activation rejected, unspecified. + * @MM_NETWORK_ERROR_SERVICE_OPTION_NOT_SUPPORTED: Service option not supported. + * @MM_NETWORK_ERROR_REQUESTED_SERVICE_OPTION_NOT_SUBSCRIBED: Requested service option not subscribed. + * @MM_NETWORK_ERROR_SERVICE_OPTION_TEMPORARILY_OUT_OF_ORDER: Service option temporarily out of order. + * @MM_NETWORK_ERROR_NO_PDP_CONTEXT_ACTIVATED: No PDP context activated. + * @MM_NETWORK_ERROR_SEMANTIC_ERROR_IN_THE_TFT_OPERATION: Semantic error in the TFT operation. + * @MM_NETWORK_ERROR_SYNTACTICAL_ERROR_IN_THE_TFT_OPERATION: Syntactical error in the TFT operation. + * @MM_NETWORK_ERROR_UNKNOWN_PDP_CONTEXT: Unknown PDP context. + * @MM_NETWORK_ERROR_SEMANTIC_ERRORS_IN_PACKET_FILTER: Semantic errors in packet filter. + * @MM_NETWORK_ERROR_SYNTACTICAL_ERRORS_IN_PACKET_FILTER: Syntactical errors in packet filter. + * @MM_NETWORK_ERROR_PDP_CONTEXT_WITHOUT_TFT_ALREADY_ACTIVATED: PDP context without TFT already activated. + * @MM_NETWORK_ERROR_REQUEST_REJECTED_OR_BEARER_CONTROL_MODE_VIOLATION: Request rejected, Bearer Control Mode violation. + * @MM_NETWORK_ERROR_LAST_PDN_DISCONNECTION_NOT_ALLOWED: Last PDN disconnection not allowed. + * @MM_NETWORK_ERROR_PDP_TYPE_IPV4_ONLY_ALLOWED: PDP type IPv4 only allowed. + * @MM_NETWORK_ERROR_PDP_TYPE_IPV6_ONLY_ALLOWED: PDP type IPv6 only allowed. + * @MM_NETWORK_ERROR_NO_NETWORK_SLICES_AVAILABLE: No network slices available. + * @MM_NETWORK_ERROR_MAXIMUM_NUMBER_OF_PDP_CONTEXTS_REACHED: Maximum number of PDP contexts reached. + * @MM_NETWORK_ERROR_REQUESTED_APN_NOT_SUPPORTED_IN_CURRENT_RAT_AND_PLMN: Requested APN not supported in current RAT and PLMN combination. + * @MM_NETWORK_ERROR_INSUFFICIENT_RESOURCES_FOR_SPECIFIC_SLICE_AND_DNN: Insufficient resources for specific slice and DNN. + * @MM_NETWORK_ERROR_INSUFFICIENT_RESOURCES_FOR_SPECIFIC_SLICE: Insufficient resources for specific slice. + * @MM_NETWORK_ERROR_NGKSI_ALREADY_IN_USE: NgKSI already in use. + * @MM_NETWORK_ERROR_NON_3GPP_ACCESS_TO_5GCN_NOT_ALLOWED: Non-3GPP access to 5GCN not allowed. + * @MM_NETWORK_ERROR_SERVING_NETWORK_NOT_AUTHORIZED: Serving network not authorized. + * @MM_NETWORK_ERROR_TEMPORARILY_NOT_AUTHORIZED_FOR_THIS_SNPN: Temporarily not authorized for this SNPN. + * @MM_NETWORK_ERROR_PERMANENTLY_NOT_AUTHORIZED_FOR_THIS_SNPN: Permanently not authorized for this SNPN. + * @MM_NETWORK_ERROR_NOT_AUTHORIZED_FOR_THIS_CAG_OR_AUTHORIZED_FOR_CAG_CELLS_ONLY: Not authorized for this CAG or authorized for CAG cells. + * @MM_NETWORK_ERROR_WIRELINE_ACCESS_AREA_NOT_ALLOWED: Wireline access area not allowed. + * @MM_NETWORK_ERROR_PAYLOAD_WAS_NOT_FORWARDED: Payload was not forwarded. + * @MM_NETWORK_ERROR_DNN_NOT_SUPPORTED_OR_NOT_SUBSCRIBED_IN_THE_SLICE: DNN not supported or not subscribed in the slice. + * @MM_NETWORK_ERROR_INSUFFICIENT_USER_PLANE_RESOURCES_FOR_THE_PDU_SESSION: Insufficient user-plane resources for the PDU session. + * @MM_NETWORK_ERROR_SEMANTICALLY_INCORRECT_MESSAGE: Semantically incorrect message. + * @MM_NETWORK_ERROR_INVALID_MANDATORY_INFORMATION: Invalid mandatory information. + * @MM_NETWORK_ERROR_MESSAGE_TYPE_NON_EXISTENT_OR_NOT_IMPLEMENTED: Message type non-existent or not implemented. + * @MM_NETWORK_ERROR_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE: Message type not compatible with protocol state. + * @MM_NETWORK_ERROR_INFORMATION_ELEMENT_NON_EXISTENT_OR_NOT_IMPLEMENTED: Information element non-existent or not implemented. + * @MM_NETWORK_ERROR_CONDITIONAL_IE_ERROR: Conditional IE error. + * @MM_NETWORK_ERROR_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE: Message not compatible with protocol state. + * @MM_NETWORK_ERROR_PROTOCOL_ERROR_UNSPECIFIED: Protocol error, unspecified. + * @MM_NETWORK_ERROR_APN_RESTRICTION_VALUE_INCOMPATIBLE_WITH_ACTIVE_PDP_CONTEXT: APN restriction value incompatible with active PDP context. + * @MM_NETWORK_ERROR_MULTIPLE_ACCESSES_TO_A_PDN_CONNECTION_NOT_ALLOWED: Multiple accesses to a PDN connection not allowed. + * + * Network errors reported by the network when registration is rejected. + * Even though some error names make reference to legacy technologies (e.g. GPRS), errors are not + * technology specific and the same type of errors are reported even for newer + * technologies like LTE and 5G. + * Network errors are defined in 3GPP TS 24.008 in sections 10.5.3.6 and + * 10.5.5.14 (detailed in annex G) and in 3GPP TS 24.301 in section 9.9.3.9. + * + * Since: 1.24 + */ +typedef enum { /*< underscore_name=mm_network_error >*/ + MM_NETWORK_ERROR_NONE = 0, + MM_NETWORK_ERROR_IMSI_UNKNOWN_IN_HLR = 2, + MM_NETWORK_ERROR_ILLEGAL_MS = 3, + MM_NETWORK_ERROR_IMSI_UNKNOWN_IN_VLR = 4, + MM_NETWORK_ERROR_IMEI_NOT_ACCEPTED = 5, + MM_NETWORK_ERROR_ILLEGAL_ME = 6, + MM_NETWORK_ERROR_GPRS_NOT_ALLOWED = 7, + MM_NETWORK_ERROR_GPRS_AND_NON_GPRS_NOT_ALLOWED = 8, + MM_NETWORK_ERROR_MS_IDENTITY_NOT_DERIVED_BY_NETWORK = 9, + MM_NETWORK_ERROR_IMPLICITLY_DETACHED = 10, + MM_NETWORK_ERROR_PLMN_NOT_ALLOWED = 11, + MM_NETWORK_ERROR_LOCATION_AREA_NOT_ALLOWED = 12, + MM_NETWORK_ERROR_ROAMING_NOT_ALLOWED_IN_LOCATION_AREA = 13, + MM_NETWORK_ERROR_GPRS_NOT_ALLOWED_IN_PLMN = 14, + MM_NETWORK_ERROR_NO_CELLS_IN_LOCATION_AREA = 15, + MM_NETWORK_ERROR_MSC_TEMPORARILY_NOT_REACHABLE = 16, + MM_NETWORK_ERROR_NETWORK_FAILURE = 17, + MM_NETWORK_ERROR_CS_DOMAIN_NOT_AVAILABLE = 18, + MM_NETWORK_ERROR_ESM_FAILURE = 19, + MM_NETWORK_ERROR_MAC_FAILURE = 20, + MM_NETWORK_ERROR_SYNCH_FAILURE = 21, + MM_NETWORK_ERROR_CONGESTION = 22, + MM_NETWORK_ERROR_GSM_AUTHENTICATION_UNACCEPTABLE = 23, + MM_NETWORK_ERROR_NOT_AUTHORIZED_FOR_CSG = 25, + MM_NETWORK_ERROR_INSUFFICIENT_RESOURCES = 26, + MM_NETWORK_ERROR_MISSING_OR_UNKNOWN_APN = 27, + MM_NETWORK_ERROR_UNKNOWN_PDP_ADDRESS_OR_TYPE = 28, + MM_NETWORK_ERROR_USER_AUTHENTICATION_FAILED = 29, + MM_NETWORK_ERROR_ACTIVATION_REJECTED_BY_GGSN_OR_GW = 30, + MM_NETWORK_ERROR_REDIRECTION_TO_5GCN_REQUIRED = 31, + MM_NETWORK_ERROR_SERVICE_OPTION_NOT_SUPPORTED = 32, + MM_NETWORK_ERROR_REQUESTED_SERVICE_OPTION_NOT_SUBSCRIBED = 33, + MM_NETWORK_ERROR_SERVICE_OPTION_TEMPORARILY_OUT_OF_ORDER = 34, + MM_NETWORK_ERROR_REQUESTED_SERVICE_OPTION_NOT_AUTHORIZED = 35, + MM_NETWORK_ERROR_CALL_CANNOT_BE_IDENTIFIED = 38, + MM_NETWORK_ERROR_CS_SERVICE_TEMPORARILY_NOT_AVAILABLE = 39, + MM_NETWORK_ERROR_NO_PDP_CONTEXT_ACTIVATED = 40, + MM_NETWORK_ERROR_SEMANTIC_ERROR_IN_THE_TFT_OPERATION = 41, + MM_NETWORK_ERROR_SYNTACTICAL_ERROR_IN_THE_TFT_OPERATION = 42, + MM_NETWORK_ERROR_UNKNOWN_PDP_CONTEXT = 43, + MM_NETWORK_ERROR_SEMANTIC_ERRORS_IN_PACKET_FILTER = 44, + MM_NETWORK_ERROR_SYNTACTICAL_ERRORS_IN_PACKET_FILTER = 45, + MM_NETWORK_ERROR_PDP_CONTEXT_WITHOUT_TFT_ALREADY_ACTIVATED = 46, + MM_NETWORK_ERROR_REQUEST_REJECTED_OR_BEARER_CONTROL_MODE_VIOLATION = 48, + MM_NETWORK_ERROR_LAST_PDN_DISCONNECTION_NOT_ALLOWED = 49, + MM_NETWORK_ERROR_PDP_TYPE_IPV4_ONLY_ALLOWED = 50, + MM_NETWORK_ERROR_PDP_TYPE_IPV6_ONLY_ALLOWED = 51, + MM_NETWORK_ERROR_NO_NETWORK_SLICES_AVAILABLE = 62, + MM_NETWORK_ERROR_MAXIMUM_NUMBER_OF_PDP_CONTEXTS_REACHED = 65, + MM_NETWORK_ERROR_REQUESTED_APN_NOT_SUPPORTED_IN_CURRENT_RAT_AND_PLMN = 66, + MM_NETWORK_ERROR_INSUFFICIENT_RESOURCES_FOR_SPECIFIC_SLICE_AND_DNN = 67, + MM_NETWORK_ERROR_INSUFFICIENT_RESOURCES_FOR_SPECIFIC_SLICE = 69, + MM_NETWORK_ERROR_NGKSI_ALREADY_IN_USE = 71, + MM_NETWORK_ERROR_NON_3GPP_ACCESS_TO_5GCN_NOT_ALLOWED = 72, + MM_NETWORK_ERROR_SERVING_NETWORK_NOT_AUTHORIZED = 73, + MM_NETWORK_ERROR_TEMPORARILY_NOT_AUTHORIZED_FOR_THIS_SNPN = 74, + MM_NETWORK_ERROR_PERMANENTLY_NOT_AUTHORIZED_FOR_THIS_SNPN = 75, + MM_NETWORK_ERROR_NOT_AUTHORIZED_FOR_THIS_CAG_OR_AUTHORIZED_FOR_CAG_CELLS_ONLY = 76, + MM_NETWORK_ERROR_WIRELINE_ACCESS_AREA_NOT_ALLOWED = 77, + MM_NETWORK_ERROR_PAYLOAD_WAS_NOT_FORWARDED = 90, + MM_NETWORK_ERROR_DNN_NOT_SUPPORTED_OR_NOT_SUBSCRIBED_IN_THE_SLICE = 91, + MM_NETWORK_ERROR_INSUFFICIENT_USER_PLANE_RESOURCES_FOR_THE_PDU_SESSION = 92, + MM_NETWORK_ERROR_SEMANTICALLY_INCORRECT_MESSAGE = 95, + MM_NETWORK_ERROR_INVALID_MANDATORY_INFORMATION = 96, + MM_NETWORK_ERROR_MESSAGE_TYPE_NON_EXISTENT_OR_NOT_IMPLEMENTED = 97, + MM_NETWORK_ERROR_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 98, + MM_NETWORK_ERROR_INFORMATION_ELEMENT_NON_EXISTENT_OR_NOT_IMPLEMENTED = 99, + MM_NETWORK_ERROR_CONDITIONAL_IE_ERROR = 100, + MM_NETWORK_ERROR_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101, + MM_NETWORK_ERROR_PROTOCOL_ERROR_UNSPECIFIED = 111, + MM_NETWORK_ERROR_APN_RESTRICTION_VALUE_INCOMPATIBLE_WITH_ACTIVE_PDP_CONTEXT = 112, + MM_NETWORK_ERROR_MULTIPLE_ACCESSES_TO_A_PDN_CONNECTION_NOT_ALLOWED = 113, + MM_NETWORK_ERROR_UNKNOWN = 114, +} MMNetworkError; + #endif /* _MODEMMANAGER_ENUMS_H_ */ diff --git a/introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml b/introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml index f7719676..04cabb8b 100644 --- a/introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml +++ b/introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml @@ -161,6 +161,53 @@ <property name="RegistrationState" type="u" access="read" /> <!-- + NetworkRejection: + + This property holds the latest network rejection information received from the + network during registration failure, and it will be cleared whenever the modem + successfully registers. + Network errors are defined in 3GPP TS 24.008 in sections 10.5.3.6 and + 10.5.5.14 (detailed in annex G) and in 3GPP TS 24.301 in section 9.9.3.9. + + Mandatory items include: + <variablelist> + <varlistentry><term><literal>"error"</literal></term> + <listitem> + A <link linkend="MMNetworkError">MMNetworkError</link>, + specifying the reason why a request from the mobile station + is rejected by the network, given as an unsigned integer value + (signature <literal>"u"</literal>). + </listitem> + </varlistentry> + </variablelist> + + Optionally following items could be included if reported by modem along + with network error. + <variablelist> + <varlistentry><term><literal>"operator-id"</literal></term> + <listitem> + Operator id reported along with network error, given as a string value (signature <literal>"s"</literal>). + </listitem> + </varlistentry> + <varlistentry><term><literal>"operator-name"</literal></term> + <listitem> + Operator name reported along with network error, given as a string value (signature <literal>"s"</literal>). + </listitem> + </varlistentry> + <varlistentry><term><literal>"access-technology"</literal></term> + <listitem> + A <link linkend="MMModemAccessTechnology">MMModemAccessTechnology</link>, + specifying the available data class reported along with network error, + given as an unsigned integer value (signature <literal>"u"</literal>). + </listitem> + </varlistentry> + </variablelist> + + Since: 1.24 + --> + <property name="NetworkRejection" type="a{sv}" access="read" /> + + <!-- OperatorCode: Code of the operator to which the mobile is currently registered. diff --git a/libmm-glib/libmm-glib.h b/libmm-glib/libmm-glib.h index 8c282562..c0fde6e0 100644 --- a/libmm-glib/libmm-glib.h +++ b/libmm-glib/libmm-glib.h @@ -93,6 +93,7 @@ #include <mm-cell-info-tdscdma.h> #include <mm-cell-info-lte.h> #include <mm-cell-info-nr5g.h> +#include <mm-network-rejection.h> #include <mm-compat.h> /* generated */ diff --git a/libmm-glib/meson.build b/libmm-glib/meson.build index de668dab..0871778c 100644 --- a/libmm-glib/meson.build +++ b/libmm-glib/meson.build @@ -61,6 +61,7 @@ headers = files( 'mm-sms.h', 'mm-sms-properties.h', 'mm-unlock-retries.h', + 'mm-network-rejection.h', ) install_headers( @@ -123,6 +124,7 @@ sources = files( 'mm-sms.c', 'mm-sms-properties.c', 'mm-unlock-retries.c', + 'mm-network-rejection.c', ) deps = [include_dep] diff --git a/libmm-glib/mm-modem-3gpp.c b/libmm-glib/mm-modem-3gpp.c index cb228108..e86360d3 100644 --- a/libmm-glib/mm-modem-3gpp.c +++ b/libmm-glib/mm-modem-3gpp.c @@ -52,6 +52,7 @@ struct _MMModem3gppPrivate { PROPERTY_OBJECT_DECLARE (initial_eps_bearer_settings, MMBearerProperties) PROPERTY_OBJECT_DECLARE (nr5g_registration_settings, MMNr5gRegistrationSettings) + PROPERTY_OBJECT_DECLARE (network_rejection, MMNetworkRejection) }; /*****************************************************************************/ @@ -696,6 +697,52 @@ PROPERTY_OBJECT_DEFINE_FAILABLE (initial_eps_bearer_settings, MMBearerProperties, mm_bearer_properties_new_from_dictionary) +/** + * mm_modem_3gpp_get_network_rejection: + * @self: A #MMModem3gpp. + * + * Gets a #MMNetworkRejection object specifying the network rejection + * information received during registration failure. + * + * <warning>The values reported by @self are not updated when the values in the + * interface change. Instead, the client is expected to call + * mm_modem_3gpp_get_network_rejection() again to get a new + * #MMNetworkRejection with the new values.</warning> + * + * Returns: (transfer full): A #MMNetworkRejection that must be freed with + * g_object_unref() or %NULL if unknown. + * + * Since: 1.24 + */ + +/** + * mm_modem_3gpp_peek_network_rejection: + * @self: A #MMModem3gpp. + * + * Gets a #MMNetworkRejection object specifying the network rejection + * information received during registration failure. + * + * <warning>The returned value is only valid until the property changes so + * it is only safe to use this function on the thread where + * @self was constructed. Use mm_modem_3gpp_get_network_rejection() + * if on another thread.</warning> + * + * Returns: (transfer none): A #MMNetworkRejection. Do not free the returned + * value, it belongs to @self. + * + * Since: 1.24 + */ + +/* helpers to match the property substring name with the one in our API */ +#define mm_gdbus_modem_3gpp_dup_network_rejection mm_gdbus_modem3gpp_dup_network_rejection + +PROPERTY_OBJECT_DEFINE_FAILABLE (network_rejection, + Modem3gpp, modem_3gpp, MODEM_3GPP, + MMNetworkRejection, + mm_network_rejection_new_from_dictionary) + +/*****************************************************************************/ + /*****************************************************************************/ static GList * @@ -1613,6 +1660,7 @@ mm_modem_3gpp_init (MMModem3gpp *self) PROPERTY_INITIALIZE (initial_eps_bearer_settings, "initial-eps-bearer-settings") PROPERTY_INITIALIZE (nr5g_registration_settings, "nr5g-registration-settings") + PROPERTY_INITIALIZE (network_rejection, "network-rejection") } static void @@ -1624,6 +1672,7 @@ finalize (GObject *object) PROPERTY_OBJECT_FINALIZE (initial_eps_bearer_settings); PROPERTY_OBJECT_FINALIZE (nr5g_registration_settings); + PROPERTY_OBJECT_FINALIZE (network_rejection); G_OBJECT_CLASS (mm_modem_3gpp_parent_class)->finalize (object); } diff --git a/libmm-glib/mm-modem-3gpp.h b/libmm-glib/mm-modem-3gpp.h index 8f137676..6a9ae8e9 100644 --- a/libmm-glib/mm-modem-3gpp.h +++ b/libmm-glib/mm-modem-3gpp.h @@ -32,6 +32,7 @@ #include "mm-bearer.h" #include "mm-nr5g-registration-settings.h" +#include "mm-network-rejection.h" #include "mm-gdbus-modem.h" G_BEGIN_DECLS @@ -98,6 +99,9 @@ MMModem3gppPacketServiceState mm_modem_3gpp_get_packet_service_state (MMModem3gp MMNr5gRegistrationSettings *mm_modem_3gpp_get_nr5g_registration_settings (MMModem3gpp *self); MMNr5gRegistrationSettings *mm_modem_3gpp_peek_nr5g_registration_settings (MMModem3gpp *self); +MMNetworkRejection *mm_modem_3gpp_get_network_rejection (MMModem3gpp *self); +MMNetworkRejection *mm_modem_3gpp_peek_network_rejection (MMModem3gpp *self); + void mm_modem_3gpp_register (MMModem3gpp *self, const gchar *network_id, GCancellable *cancellable, diff --git a/libmm-glib/mm-network-rejection.c b/libmm-glib/mm-network-rejection.c new file mode 100644 index 00000000..7bea1475 --- /dev/null +++ b/libmm-glib/mm-network-rejection.c @@ -0,0 +1,321 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * libmm-glib -- Access modem status & information from glib applications + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright (C) 2024 Google, Inc. + */ + +#include <string.h> + +#include "mm-errors-types.h" +#include "mm-network-rejection.h" + +/** + * SECTION: mm-network-rejection + * @title: MMNetworkRejection + * @short_description: Helper object to handle network rejection. + * + * The #MMNetworkRejection is an object handling the network rejection + * related information. + * + * This object is retrieved with either mm_modem_3gpp_get_network_rejection(), + * or mm_modem_3gpp_peek_network_rejection(). + */ + +G_DEFINE_TYPE (MMNetworkRejection, mm_network_rejection, G_TYPE_OBJECT) + +#define PROPERTY_ERROR "error" +#define PROPERTY_OPERATOR_ID "operator-id" +#define PROPERTY_OPERATOR_NAME "operator-name" +#define PROPERTY_ACCESS_TECHNOLOGY "access-technology" + +struct _MMNetworkRejectionPrivate { + gchar *operator_id; + gchar *operator_name; + MMModemAccessTechnology access_technology; + MMNetworkError error; +}; + +/*****************************************************************************/ + +/** + * mm_network_rejection_get_operator_id: + * @self: a #MMNetworkRejection. + * + * Gets the operator id reported with network reject. + * + * Returns: a string with the operator id, or #NULL if unknown. Do not free the + * returned value, it is owned by @self. + * + * Since: 1.24 + */ +const gchar * +mm_network_rejection_get_operator_id (MMNetworkRejection *self) +{ + g_return_val_if_fail (MM_IS_NETWORK_REJECTION (self), NULL); + + return self->priv->operator_id; +} + +/** + * mm_network_rejection_set_operator_id: (skip) + */ +void +mm_network_rejection_set_operator_id (MMNetworkRejection *self, + const gchar *operator_id) +{ + g_return_if_fail (MM_IS_NETWORK_REJECTION (self)); + + g_free (self->priv->operator_id); + self->priv->operator_id = g_strdup (operator_id); +} + +/*****************************************************************************/ + +/** + * mm_network_rejection_get_operator_name: + * @self: a #MMNetworkRejection. + * + * Gets the operator name reported with network reject. + * + * Returns: a string with the operator name, or #NULL if unknown. Do not free the + * returned value, it is owned by @self. + * + * Since: 1.24 + */ +const gchar * +mm_network_rejection_get_operator_name (MMNetworkRejection *self) +{ + g_return_val_if_fail (MM_IS_NETWORK_REJECTION (self), NULL); + + return self->priv->operator_name; +} + +/** + * mm_network_rejection_set_operator_name: (skip) + */ +void +mm_network_rejection_set_operator_name (MMNetworkRejection *self, + const gchar *operator_name) +{ + g_return_if_fail (MM_IS_NETWORK_REJECTION (self)); + + g_free (self->priv->operator_name); + self->priv->operator_name = g_strdup (operator_name); +} + +/*****************************************************************************/ + +/** + * mm_network_rejection_get_error: + * @self: a #MMNetworkRejection. + * + * Gets the network error reported with network reject. + * + * Returns: the network error. + * + * Since: 1.24 + */ +MMNetworkError +mm_network_rejection_get_error (MMNetworkRejection *self) +{ + g_return_val_if_fail (MM_IS_NETWORK_REJECTION (self), 0); + + return self->priv->error; +} + +/** + * mm_network_rejection_set_error: (skip) + */ +void +mm_network_rejection_set_error (MMNetworkRejection *self, + MMNetworkError error) +{ + g_return_if_fail (MM_IS_NETWORK_REJECTION (self)); + + self->priv->error = error; +} + +/*****************************************************************************/ + +/** + * mm_network_rejection_get_access_technology: + * @self: a #MMNetworkRejection. + * + * Gets the available class reported with network reject. + * + * Returns: the available class. + * + * Since: 1.24 + */ +MMModemAccessTechnology +mm_network_rejection_get_access_technology (MMNetworkRejection *self) +{ + g_return_val_if_fail (MM_IS_NETWORK_REJECTION (self), 0); + + return self->priv->access_technology; +} + +/** + * mm_network_rejection_set_access_technology: (skip) + */ +void +mm_network_rejection_set_access_technology (MMNetworkRejection *self, + MMModemAccessTechnology access_technology) +{ + g_return_if_fail (MM_IS_NETWORK_REJECTION (self)); + + self->priv->access_technology = access_technology; +} + +/*****************************************************************************/ + + +/** + * mm_network_rejection_get_dictionary: (skip) + */ +GVariant * +mm_network_rejection_get_dictionary (MMNetworkRejection *self) +{ + GVariantBuilder builder; + + if (!self) + return NULL; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&builder, + "{sv}", + PROPERTY_ERROR, + g_variant_new_uint32 (self->priv->error)); + + if (self->priv->operator_id) + g_variant_builder_add (&builder, + "{sv}", + PROPERTY_OPERATOR_ID, + g_variant_new_string (self->priv->operator_id)); + + if (self->priv->operator_name) + g_variant_builder_add (&builder, + "{sv}", + PROPERTY_OPERATOR_NAME, + g_variant_new_string (self->priv->operator_name)); + + if (self->priv->access_technology) + g_variant_builder_add (&builder, + "{sv}", + PROPERTY_ACCESS_TECHNOLOGY, + g_variant_new_uint32 (self->priv->access_technology)); + + return g_variant_ref_sink (g_variant_builder_end (&builder)); +} + +/*****************************************************************************/ + +/** + * mm_network_rejection_new_from_dictionary: (skip) + */ +MMNetworkRejection * +mm_network_rejection_new_from_dictionary (GVariant *dictionary, + GError **error) +{ + GVariantIter iter; + gchar *key; + GVariant *value; + MMNetworkRejection *self; + + self = mm_network_rejection_new (); + if (!dictionary) + return self; + + if (!g_variant_is_of_type (dictionary, G_VARIANT_TYPE ("a{sv}"))) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_INVALID_ARGS, + "Cannot create network rejection from dictionary: " + "invalid variant type received"); + g_object_unref (self); + return NULL; + } + + g_variant_iter_init (&iter, dictionary); + while (g_variant_iter_next (&iter, "{sv}", &key, &value)) { + if (g_str_equal (key, PROPERTY_ERROR)) { + mm_network_rejection_set_error ( + self, + g_variant_get_uint32 (value)); + } else if (g_str_equal (key, PROPERTY_OPERATOR_ID)) { + mm_network_rejection_set_operator_id ( + self, + g_variant_get_string (value, NULL)); + } else if (g_str_equal (key, PROPERTY_OPERATOR_NAME)) { + mm_network_rejection_set_operator_name ( + self, + g_variant_get_string (value, NULL)); + } else if (g_str_equal (key, PROPERTY_ACCESS_TECHNOLOGY)) { + mm_network_rejection_set_access_technology ( + self, + g_variant_get_uint32 (value)); + } + + g_free (key); + g_variant_unref (value); + } + + return self; +} + +/*****************************************************************************/ + +/** + * mm_network_rejection_new: (skip) + */ +MMNetworkRejection * +mm_network_rejection_new (void) +{ + return (MM_NETWORK_REJECTION ( + g_object_new (MM_TYPE_NETWORK_REJECTION, NULL))); +} + +static void +mm_network_rejection_init (MMNetworkRejection *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self), + MM_TYPE_NETWORK_REJECTION, + MMNetworkRejectionPrivate); +} + +static void +finalize (GObject *object) +{ + MMNetworkRejection *self = MM_NETWORK_REJECTION (object); + + g_free (self->priv->operator_id); + g_free (self->priv->operator_name); + + G_OBJECT_CLASS (mm_network_rejection_parent_class)->finalize (object); +} + +static void +mm_network_rejection_class_init (MMNetworkRejectionClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (MMNetworkRejectionPrivate)); + + object_class->finalize = finalize; +} diff --git a/libmm-glib/mm-network-rejection.h b/libmm-glib/mm-network-rejection.h new file mode 100644 index 00000000..2142454a --- /dev/null +++ b/libmm-glib/mm-network-rejection.h @@ -0,0 +1,97 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * libmm-glib -- Access modem status & information from glib applications + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright (C) 2024 Google, Inc. + */ + +#ifndef MM_NETWORK_REJECTION_H +#define MM_NETWORK_REJECTION_H + +#if !defined (__LIBMM_GLIB_H_INSIDE__) && !defined (LIBMM_GLIB_COMPILATION) +#error "Only <libmm-glib.h> can be included directly." +#endif + +#include <ModemManager.h> +#include <glib-object.h> + +G_BEGIN_DECLS + +#define MM_TYPE_NETWORK_REJECTION (mm_network_rejection_get_type ()) +#define MM_NETWORK_REJECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_NETWORK_REJECTION, MMNetworkRejection)) +#define MM_NETWORK_REJECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_NETWORK_REJECTION, MMNetworkRejectionClass)) +#define MM_IS_NETWORK_REJECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_NETWORK_REJECTION)) +#define MM_IS_NETWORK_REJECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_NETWORK_REJECTION)) +#define MM_NETWORK_REJECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_NETWORK_REJECTION, MMNetworkRejectionClass)) + +typedef struct _MMNetworkRejection MMNetworkRejection; +typedef struct _MMNetworkRejectionClass MMNetworkRejectionClass; +typedef struct _MMNetworkRejectionPrivate MMNetworkRejectionPrivate; + +/** + * MMNetworkRejection: + * + * The #MMNetworkRejection structure contains private data and should + * only be accessed using the provided API. + */ +struct _MMNetworkRejection { + /*< private >*/ + GObject parent; + MMNetworkRejectionPrivate *priv; +}; + +struct _MMNetworkRejectionClass { + /*< private >*/ + GObjectClass parent; +}; + +GType mm_network_rejection_get_type (void); +G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMNetworkRejection, g_object_unref) + +MMNetworkError mm_network_rejection_get_error (MMNetworkRejection *self); +MMModemAccessTechnology mm_network_rejection_get_access_technology (MMNetworkRejection *self); +const gchar *mm_network_rejection_get_operator_id (MMNetworkRejection *self); +const gchar *mm_network_rejection_get_operator_name (MMNetworkRejection *self); + +/*****************************************************************************/ +/* ModemManager/libmm-glib/mmcli specific methods */ + +#if defined (_LIBMM_INSIDE_MM) || \ + defined (_LIBMM_INSIDE_MMCLI) || \ + defined (LIBMM_GLIB_COMPILATION) + +MMNetworkRejection *mm_network_rejection_new (void); +MMNetworkRejection *mm_network_rejection_new_from_dictionary (GVariant *dictionary, + GError **error); + +void mm_network_rejection_set_error (MMNetworkRejection *self, + MMNetworkError error); +void mm_network_rejection_set_operator_id (MMNetworkRejection *self, + const gchar *operator_id); +void mm_network_rejection_set_operator_name (MMNetworkRejection *self, + const gchar *operator_name); +void mm_network_rejection_set_access_technology (MMNetworkRejection *self, + MMModemAccessTechnology access_technology); + +GVariant *mm_network_rejection_get_dictionary (MMNetworkRejection *self); + +#endif + +G_END_DECLS + +#endif /* MM_NETWORK_REJECTION_H */ diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c index 77599a8b..6560b475 100644 --- a/src/mm-iface-modem-3gpp.c +++ b/src/mm-iface-modem-3gpp.c @@ -2363,6 +2363,13 @@ update_registration_state (MMIfaceModem3gpp *self, if (mm_modem_3gpp_registration_state_is_registered (new_state)) { MMModemState modem_state; + /* When moving to registered state, clear network rejection */ + mm_iface_modem_3gpp_update_network_rejection (self, + MM_NETWORK_ERROR_NONE, + NULL, + NULL, + MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN); + /* If already reloading registration info, skip it */ if (priv->reloading_registration_info) return; @@ -2597,6 +2604,57 @@ mm_iface_modem_3gpp_update_pco_list (MMIfaceModem3gpp *self, /*****************************************************************************/ void +mm_iface_modem_3gpp_update_network_rejection (MMIfaceModem3gpp *self, + MMNetworkError error, + const gchar *operator_id, + const gchar *operator_name, + MMModemAccessTechnology access_technology) +{ + MmGdbusModem3gpp *skeleton = NULL; + Private *priv; + g_autoptr(MMNetworkRejection) new_code = NULL; + g_autoptr(GVariant) dictionary = NULL; + g_autofree gchar *access_tech_str = NULL; + const gchar *nw_rejection_error = NULL; + + priv = get_private (self); + if (!priv->iface_enabled) + return; + + g_object_get (self, + MM_IFACE_MODEM_3GPP_DBUS_SKELETON, &skeleton, + NULL); + if (!skeleton) + return; + + if (!error) { + mm_gdbus_modem3gpp_set_network_rejection (skeleton, NULL); + return; + } + + access_tech_str = mm_modem_access_technology_build_string_from_mask (access_technology); + nw_rejection_error = mm_network_error_get_string (error); + + mm_obj_warn (self, "Network rejection received: reason '%s' (%u), " + "operator id '%s', operator name '%s', access technology '%s'", + nw_rejection_error ? nw_rejection_error : "unknown", error, + operator_id ? operator_id : "none", + operator_name ? operator_name : "none", + access_tech_str); + + new_code = mm_network_rejection_new (); + mm_network_rejection_set_error (new_code, error); + mm_network_rejection_set_operator_id (new_code, operator_id); + mm_network_rejection_set_operator_name (new_code, operator_name); + mm_network_rejection_set_access_technology (new_code, access_technology); + + dictionary = mm_network_rejection_get_dictionary (new_code); + mm_gdbus_modem3gpp_set_network_rejection (skeleton, dictionary); +} + +/*****************************************************************************/ + +void mm_iface_modem_3gpp_update_initial_eps_bearer (MMIfaceModem3gpp *self, MMBearerProperties *properties) { diff --git a/src/mm-iface-modem-3gpp.h b/src/mm-iface-modem-3gpp.h index af726ef0..b0f74403 100644 --- a/src/mm-iface-modem-3gpp.h +++ b/src/mm-iface-modem-3gpp.h @@ -363,6 +363,12 @@ void mm_iface_modem_3gpp_update_initial_eps_bearer (MMIfaceModem3gpp *self, MMBearerProperties *properties); void mm_iface_modem_3gpp_reload_initial_eps_bearer (MMIfaceModem3gpp *self); +void mm_iface_modem_3gpp_update_network_rejection (MMIfaceModem3gpp *self, + MMNetworkError error, + const gchar *operator_code, + const gchar *operator_name, + MMModemAccessTechnology access_technology); + /* Run all registration checks */ void mm_iface_modem_3gpp_run_registration_checks (MMIfaceModem3gpp *self, GAsyncReadyCallback callback, |