1 /* |
|
2 * gabble-connection-manager.c - Source for GabbleConnectionManager |
|
3 * Copyright (C) 2005 Collabora Ltd. |
|
4 * and/or its subsidiary/subsidiaries. All rights reserved. |
|
5 * |
|
6 * This library is free software; you can redistribute it and/or |
|
7 * modify it under the terms of the GNU Lesser General Public |
|
8 * License as published by the Free Software Foundation; either |
|
9 * version 2.1 of the License, or (at your option) any later version. |
|
10 * |
|
11 * This library is distributed in the hope that it will be useful, |
|
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 * Lesser General Public License for more details. |
|
15 * |
|
16 * You should have received a copy of the GNU Lesser General Public |
|
17 * License along with this library; if not, write to the Free Software |
|
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|
19 */ |
|
20 |
|
21 #include <dbus/dbus-glib.h> |
|
22 #include <dbus/dbus-protocol.h> |
|
23 #include <stdio.h> |
|
24 #include <stdlib.h> |
|
25 #include <string.h> |
|
26 |
|
27 #include "gabble-connection.h" |
|
28 #include "telepathy-constants.h" |
|
29 #include "telepathy-errors.h" |
|
30 #include "telepathy-helpers.h" |
|
31 |
|
32 #include "gabble-connection-manager.h" |
|
33 #include "gabble-connection-manager-glue.h" |
|
34 #include "gabble-connection-manager-signals-marshal.h" |
|
35 |
|
36 #include "gabble_enums.h" |
|
37 |
|
38 #define TP_TYPE_PARAM (dbus_g_type_get_struct ("GValueArray", \ |
|
39 G_TYPE_STRING, \ |
|
40 G_TYPE_UINT, \ |
|
41 G_TYPE_STRING, \ |
|
42 G_TYPE_VALUE, \ |
|
43 G_TYPE_INVALID)) |
|
44 |
|
45 #ifndef EMULATOR |
|
46 G_DEFINE_TYPE(GabbleConnectionManager, gabble_connection_manager, G_TYPE_OBJECT) |
|
47 #endif |
|
48 |
|
49 |
|
50 /* signal enum */ |
|
51 enum |
|
52 { |
|
53 NEW_CONNECTION, |
|
54 NO_MORE_CONNECTIONS, |
|
55 LAST_SIGNAL |
|
56 #ifdef EMULATOR |
|
57 = LAST_SIGNAL_CON_MGR |
|
58 #endif |
|
59 |
|
60 }; |
|
61 |
|
62 |
|
63 #ifdef EMULATOR |
|
64 #include "libgabble_wsd_solution.h" |
|
65 |
|
66 GET_STATIC_ARRAY_FROM_TLS(signals,gabble_conmgr,guint) |
|
67 #define signals (GET_WSD_VAR_NAME(signals,gabble_conmgr, s)()) |
|
68 |
|
69 GET_STATIC_VAR_FROM_TLS(ssl,gabble_conmgr,gboolean) |
|
70 #define ssl (*GET_WSD_VAR_NAME(ssl,gabble_conmgr,s)()) |
|
71 |
|
72 GET_STATIC_VAR_FROM_TLS(httpport,gabble_conmgr,guint) |
|
73 #define httpport (*GET_WSD_VAR_NAME(httpport,gabble_conmgr,s)()) |
|
74 |
|
75 GET_STATIC_VAR_FROM_TLS(httpproxyport,gabble_conmgr,guint) |
|
76 #define httpproxyport (*GET_WSD_VAR_NAME(httpproxyport,gabble_conmgr,s)()) |
|
77 |
|
78 GET_STATIC_VAR_FROM_TLS(gabble_connection_manager_parent_class,gabble_conmgr,gpointer) |
|
79 #define gabble_connection_manager_parent_class (*GET_WSD_VAR_NAME(gabble_connection_manager_parent_class,gabble_conmgr,s)()) |
|
80 |
|
81 GET_STATIC_VAR_FROM_TLS(g_define_type_id,gabble_conmgr,GType) |
|
82 #define g_define_type_id (*GET_WSD_VAR_NAME(g_define_type_id,gabble_conmgr,s)()) |
|
83 |
|
84 |
|
85 static void gabble_connection_manager_init (GabbleConnectionManager *self); |
|
86 static void gabble_connection_manager_class_init (GabbleConnectionManagerClass *klass); |
|
87 static void gabble_connection_manager_class_intern_init (gpointer klass) |
|
88 { |
|
89 gabble_connection_manager_parent_class = g_type_class_peek_parent (klass); |
|
90 gabble_connection_manager_class_init ((GabbleConnectionManagerClass*) klass); |
|
91 } |
|
92 EXPORT_C GType gabble_connection_manager_get_type (void) |
|
93 { |
|
94 |
|
95 if ((g_define_type_id == 0)) |
|
96 { |
|
97 static const GTypeInfo g_define_type_info = |
|
98 { sizeof (GabbleConnectionManagerClass), (GBaseInitFunc) ((void *)0), (GBaseFinalizeFunc) ((void *)0), (GClassInitFunc) gabble_connection_manager_class_intern_init, (GClassFinalizeFunc) ((void *)0), ((void *)0), sizeof (GabbleConnectionManager), 0, (GInstanceInitFunc) gabble_connection_manager_init, ((void *)0) }; g_define_type_id = g_type_register_static ( ((GType) ((20) << (2))), g_intern_static_string ("GabbleConnectionManager"), &g_define_type_info, (GTypeFlags) 0); { {} ; } } return g_define_type_id; |
|
99 } ; |
|
100 |
|
101 |
|
102 #else |
|
103 |
|
104 static guint signals[LAST_SIGNAL] = {0}; |
|
105 |
|
106 static gboolean ssl = TRUE; |
|
107 static guint httpport = 8080; |
|
108 static guint httpproxyport = 443; |
|
109 |
|
110 #endif |
|
111 |
|
112 /* private structure */ |
|
113 typedef struct _GabbleConnectionManagerPrivate GabbleConnectionManagerPrivate; |
|
114 |
|
115 struct _GabbleConnectionManagerPrivate |
|
116 { |
|
117 gboolean dispose_has_run; |
|
118 GHashTable *connections; |
|
119 }; |
|
120 |
|
121 #define GABBLE_CONNECTION_MANAGER_GET_PRIVATE(obj) \ |
|
122 ((GabbleConnectionManagerPrivate *)obj->priv) |
|
123 |
|
124 /* type definition stuff */ |
|
125 |
|
126 static void |
|
127 gabble_connection_manager_init (GabbleConnectionManager *self) |
|
128 { |
|
129 GabbleConnectionManagerPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, |
|
130 GABBLE_TYPE_CONNECTION_MANAGER, GabbleConnectionManagerPrivate); |
|
131 |
|
132 self->priv = priv; |
|
133 |
|
134 priv->connections = g_hash_table_new (g_direct_hash, g_direct_equal); |
|
135 } |
|
136 |
|
137 static void gabble_connection_manager_dispose (GObject *object); |
|
138 static void gabble_connection_manager_finalize (GObject *object); |
|
139 |
|
140 static void |
|
141 gabble_connection_manager_class_init (GabbleConnectionManagerClass *gabble_connection_manager_class) |
|
142 { |
|
143 GObjectClass *object_class = G_OBJECT_CLASS (gabble_connection_manager_class); |
|
144 |
|
145 g_type_class_add_private (gabble_connection_manager_class, sizeof (GabbleConnectionManagerPrivate)); |
|
146 |
|
147 g_message("**NEW LOGS** inside gabble_connection_manager_class_init \n"); |
|
148 |
|
149 object_class->dispose = gabble_connection_manager_dispose; |
|
150 object_class->finalize = gabble_connection_manager_finalize; |
|
151 |
|
152 signals [NEW_CONNECTION] = |
|
153 g_signal_new ("new-connection", |
|
154 G_OBJECT_CLASS_TYPE (gabble_connection_manager_class), |
|
155 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, |
|
156 0, |
|
157 NULL, NULL, |
|
158 gabble_connection_manager_marshal_VOID__STRING_STRING_STRING, |
|
159 G_TYPE_NONE, 3, G_TYPE_STRING, DBUS_TYPE_G_OBJECT_PATH, G_TYPE_STRING); |
|
160 |
|
161 signals [NO_MORE_CONNECTIONS] = |
|
162 g_signal_new ("no-more-connections", |
|
163 G_OBJECT_CLASS_TYPE (gabble_connection_manager_class), |
|
164 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, |
|
165 0, |
|
166 NULL, NULL, |
|
167 g_cclosure_marshal_VOID__VOID, |
|
168 G_TYPE_NONE, 0); |
|
169 |
|
170 dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (gabble_connection_manager_class), &dbus_glib_gabble_connection_manager_object_info); |
|
171 } |
|
172 |
|
173 void |
|
174 gabble_connection_manager_dispose (GObject *object) |
|
175 { |
|
176 GabbleConnectionManager *self = GABBLE_CONNECTION_MANAGER (object); |
|
177 GabbleConnectionManagerPrivate *priv = GABBLE_CONNECTION_MANAGER_GET_PRIVATE (self); |
|
178 |
|
179 if (priv->dispose_has_run) |
|
180 return; |
|
181 |
|
182 priv->dispose_has_run = TRUE; |
|
183 |
|
184 /* release any references held by the object here */ |
|
185 |
|
186 if (G_OBJECT_CLASS (gabble_connection_manager_parent_class)->dispose) |
|
187 G_OBJECT_CLASS (gabble_connection_manager_parent_class)->dispose (object); |
|
188 } |
|
189 |
|
190 void |
|
191 gabble_connection_manager_finalize (GObject *object) |
|
192 { |
|
193 GabbleConnectionManager *self = GABBLE_CONNECTION_MANAGER (object); |
|
194 GabbleConnectionManagerPrivate *priv = GABBLE_CONNECTION_MANAGER_GET_PRIVATE (self); |
|
195 |
|
196 g_hash_table_destroy(priv->connections); |
|
197 |
|
198 G_OBJECT_CLASS (gabble_connection_manager_parent_class)->finalize (object); |
|
199 } |
|
200 |
|
201 |
|
202 enum { |
|
203 JABBER_PARAM_ACCOUNT = 0, |
|
204 JABBER_PARAM_PASSWORD, |
|
205 JABBER_PARAM_SERVER, |
|
206 JABBER_PARAM_RESOURCE, |
|
207 JABBER_PARAM_PRIORITY, |
|
208 JABBER_PARAM_PORT, |
|
209 JABBER_PARAM_OLD_SSL, |
|
210 JABBER_PARAM_REGISTER, |
|
211 JABBER_PARAM_LOW_BANDWIDTH, |
|
212 JABBER_PARAM_HTTPS_PROXY_SERVER, |
|
213 JABBER_PARAM_HTTPS_PROXY_PORT, |
|
214 JABBER_PARAM_FALLBACK_CONFERENCE_SERVER, |
|
215 JABBER_PARAM_STUN_SERVER, |
|
216 JABBER_PARAM_STUN_PORT, |
|
217 JABBER_PARAM_IGNORE_SSL_ERRORS, |
|
218 JABBER_PARAM_ALIAS, |
|
219 LAST_JABBER_PARAM |
|
220 }; |
|
221 /* private methods */ |
|
222 |
|
223 static gboolean |
|
224 get_parameters (const char *proto, const GabbleParamSpec **params, GError **error) |
|
225 { |
|
226 if (!strcmp (proto, "jabber")) |
|
227 { |
|
228 *params = jabber_params; |
|
229 } |
|
230 else |
|
231 { |
|
232 g_debug ("%s: unknown protocol %s", G_STRFUNC, proto); |
|
233 |
|
234 g_set_error (error, TELEPATHY_ERRORS, NotImplemented, |
|
235 "unknown protocol %s", proto); |
|
236 |
|
237 return FALSE; |
|
238 } |
|
239 |
|
240 return TRUE; |
|
241 } |
|
242 |
|
243 static GValue *param_default_value (const GabbleParamSpec *params, int i) |
|
244 { |
|
245 GValue *value; |
|
246 |
|
247 value = g_new0(GValue, 1); |
|
248 g_value_init(value, params[i].gtype); |
|
249 |
|
250 /* TODO: this check could be stricter if we knew whether register |
|
251 was true. In practice REQUIRED and REGISTER always go together in |
|
252 the Gabble params, though */ |
|
253 if (params[i].flags & TP_CONN_MGR_PARAM_FLAG_REQUIRED & TP_CONN_MGR_PARAM_FLAG_REGISTER) |
|
254 { |
|
255 g_assert(params[i].def == NULL); |
|
256 goto OUT; |
|
257 } |
|
258 |
|
259 switch (params[i].dtype[0]) |
|
260 { |
|
261 case DBUS_TYPE_STRING: |
|
262 g_value_set_static_string (value, (const gchar*) params[i].def); |
|
263 break; |
|
264 case DBUS_TYPE_INT16: |
|
265 g_value_set_int (value, GPOINTER_TO_INT (params[i].def)); |
|
266 break; |
|
267 case DBUS_TYPE_UINT16: |
|
268 g_value_set_uint (value, GPOINTER_TO_INT (params[i].def)); |
|
269 break; |
|
270 case DBUS_TYPE_BOOLEAN: |
|
271 g_value_set_boolean (value, GPOINTER_TO_INT (params[i].def)); |
|
272 break; |
|
273 default: |
|
274 g_error("parameter_defaults: encountered unknown type %s on argument %s", |
|
275 params[i].dtype, params[i].name); |
|
276 } |
|
277 |
|
278 OUT: |
|
279 return value; |
|
280 } |
|
281 |
|
282 static gboolean |
|
283 set_param_from_value (const GabbleParamSpec *paramspec, |
|
284 GValue *value, |
|
285 GabbleParams *params, |
|
286 GError **error) |
|
287 { |
|
288 if (G_VALUE_TYPE (value) != paramspec->gtype) |
|
289 { |
|
290 g_debug ("%s: expected type %s for parameter %s, got %s", |
|
291 G_STRFUNC, |
|
292 g_type_name (paramspec->gtype), paramspec->name, |
|
293 G_VALUE_TYPE_NAME (value)); |
|
294 g_set_error (error, TELEPATHY_ERRORS, InvalidArgument, |
|
295 "expected type %s for account parameter %s, got %s", |
|
296 g_type_name (paramspec->gtype), paramspec->name, |
|
297 G_VALUE_TYPE_NAME (value)); |
|
298 return FALSE; |
|
299 } |
|
300 |
|
301 switch (paramspec->dtype[0]) |
|
302 { |
|
303 case DBUS_TYPE_STRING: |
|
304 { |
|
305 const char *str = g_value_get_string (value); |
|
306 if (!str || *str == '\0') |
|
307 return FALSE; |
|
308 else |
|
309 *((char **) ((char *)params + paramspec->offset)) = g_value_dup_string (value); |
|
310 } |
|
311 break; |
|
312 case DBUS_TYPE_INT16: |
|
313 *((gint *) ((char *)params + paramspec->offset)) = g_value_get_int (value); |
|
314 break; |
|
315 case DBUS_TYPE_UINT16: |
|
316 *((guint *) ((char *)params + paramspec->offset)) = g_value_get_uint (value); |
|
317 break; |
|
318 case DBUS_TYPE_BOOLEAN: |
|
319 *((gboolean *) ((char *)params + paramspec->offset)) = g_value_get_boolean (value); |
|
320 break; |
|
321 default: |
|
322 g_error ("set_param_from_value: encountered unknown type %s on argument %s", |
|
323 paramspec->dtype, paramspec->name); |
|
324 return FALSE; |
|
325 } |
|
326 |
|
327 return TRUE; |
|
328 } |
|
329 |
|
330 static gboolean |
|
331 parse_parameters (const GabbleParamSpec *paramspec, |
|
332 GHashTable *provided, |
|
333 GabbleParams *params, |
|
334 GError **error) |
|
335 { |
|
336 int unhandled; |
|
337 int i; |
|
338 guint mandatory_flag = TP_CONN_MGR_PARAM_FLAG_REQUIRED; |
|
339 GValue *value; |
|
340 |
|
341 unhandled = g_hash_table_size (provided); |
|
342 |
|
343 value = g_hash_table_lookup (provided, "register"); |
|
344 if (value != NULL && G_VALUE_TYPE(value) == G_TYPE_BOOLEAN && |
|
345 g_value_get_boolean(value)) |
|
346 { |
|
347 mandatory_flag = TP_CONN_MGR_PARAM_FLAG_REGISTER; |
|
348 } |
|
349 |
|
350 for (i = 0; paramspec[i].name; i++) |
|
351 { |
|
352 value = g_hash_table_lookup (provided, paramspec[i].name); |
|
353 |
|
354 if (value == NULL) |
|
355 { |
|
356 if (paramspec[i].flags & mandatory_flag) |
|
357 { |
|
358 g_debug ("%s: missing mandatory param %s", |
|
359 G_STRFUNC, paramspec[i].name); |
|
360 g_set_error (error, TELEPATHY_ERRORS, InvalidArgument, |
|
361 "missing mandatory account parameter %s", paramspec[i].name); |
|
362 return FALSE; |
|
363 } |
|
364 else |
|
365 { |
|
366 g_debug ("%s: using default value for param %s", |
|
367 G_STRFUNC, paramspec[i].name); |
|
368 } |
|
369 } |
|
370 else |
|
371 { |
|
372 if (!set_param_from_value (¶mspec[i], value, params, error)) |
|
373 { |
|
374 g_set_error (error, TELEPATHY_ERRORS, InvalidArgument, |
|
375 "invalid value for parameter %s", paramspec[i].name); |
|
376 return FALSE; |
|
377 } |
|
378 |
|
379 params->set_mask |= 1 << i; |
|
380 |
|
381 unhandled--; |
|
382 if (paramspec[i].gtype == G_TYPE_STRING) |
|
383 { |
|
384 if (0 == strcmp (paramspec[i].name, "password")) |
|
385 { |
|
386 g_debug ("%s: accepted value <hidden> for param password", |
|
387 G_STRFUNC); |
|
388 } |
|
389 else |
|
390 { |
|
391 g_debug ("%s: accepted value %s for param %s", |
|
392 G_STRFUNC, |
|
393 *((char **) ((char *)params + paramspec[i].offset)), |
|
394 paramspec[i].name); |
|
395 } |
|
396 } |
|
397 else |
|
398 { |
|
399 g_debug ("%s: accepted value %u for param %s", G_STRFUNC, |
|
400 *((guint *) ((char *)params + paramspec[i].offset)), paramspec[i].name); |
|
401 } |
|
402 } |
|
403 } |
|
404 |
|
405 if (unhandled) |
|
406 { |
|
407 g_debug ("%s: unknown argument name provided", G_STRFUNC); |
|
408 g_set_error (error, TELEPATHY_ERRORS, InvalidArgument, |
|
409 "unknown argument name provided"); |
|
410 return FALSE; |
|
411 } |
|
412 |
|
413 return TRUE; |
|
414 } |
|
415 |
|
416 static void |
|
417 free_params (GabbleParams *params) |
|
418 { |
|
419 g_free (params->account); |
|
420 g_free (params->password); |
|
421 g_free (params->server); |
|
422 g_free (params->resource); |
|
423 g_free (params->https_proxy_server); |
|
424 g_free (params->fallback_conference_server); |
|
425 g_free (params->stun_server); |
|
426 g_free (params->alias); |
|
427 } |
|
428 |
|
429 /** |
|
430 * connection_disconnected_cb: |
|
431 * @conn: #GabbleConnection |
|
432 * @data: data passed in callback |
|
433 * |
|
434 * Signal handler called when a connection object disconnects. |
|
435 * When they become disconnected, we can unref and discard |
|
436 * them, and they will disappear from the bus. |
|
437 */ |
|
438 static void |
|
439 connection_disconnected_cb (GabbleConnection *conn, |
|
440 gpointer data) |
|
441 { |
|
442 GabbleConnectionManager *self = GABBLE_CONNECTION_MANAGER (data); |
|
443 GabbleConnectionManagerPrivate *priv = GABBLE_CONNECTION_MANAGER_GET_PRIVATE (self); |
|
444 |
|
445 g_assert (g_hash_table_lookup (priv->connections, conn)); |
|
446 |
|
447 /* fix: this check should only be done if priv->connections is not null, and conn is not null */ |
|
448 |
|
449 if( (priv->connections) && (conn)) |
|
450 g_hash_table_remove (priv->connections, conn); |
|
451 |
|
452 /* end of fix */ |
|
453 |
|
454 g_object_unref (conn); |
|
455 |
|
456 g_debug ("%s: dereferenced connection", G_STRFUNC); |
|
457 if(priv->connections) |
|
458 if (g_hash_table_size (priv->connections) == 0) |
|
459 { |
|
460 g_signal_emit (self, signals [NO_MORE_CONNECTIONS], 0); |
|
461 g_debug ("%s: emitting no more connections", G_STRFUNC); |
|
462 } |
|
463 |
|
464 |
|
465 } |
|
466 |
|
467 /* public methods */ |
|
468 |
|
469 #ifdef SYMBIAN |
|
470 EXPORT_C |
|
471 #endif |
|
472 void |
|
473 _gabble_connection_manager_register (GabbleConnectionManager *self) |
|
474 { |
|
475 DBusGConnection *bus; |
|
476 DBusGProxy *bus_proxy; |
|
477 GError *error = NULL; |
|
478 guint request_name_result; |
|
479 |
|
480 g_assert (GABBLE_IS_CONNECTION_MANAGER (self)); |
|
481 |
|
482 bus = tp_get_bus (); |
|
483 bus_proxy = tp_get_bus_proxy (); |
|
484 |
|
485 if (!dbus_g_proxy_call (bus_proxy, "RequestName", &error, |
|
486 G_TYPE_STRING, GABBLE_CONN_MGR_BUS_NAME, |
|
487 G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE, |
|
488 G_TYPE_INVALID, |
|
489 G_TYPE_UINT, &request_name_result, |
|
490 G_TYPE_INVALID)) |
|
491 g_error ("Failed to request bus name: %s", error->message); |
|
492 |
|
493 if (request_name_result == DBUS_REQUEST_NAME_REPLY_EXISTS) |
|
494 { |
|
495 g_warning ("Failed to acquire bus name, connection manager already running?"); |
|
496 exit (1); |
|
497 } |
|
498 |
|
499 dbus_g_connection_register_g_object (bus, GABBLE_CONN_MGR_OBJECT_PATH, G_OBJECT (self)); |
|
500 } |
|
501 |
|
502 /* dbus-exported methods */ |
|
503 |
|
504 /** |
|
505 * gabble_connection_manager_get_parameters |
|
506 * |
|
507 * Implements D-Bus method GetParameters |
|
508 * on interface org.freedesktop.Telepathy.ConnectionManager |
|
509 * |
|
510 * @error: Used to return a pointer to a GError detailing any error |
|
511 * that occurred, D-Bus will throw the error only if this |
|
512 * function returns FALSE. |
|
513 * |
|
514 * Returns: TRUE if successful, FALSE if an error was thrown. |
|
515 */ |
|
516 gboolean |
|
517 gabble_connection_manager_get_parameters (GabbleConnectionManager *self, |
|
518 const gchar *proto, |
|
519 GPtrArray **ret, |
|
520 GError **error) |
|
521 { |
|
522 const GabbleParamSpec *params = NULL; |
|
523 int i; |
|
524 |
|
525 if (!get_parameters (proto, ¶ms, error)) |
|
526 return FALSE; |
|
527 |
|
528 *ret = g_ptr_array_new (); |
|
529 |
|
530 for (i = 0; params[i].name; i++) |
|
531 { |
|
532 GValue *def_value; |
|
533 GValue param = { 0, }; |
|
534 |
|
535 g_value_init (¶m, TP_TYPE_PARAM); |
|
536 g_value_set_static_boxed (¶m, |
|
537 dbus_g_type_specialized_construct (TP_TYPE_PARAM)); |
|
538 |
|
539 def_value = param_default_value (params, i); |
|
540 dbus_g_type_struct_set (¶m, |
|
541 0, params[i].name, |
|
542 1, params[i].flags, |
|
543 2, params[i].dtype, |
|
544 3, def_value, |
|
545 G_MAXUINT); |
|
546 g_value_unset(def_value); |
|
547 g_free(def_value); |
|
548 |
|
549 g_ptr_array_add (*ret, g_value_get_boxed (¶m)); |
|
550 } |
|
551 |
|
552 return TRUE; |
|
553 } |
|
554 |
|
555 |
|
556 /** |
|
557 * gabble_connection_manager_list_protocols |
|
558 * |
|
559 * Implements D-Bus method ListProtocols |
|
560 * on interface org.freedesktop.Telepathy.ConnectionManager |
|
561 * |
|
562 * @error: Used to return a pointer to a GError detailing any error |
|
563 * that occurred, D-Bus will throw the error only if this |
|
564 * function returns FALSE. |
|
565 * |
|
566 * Returns: TRUE if successful, FALSE if an error was thrown. |
|
567 */ |
|
568 gboolean |
|
569 gabble_connection_manager_list_protocols (GabbleConnectionManager *self, |
|
570 gchar ***ret, |
|
571 GError **error) |
|
572 { |
|
573 const char *protocols[] = { "jabber", NULL }; |
|
574 g_message("BINGO...gabble_connection_manager_list_protocols entered \n"); |
|
575 |
|
576 *ret = g_strdupv ((gchar **)protocols); |
|
577 |
|
578 g_message("BINGO...leaving gabble_connection_manager_list_protocols \n"); |
|
579 |
|
580 return TRUE; |
|
581 } |
|
582 |
|
583 |
|
584 #define SET_PROPERTY_IF_PARAM_SET(prop, param, member) \ |
|
585 if ((params.set_mask & (1 << param)) != 0) \ |
|
586 { \ |
|
587 g_object_set (conn, prop, member, NULL); \ |
|
588 } |
|
589 |
|
590 |
|
591 /** |
|
592 * gabble_connection_manager_request_connection |
|
593 * |
|
594 * Implements D-Bus method RequestConnection |
|
595 * on interface org.freedesktop.Telepathy.ConnectionManager |
|
596 * |
|
597 * @error: Used to return a pointer to a GError detailing any error |
|
598 * that occurred, D-Bus will throw the error only if this |
|
599 * function returns FALSE. |
|
600 * |
|
601 * Returns: TRUE if successful, FALSE if an error was thrown. |
|
602 */ |
|
603 gboolean |
|
604 gabble_connection_manager_request_connection (GabbleConnectionManager *self, |
|
605 const gchar *proto, |
|
606 GHashTable *parameters, |
|
607 gchar **bus_name, |
|
608 gchar **object_path, |
|
609 GError **error) |
|
610 { |
|
611 GabbleConnectionManagerPrivate *priv; |
|
612 GabbleConnection *conn; |
|
613 const GabbleParamSpec *paramspec; |
|
614 GabbleParams params = { 0, }; |
|
615 |
|
616 g_assert (GABBLE_IS_CONNECTION_MANAGER (self)); |
|
617 |
|
618 priv = GABBLE_CONNECTION_MANAGER_GET_PRIVATE (self); |
|
619 |
|
620 if (!get_parameters (proto, ¶mspec, error)) |
|
621 return FALSE; |
|
622 |
|
623 |
|
624 if (!parse_parameters (paramspec, parameters, ¶ms, error)) |
|
625 { |
|
626 free_params (¶ms); |
|
627 return FALSE; |
|
628 } |
|
629 |
|
630 conn = g_object_new (GABBLE_TYPE_CONNECTION, |
|
631 "protocol", proto, |
|
632 "password", params.password, |
|
633 NULL); |
|
634 |
|
635 g_message("BINGO...after g_object_new \n"); |
|
636 |
|
637 SET_PROPERTY_IF_PARAM_SET ("connect-server", JABBER_PARAM_SERVER, |
|
638 params.server); |
|
639 SET_PROPERTY_IF_PARAM_SET ("resource", JABBER_PARAM_RESOURCE, |
|
640 params.resource); |
|
641 SET_PROPERTY_IF_PARAM_SET ("priority", JABBER_PARAM_PRIORITY, |
|
642 CLAMP (params.priority, G_MININT8, G_MAXINT8)); |
|
643 SET_PROPERTY_IF_PARAM_SET ("port", JABBER_PARAM_PORT, params.port); |
|
644 SET_PROPERTY_IF_PARAM_SET ("old-ssl", JABBER_PARAM_OLD_SSL, params.old_ssl); |
|
645 SET_PROPERTY_IF_PARAM_SET ("register", JABBER_PARAM_REGISTER, |
|
646 params.do_register); |
|
647 SET_PROPERTY_IF_PARAM_SET ("low-bandwidth", JABBER_PARAM_LOW_BANDWIDTH, |
|
648 params.low_bandwidth); |
|
649 SET_PROPERTY_IF_PARAM_SET ("https-proxy-server", |
|
650 JABBER_PARAM_HTTPS_PROXY_SERVER, |
|
651 params.https_proxy_server); |
|
652 SET_PROPERTY_IF_PARAM_SET ("https-proxy-port", JABBER_PARAM_HTTPS_PROXY_PORT, |
|
653 params.https_proxy_port); |
|
654 SET_PROPERTY_IF_PARAM_SET ("fallback-conference-server", |
|
655 JABBER_PARAM_FALLBACK_CONFERENCE_SERVER, |
|
656 params.fallback_conference_server); |
|
657 SET_PROPERTY_IF_PARAM_SET ("stun-server", JABBER_PARAM_STUN_SERVER, |
|
658 params.stun_server); |
|
659 SET_PROPERTY_IF_PARAM_SET ("stun-port", JABBER_PARAM_STUN_PORT, |
|
660 params.stun_port); |
|
661 SET_PROPERTY_IF_PARAM_SET ("ignore-ssl-errors", |
|
662 JABBER_PARAM_IGNORE_SSL_ERRORS, |
|
663 params.ignore_ssl_errors); |
|
664 SET_PROPERTY_IF_PARAM_SET ("alias", JABBER_PARAM_ALIAS, params.alias); |
|
665 |
|
666 // split up account into username, stream-server and resource |
|
667 if (!_gabble_connection_set_properties_from_account (conn, params.account, error)) |
|
668 { |
|
669 goto ERROR; |
|
670 } |
|
671 |
|
672 // free memory allocated by param parser |
|
673 free_params(¶ms); |
|
674 |
|
675 // with hash table usage - end |
|
676 |
|
677 |
|
678 // register on bus and save bus name and object path |
|
679 if (!_gabble_connection_register (conn, bus_name, object_path, error)) |
|
680 { |
|
681 g_debug ("%s failed: %s", G_STRFUNC, (*error)->message); |
|
682 |
|
683 goto ERROR; |
|
684 } |
|
685 |
|
686 /* bind to status change signals from the connection object */ |
|
687 g_signal_connect (conn, "disconnected", |
|
688 G_CALLBACK (connection_disconnected_cb), |
|
689 self); |
|
690 |
|
691 /* store the connection, using a hash table as a set */ |
|
692 g_hash_table_insert (priv->connections, conn, GINT_TO_POINTER(TRUE)); |
|
693 |
|
694 /* emit the new connection signal */ |
|
695 g_signal_emit (self, signals [NEW_CONNECTION], 0, *bus_name, *object_path, proto); |
|
696 |
|
697 return TRUE; |
|
698 |
|
699 ERROR: |
|
700 if (conn) |
|
701 g_object_unref (G_OBJECT (conn)); |
|
702 |
|
703 g_message("ERROR...returning FALSE\n"); |
|
704 return FALSE; |
|
705 } |
|