aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2012-09-13 14:57:55 +0200
committerAleksander Morgado <aleksander@lanedo.com>2012-09-14 06:43:49 +0200
commitc2b246414cb7d4bbd6782b7879fa66a7d627177a (patch)
tree28fc9d5854b219874c6b6f1fabe3b6b0d7b66820 /src
parent40816e5c90b73fef238da525af91b69657ceb203 (diff)
iface-modem-3gpp: update state to REGISTERED after loading operator code/name
Call managers all want to be able to set the operator ID and/or name as soon as we get registered. We will consider now that whenever we get into registered state we already have operator code and name updated to the proper values. Applications shouldn't, though, just rely on those values to be valid as long as we're registered, as the modem may re-register automatically in some other network (e.g. going from a roaming network to the home network). This change involves not setting the state to REGISTERED until operator name and code loading sequences have been run. We will still signal in the log the change, with a new 'registering' intermediate state indication.
Diffstat (limited to 'src')
-rw-r--r--src/mm-broadband-modem.c3
-rw-r--r--src/mm-iface-modem-3gpp.c254
-rw-r--r--src/mm-iface-modem-3gpp.h8
3 files changed, 189 insertions, 76 deletions
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index 14c0d40c..3863c71c 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -6107,7 +6107,8 @@ enable_location_gathering (MMIfaceModemLocation *self,
/* Reload registration to get LAC/CI */
mm_iface_modem_3gpp_run_registration_checks (MM_IFACE_MODEM_3GPP (self), NULL, NULL);
/* Reload operator to get MCC/MNC */
- mm_iface_modem_3gpp_reload_current_operator (MM_IFACE_MODEM_3GPP (self));
+ if (MM_BROADBAND_MODEM (self)->priv->modem_state >= MM_MODEM_STATE_REGISTERED)
+ mm_iface_modem_3gpp_reload_current_operator (MM_IFACE_MODEM_3GPP (self), NULL, NULL);
}
/* Done we are */
diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c
index 0000aee7..a3dcb86f 100644
--- a/src/mm-iface-modem-3gpp.c
+++ b/src/mm-iface-modem-3gpp.c
@@ -71,6 +71,7 @@ typedef struct {
MMModem3gppRegistrationState ps;
gboolean manual_registration;
GCancellable *pending_registration_cancellable;
+ gboolean reloading_operator;
} RegistrationStateContext;
static void
@@ -727,12 +728,41 @@ mm_iface_modem_3gpp_run_registration_checks (MMIfaceModem3gpp *self,
/*****************************************************************************/
+typedef struct {
+ MMIfaceModem3gpp *self;
+ MmGdbusModem3gpp *skeleton;
+ GSimpleAsyncResult *result;
+ gboolean operator_code_loaded;
+ gboolean operator_name_loaded;
+} ReloadCurrentOperatorContext;
+
+static void
+reload_current_operator_context_complete_and_free (ReloadCurrentOperatorContext *ctx)
+{
+ g_simple_async_result_complete_in_idle (ctx->result);
+ g_object_unref (ctx->result);
+ if (ctx->skeleton)
+ g_object_unref (ctx->skeleton);
+ g_object_unref (ctx->self);
+ g_slice_free (ReloadCurrentOperatorContext, ctx);
+}
+
+gboolean
+mm_iface_modem_3gpp_reload_current_operator_finish (MMIfaceModem3gpp *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
+}
+
+static void reload_current_operator_context_step (ReloadCurrentOperatorContext *ctx);
+
static void
load_operator_name_ready (MMIfaceModem3gpp *self,
- GAsyncResult *res)
+ GAsyncResult *res,
+ ReloadCurrentOperatorContext *ctx)
{
GError *error = NULL;
- MmGdbusModem3gpp *skeleton = NULL;
gchar *str;
str = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_operator_name_finish (self, res, &error);
@@ -741,12 +771,12 @@ load_operator_name_ready (MMIfaceModem3gpp *self,
g_error_free (error);
}
- g_object_get (self,
- MM_IFACE_MODEM_3GPP_DBUS_SKELETON, &skeleton,
- NULL);
- mm_gdbus_modem3gpp_set_operator_name (skeleton, str);
+ if (ctx->skeleton)
+ mm_gdbus_modem3gpp_set_operator_name (ctx->skeleton, str);
g_free (str);
- g_object_unref (skeleton);
+
+ ctx->operator_name_loaded = TRUE;
+ reload_current_operator_context_step (ctx);
}
static gboolean
@@ -779,10 +809,10 @@ parse_mcc_mnc (const gchar *mccmnc,
static void
load_operator_code_ready (MMIfaceModem3gpp *self,
- GAsyncResult *res)
+ GAsyncResult *res,
+ ReloadCurrentOperatorContext *ctx)
{
GError *error = NULL;
- MmGdbusModem3gpp *skeleton = NULL;
gchar *str;
str = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_operator_code_finish (self, res, &error);
@@ -791,10 +821,8 @@ load_operator_code_ready (MMIfaceModem3gpp *self,
g_error_free (error);
}
- g_object_get (self,
- MM_IFACE_MODEM_3GPP_DBUS_SKELETON, &skeleton,
- NULL);
- mm_gdbus_modem3gpp_set_operator_code (skeleton, str);
+ if (ctx->skeleton)
+ mm_gdbus_modem3gpp_set_operator_code (ctx->skeleton, str);
/* If we also implement the location interface, update the 3GPP location */
if (str && MM_IS_IFACE_MODEM_LOCATION (self)) {
@@ -804,46 +832,87 @@ load_operator_code_ready (MMIfaceModem3gpp *self,
if (parse_mcc_mnc (str, &mcc, &mnc))
mm_iface_modem_location_3gpp_update_mcc_mnc (MM_IFACE_MODEM_LOCATION (self), mcc, mnc);
}
-
g_free (str);
- g_object_unref (skeleton);
+
+ ctx->operator_code_loaded = TRUE;
+ reload_current_operator_context_step (ctx);
+}
+
+static void
+reload_current_operator_context_step (ReloadCurrentOperatorContext *ctx)
+{
+ if (!ctx->operator_code_loaded) {
+ /* Launch operator code update */
+ MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->load_operator_code (
+ ctx->self,
+ (GAsyncReadyCallback)load_operator_code_ready,
+ ctx);
+ return;
+ }
+
+ if (!ctx->operator_name_loaded) {
+ /* Launch operator name update */
+ MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->load_operator_name (
+ ctx->self,
+ (GAsyncReadyCallback)load_operator_name_ready,
+ ctx);
+ return;
+ }
+
+ /* If both loaded, all done */
+ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
+ reload_current_operator_context_complete_and_free (ctx);
}
void
-mm_iface_modem_3gpp_reload_current_operator (MMIfaceModem3gpp *self)
+mm_iface_modem_3gpp_reload_current_operator (MMIfaceModem3gpp *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- MMModem3gppRegistrationState state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
- MmGdbusModem3gpp *skeleton = NULL;
+ ReloadCurrentOperatorContext *ctx;
+
+ ctx = g_slice_new0 (ReloadCurrentOperatorContext);
+ ctx->self = g_object_ref (self);
+ ctx->result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ mm_iface_modem_3gpp_reload_current_operator);
g_object_get (self,
- MM_IFACE_MODEM_3GPP_REGISTRATION_STATE, &state,
- MM_IFACE_MODEM_3GPP_DBUS_SKELETON, &skeleton,
+ MM_IFACE_MODEM_3GPP_DBUS_SKELETON, &ctx->skeleton,
NULL);
- if (state == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
- state == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) {
- /* Launch operator code update */
- if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_operator_code &&
- MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_operator_code_finish)
- MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_operator_code (
- self,
- (GAsyncReadyCallback)load_operator_code_ready,
- NULL);
- /* Launch operator name update */
- if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_operator_name &&
- MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_operator_name_finish)
- MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_operator_name (
- self,
- (GAsyncReadyCallback)load_operator_name_ready,
- NULL);
- } else {
- mm_gdbus_modem3gpp_set_operator_code (skeleton, NULL);
- mm_gdbus_modem3gpp_set_operator_name (skeleton, NULL);
+ ctx->operator_code_loaded = !(MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_operator_code &&
+ MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_operator_code_finish);
+ if (ctx->operator_code_loaded) {
+ mm_gdbus_modem3gpp_set_operator_code (ctx->skeleton, NULL);
if (MM_IS_IFACE_MODEM_LOCATION (self))
mm_iface_modem_location_3gpp_update_mcc_mnc (MM_IFACE_MODEM_LOCATION (self), 0, 0);
}
- g_object_unref (skeleton);
+ ctx->operator_name_loaded = !(MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_operator_name &&
+ MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_operator_name_finish);
+ if (ctx->operator_name_loaded)
+ mm_gdbus_modem3gpp_set_operator_name (ctx->skeleton, NULL);
+
+ reload_current_operator_context_step (ctx);
+}
+
+void
+mm_iface_modem_3gpp_clear_current_operator (MMIfaceModem3gpp *self)
+{
+ MmGdbusModem3gpp *skeleton = NULL;
+
+ g_object_get (self,
+ MM_IFACE_MODEM_3GPP_DBUS_SKELETON, &skeleton,
+ NULL);
+ if (!skeleton)
+ return;
+
+ mm_gdbus_modem3gpp_set_operator_code (skeleton, NULL);
+ mm_gdbus_modem3gpp_set_operator_name (skeleton, NULL);
+ if (MM_IS_IFACE_MODEM_LOCATION (self))
+ mm_iface_modem_location_3gpp_update_mcc_mnc (MM_IFACE_MODEM_LOCATION (self), 0, 0);
}
/*****************************************************************************/
@@ -901,56 +970,93 @@ mm_iface_modem_3gpp_update_location (MMIfaceModem3gpp *self,
/*****************************************************************************/
static void
+update_registration_reload_current_operator_ready (MMIfaceModem3gpp *self,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ MMModem3gppRegistrationState new_state;
+ RegistrationStateContext *ctx;
+
+ new_state = GPOINTER_TO_UINT (user_data);
+
+ mm_info ("Modem %s: 3GPP Registration state changed (registering -> %s)",
+ g_dbus_object_get_object_path (G_DBUS_OBJECT (self)),
+ mm_modem_3gpp_registration_state_get_string (new_state));
+
+ /* The property in the interface is bound to the property
+ * in the skeleton, so just updating here is enough */
+ g_object_set (self,
+ MM_IFACE_MODEM_3GPP_REGISTRATION_STATE, new_state,
+ NULL);
+
+ mm_iface_modem_update_subsystem_state (MM_IFACE_MODEM (self),
+ SUBSYSTEM_3GPP,
+ MM_MODEM_STATE_REGISTERED,
+ MM_MODEM_STATE_CHANGE_REASON_UNKNOWN);
+
+ ctx = get_registration_state_context (self);
+ ctx->reloading_operator = FALSE;
+}
+
+static void
update_registration_state (MMIfaceModem3gpp *self,
MMModem3gppRegistrationState new_state)
{
MMModem3gppRegistrationState old_state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
- MmGdbusModem3gpp *skeleton = NULL;
g_object_get (self,
MM_IFACE_MODEM_3GPP_REGISTRATION_STATE, &old_state,
- MM_IFACE_MODEM_3GPP_DBUS_SKELETON, &skeleton,
NULL);
- if (!skeleton)
+ /* Only set new state if different */
+ if (new_state == old_state)
return;
- /* Only set new state if different */
- if (new_state != old_state) {
- mm_info ("Modem %s: 3GPP Registration state changed (%s -> %s)",
- g_dbus_object_get_object_path (G_DBUS_OBJECT (self)),
- mm_modem_3gpp_registration_state_get_string (old_state),
- mm_modem_3gpp_registration_state_get_string (new_state));
+ if (new_state == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
+ new_state == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) {
+ RegistrationStateContext *ctx;
- /* The property in the interface is bound to the property
- * in the skeleton, so just updating here is enough */
- g_object_set (self,
- MM_IFACE_MODEM_3GPP_REGISTRATION_STATE, new_state,
- NULL);
+ ctx = get_registration_state_context (self);
- /* Reload current operator */
- mm_iface_modem_3gpp_reload_current_operator (self);
+ /* If already reloading operator, skip it */
+ if (ctx->reloading_operator)
+ return;
- if (new_state == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
- new_state == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) {
- mm_iface_modem_update_subsystem_state (MM_IFACE_MODEM (self),
- SUBSYSTEM_3GPP,
- MM_MODEM_STATE_REGISTERED,
- MM_MODEM_STATE_CHANGE_REASON_UNKNOWN);
- }
- /* Not registered neither in home nor roaming network */
- else {
- mm_iface_modem_update_subsystem_state (
- MM_IFACE_MODEM (self),
- SUBSYSTEM_3GPP,
- (new_state == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING ?
- MM_MODEM_STATE_SEARCHING :
- MM_MODEM_STATE_ENABLED),
- MM_MODEM_STATE_CHANGE_REASON_UNKNOWN);
- }
+ mm_info ("Modem %s: 3GPP Registration state changed (%s -> registering)",
+ g_dbus_object_get_object_path (G_DBUS_OBJECT (self)),
+ mm_modem_3gpp_registration_state_get_string (old_state));
+
+ /* Reload current operator. ONLY update the state to REGISTERED after
+ * having loaded operator code/name */
+ ctx->reloading_operator = TRUE;
+ mm_iface_modem_3gpp_reload_current_operator (
+ self,
+ (GAsyncReadyCallback)update_registration_reload_current_operator_ready,
+ GUINT_TO_POINTER (new_state));
+ return;
}
- g_object_unref (skeleton);
+ mm_info ("Modem %s: 3GPP Registration state changed (%s -> %s)",
+ g_dbus_object_get_object_path (G_DBUS_OBJECT (self)),
+ mm_modem_3gpp_registration_state_get_string (old_state),
+ mm_modem_3gpp_registration_state_get_string (new_state));
+
+ /* Not registered neither in home nor roaming network */
+ mm_iface_modem_3gpp_clear_current_operator (self);
+
+ /* The property in the interface is bound to the property
+ * in the skeleton, so just updating here is enough */
+ g_object_set (self,
+ MM_IFACE_MODEM_3GPP_REGISTRATION_STATE, new_state,
+ NULL);
+
+ mm_iface_modem_update_subsystem_state (
+ MM_IFACE_MODEM (self),
+ SUBSYSTEM_3GPP,
+ (new_state == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING ?
+ MM_MODEM_STATE_SEARCHING :
+ MM_MODEM_STATE_ENABLED),
+ MM_MODEM_STATE_CHANGE_REASON_UNKNOWN);
}
void
diff --git a/src/mm-iface-modem-3gpp.h b/src/mm-iface-modem-3gpp.h
index 2bc25613..aaf727cd 100644
--- a/src/mm-iface-modem-3gpp.h
+++ b/src/mm-iface-modem-3gpp.h
@@ -234,7 +234,13 @@ gboolean mm_iface_modem_3gpp_run_registration_checks_finish (MMIfaceModem3gpp *s
GError **error);
/* Request to reload current operator */
-void mm_iface_modem_3gpp_reload_current_operator (MMIfaceModem3gpp *self);
+void mm_iface_modem_3gpp_reload_current_operator (MMIfaceModem3gpp *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean mm_iface_modem_3gpp_reload_current_operator_finish (MMIfaceModem3gpp *self,
+ GAsyncResult *res,
+ GError **error);
+void mm_iface_modem_3gpp_clear_current_operator (MMIfaceModem3gpp *self);
/* Allow registering in the network */
gboolean mm_iface_modem_3gpp_register_in_network_finish (MMIfaceModem3gpp *self,