diff options
author | Pekka Pessi <Pekka.Pessi@nokia.com> | 2010-10-20 16:32:21 +0300 |
---|---|---|
committer | Pekka Pessi <Pekka.Pessi@nokia.com> | 2010-10-21 15:55:43 +0300 |
commit | 60b093c80138b84baf7782cd1f2ed34b83cda7d4 (patch) | |
tree | e1382942945374ede63408a67cadff63be9361e2 | |
parent | eada2e29386067f68463a6d22f3be536e4188e26 (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.am | 1 | ||||
-rw-r--r-- | src/ring-connection-manager.c | 51 | ||||
-rw-r--r-- | src/ring-connection.c | 172 | ||||
-rw-r--r-- | src/ring-connection.h | 7 | ||||
-rw-r--r-- | src/ring-protocol.c | 137 | ||||
-rw-r--r-- | src/ring-protocol.h | 73 |
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 |