summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPekka Pessi <Pekka.Pessi@nokia.com>2010-10-20 16:32:21 +0300
committerPekka Pessi <Pekka.Pessi@nokia.com>2010-10-21 15:55:43 +0300
commit60b093c80138b84baf7782cd1f2ed34b83cda7d4 (patch)
treee1382942945374ede63408a67cadff63be9361e2
parenteada2e29386067f68463a6d22f3be536e4188e26 (diff)
Added RingProtocol implementation.
New connections are created through a Protocol object. Connection parameters are also parsed to an asv hash instead of a private structure.
-rw-r--r--src/Makefile.am1
-rw-r--r--src/ring-connection-manager.c51
-rw-r--r--src/ring-connection.c172
-rw-r--r--src/ring-connection.h7
-rw-r--r--src/ring-protocol.c137
-rw-r--r--src/ring-protocol.h73
6 files changed, 297 insertions, 144 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index e27f9f8..07ca91b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -45,6 +45,7 @@ test_ring_LDADD = \
libtpring_la_SOURCES = \
ring-connection-manager.h ring-connection-manager.c \
+ ring-protocol.h ring-protocol.c \
ring-connection.h ring-connection.c \
ring-debug.h ring-debug.c \
ring-text-manager.h ring-text-manager.c \
diff --git a/src/ring-connection-manager.c b/src/ring-connection-manager.c
index 5b25c8f..c6960d4 100644
--- a/src/ring-connection-manager.c
+++ b/src/ring-connection-manager.c
@@ -40,6 +40,7 @@
#include "ring-connection-manager.h"
#include "ring-connection.h"
+#include "ring-protocol.h"
#include "modem/service.h"
@@ -68,46 +69,34 @@ ring_connection_manager_init(RingConnectionManager *self)
modem_service_refresh (modem_service ());
}
-static TpCMProtocolSpec ring_protocols[] = {
- {
- "tel",
- NULL, /* filled in in ring_connection_manager_class_init() */
- ring_connection_params_alloc,
- ring_connection_params_free
- },
- { NULL, NULL }
-};
-
-static TpBaseConnection *
-new_connection(TpBaseConnectionManager *base,
- const char *proto,
- TpIntSet *params_present,
- gpointer parsed_params,
- GError **error)
+static void
+ring_connection_manager_constructed (GObject *obj)
{
- if (strcmp(proto, "tel")) {
- g_set_error(error, TP_ERRORS,
- TP_ERROR_INVALID_ARGUMENT, "Protocol is not supported");
- return NULL;
- }
-
- if (dbus_g_bus_get(DBUS_BUS_SYSTEM, error) == NULL)
- return NULL;
-
- return (TpBaseConnection *)ring_connection_new(params_present, parsed_params);
+ RingConnectionManager *self = RING_CONNECTION_MANAGER (obj);
+ TpBaseConnectionManager *base = (TpBaseConnectionManager *) self;
+ GObjectClass *base_class = (GObjectClass *)
+ ring_connection_manager_parent_class;
+ RingProtocol *protocol;
+
+ if (base_class->constructed)
+ base_class->constructed (obj);
+
+ protocol = ring_protocol_new ();
+ tp_base_connection_manager_add_protocol (base, TP_BASE_PROTOCOL (protocol));
+ g_object_unref (protocol);
}
static void
ring_connection_manager_class_init(RingConnectionManagerClass *klass)
{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
TpBaseConnectionManagerClass *parent_class = &klass->parent_class;
- g_type_class_add_private (klass,
- sizeof (RingConnectionManagerPrivate));
+ g_type_class_add_private (klass, sizeof (RingConnectionManagerPrivate));
- ring_protocols[0].parameters = ring_connection_get_param_specs();
+ object_class->constructed = ring_connection_manager_constructed;
- parent_class->new_connection = new_connection;
+ parent_class->new_connection = NULL;
parent_class->cm_dbus_name = "ring";
- parent_class->protocol_params = ring_protocols;
+ parent_class->protocol_params = NULL;
}
diff --git a/src/ring-connection.c b/src/ring-connection.c
index 056c9e8..94852f2 100644
--- a/src/ring-connection.c
+++ b/src/ring-connection.c
@@ -136,8 +136,8 @@ static char const ring_self_handle_name[] = "<SelfHandle>";
/* ---------------------------------------------------------------------- */
/* GObject interface */
-G_DEFINE_TYPE_WITH_CODE(
- RingConnection, ring_connection, TP_TYPE_BASE_CONNECTION,
+G_DEFINE_TYPE_WITH_CODE (RingConnection,
+ ring_connection, TP_TYPE_BASE_CONNECTION,
G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_DBUS_PROPERTIES,
tp_dbus_properties_mixin_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACTS,
@@ -412,7 +412,7 @@ ring_connection_class_init(RingConnectionClass *ring_connection_class)
"Modem path",
"oFono object path of the modem to use",
DBUS_TYPE_G_OBJECT_PATH,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property(
@@ -506,58 +506,6 @@ ring_connection_dbus_property_interfaces[] = {
/* ------------------------------------------------------------------------- */
-typedef struct {
- char *imsi; /* Internation Mobile Subscriber Identifier */
- char *sms_service_centre; /* SMS Service Center address */
- guint sms_validity_period; /* SMS validity period, 0 if default */
- gboolean sms_reduced_charset; /* SMS reduced character set support */
-
- gboolean anon_mandatory; /* Whether anonymity modes are mandatory */
- guint anon_modes; /* Required anonymity mode */
-
- gchar *modem; /* Object path of the modem to use; NULL to
- * pick one arbitrarily.
- */
-
- /* Deprecated */
- char *account; /* Ignored */
- char *password; /* Ignored */
-} RingConnectionParams;
-
-#if nomore
-/**
- * param_filter_tokens:
- * @paramspec: The parameter specification for a string parameter
- * @value: A GValue containing a string, which will not be altered
- * @error: Used to return an error if the string has non-empty value
- * that does not match filter_data
- *
- * A #TpCMParamFilter which rejects empty strings.
- *
- * Returns: %TRUE to accept, %FALSE (with @error set) to reject
- */
-static gboolean
-param_filter_tokens(TpCMParamSpec const *paramspec,
- GValue *value,
- GError **error)
-{
- const char * const *values;
- const char *str = g_value_get_string(value);
-
- if (str == NULL || str[0] == '\0')
- return TRUE;
-
- for (values = paramspec->filter_data; *values; values++)
- if (strcmp(str, *values) == 0)
- return TRUE;
-
- g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
- "Account parameter '%s' with invalid value",
- paramspec->name);
- return FALSE;
-}
-#endif
-
/* Validate ISDN number */
static gboolean
param_filter_isdn(TpCMParamSpec const *paramspec,
@@ -652,8 +600,6 @@ TpCMParamSpec ring_connection_params[] = {
DBUS_TYPE_STRING_AS_STRING, G_TYPE_STRING,
TP_CONN_MGR_PARAM_FLAG_DBUS_PROPERTY,
"",
- G_STRUCT_OFFSET(RingConnectionParams, imsi),
- NULL,
},
#define CELLULAR_SMS_VALIDITY_PERIOD_PARAM_SPEC (ring_connection_params + 1)
@@ -661,8 +607,9 @@ TpCMParamSpec ring_connection_params[] = {
DBUS_TYPE_UINT32_AS_STRING, G_TYPE_UINT,
TP_CONN_MGR_PARAM_FLAG_DBUS_PROPERTY,
GUINT_TO_POINTER(0),
- G_STRUCT_OFFSET(RingConnectionParams, sms_validity_period),
+ 0,
param_filter_validity,
+ .setter_data = "sms-validity-period",
},
#define CELLULAR_SMS_SERVICE_CENTRE_PARAM_SPEC (ring_connection_params + 2)
@@ -670,8 +617,9 @@ TpCMParamSpec ring_connection_params[] = {
DBUS_TYPE_STRING_AS_STRING, G_TYPE_STRING,
TP_CONN_MGR_PARAM_FLAG_DBUS_PROPERTY,
"",
- G_STRUCT_OFFSET(RingConnectionParams, sms_service_centre),
+ 0,
param_filter_isdn,
+ .setter_data = "sms-service-centre",
},
#define CELLULAR_SMS_REDUCED_CHARSET_PARAM_SPEC (ring_connection_params + 3)
@@ -679,24 +627,25 @@ TpCMParamSpec ring_connection_params[] = {
DBUS_TYPE_BOOLEAN_AS_STRING, G_TYPE_BOOLEAN,
TP_CONN_MGR_PARAM_FLAG_DBUS_PROPERTY,
GUINT_TO_POINTER(0),
- G_STRUCT_OFFSET(RingConnectionParams, sms_reduced_charset),
+ 0,
NULL,
+ .setter_data = "sms-validity-period",
},
{ TP_IFACE_CONNECTION_INTERFACE_ANONYMITY ".AnonymityMandatory",
DBUS_TYPE_BOOLEAN_AS_STRING, G_TYPE_BOOLEAN,
TP_CONN_MGR_PARAM_FLAG_DBUS_PROPERTY,
GUINT_TO_POINTER(FALSE),
- G_STRUCT_OFFSET(RingConnectionParams, anon_mandatory),
- NULL,
+ .setter_data = "anon-mandatory",
},
{ TP_IFACE_CONNECTION_INTERFACE_ANONYMITY ".AnonymityModes",
DBUS_TYPE_UINT32_AS_STRING, G_TYPE_UINT,
TP_CONN_MGR_PARAM_FLAG_DBUS_PROPERTY,
GUINT_TO_POINTER(0),
- G_STRUCT_OFFSET(RingConnectionParams, anon_modes),
+ 0,
param_filter_anon_modes,
+ .setter_data = "anon-supported-modes",
},
#define MODEM_PARAM_SPEC (ring_connection_params + 6)
@@ -708,19 +657,16 @@ TpCMParamSpec ring_connection_params[] = {
(GType) 0,
0,
NULL,
- G_STRUCT_OFFSET(RingConnectionParams, modem),
+ 0,
param_filter_valid_object_path,
+ .setter_data = "modem-path",
},
/* Deprecated... */
- { "account", DBUS_TYPE_STRING_AS_STRING, G_TYPE_STRING,
- 0, NULL,
- G_STRUCT_OFFSET (RingConnectionParams, account),
- },
+ { "account", DBUS_TYPE_STRING_AS_STRING, G_TYPE_STRING, },
{ "password", DBUS_TYPE_STRING_AS_STRING, G_TYPE_STRING,
- TP_CONN_MGR_PARAM_FLAG_SECRET, NULL,
- G_STRUCT_OFFSET (RingConnectionParams, password),
+ TP_CONN_MGR_PARAM_FLAG_SECRET,
},
{ NULL }
@@ -729,47 +675,38 @@ TpCMParamSpec ring_connection_params[] = {
TpCMParamSpec *
ring_connection_get_param_specs (void)
{
- TpCMParamSpec *modem = MODEM_PARAM_SPEC;
+ static gsize once;
+
+ if (g_once_init_enter (&once))
+ {
+ TpCMParamSpec *modem = MODEM_PARAM_SPEC;
- modem->gtype = DBUS_TYPE_G_OBJECT_PATH;
+ modem->gtype = DBUS_TYPE_G_OBJECT_PATH;
+
+ g_once_init_leave (&once, 1);
+ }
return ring_connection_params;
}
-gpointer
-ring_connection_params_alloc(void)
+RingConnection *
+ring_connection_new(GHashTable *params)
{
- return g_slice_new0(RingConnectionParams);
-}
+ gpointer conn = g_object_new(RING_TYPE_CONNECTION, "protocol", "tel", NULL);
+ guint i;
+ GValue *value;
+ TpCMParamSpec *specs = ring_connection_get_param_specs ();
-void
-ring_connection_params_free(gpointer p)
-{
- RingConnectionParams *params = p;
+ for (i = 0; specs[i].name; i++) {
+ if (!specs[i].setter_data)
+ continue;
- g_free(params->modem);
- g_free(params->account);
- g_free(params->password);
+ value = g_hash_table_lookup(params, specs[i].name);
+ if (value)
+ g_object_set_property (conn, specs[i].setter_data, value);
+ }
- g_slice_free(RingConnectionParams, params);
-}
-
-RingConnection *
-ring_connection_new(TpIntSet *params_present,
- gpointer parsed_params)
-{
- RingConnectionParams *params = parsed_params;
- char *sms_service_centre = params->sms_service_centre;
-
- return (RingConnection *) g_object_new(RING_TYPE_CONNECTION,
- "protocol", "tel",
- "modem-path", params->modem,
- "sms-service-centre", sms_service_centre ? sms_service_centre : "",
- "sms-validity-period", params->sms_validity_period,
- "sms-reduced-charset", params->sms_reduced_charset,
- "anon-modes", params->anon_modes,
- "anon-mandatory", params->anon_mandatory,
- NULL);
+ return conn;
}
@@ -789,14 +726,12 @@ gpointer ring_network_normalization_context(void)
* international phone number ("'+' and up to 20 digits), SOS URN or
* an alphanumeric address with up to 11 GSM characters.
*
- * Normalize a telephone number can contain an an optional service prefix
+ * Normalized telephone number can contain an an optional service prefix
* and dial string.
*/
-static char *
-ring_normalize_name(TpHandleRepoIface *repo,
- char const *input,
- gpointer context,
- GError **return_error)
+char *
+ring_normalize_contact (char const *input,
+ GError **return_error)
{
char const *sos;
char *s;
@@ -817,9 +752,6 @@ ring_normalize_name(TpHandleRepoIface *repo,
s = g_strdup(input);
- if (context == ring_network_normalization_context())
- return s;
-
/* Remove usual extra chars like (-. ) */
for (i = j = 0; s[i]; i++) {
switch (s[i]) {
@@ -851,6 +783,18 @@ ring_normalize_name(TpHandleRepoIface *repo,
return NULL;
}
+static char *
+ring_normalize_name (TpHandleRepoIface *repo G_GNUC_UNUSED,
+ char const *input,
+ gpointer context,
+ GError **return_error)
+{
+ if (context == ring_network_normalization_context ())
+ return g_strdup (input);
+
+ return ring_normalize_contact (input, return_error);
+}
+
static void
ring_connection_create_handle_repos(TpBaseConnection *base,
TpHandleRepoIface *repos[NUM_TP_HANDLE_TYPES])
@@ -1065,6 +1009,12 @@ ring_connection_class_init_base_connection(TpBaseConnectionClass *klass)
/* ---------------------------------------------------------------------- */
/* RingConnection interface */
+gchar **
+ring_connection_dup_implemented_interfaces (void)
+{
+ return g_strdupv ((GStrv)ring_connection_interfaces_always_present);
+}
+
static gboolean
ring_connection_connecting_timeout (gpointer _self)
{
diff --git a/src/ring-connection.h b/src/ring-connection.h
index 55a3f93..6b0c2ca 100644
--- a/src/ring-connection.h
+++ b/src/ring-connection.h
@@ -69,8 +69,11 @@ TpCMParamSpec *ring_connection_get_param_specs (void);
gpointer ring_connection_params_alloc(void);
void ring_connection_params_free(gpointer p);
-RingConnection *ring_connection_new(
- TpIntSet *params_present, gpointer ring_connection_params);
+gchar **ring_connection_dup_implemented_interfaces (void);
+
+char *ring_normalize_contact (char const *input, GError **return_error);
+
+RingConnection *ring_connection_new(GHashTable *params);
gboolean ring_connection_check_status(RingConnection *self);
diff --git a/src/ring-protocol.c b/src/ring-protocol.c
new file mode 100644
index 0000000..07d390c
--- /dev/null
+++ b/src/ring-protocol.c
@@ -0,0 +1,137 @@
+/*
+ * ring-protocol.c - source for RingProtocol
+ * Copyright (C) 2007-2010 Collabora Ltd.
+ * Copyright (C) 2007-2010 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "ring-protocol.h"
+
+#include <telepathy-glib/base-connection-manager.h>
+#include <telepathy-glib/dbus.h>
+#include <dbus/dbus-protocol.h>
+#include <dbus/dbus-glib.h>
+
+#include "ring-connection.h"
+#include "ring-media-manager.h"
+#include "ring-text-manager.h"
+
+#define NAME "tel"
+#define ICON_NAME "im-tel"
+#define VCARD_FIELD_NAME "TEL"
+#define ENGLISH_NAME "Mobile Telephony"
+
+G_DEFINE_TYPE (RingProtocol, ring_protocol, TP_TYPE_BASE_PROTOCOL)
+
+static void
+ring_protocol_init (RingProtocol *self)
+{
+}
+
+static const TpCMParamSpec *
+get_parameters (TpBaseProtocol *self G_GNUC_UNUSED)
+{
+ return ring_connection_get_param_specs ();
+}
+
+static TpBaseConnection *
+new_connection (TpBaseProtocol *protocol G_GNUC_UNUSED,
+ GHashTable *params,
+ GError **error)
+{
+ if (dbus_g_bus_get (DBUS_BUS_SYSTEM, error) == NULL)
+ return NULL;
+
+ return TP_BASE_CONNECTION (ring_connection_new (params));
+}
+
+static gchar *
+normalize_contact (TpBaseProtocol *self G_GNUC_UNUSED,
+ const gchar *contact,
+ GError **error)
+{
+ return ring_normalize_contact (contact, error);
+}
+
+static gchar *
+identify_account (TpBaseProtocol *self G_GNUC_UNUSED,
+ GHashTable *asv,
+ GError **error)
+{
+ const gchar *account = tp_asv_get_string (asv, "account");
+
+ g_assert (account != NULL);
+
+ return g_strdup (account);
+}
+
+static GStrv
+get_interfaces (TpBaseProtocol *self)
+{
+ return g_new0 (gchar *, 1);
+}
+
+static void
+get_connection_details (TpBaseProtocol *self,
+ GStrv *connection_interfaces,
+ GType **channel_managers,
+ gchar **icon_name,
+ gchar **english_name,
+ gchar **vcard_field)
+{
+ if (connection_interfaces)
+ *connection_interfaces = ring_connection_dup_implemented_interfaces ();
+
+ if (channel_managers)
+ {
+ GType types[] = {
+ RING_TYPE_TEXT_MANAGER,
+ RING_TYPE_MEDIA_MANAGER,
+ G_TYPE_INVALID
+ };
+
+ *channel_managers = g_memdup (types, sizeof(types));
+ }
+
+ if (icon_name)
+ *icon_name = g_strdup (ICON_NAME);
+
+ if (english_name)
+ *english_name = g_strdup (ENGLISH_NAME);
+
+ if (vcard_field)
+ *vcard_field = g_strdup (VCARD_FIELD_NAME);
+}
+
+static void
+ring_protocol_class_init (RingProtocolClass *klass)
+{
+ TpBaseProtocolClass *base_class = (TpBaseProtocolClass *) klass;
+
+ base_class->get_parameters = get_parameters;
+ base_class->new_connection = new_connection;
+ base_class->normalize_contact = normalize_contact;
+ base_class->identify_account = identify_account;
+ base_class->get_interfaces = get_interfaces;
+ base_class->get_connection_details = get_connection_details;
+}
+
+RingProtocol *
+ring_protocol_new (void)
+{
+ return g_object_new (RING_TYPE_PROTOCOL, "name", NAME, NULL);
+}
+
diff --git a/src/ring-protocol.h b/src/ring-protocol.h
new file mode 100644
index 0000000..a16e5a2
--- /dev/null
+++ b/src/ring-protocol.h
@@ -0,0 +1,73 @@
+/*
+ * protocol.h - header for RingProtocol
+ * Copyright (C) 2007-2010 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef RING_PROTOCOL_H
+#define RING_PROTOCOL_H
+
+#include <glib-object.h>
+#include <telepathy-glib/base-protocol.h>
+
+G_BEGIN_DECLS
+
+typedef struct _RingProtocol
+ RingProtocol;
+typedef struct _RingProtocolPrivate
+ RingProtocolPrivate;
+typedef struct _RingProtocolClass
+ RingProtocolClass;
+typedef struct _RingProtocolClassPrivate
+ RingProtocolClassPrivate;
+
+struct _RingProtocolClass {
+ TpBaseProtocolClass parent_class;
+
+ RingProtocolClassPrivate *priv;
+};
+
+struct _RingProtocol {
+ TpBaseProtocol parent;
+
+ RingProtocolPrivate *priv;
+};
+
+GType ring_protocol_get_type (void);
+
+#define RING_TYPE_PROTOCOL \
+ (ring_protocol_get_type ())
+#define RING_PROTOCOL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ RING_TYPE_PROTOCOL, \
+ RingProtocol))
+#define RING_PROTOCOL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ RING_TYPE_PROTOCOL, \
+ RingProtocolClass))
+#define IS_RING_PROTOCOL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ RING_TYPE_PROTOCOL))
+#define RING_PROTOCOL_GET_CLASS(klass) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ RING_TYPE_PROTOCOL, \
+ RingProtocolClass))
+
+RingProtocol *ring_protocol_new (void);
+
+G_END_DECLS
+
+#endif