diff options
-rw-r--r-- | src/mm-bearer-3gpp.c | 57 | ||||
-rw-r--r-- | src/mm-bearer-3gpp.h | 4 | ||||
-rw-r--r-- | src/mm-broadband-modem.c | 40 | ||||
-rw-r--r-- | src/mm-iface-modem-3gpp.c | 132 | ||||
-rw-r--r-- | src/mm-iface-modem-3gpp.h | 15 |
5 files changed, 144 insertions, 104 deletions
diff --git a/src/mm-bearer-3gpp.c b/src/mm-bearer-3gpp.c index 2601d039..d6cf3f38 100644 --- a/src/mm-bearer-3gpp.c +++ b/src/mm-bearer-3gpp.c @@ -786,63 +786,6 @@ disconnect (MMBearer *self, /*****************************************************************************/ MMBearer * -mm_bearer_3gpp_new_from_properties (MMBaseModem *modem, - GVariant *properties, - GError **error) -{ - GVariantIter iter; - const gchar *key; - GVariant *value; - gchar *apn = NULL; - gchar *ip_type = NULL; - gboolean allow_roaming = FALSE; - gboolean allow_roaming_found = FALSE; - - mm_dbg ("Creating 3GPP bearer with properties..."); - g_variant_iter_init (&iter, properties); - while (g_variant_iter_loop (&iter, "{sv}", &key, &value)) { - if (g_str_equal (key, "apn")) { - if (apn) - mm_warn ("Duplicate 'apn' property found, ignoring value '%s'", - g_variant_get_string (value, NULL)); - else - apn = g_variant_dup_string (value, NULL); - } else if (g_str_equal (key, "ip-type")) { - if (ip_type) - mm_warn ("Duplicate 'ip-type' property found, ignoring value '%s'", - g_variant_get_string (value, NULL)); - else - ip_type = g_variant_dup_string (value, NULL); - } else if (g_str_equal (key, "allow-roaming")) { - if (allow_roaming_found) - mm_warn ("Duplicate 'allow-roaming' property found, ignoring value '%s'", - g_variant_get_string (value, NULL)); - else { - allow_roaming_found = TRUE; - allow_roaming = g_variant_get_boolean (value); - } - } - else - mm_dbg ("Ignoring property '%s' in 3GPP bearer", key); - } - - /* Check mandatory properties */ - if (!apn) { - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_INVALID_ARGS, - "Invalid input properties: 3GPP bearer requires 'apn'"); - g_free (ip_type); - return NULL; - } - - return mm_bearer_3gpp_new (modem, - apn, - ip_type, - allow_roaming); -} - -MMBearer * mm_bearer_3gpp_new (MMBaseModem *modem, const gchar *apn, const gchar *ip_type, diff --git a/src/mm-bearer-3gpp.h b/src/mm-bearer-3gpp.h index d1951397..b79d13a0 100644 --- a/src/mm-bearer-3gpp.h +++ b/src/mm-bearer-3gpp.h @@ -54,13 +54,11 @@ struct _MMBearer3gppClass { GType mm_bearer_3gpp_get_type (void); +/* Default 3GPP bearer creation implementation */ MMBearer *mm_bearer_3gpp_new (MMBaseModem *modem, const gchar *apn, const gchar *ip_type, gboolean allow_roaming); -MMBearer *mm_bearer_3gpp_new_from_properties (MMBaseModem *modem, - GVariant *properties, - GError **error); const gchar *mm_bearer_3gpp_get_apn (MMBearer3gpp *self); const gchar *mm_bearer_3gpp_get_ip_type (MMBearer3gpp *self); diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c index fbe655aa..af655f13 100644 --- a/src/mm-broadband-modem.c +++ b/src/mm-broadband-modem.c @@ -108,7 +108,7 @@ modem_create_bearer (MMIfaceModem *self, gpointer user_data) { GSimpleAsyncResult *result; - MMBearer *bearer; + MMBearer *bearer = NULL; GError *error = NULL; /* TODO: We'll need to guess the capability of the bearer, based on the @@ -116,28 +116,23 @@ modem_create_bearer (MMIfaceModem *self, * configured in the modem. Use 3GPP for testing now */ /* New 3GPP bearer */ - { - MMModem3gppRegistrationState state; - - bearer = mm_bearer_3gpp_new_from_properties (MM_BASE_MODEM (self), - properties, - &error); - if (!bearer) { - g_simple_async_report_take_gerror_in_idle (G_OBJECT (self), - callback, - user_data, - error); - return; - } + if (MM_BROADBAND_MODEM (self)->priv->modem_3gpp_dbus_skeleton) { + bearer = mm_iface_modem_3gpp_create_bearer_from_properties (MM_IFACE_MODEM_3GPP (self), + properties, + &error); + } else { + g_set_error (&error, + MM_CORE_ERROR, + MM_CORE_ERROR_UNSUPPORTED, + "Cannot create bearer in modem of unknown type"); + } - /* Based on our current 3GPP registration state, allow or forbid - * connections */ - state = get_consolidated_reg_state (MM_BROADBAND_MODEM (self)); - if (state == MM_MODEM_3GPP_REGISTRATION_STATE_HOME || - state == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) - mm_bearer_set_connection_allowed (bearer); - else - mm_bearer_set_connection_forbidden (bearer); + if (!bearer) { + g_simple_async_report_take_gerror_in_idle (G_OBJECT (self), + callback, + user_data, + error); + return; } /* Set a new ref to the bearer object as result */ @@ -2649,6 +2644,7 @@ iface_modem_3gpp_init (MMIfaceModem3gpp *iface) iface->register_in_network_finish = register_in_network_finish; iface->scan_networks = scan_networks; iface->scan_networks_finish = scan_networks_finish; + iface->create_3gpp_bearer = mm_bearer_3gpp_new; } static void diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c index 1ff7a11a..c804dc3a 100644 --- a/src/mm-iface-modem-3gpp.c +++ b/src/mm-iface-modem-3gpp.c @@ -276,6 +276,97 @@ handle_scan (MmGdbusModem3gpp *skeleton, /*****************************************************************************/ +/* Create new 3GPP bearer */ +MMBearer * +mm_iface_modem_3gpp_create_bearer (MMIfaceModem3gpp *self, + const gchar *apn, + const gchar *ip_type, + gboolean allow_roaming) +{ + MMModem3gppRegistrationState current_state; + MMBearer3gpp *bearer; + + g_assert (MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->create_3gpp_bearer != NULL); + + /* Create new 3GPP bearer using the method set in the interface, so that + * plugins can subclass it and implement their own. */ + bearer = MM_BEARER_3GPP (MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)-> + create_3gpp_bearer (MM_BASE_MODEM (self), + apn, + ip_type, + allow_roaming)); + + g_object_get (self, + MM_IFACE_MODEM_3GPP_REGISTRATION_STATE, ¤t_state, + NULL); + + /* Don't allow bearer to get connected if roaming forbidden */ + if (current_state == MM_MODEM_3GPP_REGISTRATION_STATE_HOME || + (current_state == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING && + mm_bearer_3gpp_get_allow_roaming (bearer))) + mm_bearer_set_connection_allowed (MM_BEARER (bearer)); + else + mm_bearer_set_connection_forbidden (MM_BEARER (bearer)); + + return MM_BEARER (bearer); +} + +MMBearer * +mm_iface_modem_3gpp_create_bearer_from_properties (MMIfaceModem3gpp *self, + GVariant *properties, + GError **error) +{ + GVariantIter iter; + const gchar *key; + GVariant *value; + gchar *apn = NULL; + gchar *ip_type = NULL; + gboolean allow_roaming = FALSE; + gboolean allow_roaming_found = FALSE; + + mm_dbg ("Creating 3GPP bearer with properties..."); + g_variant_iter_init (&iter, properties); + while (g_variant_iter_loop (&iter, "{sv}", &key, &value)) { + if (g_str_equal (key, "apn")) { + if (apn) + mm_warn ("Duplicate 'apn' property found, ignoring value '%s'", + g_variant_get_string (value, NULL)); + else + apn = g_variant_dup_string (value, NULL); + } else if (g_str_equal (key, "ip-type")) { + if (ip_type) + mm_warn ("Duplicate 'ip-type' property found, ignoring value '%s'", + g_variant_get_string (value, NULL)); + else + ip_type = g_variant_dup_string (value, NULL); + } else if (g_str_equal (key, "allow-roaming")) { + if (allow_roaming_found) + mm_warn ("Duplicate 'allow-roaming' property found, ignoring value '%s'", + g_variant_get_string (value, NULL)); + else { + allow_roaming_found = TRUE; + allow_roaming = g_variant_get_boolean (value); + } + } + else + mm_dbg ("Ignoring property '%s' in 3GPP bearer", key); + } + + /* Check mandatory properties */ + if (!apn) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_INVALID_ARGS, + "Invalid input properties: 3GPP bearer requires 'apn'"); + g_free (ip_type); + return NULL; + } + + return mm_iface_modem_3gpp_create_bearer (self, apn, ip_type, allow_roaming); +} + +/*****************************************************************************/ + typedef struct { GSimpleAsyncResult *result; gboolean cs_done; @@ -410,15 +501,19 @@ STR_REPLY_READY_FN (operator_code, "Operator Code") STR_REPLY_READY_FN (operator_name, "Operator Name") static void -set_bearer_3gpp_connection_allowed (MMBearer *bearer) +set_bearer_3gpp_connection_allowed (MMBearer *bearer, + const gboolean *roaming_network) { - /* TODO: don't allow bearers to get connected if roaming forbidden */ - if (MM_IS_BEARER_3GPP (bearer)) + /* Don't allow bearer to get connected if roaming forbidden */ + if (MM_IS_BEARER_3GPP (bearer) && + (!*roaming_network || + mm_bearer_3gpp_get_allow_roaming (MM_BEARER_3GPP (bearer)))) mm_bearer_set_connection_allowed (bearer); } static void -bearer_3gpp_connection_allowed (MMIfaceModem3gpp *self) +bearer_3gpp_connection_allowed (MMIfaceModem3gpp *self, + gboolean roaming_network) { MMBearerList *bearer_list = NULL; @@ -431,7 +526,7 @@ bearer_3gpp_connection_allowed (MMIfaceModem3gpp *self) /* Once registered, allow 3GPP bearers to get connected */ mm_bearer_list_foreach (bearer_list, (MMBearerListForeachFunc)set_bearer_3gpp_connection_allowed, - NULL); + &roaming_network); g_object_unref (bearer_list); } @@ -505,16 +600,13 @@ mm_iface_modem_3gpp_update_registration_state (MMIfaceModem3gpp *self, MM_IFACE_MODEM_3GPP_REGISTRATION_STATE, new_state, NULL); - /* TODO: - * If we're connected and we're not supposed to roam, but the device - * just roamed, disconnect the connection to avoid charging the user - * loads of money. - */ switch (new_state) { case MM_MODEM_3GPP_REGISTRATION_STATE_HOME: case MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING: /* Allow connection in 3GPP bearers */ - bearer_3gpp_connection_allowed (self); + bearer_3gpp_connection_allowed ( + self, + new_state == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING); /* Launch operator code update */ if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_operator_code && @@ -541,15 +633,8 @@ mm_iface_modem_3gpp_update_registration_state (MMIfaceModem3gpp *self, MM_MODEM_STATE_REGISTERED, MM_MODEM_STATE_REASON_NONE); break; + case MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING: - mm_iface_modem_update_access_tech (MM_IFACE_MODEM (self), - 0, - ALL_3GPP_ACCESS_TECHNOLOGIES_MASK); - bearer_3gpp_connection_forbidden (self); - mm_iface_modem_update_state (MM_IFACE_MODEM (self), - MM_MODEM_STATE_SEARCHING, - MM_MODEM_STATE_REASON_NONE); - break; case MM_MODEM_3GPP_REGISTRATION_STATE_IDLE: case MM_MODEM_3GPP_REGISTRATION_STATE_DENIED: case MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN: @@ -557,9 +642,12 @@ mm_iface_modem_3gpp_update_registration_state (MMIfaceModem3gpp *self, 0, ALL_3GPP_ACCESS_TECHNOLOGIES_MASK); bearer_3gpp_connection_forbidden (self); - mm_iface_modem_update_state (MM_IFACE_MODEM (self), - MM_MODEM_STATE_ENABLED, - MM_MODEM_STATE_REASON_NONE); + mm_iface_modem_update_state ( + MM_IFACE_MODEM (self), + (new_state == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING ? + MM_MODEM_STATE_SEARCHING : + MM_MODEM_STATE_ENABLED), + MM_MODEM_STATE_REASON_NONE); break; } } diff --git a/src/mm-iface-modem-3gpp.h b/src/mm-iface-modem-3gpp.h index ccd225c1..2e5bdbe6 100644 --- a/src/mm-iface-modem-3gpp.h +++ b/src/mm-iface-modem-3gpp.h @@ -142,6 +142,12 @@ struct _MMIfaceModem3gpp { GList * (*scan_networks_finish) (MMIfaceModem3gpp *self, GAsyncResult *res, GError **error); + + /* Create 3GPP bearer */ + MMBearer * (* create_3gpp_bearer) (MMBaseModem *modem, + const gchar *apn, + const gchar *ip_type, + gboolean allow_roaming); }; GType mm_iface_modem_3gpp_get_type (void); @@ -190,4 +196,13 @@ gboolean mm_iface_modem_3gpp_run_all_registration_checks_finish (MMIfaceModem3gp GAsyncResult *res, GError **error); +/* Create new 3GPP bearer */ +MMBearer *mm_iface_modem_3gpp_create_bearer (MMIfaceModem3gpp *self, + const gchar *apn, + const gchar *ip_type, + gboolean allow_roaming); +MMBearer *mm_iface_modem_3gpp_create_bearer_from_properties (MMIfaceModem3gpp *self, + GVariant *properties, + GError **error); + #endif /* MM_IFACE_MODEM_3GPP_H */ |