3gpp: control 3GPP bearer creation in the 3GPP modem interface
And implement bearer connection allowance based on roaming status.
This commit is contained in:
@@ -785,63 +785,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 *
|
MMBearer *
|
||||||
mm_bearer_3gpp_new (MMBaseModem *modem,
|
mm_bearer_3gpp_new (MMBaseModem *modem,
|
||||||
const gchar *apn,
|
const gchar *apn,
|
||||||
|
@@ -54,13 +54,11 @@ struct _MMBearer3gppClass {
|
|||||||
|
|
||||||
GType mm_bearer_3gpp_get_type (void);
|
GType mm_bearer_3gpp_get_type (void);
|
||||||
|
|
||||||
|
/* Default 3GPP bearer creation implementation */
|
||||||
MMBearer *mm_bearer_3gpp_new (MMBaseModem *modem,
|
MMBearer *mm_bearer_3gpp_new (MMBaseModem *modem,
|
||||||
const gchar *apn,
|
const gchar *apn,
|
||||||
const gchar *ip_type,
|
const gchar *ip_type,
|
||||||
gboolean allow_roaming);
|
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_apn (MMBearer3gpp *self);
|
||||||
const gchar *mm_bearer_3gpp_get_ip_type (MMBearer3gpp *self);
|
const gchar *mm_bearer_3gpp_get_ip_type (MMBearer3gpp *self);
|
||||||
|
@@ -108,7 +108,7 @@ modem_create_bearer (MMIfaceModem *self,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GSimpleAsyncResult *result;
|
GSimpleAsyncResult *result;
|
||||||
MMBearer *bearer;
|
MMBearer *bearer = NULL;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
/* TODO: We'll need to guess the capability of the bearer, based on the
|
/* 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 */
|
* configured in the modem. Use 3GPP for testing now */
|
||||||
|
|
||||||
/* New 3GPP bearer */
|
/* New 3GPP bearer */
|
||||||
{
|
if (MM_BROADBAND_MODEM (self)->priv->modem_3gpp_dbus_skeleton) {
|
||||||
MMModem3gppRegistrationState state;
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
bearer = mm_bearer_3gpp_new_from_properties (MM_BASE_MODEM (self),
|
if (!bearer) {
|
||||||
properties,
|
g_simple_async_report_take_gerror_in_idle (G_OBJECT (self),
|
||||||
&error);
|
callback,
|
||||||
if (!bearer) {
|
user_data,
|
||||||
g_simple_async_report_take_gerror_in_idle (G_OBJECT (self),
|
error);
|
||||||
callback,
|
|
||||||
user_data,
|
|
||||||
error);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set a new ref to the bearer object as result */
|
/* 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->register_in_network_finish = register_in_network_finish;
|
||||||
iface->scan_networks = scan_networks;
|
iface->scan_networks = scan_networks;
|
||||||
iface->scan_networks_finish = scan_networks_finish;
|
iface->scan_networks_finish = scan_networks_finish;
|
||||||
|
iface->create_3gpp_bearer = mm_bearer_3gpp_new;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@@ -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 {
|
typedef struct {
|
||||||
GSimpleAsyncResult *result;
|
GSimpleAsyncResult *result;
|
||||||
gboolean cs_done;
|
gboolean cs_done;
|
||||||
@@ -410,15 +501,19 @@ STR_REPLY_READY_FN (operator_code, "Operator Code")
|
|||||||
STR_REPLY_READY_FN (operator_name, "Operator Name")
|
STR_REPLY_READY_FN (operator_name, "Operator Name")
|
||||||
|
|
||||||
static void
|
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 */
|
/* Don't allow bearer to get connected if roaming forbidden */
|
||||||
if (MM_IS_BEARER_3GPP (bearer))
|
if (MM_IS_BEARER_3GPP (bearer) &&
|
||||||
|
(!*roaming_network ||
|
||||||
|
mm_bearer_3gpp_get_allow_roaming (MM_BEARER_3GPP (bearer))))
|
||||||
mm_bearer_set_connection_allowed (bearer);
|
mm_bearer_set_connection_allowed (bearer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bearer_3gpp_connection_allowed (MMIfaceModem3gpp *self)
|
bearer_3gpp_connection_allowed (MMIfaceModem3gpp *self,
|
||||||
|
gboolean roaming_network)
|
||||||
{
|
{
|
||||||
MMBearerList *bearer_list = NULL;
|
MMBearerList *bearer_list = NULL;
|
||||||
|
|
||||||
@@ -431,7 +526,7 @@ bearer_3gpp_connection_allowed (MMIfaceModem3gpp *self)
|
|||||||
/* Once registered, allow 3GPP bearers to get connected */
|
/* Once registered, allow 3GPP bearers to get connected */
|
||||||
mm_bearer_list_foreach (bearer_list,
|
mm_bearer_list_foreach (bearer_list,
|
||||||
(MMBearerListForeachFunc)set_bearer_3gpp_connection_allowed,
|
(MMBearerListForeachFunc)set_bearer_3gpp_connection_allowed,
|
||||||
NULL);
|
&roaming_network);
|
||||||
g_object_unref (bearer_list);
|
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,
|
MM_IFACE_MODEM_3GPP_REGISTRATION_STATE, new_state,
|
||||||
NULL);
|
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) {
|
switch (new_state) {
|
||||||
case MM_MODEM_3GPP_REGISTRATION_STATE_HOME:
|
case MM_MODEM_3GPP_REGISTRATION_STATE_HOME:
|
||||||
case MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING:
|
case MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING:
|
||||||
/* Allow connection in 3GPP bearers */
|
/* 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 */
|
/* Launch operator code update */
|
||||||
if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_operator_code &&
|
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_REGISTERED,
|
||||||
MM_MODEM_STATE_REASON_NONE);
|
MM_MODEM_STATE_REASON_NONE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING:
|
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_IDLE:
|
||||||
case MM_MODEM_3GPP_REGISTRATION_STATE_DENIED:
|
case MM_MODEM_3GPP_REGISTRATION_STATE_DENIED:
|
||||||
case MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN:
|
case MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN:
|
||||||
@@ -557,9 +642,12 @@ mm_iface_modem_3gpp_update_registration_state (MMIfaceModem3gpp *self,
|
|||||||
0,
|
0,
|
||||||
ALL_3GPP_ACCESS_TECHNOLOGIES_MASK);
|
ALL_3GPP_ACCESS_TECHNOLOGIES_MASK);
|
||||||
bearer_3gpp_connection_forbidden (self);
|
bearer_3gpp_connection_forbidden (self);
|
||||||
mm_iface_modem_update_state (MM_IFACE_MODEM (self),
|
mm_iface_modem_update_state (
|
||||||
MM_MODEM_STATE_ENABLED,
|
MM_IFACE_MODEM (self),
|
||||||
MM_MODEM_STATE_REASON_NONE);
|
(new_state == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING ?
|
||||||
|
MM_MODEM_STATE_SEARCHING :
|
||||||
|
MM_MODEM_STATE_ENABLED),
|
||||||
|
MM_MODEM_STATE_REASON_NONE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -142,6 +142,12 @@ struct _MMIfaceModem3gpp {
|
|||||||
GList * (*scan_networks_finish) (MMIfaceModem3gpp *self,
|
GList * (*scan_networks_finish) (MMIfaceModem3gpp *self,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
GError **error);
|
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);
|
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,
|
GAsyncResult *res,
|
||||||
GError **error);
|
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 */
|
#endif /* MM_IFACE_MODEM_3GPP_H */
|
||||||
|
Reference in New Issue
Block a user