modem-3gpp: allow loading and changing EPS UE mode of operation

The UE modes of operation for LTE are defined in 3GPP TS 24.301 (e.g.
section 4.3 in v10.3.0):
  * PS mode 1: EPS only, 'voice centric'
  * PS mode 2: EPS only, 'data centric'
  * CS/PS mode 1: EPS and non-EPS, 'voice centric'
  * CS/PS mode 2: EPS and non-EPS, 'data centric'

The mode specifies, among other things, how the UE should behave w.r.t
CS fallback depending on the capabilities reported by the network.
This commit is contained in:
Aleksander Morgado
2017-12-28 18:41:50 +01:00
parent c5c9ab279d
commit d4aaa436d9
12 changed files with 418 additions and 4 deletions

View File

@@ -49,6 +49,7 @@ static Context *ctx;
static gboolean scan_flag; static gboolean scan_flag;
static gboolean register_home_flag; static gboolean register_home_flag;
static gchar *register_in_operator_str; static gchar *register_in_operator_str;
static gchar *set_eps_ue_mode_operation_str;
static gboolean ussd_status_flag; static gboolean ussd_status_flag;
static gchar *ussd_initiate_str; static gchar *ussd_initiate_str;
static gchar *ussd_respond_str; static gchar *ussd_respond_str;
@@ -67,6 +68,10 @@ static GOptionEntry entries[] = {
"Request a given modem to register in the network of the given operator", "Request a given modem to register in the network of the given operator",
"[MCCMNC]" "[MCCMNC]"
}, },
{ "3gpp-set-eps-ue-mode-operation", 0, 0, G_OPTION_ARG_STRING, &set_eps_ue_mode_operation_str,
"Set the UE mode of operation for EPS",
"[ps-1|ps-2|csps-1|csps-2]"
},
{ "3gpp-ussd-status", 0, 0, G_OPTION_ARG_NONE, &ussd_status_flag, { "3gpp-ussd-status", 0, 0, G_OPTION_ARG_NONE, &ussd_status_flag,
"Show status of any ongoing USSD session", "Show status of any ongoing USSD session",
NULL NULL
@@ -113,6 +118,7 @@ mmcli_modem_3gpp_options_enabled (void)
n_actions = (scan_flag + n_actions = (scan_flag +
register_home_flag + register_home_flag +
!!register_in_operator_str + !!register_in_operator_str +
!!set_eps_ue_mode_operation_str +
ussd_status_flag + ussd_status_flag +
!!ussd_initiate_str + !!ussd_initiate_str +
!!ussd_respond_str + !!ussd_respond_str +
@@ -291,6 +297,45 @@ register_ready (MMModem3gpp *modem_3gpp,
mmcli_async_operation_done (); mmcli_async_operation_done ();
} }
static void
set_eps_ue_mode_operation_process_reply (gboolean result,
const GError *error)
{
if (!result) {
g_printerr ("error: couldn't set UE mode of operation for EPS: '%s'\n",
error ? error->message : "unknown error");
exit (EXIT_FAILURE);
}
g_print ("successfully set UE mode of operation for EPS\n");
}
static void
set_eps_ue_mode_operation_ready (MMModem3gpp *modem,
GAsyncResult *result)
{
gboolean operation_result;
GError *error = NULL;
operation_result = mm_modem_3gpp_set_eps_ue_mode_operation_finish (modem, result, &error);
set_eps_ue_mode_operation_process_reply (operation_result, error);
mmcli_async_operation_done ();
}
static void
parse_eps_ue_mode_operation (MMModem3gppEpsUeModeOperation *uemode)
{
GError *error = NULL;
*uemode = mm_common_get_eps_ue_mode_operation_from_string (set_eps_ue_mode_operation_str, &error);
if (error) {
g_printerr ("error: couldn't parse UE mode of operation for EPS: '%s'\n",
error->message);
exit (EXIT_FAILURE);
}
}
static void static void
print_ussd_status (void) print_ussd_status (void)
{ {
@@ -438,6 +483,21 @@ get_modem_ready (GObject *source,
return; return;
} }
/* Request to set UE mode of operation for EPS? */
if (set_eps_ue_mode_operation_str) {
MMModem3gppEpsUeModeOperation uemode;
parse_eps_ue_mode_operation (&uemode);
g_debug ("Asynchronously setting UE mode of operation for EPS...");
mm_modem_3gpp_set_eps_ue_mode_operation (ctx->modem_3gpp,
uemode,
ctx->cancellable,
(GAsyncReadyCallback)set_eps_ue_mode_operation_ready,
NULL);
return;
}
/* Request to initiate USSD session? */ /* Request to initiate USSD session? */
if (ussd_initiate_str) { if (ussd_initiate_str) {
ensure_modem_3gpp_ussd (); ensure_modem_3gpp_ussd ();
@@ -538,6 +598,22 @@ mmcli_modem_3gpp_run_synchronous (GDBusConnection *connection)
return; return;
} }
/* Request to set UE mode of operation for EPS? */
if (set_eps_ue_mode_operation_str) {
MMModem3gppEpsUeModeOperation uemode;
gboolean result;
parse_eps_ue_mode_operation (&uemode);
g_debug ("Synchronously setting UE mode of operation for EPS...");
result = mm_modem_3gpp_set_eps_ue_mode_operation_sync (ctx->modem_3gpp,
uemode,
NULL,
&error);
set_eps_ue_mode_operation_process_reply (result, error);
return;
}
/* Request to show USSD status? */ /* Request to show USSD status? */
if (ussd_status_flag) { if (ussd_status_flag) {
ensure_modem_3gpp_ussd (); ensure_modem_3gpp_ussd ();

View File

@@ -470,15 +470,18 @@ print_modem_info (void)
" | operator id: '%s'\n" " | operator id: '%s'\n"
" | operator name: '%s'\n" " | operator name: '%s'\n"
" | subscription: '%s'\n" " | subscription: '%s'\n"
" | registration: '%s'\n", " | registration: '%s'\n"
" | EPS UE mode: '%s'\n",
VALIDATE_UNKNOWN (mm_modem_3gpp_get_imei (ctx->modem_3gpp)), VALIDATE_UNKNOWN (mm_modem_3gpp_get_imei (ctx->modem_3gpp)),
facility_locks, facility_locks,
VALIDATE_UNKNOWN (mm_modem_3gpp_get_operator_code (ctx->modem_3gpp)), VALIDATE_UNKNOWN (mm_modem_3gpp_get_operator_code (ctx->modem_3gpp)),
VALIDATE_UNKNOWN (mm_modem_3gpp_get_operator_name (ctx->modem_3gpp)), VALIDATE_UNKNOWN (mm_modem_3gpp_get_operator_name (ctx->modem_3gpp)),
mm_modem_3gpp_subscription_state_get_string ( mm_modem_3gpp_subscription_state_get_string (
mm_modem_3gpp_get_subscription_state ((ctx->modem_3gpp))), mm_modem_3gpp_get_subscription_state (ctx->modem_3gpp)),
mm_modem_3gpp_registration_state_get_string ( mm_modem_3gpp_registration_state_get_string (
mm_modem_3gpp_get_registration_state ((ctx->modem_3gpp)))); mm_modem_3gpp_get_registration_state (ctx->modem_3gpp)),
mm_modem_3gpp_eps_ue_mode_operation_get_string (
mm_modem_3gpp_get_eps_ue_mode_operation (ctx->modem_3gpp)));
g_free (facility_locks); g_free (facility_locks);
} }

View File

@@ -22,6 +22,7 @@ MMModem3gppNetworkAvailability
MMModem3gppSubscriptionState MMModem3gppSubscriptionState
MMModem3gppRegistrationState MMModem3gppRegistrationState
MMModem3gppUssdSessionState MMModem3gppUssdSessionState
MMModem3gppEpsUeModeOperation
MMModemAccessTechnology MMModemAccessTechnology
MMModemBand MMModemBand
MMModemCapability MMModemCapability

View File

@@ -283,6 +283,9 @@ mm_modem_3gpp_register_sync
mm_modem_3gpp_scan mm_modem_3gpp_scan
mm_modem_3gpp_scan_finish mm_modem_3gpp_scan_finish
mm_modem_3gpp_scan_sync mm_modem_3gpp_scan_sync
mm_modem_3gpp_set_eps_ue_mode_operation
mm_modem_3gpp_set_eps_ue_mode_operation_finish
mm_modem_3gpp_set_eps_ue_mode_operation_sync
<SUBSECTION Standard> <SUBSECTION Standard>
MMModem3gppClass MMModem3gppClass
MM_IS_MODEM_3GPP MM_IS_MODEM_3GPP
@@ -1325,6 +1328,7 @@ mm_modem_3gpp_subscription_state_get_string
mm_modem_3gpp_facility_build_string_from_mask mm_modem_3gpp_facility_build_string_from_mask
mm_modem_3gpp_network_availability_get_string mm_modem_3gpp_network_availability_get_string
mm_modem_3gpp_ussd_session_state_get_string mm_modem_3gpp_ussd_session_state_get_string
mm_modem_3gpp_eps_ue_mode_operation_get_string
mm_modem_cdma_registration_state_get_string mm_modem_cdma_registration_state_get_string
mm_modem_cdma_activation_state_get_string mm_modem_cdma_activation_state_get_string
mm_modem_cdma_rm_protocol_get_string mm_modem_cdma_rm_protocol_get_string
@@ -1375,6 +1379,7 @@ mm_modem_3gpp_subscription_state_build_string_from_mask
mm_modem_3gpp_facility_get_string mm_modem_3gpp_facility_get_string
mm_modem_3gpp_network_availability_build_string_from_mask mm_modem_3gpp_network_availability_build_string_from_mask
mm_modem_3gpp_ussd_session_state_build_string_from_mask mm_modem_3gpp_ussd_session_state_build_string_from_mask
mm_modem_3gpp_eps_ue_mode_operation_build_string_from_mask
mm_firmware_image_type_build_string_from_mask mm_firmware_image_type_build_string_from_mask
mm_modem_port_type_build_string_from_mask mm_modem_port_type_build_string_from_mask
mm_oma_feature_get_string mm_oma_feature_get_string
@@ -1394,6 +1399,7 @@ MM_TYPE_MODEM_3GPP_NETWORK_AVAILABILITY
MM_TYPE_MODEM_3GPP_REGISTRATION_STATE MM_TYPE_MODEM_3GPP_REGISTRATION_STATE
MM_TYPE_MODEM_3GPP_SUBSCRIPTION_STATE MM_TYPE_MODEM_3GPP_SUBSCRIPTION_STATE
MM_TYPE_MODEM_3GPP_USSD_SESSION_STATE MM_TYPE_MODEM_3GPP_USSD_SESSION_STATE
MM_TYPE_MODEM_3GPP_EPS_UE_MODE_OPERATION
MM_TYPE_MODEM_ACCESS_TECHNOLOGY MM_TYPE_MODEM_ACCESS_TECHNOLOGY
MM_TYPE_MODEM_BAND MM_TYPE_MODEM_BAND
MM_TYPE_MODEM_CAPABILITY MM_TYPE_MODEM_CAPABILITY
@@ -1432,6 +1438,7 @@ mm_modem_3gpp_network_availability_get_type
mm_modem_3gpp_registration_state_get_type mm_modem_3gpp_registration_state_get_type
mm_modem_3gpp_subscription_state_get_type mm_modem_3gpp_subscription_state_get_type
mm_modem_3gpp_ussd_session_state_get_type mm_modem_3gpp_ussd_session_state_get_type
mm_modem_3gpp_eps_ue_mode_operation_get_type
mm_modem_access_technology_get_type mm_modem_access_technology_get_type
mm_modem_band_get_type mm_modem_band_get_type
mm_modem_capability_get_type mm_modem_capability_get_type
@@ -1666,6 +1673,7 @@ mm_gdbus_modem3gpp_get_operator_name
mm_gdbus_modem3gpp_dup_operator_name mm_gdbus_modem3gpp_dup_operator_name
mm_gdbus_modem3gpp_get_enabled_facility_locks mm_gdbus_modem3gpp_get_enabled_facility_locks
mm_gdbus_modem3gpp_get_subscription_state mm_gdbus_modem3gpp_get_subscription_state
mm_gdbus_modem3gpp_get_eps_ue_mode_operation
<SUBSECTION Methods> <SUBSECTION Methods>
mm_gdbus_modem3gpp_call_register mm_gdbus_modem3gpp_call_register
mm_gdbus_modem3gpp_call_register_finish mm_gdbus_modem3gpp_call_register_finish
@@ -1673,9 +1681,13 @@ mm_gdbus_modem3gpp_call_register_sync
mm_gdbus_modem3gpp_call_scan mm_gdbus_modem3gpp_call_scan
mm_gdbus_modem3gpp_call_scan_finish mm_gdbus_modem3gpp_call_scan_finish
mm_gdbus_modem3gpp_call_scan_sync mm_gdbus_modem3gpp_call_scan_sync
mm_gdbus_modem3gpp_call_set_eps_ue_mode_operation
mm_gdbus_modem3gpp_call_set_eps_ue_mode_operation_finish
mm_gdbus_modem3gpp_call_set_eps_ue_mode_operation_sync
<SUBSECTION Private> <SUBSECTION Private>
mm_gdbus_modem3gpp_complete_register mm_gdbus_modem3gpp_complete_register
mm_gdbus_modem3gpp_complete_scan mm_gdbus_modem3gpp_complete_scan
mm_gdbus_modem3gpp_complete_set_eps_ue_mode_operation
mm_gdbus_modem3gpp_interface_info mm_gdbus_modem3gpp_interface_info
mm_gdbus_modem3gpp_override_properties mm_gdbus_modem3gpp_override_properties
mm_gdbus_modem3gpp_set_enabled_facility_locks mm_gdbus_modem3gpp_set_enabled_facility_locks
@@ -1684,6 +1696,7 @@ mm_gdbus_modem3gpp_set_operator_code
mm_gdbus_modem3gpp_set_operator_name mm_gdbus_modem3gpp_set_operator_name
mm_gdbus_modem3gpp_set_registration_state mm_gdbus_modem3gpp_set_registration_state
mm_gdbus_modem3gpp_set_subscription_state mm_gdbus_modem3gpp_set_subscription_state
mm_gdbus_modem3gpp_set_eps_ue_mode_operation
<SUBSECTION Standard> <SUBSECTION Standard>
MM_GDBUS_IS_MODEM3GPP MM_GDBUS_IS_MODEM3GPP
MM_GDBUS_MODEM3GPP MM_GDBUS_MODEM3GPP

View File

@@ -1155,6 +1155,24 @@ typedef enum { /*< underscore_name=mm_modem_3gpp_ussd_session_state >*/
MM_MODEM_3GPP_USSD_SESSION_STATE_USER_RESPONSE = 3, MM_MODEM_3GPP_USSD_SESSION_STATE_USER_RESPONSE = 3,
} MMModem3gppUssdSessionState; } MMModem3gppUssdSessionState;
/**
* MMModem3gppEpsUeModeOperation:
* @MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_UNKNOWN: Unknown or not applicable.
* @MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_PS_1: PS mode 1 of operation: EPS only, voice-centric.
* @MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_PS_2: PS mode 2 of operation: EPS only, data-centric.
* @MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_CSPS_1: CS/PS mode 1 of operation: EPS and non-EPS, voice-centric.
* @MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_CSPS_2: CS/PS mode 2 of operation: EPS and non-EPS, data-centric.
*
* UE mode of operation for EPS, as per 3GPP TS 24.301.
*/
typedef enum { /*< underscore_name=mm_modem_3gpp_eps_ue_mode_operation >*/
MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_UNKNOWN = 0,
MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_PS_1 = 1,
MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_PS_2 = 2,
MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_CSPS_1 = 3,
MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_CSPS_2 = 4,
} MMModem3gppEpsUeModeOperation;
/** /**
* MMFirmwareImageType: * MMFirmwareImageType:
* @MM_FIRMWARE_IMAGE_TYPE_UNKNOWN: Unknown firmware type. * @MM_FIRMWARE_IMAGE_TYPE_UNKNOWN: Unknown firmware type.

View File

@@ -85,6 +85,16 @@
<arg name="results" type="aa{sv}" direction="out" /> <arg name="results" type="aa{sv}" direction="out" />
</method> </method>
<!--
SetEpsUeModeOperation:
@mode: a <link linkend="MMModem3gppEpsUeModeOperation">MMModem3gppEpsUeModeOperation</link>.
Sets the UE mode of operation for EPS.
-->
<method name="SetEpsUeModeOperation">
<arg name="mode" type="u" direction="in" />
</method>
<!-- <!--
Imei: Imei:
@@ -145,5 +155,14 @@
--> -->
<property name="SubscriptionState" type="u" access="read" /> <property name="SubscriptionState" type="u" access="read" />
<!--
EpsUeModeOperation:
A <link linkend="MMModem3gppEpsUeModeOperation">MMModem3gppEpsUeModeOperation</link>
value representing the UE mode of operation for EPS, given as an unsigned integer
(signature <literal>"u"</literal>).
-->
<property name="EpsUeModeOperation" type="u" access="read" />
</interface> </interface>
</node> </node>

View File

@@ -758,6 +758,28 @@ mm_common_build_mode_combinations_default (void)
return g_variant_builder_end (&builder); return g_variant_builder_end (&builder);
} }
MMModem3gppEpsUeModeOperation
mm_common_get_eps_ue_mode_operation_from_string (const gchar *str,
GError **error)
{
GEnumClass *enum_class;
guint i;
enum_class = G_ENUM_CLASS (g_type_class_ref (MM_TYPE_MODEM_3GPP_EPS_UE_MODE_OPERATION));
for (i = 0; enum_class->values[i].value_nick; i++) {
if (!g_ascii_strcasecmp (str, enum_class->values[i].value_nick))
return enum_class->values[i].value;
}
g_set_error (error,
MM_CORE_ERROR,
MM_CORE_ERROR_INVALID_ARGS,
"Couldn't match '%s' with a valid MMModem3gppEpsUeModeOperation value",
str);
return MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_UNKNOWN;
}
GArray * GArray *
mm_common_oma_pending_network_initiated_sessions_variant_to_garray (GVariant *variant) mm_common_oma_pending_network_initiated_sessions_variant_to_garray (GVariant *variant)
{ {

View File

@@ -76,6 +76,9 @@ MMOmaFeature mm_common_get_oma_features_from_string (const gchar *str,
MMOmaSessionType mm_common_get_oma_session_type_from_string (const gchar *str, MMOmaSessionType mm_common_get_oma_session_type_from_string (const gchar *str,
GError **error); GError **error);
MMModem3gppEpsUeModeOperation mm_common_get_eps_ue_mode_operation_from_string (const gchar *str,
GError **error);
GArray *mm_common_ports_variant_to_garray (GVariant *variant); GArray *mm_common_ports_variant_to_garray (GVariant *variant);
MMModemPortInfo *mm_common_ports_variant_to_array (GVariant *variant, MMModemPortInfo *mm_common_ports_variant_to_array (GVariant *variant,
guint *n_ports); guint *n_ports);

View File

@@ -280,6 +280,22 @@ mm_modem_3gpp_get_enabled_facility_locks (MMModem3gpp *self)
return mm_gdbus_modem3gpp_get_enabled_facility_locks (MM_GDBUS_MODEM3GPP (self)); return mm_gdbus_modem3gpp_get_enabled_facility_locks (MM_GDBUS_MODEM3GPP (self));
} }
/**
* mm_modem_3gpp_get_eps_ue_mode_operation:
* @self: A #MMModem3gpp.
*
* Get the UE mode of operation for EPS.
*
* Returns: A #MMModem3gppEpsUeModeOperation.
*/
MMModem3gppEpsUeModeOperation
mm_modem_3gpp_get_eps_ue_mode_operation (MMModem3gpp *self)
{
g_return_val_if_fail (MM_IS_MODEM_3GPP (self), MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_UNKNOWN);
return mm_gdbus_modem3gpp_get_eps_ue_mode_operation (MM_GDBUS_MODEM3GPP (self));
}
/*****************************************************************************/ /*****************************************************************************/
/** /**
@@ -590,6 +606,43 @@ mm_modem_3gpp_scan_sync (MMModem3gpp *self,
/*****************************************************************************/ /*****************************************************************************/
gboolean
mm_modem_3gpp_set_eps_ue_mode_operation_finish (MMModem3gpp *self,
GAsyncResult *res,
GError **error)
{
g_return_val_if_fail (MM_IS_MODEM_3GPP (self), FALSE);
return mm_gdbus_modem3gpp_call_set_eps_ue_mode_operation_finish (MM_GDBUS_MODEM3GPP (self), res, error);
}
void
mm_modem_3gpp_set_eps_ue_mode_operation (MMModem3gpp *self,
MMModem3gppEpsUeModeOperation mode,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_return_if_fail (MM_IS_MODEM_3GPP (self));
g_return_if_fail (mode != MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_UNKNOWN);
mm_gdbus_modem3gpp_call_set_eps_ue_mode_operation (MM_GDBUS_MODEM3GPP (self), (guint) mode, cancellable, callback, user_data);
}
gboolean
mm_modem_3gpp_set_eps_ue_mode_operation_sync (MMModem3gpp *self,
MMModem3gppEpsUeModeOperation mode,
GCancellable *cancellable,
GError **error)
{
g_return_val_if_fail (MM_IS_MODEM_3GPP (self), FALSE);
g_return_val_if_fail (mode != MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_UNKNOWN, FALSE);
return mm_gdbus_modem3gpp_call_set_eps_ue_mode_operation_sync (MM_GDBUS_MODEM3GPP (self), (guint) mode, cancellable, error);
}
/*****************************************************************************/
static void static void
mm_modem_3gpp_init (MMModem3gpp *self) mm_modem_3gpp_init (MMModem3gpp *self)
{ {

View File

@@ -80,6 +80,7 @@ MMModem3gppSubscriptionState mm_modem_3gpp_get_subscription_state (MMModem3
MMModem3gppFacility mm_modem_3gpp_get_enabled_facility_locks (MMModem3gpp *self); MMModem3gppFacility mm_modem_3gpp_get_enabled_facility_locks (MMModem3gpp *self);
MMModem3gppEpsUeModeOperation mm_modem_3gpp_get_eps_ue_mode_operation (MMModem3gpp *self);
void mm_modem_3gpp_register (MMModem3gpp *self, void mm_modem_3gpp_register (MMModem3gpp *self,
const gchar *network_id, const gchar *network_id,
@@ -120,6 +121,19 @@ GList *mm_modem_3gpp_scan_sync (MMModem3gpp *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
void mm_modem_3gpp_set_eps_ue_mode_operation (MMModem3gpp *self,
MMModem3gppEpsUeModeOperation mode,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean mm_modem_3gpp_set_eps_ue_mode_operation_finish (MMModem3gpp *self,
GAsyncResult *res,
GError **error);
gboolean mm_modem_3gpp_set_eps_ue_mode_operation_sync (MMModem3gpp *self,
MMModem3gppEpsUeModeOperation mode,
GCancellable *cancellable,
GError **error);
G_END_DECLS G_END_DECLS
#endif /* _MM_MODEM_3GPP_H_ */ #endif /* _MM_MODEM_3GPP_H_ */

View File

@@ -774,6 +774,141 @@ handle_scan (MmGdbusModem3gpp *skeleton,
/*****************************************************************************/ /*****************************************************************************/
typedef struct {
MmGdbusModem3gpp *skeleton;
GDBusMethodInvocation *invocation;
MMIfaceModem3gpp *self;
MMModem3gppEpsUeModeOperation mode;
} HandleSetEpsUeModeOperationContext;
static void
handle_set_eps_ue_mode_operation_context_free (HandleSetEpsUeModeOperationContext *ctx)
{
g_object_unref (ctx->skeleton);
g_object_unref (ctx->invocation);
g_object_unref (ctx->self);
g_slice_free (HandleSetEpsUeModeOperationContext, ctx);
}
static void
after_set_load_eps_ue_mode_operation_ready (MMIfaceModem3gpp *self,
GAsyncResult *res,
HandleSetEpsUeModeOperationContext *ctx)
{
MMModem3gppEpsUeModeOperation uemode;
GError *error = NULL;
uemode = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_eps_ue_mode_operation_finish (self, res, &error);
if (error) {
g_dbus_method_invocation_take_error (ctx->invocation, error);
handle_set_eps_ue_mode_operation_context_free (ctx);
return;
}
if (uemode != ctx->mode) {
g_dbus_method_invocation_return_error_literal (ctx->invocation,
MM_CORE_ERROR,
MM_CORE_ERROR_FAILED,
"UE mode of operation for EPS wasn't updated");
handle_set_eps_ue_mode_operation_context_free (ctx);
return;
}
mm_gdbus_modem3gpp_set_eps_ue_mode_operation (ctx->skeleton, uemode);
mm_gdbus_modem3gpp_complete_set_eps_ue_mode_operation (ctx->skeleton, ctx->invocation);
handle_set_eps_ue_mode_operation_context_free (ctx);
}
static void
handle_set_eps_ue_mode_operation_ready (MMIfaceModem3gpp *self,
GAsyncResult *res,
HandleSetEpsUeModeOperationContext *ctx)
{
GError *error = NULL;
if (!MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->set_eps_ue_mode_operation_finish (self, res, &error)) {
g_dbus_method_invocation_take_error (ctx->invocation, error);
handle_set_eps_ue_mode_operation_context_free (ctx);
return;
}
if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_eps_ue_mode_operation &&
MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_eps_ue_mode_operation_finish) {
MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_eps_ue_mode_operation (
self,
(GAsyncReadyCallback)after_set_load_eps_ue_mode_operation_ready,
ctx);
return;
}
/* Assume we're ok */
mm_gdbus_modem3gpp_complete_set_eps_ue_mode_operation (ctx->skeleton, ctx->invocation);
handle_set_eps_ue_mode_operation_context_free (ctx);
}
static void
handle_set_eps_ue_mode_operation_auth_ready (MMBaseModem *self,
GAsyncResult *res,
HandleSetEpsUeModeOperationContext *ctx)
{
GError *error = NULL;
if (!mm_base_modem_authorize_finish (self, res, &error)) {
g_dbus_method_invocation_take_error (ctx->invocation, error);
handle_set_eps_ue_mode_operation_context_free (ctx);
return;
}
/* Check if we already are in the requested mode */
if (mm_gdbus_modem3gpp_get_eps_ue_mode_operation (ctx->skeleton) == ctx->mode) {
/* Nothing to do */
mm_gdbus_modem3gpp_complete_set_eps_ue_mode_operation (ctx->skeleton, ctx->invocation);
handle_set_eps_ue_mode_operation_context_free (ctx);
return;
}
/* If UE mode update is not implemented, report an error */
if (!MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->set_eps_ue_mode_operation ||
!MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->set_eps_ue_mode_operation_finish) {
g_dbus_method_invocation_return_error (ctx->invocation,
MM_CORE_ERROR,
MM_CORE_ERROR_UNSUPPORTED,
"Cannot set UE mode of operation for EPS: operation not supported");
handle_set_eps_ue_mode_operation_context_free (ctx);
return;
}
MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->set_eps_ue_mode_operation (
MM_IFACE_MODEM_3GPP (self),
ctx->mode,
(GAsyncReadyCallback)handle_set_eps_ue_mode_operation_ready,
ctx);
}
static gboolean
handle_set_eps_ue_mode_operation (MmGdbusModem3gpp *skeleton,
GDBusMethodInvocation *invocation,
guint mode,
MMIfaceModem3gpp *self)
{
HandleSetEpsUeModeOperationContext *ctx;
ctx = g_slice_new (HandleSetEpsUeModeOperationContext);
ctx->skeleton = g_object_ref (skeleton);
ctx->invocation = g_object_ref (invocation);
ctx->self = g_object_ref (self);
ctx->mode = mode;
mm_base_modem_authorize (MM_BASE_MODEM (self),
invocation,
MM_AUTHORIZATION_DEVICE_CONTROL,
(GAsyncReadyCallback)handle_set_eps_ue_mode_operation_auth_ready,
ctx);
return TRUE;
}
/*****************************************************************************/
gboolean gboolean
mm_iface_modem_3gpp_run_registration_checks_finish (MMIfaceModem3gpp *self, mm_iface_modem_3gpp_run_registration_checks_finish (MMIfaceModem3gpp *self,
GAsyncResult *res, GAsyncResult *res,
@@ -1879,6 +2014,7 @@ typedef enum {
INITIALIZATION_STEP_FIRST, INITIALIZATION_STEP_FIRST,
INITIALIZATION_STEP_IMEI, INITIALIZATION_STEP_IMEI,
INITIALIZATION_STEP_ENABLED_FACILITY_LOCKS, INITIALIZATION_STEP_ENABLED_FACILITY_LOCKS,
INITIALIZATION_STEP_EPS_UE_MODE_OPERATION,
INITIALIZATION_STEP_LAST INITIALIZATION_STEP_LAST
} InitializationStep; } InitializationStep;
@@ -1910,6 +2046,30 @@ sim_pin_lock_enabled_cb (MMBaseSim *self,
mm_gdbus_modem3gpp_set_enabled_facility_locks (skeleton, facilities); mm_gdbus_modem3gpp_set_enabled_facility_locks (skeleton, facilities);
} }
static void
load_eps_ue_mode_operation_ready (MMIfaceModem3gpp *self,
GAsyncResult *res,
GTask *task)
{
InitializationContext *ctx;
MMModem3gppEpsUeModeOperation uemode;
GError *error = NULL;
ctx = g_task_get_task_data (task);
uemode = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_eps_ue_mode_operation_finish (self, res, &error);
mm_gdbus_modem3gpp_set_eps_ue_mode_operation (ctx->skeleton, uemode);
if (error) {
mm_warn ("couldn't load UE mode of operation for EPS: '%s'", error->message);
g_error_free (error);
}
/* Go on to next step */
ctx->step++;
interface_initialization_step (task);
}
static void static void
load_enabled_facility_locks_ready (MMIfaceModem3gpp *self, load_enabled_facility_locks_ready (MMIfaceModem3gpp *self,
GAsyncResult *res, GAsyncResult *res,
@@ -2022,6 +2182,18 @@ interface_initialization_step (GTask *task)
/* Fall down to next step */ /* Fall down to next step */
ctx->step++; ctx->step++;
case INITIALIZATION_STEP_EPS_UE_MODE_OPERATION:
if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_eps_ue_mode_operation &&
MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_eps_ue_mode_operation_finish) {
MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_eps_ue_mode_operation (
self,
(GAsyncReadyCallback)load_eps_ue_mode_operation_ready,
task);
return;
}
/* Fall down to next step */
ctx->step++;
case INITIALIZATION_STEP_LAST: case INITIALIZATION_STEP_LAST:
/* We are done without errors! */ /* We are done without errors! */
@@ -2034,7 +2206,10 @@ interface_initialization_step (GTask *task)
"handle-scan", "handle-scan",
G_CALLBACK (handle_scan), G_CALLBACK (handle_scan),
self); self);
g_signal_connect (ctx->skeleton,
"handle-set-eps-ue-mode-operation",
G_CALLBACK (handle_set_eps_ue_mode_operation),
self);
/* Finally, export the new interface */ /* Finally, export the new interface */
mm_gdbus_object_skeleton_set_modem3gpp (MM_GDBUS_OBJECT_SKELETON (self), mm_gdbus_object_skeleton_set_modem3gpp (MM_GDBUS_OBJECT_SKELETON (self),

View File

@@ -68,6 +68,14 @@ struct _MMIfaceModem3gpp {
GAsyncResult *res, GAsyncResult *res,
GError **error); GError **error);
/* Loading of the UE mode of operation for EPS property */
void (* load_eps_ue_mode_operation) (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data);
MMModem3gppEpsUeModeOperation (* load_eps_ue_mode_operation_finish) (MMIfaceModem3gpp *self,
GAsyncResult *res,
GError **error);
/* Asynchronous setting up unsolicited events */ /* Asynchronous setting up unsolicited events */
void (*setup_unsolicited_events) (MMIfaceModem3gpp *self, void (*setup_unsolicited_events) (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
@@ -191,6 +199,15 @@ struct _MMIfaceModem3gpp {
GList * (*scan_networks_finish) (MMIfaceModem3gpp *self, GList * (*scan_networks_finish) (MMIfaceModem3gpp *self,
GAsyncResult *res, GAsyncResult *res,
GError **error); GError **error);
/* Set UE mode of operation for EPS */
void (* set_eps_ue_mode_operation) (MMIfaceModem3gpp *self,
MMModem3gppEpsUeModeOperation mode,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean (* set_eps_ue_mode_operation_finish) (MMIfaceModem3gpp *self,
GAsyncResult *res,
GError **error);
}; };
GType mm_iface_modem_3gpp_get_type (void); GType mm_iface_modem_3gpp_get_type (void);