bearer: keep properties given as input, and avoid async creation
No need to create this object asynchronously.
This commit is contained in:
+214
-62
@@ -36,17 +36,19 @@
|
||||
#include "mm-log.h"
|
||||
#include "mm-modem-helpers.h"
|
||||
|
||||
static void async_initable_iface_init (GAsyncInitableIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (MMBearer, mm_bearer, MM_GDBUS_TYPE_BEARER_SKELETON, 0,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE,
|
||||
async_initable_iface_init));
|
||||
G_DEFINE_TYPE (MMBearer, mm_bearer, MM_GDBUS_TYPE_BEARER_SKELETON);
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_PATH,
|
||||
PROP_CONNECTION,
|
||||
PROP_MODEM,
|
||||
PROP_CAPABILITY,
|
||||
PROP_CONNECTION_APN,
|
||||
PROP_CONNECTION_IP_TYPE,
|
||||
PROP_CONNECTION_USER,
|
||||
PROP_CONNECTION_PASSWORD,
|
||||
PROP_CONNECTION_NUMBER,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
@@ -59,6 +61,15 @@ struct _MMBearerPrivate {
|
||||
MMBaseModem *modem;
|
||||
/* The path where the BEARER object is exported */
|
||||
gchar *path;
|
||||
/* Capability of this bearer */
|
||||
MMModemCapability capability;
|
||||
|
||||
/* Input properties configured */
|
||||
gchar *connection_apn;
|
||||
gchar *connection_ip_type;
|
||||
gchar *connection_user;
|
||||
gchar *connection_password;
|
||||
gchar *connection_number;
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -119,67 +130,119 @@ mm_bearer_unexport (MMBearer *self)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
MMBearer *
|
||||
mm_bearer_new_finish (GAsyncInitable *initable,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
return MM_BEARER (g_async_initable_new_finish (initable, res, error));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
initable_init_finish (GAsyncInitable *initable,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
parse_input_properties (MMBearer *bearer,
|
||||
MMModemCapability bearer_capability,
|
||||
GVariant *properties,
|
||||
GError **error)
|
||||
{
|
||||
return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
|
||||
GVariantIter iter;
|
||||
gchar *key;
|
||||
gchar *value;
|
||||
|
||||
g_variant_iter_init (&iter, properties);
|
||||
while (g_variant_iter_loop (&iter, "{ss}", &key, &value)) {
|
||||
gchar *previous = NULL;
|
||||
|
||||
g_object_get (G_OBJECT (bearer),
|
||||
key, &previous,
|
||||
NULL);
|
||||
|
||||
if (previous) {
|
||||
if (g_str_equal (previous, value)) {
|
||||
/* no big deal */
|
||||
g_free (previous);
|
||||
continue;
|
||||
}
|
||||
|
||||
g_free (previous);
|
||||
g_set_error (error,
|
||||
MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_INVALID_ARGS,
|
||||
"Invalid input properties: duplicated key '%s'",
|
||||
key);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_object_set (G_OBJECT (bearer),
|
||||
key, value,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* Check mandatory properties for each capability */
|
||||
#define CHECK_MANDATORY_PROPERTY(NAME, PROPERTY) do \
|
||||
{ \
|
||||
gchar *value; \
|
||||
\
|
||||
g_object_get (G_OBJECT (bearer), \
|
||||
PROPERTY, &value, \
|
||||
NULL); \
|
||||
if (!value) { \
|
||||
g_set_error (error, \
|
||||
MM_CORE_ERROR, \
|
||||
MM_CORE_ERROR_INVALID_ARGS, \
|
||||
"Invalid input properties: %s bearer requires '%s'", \
|
||||
NAME, \
|
||||
PROPERTY); \
|
||||
return FALSE; \
|
||||
} \
|
||||
g_free (value); \
|
||||
} while (0)
|
||||
|
||||
/* POTS bearer? */
|
||||
if (bearer_capability & MM_MODEM_CAPABILITY_POTS) {
|
||||
CHECK_MANDATORY_PROPERTY ("POTS", MM_BEARER_CONNECTION_NUMBER);
|
||||
}
|
||||
/* CDMA bearer? */
|
||||
else if (bearer_capability & MM_MODEM_CAPABILITY_CDMA_EVDO) {
|
||||
/* No mandatory properties here */
|
||||
}
|
||||
/* 3GPP bearer? */
|
||||
else {
|
||||
CHECK_MANDATORY_PROPERTY ("3GPP", MM_BEARER_CONNECTION_APN);
|
||||
}
|
||||
|
||||
#undef CHECK_MANDATORY_PROPERTY
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
initable_init_async (GAsyncInitable *initable,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSimpleAsyncResult *result;
|
||||
|
||||
/* Set defaults */
|
||||
mm_gdbus_bearer_set_interface (MM_GDBUS_BEARER (initable), NULL);
|
||||
mm_gdbus_bearer_set_connected (MM_GDBUS_BEARER (initable), FALSE);
|
||||
mm_gdbus_bearer_set_suspended (MM_GDBUS_BEARER (initable), FALSE);
|
||||
mm_gdbus_bearer_set_ip4_config (MM_GDBUS_BEARER (initable), NULL);
|
||||
mm_gdbus_bearer_set_ip6_config (MM_GDBUS_BEARER (initable), NULL);
|
||||
/* Complete */
|
||||
result = g_simple_async_result_new (G_OBJECT (initable),
|
||||
callback,
|
||||
user_data,
|
||||
initable_init_async);
|
||||
g_simple_async_result_set_op_res_gboolean (result, TRUE);
|
||||
g_simple_async_result_complete_in_idle (result);
|
||||
g_object_unref (result);
|
||||
}
|
||||
|
||||
void
|
||||
MMBearer *
|
||||
mm_bearer_new (MMBaseModem *modem,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
GVariant *properties,
|
||||
MMModemCapability capability,
|
||||
GError **error)
|
||||
{
|
||||
gchar *path;
|
||||
static guint32 id = 0;
|
||||
gchar *path;
|
||||
MMBearer *bearer;
|
||||
|
||||
/* Ensure only one capability is set */
|
||||
g_assert_cmpuint (mm_count_bits_set (capability), ==, 1);
|
||||
|
||||
/* Build the unique path for the Bearer, and create the object */
|
||||
path = g_strdup_printf (MM_DBUS_PATH"/Bearers/%d", id++);
|
||||
g_async_initable_new_async (MM_TYPE_BEARER,
|
||||
G_PRIORITY_DEFAULT,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data,
|
||||
MM_BEARER_PATH, path,
|
||||
MM_BEARER_MODEM, modem,
|
||||
NULL);
|
||||
bearer = g_object_new (MM_TYPE_BEARER,
|
||||
MM_BEARER_PATH, path,
|
||||
MM_BEARER_MODEM, modem,
|
||||
MM_BEARER_CAPABILITY, capability,
|
||||
NULL);
|
||||
g_free (path);
|
||||
|
||||
/* Parse and set input properties */
|
||||
if (!parse_input_properties (bearer, capability, properties, error)) {
|
||||
g_object_unref (bearer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set defaults */
|
||||
mm_gdbus_bearer_set_interface (MM_GDBUS_BEARER (bearer), NULL);
|
||||
mm_gdbus_bearer_set_connected (MM_GDBUS_BEARER (bearer), FALSE);
|
||||
mm_gdbus_bearer_set_suspended (MM_GDBUS_BEARER (bearer), FALSE);
|
||||
mm_gdbus_bearer_set_ip4_config (MM_GDBUS_BEARER (bearer), NULL);
|
||||
mm_gdbus_bearer_set_ip6_config (MM_GDBUS_BEARER (bearer), NULL);
|
||||
|
||||
return bearer;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -218,6 +281,29 @@ set_property (GObject *object,
|
||||
G_BINDING_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case PROP_CAPABILITY:
|
||||
self->priv->capability = g_value_get_flags (value);
|
||||
break;
|
||||
case PROP_CONNECTION_APN:
|
||||
g_free (self->priv->connection_apn);
|
||||
self->priv->connection_apn = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_CONNECTION_IP_TYPE:
|
||||
g_free (self->priv->connection_ip_type);
|
||||
self->priv->connection_ip_type = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_CONNECTION_USER:
|
||||
g_free (self->priv->connection_user);
|
||||
self->priv->connection_user = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_CONNECTION_PASSWORD:
|
||||
g_free (self->priv->connection_password);
|
||||
self->priv->connection_password = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_CONNECTION_NUMBER:
|
||||
g_free (self->priv->connection_number);
|
||||
self->priv->connection_number = g_value_dup_string (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -242,6 +328,24 @@ get_property (GObject *object,
|
||||
case PROP_MODEM:
|
||||
g_value_set_object (value, self->priv->modem);
|
||||
break;
|
||||
case PROP_CAPABILITY:
|
||||
g_value_set_flags (value, self->priv->capability);
|
||||
break;
|
||||
case PROP_CONNECTION_APN:
|
||||
g_value_set_string (value, self->priv->connection_apn);
|
||||
break;
|
||||
case PROP_CONNECTION_IP_TYPE:
|
||||
g_value_set_string (value, self->priv->connection_ip_type);
|
||||
break;
|
||||
case PROP_CONNECTION_USER:
|
||||
g_value_set_string (value, self->priv->connection_user);
|
||||
break;
|
||||
case PROP_CONNECTION_PASSWORD:
|
||||
g_value_set_string (value, self->priv->connection_password);
|
||||
break;
|
||||
case PROP_CONNECTION_NUMBER:
|
||||
g_value_set_string (value, self->priv->connection_number);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -264,6 +368,12 @@ finalize (GObject *object)
|
||||
|
||||
g_free (self->priv->path);
|
||||
|
||||
g_free (self->priv->connection_apn);
|
||||
g_free (self->priv->connection_ip_type);
|
||||
g_free (self->priv->connection_user);
|
||||
g_free (self->priv->connection_password);
|
||||
g_free (self->priv->connection_number);
|
||||
|
||||
G_OBJECT_CLASS (mm_bearer_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@@ -281,13 +391,6 @@ dispose (GObject *object)
|
||||
G_OBJECT_CLASS (mm_bearer_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
async_initable_iface_init (GAsyncInitableIface *iface)
|
||||
{
|
||||
iface->init_async = initable_init_async;
|
||||
iface->init_finish = initable_init_finish;
|
||||
}
|
||||
|
||||
static void
|
||||
mm_bearer_class_init (MMBearerClass *klass)
|
||||
{
|
||||
@@ -324,4 +427,53 @@ mm_bearer_class_init (MMBearerClass *klass)
|
||||
MM_TYPE_BASE_MODEM,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (object_class, PROP_MODEM, properties[PROP_MODEM]);
|
||||
|
||||
properties[PROP_CAPABILITY] =
|
||||
g_param_spec_flags (MM_BEARER_CAPABILITY,
|
||||
"Capability",
|
||||
"The Capability supported by this Bearer",
|
||||
MM_TYPE_MODEM_CAPABILITY,
|
||||
MM_MODEM_CAPABILITY_NONE,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (object_class, PROP_CAPABILITY, properties[PROP_CAPABILITY]);
|
||||
|
||||
properties[PROP_CONNECTION_APN] =
|
||||
g_param_spec_string (MM_BEARER_CONNECTION_APN,
|
||||
"Connection APN",
|
||||
"Access Point Name to use in the connection",
|
||||
NULL,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (object_class, PROP_CONNECTION_APN, properties[PROP_CONNECTION_APN]);
|
||||
|
||||
properties[PROP_CONNECTION_IP_TYPE] =
|
||||
g_param_spec_string (MM_BEARER_CONNECTION_IP_TYPE,
|
||||
"Connection IP type",
|
||||
"IP setup to use in the connection",
|
||||
NULL,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (object_class, PROP_CONNECTION_IP_TYPE, properties[PROP_CONNECTION_IP_TYPE]);
|
||||
|
||||
properties[PROP_CONNECTION_USER] =
|
||||
g_param_spec_string (MM_BEARER_CONNECTION_USER,
|
||||
"Connection User",
|
||||
"User to use in the connection",
|
||||
NULL,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (object_class, PROP_CONNECTION_USER, properties[PROP_CONNECTION_USER]);
|
||||
|
||||
properties[PROP_CONNECTION_PASSWORD] =
|
||||
g_param_spec_string (MM_BEARER_CONNECTION_PASSWORD,
|
||||
"Connection Password",
|
||||
"Password to use in the connection",
|
||||
NULL,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (object_class, PROP_CONNECTION_PASSWORD, properties[PROP_CONNECTION_PASSWORD]);
|
||||
|
||||
properties[PROP_CONNECTION_NUMBER] =
|
||||
g_param_spec_string (MM_BEARER_CONNECTION_NUMBER,
|
||||
"Connection Number",
|
||||
"Number to use in the connection",
|
||||
NULL,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (object_class, PROP_CONNECTION_NUMBER, properties[PROP_CONNECTION_NUMBER]);
|
||||
}
|
||||
|
||||
+12
-7
@@ -38,6 +38,14 @@ typedef struct _MMBearerPrivate MMBearerPrivate;
|
||||
#define MM_BEARER_PATH "bearer-path"
|
||||
#define MM_BEARER_CONNECTION "bearer-connection"
|
||||
#define MM_BEARER_MODEM "bearer-modem"
|
||||
#define MM_BEARER_CAPABILITY "bearer-capability"
|
||||
|
||||
/* same names as the ones used in DBus properties */
|
||||
#define MM_BEARER_CONNECTION_APN "apn"
|
||||
#define MM_BEARER_CONNECTION_IP_TYPE "ip-type"
|
||||
#define MM_BEARER_CONNECTION_USER "user"
|
||||
#define MM_BEARER_CONNECTION_PASSWORD "password"
|
||||
#define MM_BEARER_CONNECTION_NUMBER "number"
|
||||
|
||||
struct _MMBearer {
|
||||
MmGdbusBearerSkeleton parent;
|
||||
@@ -50,12 +58,9 @@ struct _MMBearerClass {
|
||||
|
||||
GType mm_bearer_get_type (void);
|
||||
|
||||
void mm_bearer_new (MMBaseModem *modem,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
MMBearer *mm_bearer_new_finish (GAsyncInitable *initable,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
MMBearer *mm_bearer_new (MMBaseModem *modem,
|
||||
GVariant *properties,
|
||||
MMModemCapability capability,
|
||||
GError **error);
|
||||
|
||||
#endif /* MM_BEARER_H */
|
||||
|
||||
Reference in New Issue
Block a user