2 * @file telepathy-connection.c
6 * Copyright (C) 2012 SIPE Project <http://sipe.sourceforge.net/>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #include <glib-object.h>
30 #include <telepathy-glib/base-connection.h>
31 #include <telepathy-glib/base-protocol.h>
32 #include <telepathy-glib/contacts-mixin.h>
33 #include <telepathy-glib/handle-repo-dynamic.h>
34 #include <telepathy-glib/presence-mixin.h>
35 #include <telepathy-glib/simple-password-manager.h>
36 #include <telepathy-glib/telepathy-glib.h>
38 #include "sipe-backend.h"
39 #include "sipe-common.h"
40 #include "sipe-core.h"
42 #include "telepathy-private.h"
46 * Connection class - data structures
48 typedef struct _SipeConnectionClass
{
49 TpBaseConnectionClass parent_class
;
50 TpContactsMixinClass contacts_mixin
;
51 TpPresenceMixinClass presence_mixin
;
52 } SipeConnectionClass
;
54 typedef struct _SipeConnection
{
55 TpBaseConnection parent
;
56 TpContactsMixinClass contacts_mixin
;
57 TpPresenceMixin presence_mixin
;
59 /* channel managers */
60 TpSimplePasswordManager
*password_manager
;
61 struct _SipeContactList
*contact_list
;
63 struct sipe_backend_private
private;
71 gchar
*authentication
;
72 gboolean is_disconnecting
;
75 #define SIPE_PUBLIC_TO_CONNECTION sipe_public->backend_private->connection
78 * Connection class - type macros
80 static GType
sipe_connection_get_type(void) G_GNUC_CONST
;
81 #define SIPE_TYPE_CONNECTION \
82 (sipe_connection_get_type())
83 #define SIPE_CONNECTION(obj) \
84 (G_TYPE_CHECK_INSTANCE_CAST((obj), SIPE_TYPE_CONNECTION, \
89 * Connection class - type definition
91 static void init_aliasing (gpointer
, gpointer
);
92 G_DEFINE_TYPE_WITH_CODE(SipeConnection
,
94 TP_TYPE_BASE_CONNECTION
,
95 G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_CONNECTION_INTERFACE_ALIASING
,
97 G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACTS
,
98 tp_contacts_mixin_iface_init
);
99 G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_GROUPS
,
100 tp_base_contact_list_mixin_groups_iface_init
);
101 G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_LIST
,
102 tp_base_contact_list_mixin_list_iface_init
);
103 G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_CONNECTION_INTERFACE_PRESENCE
,
104 tp_presence_mixin_iface_init
);
105 G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_CONNECTION_INTERFACE_SIMPLE_PRESENCE
,
106 tp_presence_mixin_simple_presence_iface_init
)
111 * Connection class - instance methods
113 static gchar
*normalize_contact(SIPE_UNUSED_PARAMETER TpHandleRepoIface
*repo
,
115 SIPE_UNUSED_PARAMETER gpointer context
,
118 return(sipe_telepathy_protocol_normalize_contact(NULL
, id
, error
));
121 static void create_handle_repos(SIPE_UNUSED_PARAMETER TpBaseConnection
*conn
,
122 TpHandleRepoIface
*repos
[NUM_TP_HANDLE_TYPES
])
124 repos
[TP_HANDLE_TYPE_CONTACT
] = tp_dynamic_handle_repo_new(TP_HANDLE_TYPE_CONTACT
,
129 static gboolean
connect_to_core(SipeConnection
*self
,
132 gchar
*login_domain
= NULL
;
133 gchar
*login_account
= NULL
;
134 struct sipe_core_public
*sipe_public
;
137 /* login name specified? */
138 if (self
->login
&& strlen(self
->login
)) {
139 /* Allowed domain-account separators are / or \ */
140 gchar
**domain_user
= g_strsplit_set(self
->login
, "/\\", 2);
141 gboolean has_domain
= domain_user
[1] != NULL
;
142 SIPE_DEBUG_INFO("connect_to_core: login '%s'", self
->login
);
143 login_domain
= has_domain
? g_strdup(domain_user
[0]) : NULL
;
144 login_account
= g_strdup(domain_user
[has_domain
? 1 : 0]);
145 SIPE_DEBUG_INFO("connect_to_core: auth domain '%s' user '%s'",
146 login_domain
? login_domain
: "",
148 g_strfreev(domain_user
);
151 sipe_public
= sipe_core_allocate(self
->account
,
152 login_domain
, login_account
,
154 NULL
, /* @TODO: email */
155 NULL
, /* @TODO: email_url */
157 g_free(login_domain
);
158 g_free(login_account
);
160 SIPE_DEBUG_INFO("connect_to_core: created %p", sipe_public
);
163 struct sipe_backend_private
*telepathy_private
= &self
->private;
165 /* initialize backend private data */
166 sipe_public
->backend_private
= telepathy_private
;
167 telepathy_private
->public = sipe_public
;
168 telepathy_private
->contact_list
= self
->contact_list
;
169 telepathy_private
->connection
= self
;
170 telepathy_private
->activity
= SIPE_ACTIVITY_UNSET
;
171 telepathy_private
->message
= NULL
;
172 telepathy_private
->transport
= NULL
;
173 telepathy_private
->ipaddress
= NULL
;
175 /* map option list to flags - default is NTLM */
176 SIPE_CORE_FLAG_UNSET(KRB5
);
177 SIPE_CORE_FLAG_UNSET(TLS_DSK
);
179 if (sipe_strequal(self
->authentication
, "krb5")) {
180 SIPE_DEBUG_INFO_NOFORMAT("connect_to_core: KRB5 selected");
181 SIPE_CORE_FLAG_SET(KRB5
);
184 if (sipe_strequal(self
->authentication
, "tls-dsk")) {
185 SIPE_DEBUG_INFO_NOFORMAT("connect_to_core: TLS-DSK selected");
186 SIPE_CORE_FLAG_SET(TLS_DSK
);
189 /* @TODO: add parameter for SSO */
190 SIPE_CORE_FLAG_UNSET(SSO
);
192 sipe_core_transport_sip_connect(sipe_public
,
199 g_set_error_literal(error
, TP_ERROR
, TP_ERROR_INVALID_ARGUMENT
,
205 static void password_manager_cb(GObject
*source
,
206 GAsyncResult
*result
,
209 SipeConnection
*self
= data
;
210 TpBaseConnection
*base
= TP_BASE_CONNECTION(self
);
211 GError
*error
= NULL
;
212 const GString
*password
= tp_simple_password_manager_prompt_finish(
213 TP_SIMPLE_PASSWORD_MANAGER(source
),
217 if (password
== NULL
) {
218 SIPE_DEBUG_ERROR("password_manager_cb: failed: %s",
219 error
? error
->message
: "UNKNOWN");
221 if (base
->status
!= TP_CONNECTION_STATUS_DISCONNECTED
) {
222 tp_base_connection_disconnect_with_dbus_error(base
,
223 error
? tp_error_get_dbus_name(error
->code
) : "",
225 TP_CONNECTION_STATUS_REASON_AUTHENTICATION_FAILED
);
230 g_free(self
->password
);
231 self
->password
= g_strdup(password
->str
);
233 if (!connect_to_core(self
, &error
)) {
234 if (base
->status
!= TP_CONNECTION_STATUS_DISCONNECTED
) {
235 tp_base_connection_disconnect_with_dbus_error(base
,
236 tp_error_get_dbus_name(error
->code
),
238 TP_CONNECTION_STATUS_REASON_AUTHENTICATION_FAILED
);
245 static gboolean
start_connecting(TpBaseConnection
*base
,
248 SipeConnection
*self
= SIPE_CONNECTION(base
);
250 gchar
*uri
= sipe_telepathy_protocol_normalize_contact(NULL
,
254 SIPE_DEBUG_INFO_NOFORMAT("SipeConnection::start_connecting");
256 /* set up mandatory self-handle */
258 base
->self_handle
= tp_handle_ensure(tp_base_connection_get_handles(base
,
259 TP_HANDLE_TYPE_CONTACT
),
264 if (!base
->self_handle
) {
265 SIPE_DEBUG_ERROR("SipeConnection::start_connecting: self handle creation failed: %s",
270 SIPE_DEBUG_ERROR("SipeConnection::start_connecting: %s",
275 tp_base_connection_change_status(base
, TP_CONNECTION_STATUS_CONNECTING
,
276 TP_CONNECTION_STATUS_REASON_REQUESTED
);
278 /* we need a password */
280 rc
= connect_to_core(self
, error
);
282 SIPE_DEBUG_INFO_NOFORMAT("SipeConnection::start_connecting: requesting password from user");
283 tp_simple_password_manager_prompt_async(self
->password_manager
,
291 static gboolean
disconnect_from_core(gpointer data
)
293 TpBaseConnection
*base
= data
;
294 SipeConnection
*self
= SIPE_CONNECTION(base
);
295 struct sipe_backend_private
*telepathy_private
= &self
->private;
296 struct sipe_core_public
*sipe_public
= telepathy_private
->public;
298 SIPE_DEBUG_INFO("disconnect_from_core: %p", sipe_public
);
301 sipe_core_deallocate(sipe_public
);
302 telepathy_private
->public = NULL
;
303 telepathy_private
->transport
= NULL
;
305 g_free(telepathy_private
->ipaddress
);
306 telepathy_private
->ipaddress
= NULL
;
308 g_free(telepathy_private
->message
);
309 telepathy_private
->message
= NULL
;
311 SIPE_DEBUG_INFO_NOFORMAT("disconnect_from_core: core deallocated");
313 /* now it is OK to destroy the connection object */
314 tp_base_connection_finish_shutdown(base
);
319 static void shut_down(TpBaseConnection
*base
)
321 SIPE_DEBUG_INFO_NOFORMAT("SipeConnection::shut_down");
323 /* this can be called synchronously, defer destruction */
324 g_idle_add(disconnect_from_core
, base
);
327 static GPtrArray
*create_channel_managers(TpBaseConnection
*base
)
329 SipeConnection
*self
= SIPE_CONNECTION(base
);
330 GPtrArray
*channel_managers
= g_ptr_array_new();
332 SIPE_DEBUG_INFO_NOFORMAT("SipeConnection::create_channel_managers");
334 self
->contact_list
= sipe_telepathy_contact_list_new(base
);
335 g_ptr_array_add(channel_managers
, self
->contact_list
);
337 self
->password_manager
= tp_simple_password_manager_new(base
);
338 g_ptr_array_add(channel_managers
, self
->password_manager
);
340 g_ptr_array_add(channel_managers
, sipe_telepathy_search_new(base
));
342 return(channel_managers
);
345 static void aliasing_fill_contact_attributes(GObject
*object
,
346 const GArray
*contacts
,
347 GHashTable
*attributes
)
349 SipeConnection
*self
= SIPE_CONNECTION(object
);
352 for (i
= 0; i
< contacts
->len
; i
++) {
353 TpHandle contact
= g_array_index(contacts
, guint
, i
);
355 tp_contacts_mixin_set_contact_attribute(attributes
,
357 TP_TOKEN_CONNECTION_INTERFACE_ALIASING_ALIAS
,
358 tp_g_value_slice_new_string(
359 sipe_telepathy_buddy_get_alias(self
->contact_list
,
364 static void sipe_connection_constructed(GObject
*object
)
366 TpBaseConnection
*base
= TP_BASE_CONNECTION(object
);
367 void (*chain_up
)(GObject
*) = G_OBJECT_CLASS(sipe_connection_parent_class
)->constructed
;
372 tp_contacts_mixin_init(object
,
373 G_STRUCT_OFFSET(SipeConnection
, contacts_mixin
));
374 tp_base_connection_register_with_contacts_mixin(base
);
376 tp_base_contact_list_mixin_register_with_contacts_mixin(base
);
378 tp_contacts_mixin_add_contact_attributes_iface(object
,
379 TP_IFACE_CONNECTION_INTERFACE_ALIASING
,
380 aliasing_fill_contact_attributes
);
382 tp_presence_mixin_init(object
,
383 G_STRUCT_OFFSET(SipeConnection
,
385 tp_presence_mixin_simple_presence_register_with_contacts_mixin(object
);
388 static void sipe_connection_finalize(GObject
*object
)
390 SipeConnection
*self
= SIPE_CONNECTION(object
);
392 SIPE_DEBUG_INFO_NOFORMAT("SipeConnection::finalize");
394 tp_contacts_mixin_finalize(object
);
396 g_free(self
->authentication
);
397 g_free(self
->user_agent
);
399 g_free(self
->server
);
400 g_free(self
->password
);
402 g_free(self
->account
);
404 G_OBJECT_CLASS(sipe_connection_parent_class
)->finalize(object
);
408 * Connection class - type implementation
410 static const gchar
*interfaces_always_present
[] = {
412 TP_IFACE_CONNECTION_INTERFACE_ALIASING
,
413 TP_IFACE_CONNECTION_INTERFACE_CONTACT_GROUPS
,
414 TP_IFACE_CONNECTION_INTERFACE_CONTACT_LIST
,
415 TP_IFACE_CONNECTION_INTERFACE_CONTACTS
,
416 TP_IFACE_CONNECTION_INTERFACE_PRESENCE
,
417 TP_IFACE_CONNECTION_INTERFACE_REQUESTS
,
418 TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE
,
422 static void sipe_connection_class_init(SipeConnectionClass
*klass
)
424 GObjectClass
*object_class
= G_OBJECT_CLASS(klass
);
425 TpBaseConnectionClass
*base_class
= TP_BASE_CONNECTION_CLASS(klass
);
427 SIPE_DEBUG_INFO_NOFORMAT("SipeConnection::class_init");
429 object_class
->constructed
= sipe_connection_constructed
;
430 object_class
->finalize
= sipe_connection_finalize
;
432 base_class
->create_handle_repos
= create_handle_repos
;
433 base_class
->start_connecting
= start_connecting
;
434 base_class
->shut_down
= shut_down
;
435 base_class
->create_channel_managers
= create_channel_managers
;
437 base_class
->interfaces_always_present
= interfaces_always_present
;
439 tp_contacts_mixin_class_init(object_class
,
440 G_STRUCT_OFFSET(SipeConnectionClass
,
442 sipe_telepathy_status_init(object_class
,
443 G_STRUCT_OFFSET(SipeConnectionClass
,
445 tp_presence_mixin_simple_presence_init_dbus_properties(object_class
);
446 tp_base_contact_list_mixin_class_init(base_class
);
449 static void sipe_connection_init(SIPE_UNUSED_PARAMETER SipeConnection
*self
)
451 SIPE_DEBUG_INFO_NOFORMAT("SipeConnection::init");
455 * Connection class - interface implementation
459 static void get_alias_flags(TpSvcConnectionInterfaceAliasing
*aliasing
,
460 DBusGMethodInvocation
*context
)
462 TpBaseConnection
*base
= TP_BASE_CONNECTION(aliasing
);
464 TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED(base
, context
);
465 SIPE_DEBUG_INFO_NOFORMAT("SipeConnection::get_alias_flags called");
467 tp_svc_connection_interface_aliasing_return_from_get_alias_flags(context
,
468 TP_CONNECTION_ALIAS_FLAG_USER_SET
);
471 static void get_aliases(TpSvcConnectionInterfaceAliasing
*aliasing
,
472 const GArray
*contacts
,
473 DBusGMethodInvocation
*context
)
475 SipeConnection
*self
= SIPE_CONNECTION(aliasing
);
476 TpBaseConnection
*base
= TP_BASE_CONNECTION(aliasing
);
477 TpHandleRepoIface
*contact_repo
= tp_base_connection_get_handles(base
,
478 TP_HANDLE_TYPE_CONTACT
);
479 GError
*error
= NULL
;
483 TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED(base
, context
);
484 SIPE_DEBUG_INFO_NOFORMAT("SipeConnection::get_aliases called");
486 if (!tp_handles_are_valid(contact_repo
, contacts
, FALSE
, &error
)) {
487 dbus_g_method_return_error(context
, error
);
492 result
= g_hash_table_new(g_direct_hash
, g_direct_equal
);
494 for (i
= 0; i
< contacts
->len
; i
++) {
495 TpHandle contact
= g_array_index(contacts
, TpHandle
, i
);
496 const gchar
*alias
= sipe_telepathy_buddy_get_alias(self
->contact_list
,
498 g_hash_table_insert(result
,
499 GUINT_TO_POINTER(contact
),
503 tp_svc_connection_interface_aliasing_return_from_get_aliases(context
,
505 g_hash_table_unref(result
);
508 static void request_aliases(TpSvcConnectionInterfaceAliasing
*aliasing
,
509 const GArray
*contacts
,
510 DBusGMethodInvocation
*context
)
512 SipeConnection
*self
= SIPE_CONNECTION(aliasing
);
513 TpBaseConnection
*base
= TP_BASE_CONNECTION(aliasing
);
514 TpHandleRepoIface
*contact_repo
= tp_base_connection_get_handles(base
,
515 TP_HANDLE_TYPE_CONTACT
);
516 GError
*error
= NULL
;
521 TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED(base
, context
);
522 SIPE_DEBUG_INFO_NOFORMAT("SipeConnection::request_aliases called");
524 if (!tp_handles_are_valid(contact_repo
, contacts
, FALSE
, &error
)) {
525 dbus_g_method_return_error(context
, error
);
530 result
= g_ptr_array_sized_new(contacts
->len
+ 1);
532 for (i
= 0; i
< contacts
->len
; i
++) {
533 TpHandle contact
= g_array_index(contacts
, TpHandle
, i
);
534 const gchar
*alias
= sipe_telepathy_buddy_get_alias(self
->contact_list
,
536 g_ptr_array_add(result
, (gchar
*) alias
);
539 g_ptr_array_add(result
, NULL
);
540 strings
= (gchar
**) g_ptr_array_free(result
, FALSE
);
542 tp_svc_connection_interface_aliasing_return_from_request_aliases(context
,
543 (const gchar
**) strings
);
547 static void set_aliases(TpSvcConnectionInterfaceAliasing
*aliasing
,
549 DBusGMethodInvocation
*context
)
551 SipeConnection
*self
= SIPE_CONNECTION(aliasing
);
552 TpBaseConnection
*base
= TP_BASE_CONNECTION(aliasing
);
553 TpHandleRepoIface
*contact_repo
= tp_base_connection_get_handles(base
,
554 TP_HANDLE_TYPE_CONTACT
);
558 SIPE_DEBUG_INFO_NOFORMAT("SipeConnection::set_aliases called");
560 g_hash_table_iter_init(&iter
, aliases
);
562 while (g_hash_table_iter_next(&iter
, &key
, NULL
)) {
563 GError
*error
= NULL
;
565 if (!tp_handle_is_valid(contact_repo
,
566 GPOINTER_TO_UINT(key
),
568 dbus_g_method_return_error(context
, error
);
574 g_hash_table_iter_init(&iter
, aliases
);
576 while (g_hash_table_iter_next(&iter
, &key
, &value
)) {
577 sipe_telepathy_buddy_set_alias(self
->contact_list
,
578 GPOINTER_TO_UINT(key
),
582 tp_svc_connection_interface_aliasing_return_from_set_aliases(context
);
585 static void init_aliasing(gpointer iface
,
586 SIPE_UNUSED_PARAMETER gpointer iface_data
)
588 TpSvcConnectionInterfaceAliasingClass
*klass
= iface
;
590 SIPE_DEBUG_INFO_NOFORMAT("SipeConnection::init_aliasing called");
592 tp_svc_connection_interface_aliasing_implement_get_alias_flags(klass
, get_alias_flags
);
593 tp_svc_connection_interface_aliasing_implement_request_aliases(klass
, request_aliases
);
594 tp_svc_connection_interface_aliasing_implement_get_aliases(klass
, get_aliases
);
595 tp_svc_connection_interface_aliasing_implement_set_aliases(klass
, set_aliases
);
598 /* create new connection object */
599 TpBaseConnection
*sipe_telepathy_connection_new(TpBaseProtocol
*protocol
,
601 SIPE_UNUSED_PARAMETER GError
**error
)
603 SipeConnection
*conn
= g_object_new(SIPE_TYPE_CONNECTION
,
604 "protocol", tp_base_protocol_get_name(protocol
),
610 SIPE_DEBUG_INFO_NOFORMAT("sipe_telepathy_connection_new");
612 /* initialize private fields */
613 conn
->is_disconnecting
= FALSE
;
615 /* account & login are required fields */
616 conn
->account
= g_strdup(tp_asv_get_string(params
, "account"));
617 conn
->login
= g_strdup(tp_asv_get_string(params
, "login"));
620 value
= tp_asv_get_string(params
, "password");
621 if (value
&& strlen(value
))
622 conn
->password
= g_strdup(value
);
624 conn
->password
= NULL
;
627 value
= tp_asv_get_string(params
, "server");
628 if (value
&& strlen(value
))
629 conn
->server
= g_strdup(value
);
633 /* server port: core expects a string */
634 port
= tp_asv_get_uint32(params
, "port", &valid
);
636 conn
->port
= g_strdup_printf("%d", port
);
641 value
= tp_asv_get_string(params
, "transport");
642 if (sipe_strequal(value
, "auto")) {
643 conn
->transport
= conn
->server
?
644 SIPE_TRANSPORT_TLS
: SIPE_TRANSPORT_AUTO
;
645 } else if (sipe_strequal(value
, "tls")) {
646 conn
->transport
= SIPE_TRANSPORT_TLS
;
648 conn
->transport
= SIPE_TRANSPORT_TCP
;
651 /* User-Agent: override */
652 value
= tp_asv_get_string(params
, "useragent");
653 if (value
&& strlen(value
))
654 conn
->user_agent
= g_strdup(value
);
656 conn
->user_agent
= NULL
;
658 /* authentication type */
659 value
= tp_asv_get_string(params
, "authentication");
660 if (value
&& strlen(value
) && strcmp(value
, "ntlm"))
661 conn
->authentication
= g_strdup(value
);
663 conn
->authentication
= NULL
; /* NTLM is default */
665 return(TP_BASE_CONNECTION(conn
));
668 struct sipe_backend_private
*sipe_telepathy_connection_private(GObject
*object
)
670 SipeConnection
*self
= SIPE_CONNECTION(object
);
671 /* connected to core already? */
672 if (self
->private.public)
673 return(&self
->private);
679 * Backend adaptor functions
681 void sipe_backend_connection_completed(struct sipe_core_public
*sipe_public
)
683 SipeConnection
*self
= SIPE_PUBLIC_TO_CONNECTION
;
684 TpBaseConnection
*base
= TP_BASE_CONNECTION(self
);
686 /* we are only allowed to do this once */
687 if (base
->status
!= TP_CONNECTION_STATUS_CONNECTED
)
688 tp_base_connection_change_status(base
,
689 TP_CONNECTION_STATUS_CONNECTED
,
690 TP_CONNECTION_STATUS_REASON_REQUESTED
);
693 void sipe_backend_connection_error(struct sipe_core_public
*sipe_public
,
694 sipe_connection_error error
,
697 SipeConnection
*self
= SIPE_PUBLIC_TO_CONNECTION
;
698 TpBaseConnection
*base
= TP_BASE_CONNECTION(self
);
699 GHashTable
*details
= tp_asv_new("server-message", G_TYPE_STRING
, msg
,
701 TpConnectionStatusReason reason
;
704 self
->is_disconnecting
= TRUE
;
707 case SIPE_CONNECTION_ERROR_NETWORK
:
708 reason
= TP_CONNECTION_STATUS_REASON_NETWORK_ERROR
;
709 if (base
->status
== TP_CONNECTION_STATUS_CONNECTING
)
710 name
= TP_ERROR_STR_CONNECTION_FAILED
;
712 name
= TP_ERROR_STR_CONNECTION_LOST
;
715 case SIPE_CONNECTION_ERROR_INVALID_USERNAME
:
716 case SIPE_CONNECTION_ERROR_INVALID_SETTINGS
:
717 case SIPE_CONNECTION_ERROR_AUTHENTICATION_FAILED
:
718 case SIPE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE
:
719 /* copied from haze code. I agree there should be better ones */
720 reason
= TP_CONNECTION_STATUS_REASON_AUTHENTICATION_FAILED
;
721 name
= TP_ERROR_STR_AUTHENTICATION_FAILED
;
725 reason
= TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED
;
726 name
= TP_ERROR_STR_DISCONNECTED
;
730 SIPE_DEBUG_ERROR("sipe_backend_connection_error: %s (%s)", name
, msg
);
731 tp_base_connection_disconnect_with_dbus_error(base
,
735 g_hash_table_unref(details
);
738 gboolean
sipe_backend_connection_is_disconnecting(struct sipe_core_public
*sipe_public
)
740 SipeConnection
*self
= SIPE_PUBLIC_TO_CONNECTION
;
742 /* disconnect was requested or transport was already disconnected */
743 return(self
->is_disconnecting
||
744 self
->private.transport
== NULL
);
747 gboolean
sipe_backend_connection_is_valid(struct sipe_core_public
*sipe_public
)
749 return(!sipe_backend_connection_is_disconnecting(sipe_public
));
752 const gchar
*sipe_backend_setting(struct sipe_core_public
*sipe_public
,
755 SipeConnection
*self
= SIPE_PUBLIC_TO_CONNECTION
;
759 case SIPE_SETTING_USER_AGENT
:
760 value
= self
->user_agent
;
763 /* @TODO: update when settings are implemented */