6 * Purple is the legal property of its developers, whose names are too numerous
7 * to list here. Please refer to the COPYRIGHT file distributed with this
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
24 #ifndef PURPLE_JABBER_H_
25 #define PURPLE_JABBER_H_
29 /* JABBER_CAP_XHTML = 1 << 0, */
30 /* JABBER_CAP_COMPOSING = 1 << 1, */
31 JABBER_CAP_SI
= 1 << 2,
32 JABBER_CAP_SI_FILE_XFER
= 1 << 3,
33 JABBER_CAP_BYTESTREAMS
= 1 << 4,
34 JABBER_CAP_IBB
= 1 << 5,
35 JABBER_CAP_CHAT_STATES
= 1 << 6,
36 JABBER_CAP_IQ_SEARCH
= 1 << 7,
37 JABBER_CAP_IQ_REGISTER
= 1 << 8,
39 /* Google Talk extensions:
40 * https://developers.google.com/talk/jep_extensions/extensions
42 JABBER_CAP_GMAIL_NOTIFY
= 1 << 9,
43 JABBER_CAP_GOOGLE_ROSTER
= 1 << 10,
45 JABBER_CAP_PING
= 1 << 11,
46 JABBER_CAP_ADHOC
= 1 << 12,
47 JABBER_CAP_BLOCKING
= 1 << 13,
49 JABBER_CAP_ITEMS
= 1 << 14,
50 JABBER_CAP_ROSTER_VERSIONING
= 1 << 15,
52 JABBER_CAP_RETRIEVED
= 1 << 31
55 typedef struct _JabberStream JabberStream
;
57 #include <libxml/parser.h>
62 #include "circularbuffer.h"
63 #include "connection.h"
66 #include "mediamanager.h"
71 #include "namespaces.h"
80 #ifdef HAVE_CYRUS_SASL
81 #include <sasl/sasl.h>
84 #define CAPS0115_NODE "https://pidgin.im/"
86 #define JABBER_TYPE_PROTOCOL (jabber_protocol_get_type())
87 #define JABBER_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), JABBER_TYPE_PROTOCOL, JabberProtocol))
88 #define JABBER_PROTOCOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), JABBER_TYPE_PROTOCOL, JabberProtocolClass))
89 #define JABBER_IS_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), JABBER_TYPE_PROTOCOL))
90 #define JABBER_IS_PROTOCOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), JABBER_TYPE_PROTOCOL))
91 #define JABBER_PROTOCOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), JABBER_TYPE_PROTOCOL, JabberProtocolClass))
93 #define JABBER_DEFAULT_REQUIRE_TLS "require_starttls"
95 /* Index into attention_types list */
99 JABBER_STREAM_OFFLINE
,
100 JABBER_STREAM_CONNECTING
,
101 JABBER_STREAM_INITIALIZING
,
102 JABBER_STREAM_INITIALIZING_ENCRYPTION
,
103 JABBER_STREAM_AUTHENTICATING
,
104 JABBER_STREAM_POST_AUTH
,
105 JABBER_STREAM_CONNECTED
108 typedef struct _JabberProtocol
110 PurpleProtocol parent
;
113 typedef struct _JabberProtocolClass
115 PurpleProtocolClass parent_class
;
116 } JabberProtocolClass
;
123 GCancellable
*cancellable
;
125 xmlParserCtxt
*context
;
126 PurpleXmlNode
*current
;
133 JabberSaslMech
*auth_mech
;
134 gpointer auth_mech_data
;
137 * The header from the opening <stream/> tag. This being NULL is treated
138 * as a special condition in the parsing code (signifying the next
139 * stanza started is an opening stream tag), and its being missing on
140 * the stream header is treated as a fatal error.
143 JabberStreamState state
;
148 * This boolean was added to eliminate a heinous bug where we would
149 * get into a loop with the server and move a buddy back and forth
150 * from one group to another.
152 * The sequence goes something like this:
153 * 1. Our resource and another resource both approve an authorization
154 * request at the exact same time. We put the buddy in group A and
155 * the other resource put the buddy in group B.
156 * 2. The server receives the roster add for group B and sends us a
158 * 3. We receive this roster push and modify our local blist. This
159 * triggers us to send a roster add for group B.
160 * 4. The server recieves our earlier roster add for group A and sends
162 * 5. We receive this roster push and modify our local blist. This
163 * triggers us to send a roster add for group A.
164 * 6. The server receives our earlier roster add for group B and sends
166 * (repeat steps 3 through 6 ad infinitum)
168 * This boolean is used to short-circuit the sending of a roster add
169 * when we receive a roster push.
171 * See these bug reports:
172 * https://trac.adium.im/ticket/8834
173 * https://developer.pidgin.im/ticket/5484
174 * https://developer.pidgin.im/ticket/6188
176 gboolean currently_parsing_roster_push
;
180 PurpleRoomlist
*roomlist
;
181 GList
*user_directories
;
183 GHashTable
*iq_callbacks
;
187 GList
*oob_file_transfers
;
188 GList
*file_transfers
;
193 /** When we last pinged the server, so we don't ping more
194 * often than once every minute.
199 JabberBuddy
*user_jb
;
201 PurpleConnection
*gc
;
202 PurpleSslConnection
*gsc
;
204 gboolean registration
;
206 char *initial_avatar_hash
;
208 GSList
*pending_avatar_requests
;
210 GSList
*pending_buddy_info_requests
;
212 PurpleCircularBuffer
*write_buffer
;
217 JabberCapabilities server_caps
;
221 char *gmail_last_time
;
222 char *gmail_last_tid
;
226 #ifdef HAVE_CYRUS_SASL
228 sasl_callback_t
*sasl_cb
;
229 sasl_secret_t
*sasl_secret
;
230 const char *current_mech
;
237 gchar
*sasl_password
;
240 gboolean unregistration
;
241 PurpleAccountUnregistrationCb unregistration_cb
;
242 void *unregistration_user_data
;
244 gboolean vcard_fetched
;
245 /* Timer at login to push updated avatar */
248 /* Entity Capabilities hash */
251 /* does the local server support PEP? */
254 /* Is Buzz enabled? */
257 /* A list of JabberAdHocCommands supported by the server */
260 /* last presence update to check for differences */
261 JabberBuddyState old_state
;
264 char *old_avatarhash
;
266 /* same for user tune */
274 char *certificate_CN
;
276 /* A purple timeout tag for the keepalive */
277 guint keepalive_timeout
;
278 guint max_inactivity
;
279 guint inactivity_timer
;
280 guint conn_close_timeout
;
282 PurpleJabberBOSHConnection
*bosh
;
284 PurpleHttpConnectionSet
*http_conns
;
286 /* keep a hash table of JingleSessions */
287 GHashTable
*sessions
;
289 /* maybe this should only be present when USE_VV? */
293 /* stuff for Google's relay handling */
294 gchar
*google_relay_token
;
295 gchar
*google_relay_host
;
298 typedef gboolean (JabberFeatureEnabled
)(JabberStream
*js
, const gchar
*namespace);
300 typedef struct _JabberFeature
303 JabberFeatureEnabled
*is_enabled
;
306 typedef struct _JabberIdentity
314 typedef struct _JabberBytestreamsStreamhost
{
319 } JabberBytestreamsStreamhost
;
321 /* what kind of additional features as returned from disco#info are supported? */
322 extern GList
*jabber_features
;
323 /* A sorted list of identities advertised. Use jabber_add_identity to add
324 * so it remains sorted.
326 extern GList
*jabber_identities
;
329 * Returns the GType for the JabberProtocol object.
331 G_MODULE_EXPORT GType
jabber_protocol_get_type(void);
333 void jabber_stream_features_parse(JabberStream
*js
, PurpleXmlNode
*packet
);
334 void jabber_process_packet(JabberStream
*js
, PurpleXmlNode
**packet
);
335 void jabber_send(JabberStream
*js
, PurpleXmlNode
*data
);
336 void jabber_send_raw(JabberStream
*js
, const char *data
, int len
);
337 void jabber_send_signal_cb(PurpleConnection
*pc
, PurpleXmlNode
**packet
,
340 void jabber_stream_set_state(JabberStream
*js
, JabberStreamState state
);
342 void jabber_register_parse(JabberStream
*js
, const char *from
,
343 JabberIqType type
, const char *id
, PurpleXmlNode
*query
);
344 void jabber_register_start(JabberStream
*js
);
346 char *jabber_get_next_id(JabberStream
*js
);
348 /** Parse an error into a human-readable string and optionally a disconnect
350 * @param js the stream on which the error occurred.
351 * @param packet the error packet
352 * @param reason where to store the disconnection reason, or @c NULL if you
353 * don't care or you don't intend to close the connection.
355 char *jabber_parse_error(JabberStream
*js
, PurpleXmlNode
*packet
, PurpleConnectionError
*reason
);
358 * Add a feature to the list of features advertised via disco#info. If you
359 * call this while accounts are connected, Bad Things(TM) will happen because
360 * the Entity Caps hash will be out-of-date (which should be fixed :/)
362 * @param namespace The namespace of the feature
363 * @param cb A callback determining whether or not this feature
364 * will advertised; may be NULL.
366 void jabber_add_feature(const gchar
*namespace, JabberFeatureEnabled cb
);
367 void jabber_remove_feature(const gchar
*namespace);
369 /** Adds an identity to this jabber library instance. For list of valid values
370 * visit the website of the XMPP Registrar
371 * (http://xmpp.org/registrar/disco-categories.html#client)
373 * Like with jabber_add_feature, if you call this while accounts are connected,
374 * Bad Things will happen.
376 * @param category the category of the identity.
377 * @param type the type of the identity.
378 * @param language the language localization of the name. Can be NULL.
379 * @param name the name of the identity.
381 void jabber_add_identity(const gchar
*category
, const gchar
*type
, const gchar
*lang
, const gchar
*name
);
384 * GCompareFunc for JabberIdentity structs.
386 gint
jabber_identity_compare(gconstpointer a
, gconstpointer b
);
389 * Returns true if this connection is over a secure (SSL) stream. Use this
390 * instead of checking js->gsc because BOSH stores its PurpleSslConnection
391 * members in its own data structure.
393 gboolean
jabber_stream_is_ssl(JabberStream
*js
);
396 * Restart the "we haven't sent anything in a while and should send
397 * something or the server will kick us off" timer (obviously
398 * called when sending something. It's exposed for BOSH.)
400 void jabber_stream_restart_inactivity_timer(JabberStream
*js
);
402 /** Protocol functions */
403 const char *jabber_list_icon(PurpleAccount
*a
, PurpleBuddy
*b
);
404 const char* jabber_list_emblem(PurpleBuddy
*b
);
405 char *jabber_status_text(PurpleBuddy
*b
);
406 void jabber_tooltip_text(PurpleBuddy
*b
, PurpleNotifyUserInfo
*user_info
, gboolean full
);
407 GList
*jabber_status_types(PurpleAccount
*account
);
408 void jabber_login(PurpleAccount
*account
);
409 void jabber_close(PurpleConnection
*gc
);
410 void jabber_idle_set(PurpleConnection
*gc
, int idle
);
411 void jabber_blocklist_parse_push(JabberStream
*js
, const char *from
,
412 JabberIqType type
, const char *id
,
413 PurpleXmlNode
*child
);
414 void jabber_request_block_list(JabberStream
*js
);
415 void jabber_add_deny(PurpleConnection
*gc
, const char *who
);
416 void jabber_rem_deny(PurpleConnection
*gc
, const char *who
);
417 void jabber_keepalive(PurpleConnection
*gc
);
418 void jabber_register_gateway(JabberStream
*js
, const char *gateway
);
419 void jabber_register_account(PurpleAccount
*account
);
420 void jabber_unregister_account(PurpleAccount
*account
, PurpleAccountUnregistrationCb cb
, void *user_data
);
421 gboolean
jabber_send_attention(PurpleConnection
*gc
, const char *username
, guint code
);
422 GList
*jabber_attention_types(PurpleAccount
*account
);
423 void jabber_convo_closed(PurpleConnection
*gc
, const char *who
);
424 PurpleChat
*jabber_find_blist_chat(PurpleAccount
*account
, const char *name
);
425 gboolean
jabber_offline_message(const PurpleBuddy
*buddy
);
426 int jabber_protocol_send_raw(PurpleConnection
*gc
, const char *buf
, int len
);
427 GList
*jabber_get_actions(PurpleConnection
*gc
);
429 gboolean
jabber_audio_enabled(JabberStream
*js
, const char *unused
);
430 gboolean
jabber_video_enabled(JabberStream
*js
, const char *unused
);
431 gboolean
jabber_initiate_media(PurpleAccount
*account
, const char *who
,
432 PurpleMediaSessionType type
);
433 PurpleMediaCaps
jabber_get_media_caps(PurpleAccount
*account
, const char *who
);
434 gboolean
jabber_can_receive_file(PurpleConnection
*gc
, const gchar
*who
);
436 #endif /* PURPLE_JABBER_H_ */