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
25 #ifndef PURPLE_JABBER_JABBER_H
26 #define PURPLE_JABBER_JABBER_H
30 /* JABBER_CAP_XHTML = 1 << 0, */
31 /* JABBER_CAP_COMPOSING = 1 << 1, */
32 JABBER_CAP_SI
= 1 << 2,
33 JABBER_CAP_SI_FILE_XFER
= 1 << 3,
34 JABBER_CAP_BYTESTREAMS
= 1 << 4,
35 JABBER_CAP_IBB
= 1 << 5,
36 JABBER_CAP_CHAT_STATES
= 1 << 6,
37 JABBER_CAP_IQ_SEARCH
= 1 << 7,
38 JABBER_CAP_IQ_REGISTER
= 1 << 8,
40 /* Google Talk extensions:
41 * https://developers.google.com/talk/jep_extensions/extensions
43 JABBER_CAP_GMAIL_NOTIFY
= 1 << 9,
44 JABBER_CAP_GOOGLE_ROSTER
= 1 << 10,
46 JABBER_CAP_PING
= 1 << 11,
47 JABBER_CAP_ADHOC
= 1 << 12,
48 JABBER_CAP_BLOCKING
= 1 << 13,
50 JABBER_CAP_ITEMS
= 1 << 14,
51 JABBER_CAP_ROSTER_VERSIONING
= 1 << 15,
53 JABBER_CAP_RETRIEVED
= 1 << 31
56 typedef struct _JabberStream JabberStream
;
58 #include <libxml/parser.h>
63 #include "attention.h"
64 #include "circularbuffer.h"
65 #include "connection.h"
68 #include "mediamanager.h"
73 #include "namespaces.h"
82 #ifdef HAVE_CYRUS_SASL
83 #include <sasl/sasl.h>
86 #define CAPS0115_NODE "https://pidgin.im/"
88 #define JABBER_TYPE_PROTOCOL (jabber_protocol_get_type())
89 #define JABBER_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), JABBER_TYPE_PROTOCOL, JabberProtocol))
90 #define JABBER_PROTOCOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), JABBER_TYPE_PROTOCOL, JabberProtocolClass))
91 #define JABBER_IS_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), JABBER_TYPE_PROTOCOL))
92 #define JABBER_IS_PROTOCOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), JABBER_TYPE_PROTOCOL))
93 #define JABBER_PROTOCOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), JABBER_TYPE_PROTOCOL, JabberProtocolClass))
95 #define JABBER_DEFAULT_REQUIRE_TLS "require_starttls"
97 /* Index into attention_types list */
101 JABBER_STREAM_OFFLINE
,
102 JABBER_STREAM_CONNECTING
,
103 JABBER_STREAM_INITIALIZING
,
104 JABBER_STREAM_INITIALIZING_ENCRYPTION
,
105 JABBER_STREAM_AUTHENTICATING
,
106 JABBER_STREAM_POST_AUTH
,
107 JABBER_STREAM_CONNECTED
112 PurpleProtocol parent
;
117 PurpleProtocolClass parent_class
;
118 } JabberProtocolClass
;
125 GCancellable
*cancellable
;
127 xmlParserCtxt
*context
;
128 PurpleXmlNode
*current
;
135 JabberSaslMech
*auth_mech
;
136 gpointer auth_mech_data
;
139 * The header from the opening <stream/> tag. This being NULL is treated
140 * as a special condition in the parsing code (signifying the next
141 * stanza started is an opening stream tag), and its being missing on
142 * the stream header is treated as a fatal error.
145 JabberStreamState state
;
150 * This boolean was added to eliminate a heinous bug where we would
151 * get into a loop with the server and move a buddy back and forth
152 * from one group to another.
154 * The sequence goes something like this:
155 * 1. Our resource and another resource both approve an authorization
156 * request at the exact same time. We put the buddy in group A and
157 * the other resource put the buddy in group B.
158 * 2. The server receives the roster add for group B and sends us a
160 * 3. We receive this roster push and modify our local blist. This
161 * triggers us to send a roster add for group B.
162 * 4. The server recieves our earlier roster add for group A and sends
164 * 5. We receive this roster push and modify our local blist. This
165 * triggers us to send a roster add for group A.
166 * 6. The server receives our earlier roster add for group B and sends
168 * (repeat steps 3 through 6 ad infinitum)
170 * This boolean is used to short-circuit the sending of a roster add
171 * when we receive a roster push.
173 * See these bug reports:
174 * https://trac.adium.im/ticket/8834
175 * https://developer.pidgin.im/ticket/5484
176 * https://developer.pidgin.im/ticket/6188
178 gboolean currently_parsing_roster_push
;
182 PurpleRoomlist
*roomlist
;
183 GList
*user_directories
;
185 GHashTable
*iq_callbacks
;
189 GList
*oob_file_transfers
;
190 GList
*file_transfers
;
196 JabberBuddy
*user_jb
;
198 PurpleConnection
*gc
;
199 PurpleSslConnection
*gsc
;
201 gboolean registration
;
203 char *initial_avatar_hash
;
205 GSList
*pending_avatar_requests
;
207 GSList
*pending_buddy_info_requests
;
209 PurpleCircularBuffer
*write_buffer
;
214 JabberCapabilities server_caps
;
218 char *gmail_last_time
;
219 char *gmail_last_tid
;
223 #ifdef HAVE_CYRUS_SASL
225 sasl_callback_t
*sasl_cb
;
226 sasl_secret_t
*sasl_secret
;
227 const char *current_mech
;
234 gchar
*sasl_password
;
237 gboolean unregistration
;
238 PurpleAccountUnregistrationCb unregistration_cb
;
239 void *unregistration_user_data
;
241 gboolean vcard_fetched
;
242 /* Timer at login to push updated avatar */
245 /* Entity Capabilities hash */
248 /* does the local server support PEP? */
251 /* Is Buzz enabled? */
254 /* A list of JabberAdHocCommands supported by the server */
257 /* last presence update to check for differences */
258 JabberBuddyState old_state
;
261 char *old_avatarhash
;
263 /* same for user tune */
271 char *certificate_CN
;
273 /* A purple timeout tag for the keepalive */
274 guint keepalive_timeout
;
275 guint max_inactivity
;
276 guint inactivity_timer
;
277 guint conn_close_timeout
;
279 PurpleJabberBOSHConnection
*bosh
;
281 PurpleHttpConnectionSet
*http_conns
;
283 /* keep a hash table of JingleSessions */
284 GHashTable
*sessions
;
286 /* maybe this should only be present when USE_VV? */
290 /* stuff for Google's relay handling */
291 gchar
*google_relay_token
;
292 gchar
*google_relay_host
;
295 typedef gboolean (JabberFeatureEnabled
)(JabberStream
*js
, const gchar
*namespace);
300 JabberFeatureEnabled
*is_enabled
;
316 } JabberBytestreamsStreamhost
;
318 /* what kind of additional features as returned from disco#info are supported? */
319 extern GList
*jabber_features
;
320 /* A sorted list of identities advertised. Use jabber_add_identity to add
321 * so it remains sorted.
323 extern GList
*jabber_identities
;
326 * Returns the GType for the JabberProtocol object.
328 G_MODULE_EXPORT GType
jabber_protocol_get_type(void);
330 void jabber_stream_features_parse(JabberStream
*js
, PurpleXmlNode
*packet
);
331 void jabber_process_packet(JabberStream
*js
, PurpleXmlNode
**packet
);
332 void jabber_send(JabberStream
*js
, PurpleXmlNode
*data
);
333 void jabber_send_raw(JabberStream
*js
, const char *data
, int len
);
334 void jabber_send_signal_cb(PurpleConnection
*pc
, PurpleXmlNode
**packet
,
337 void jabber_stream_set_state(JabberStream
*js
, JabberStreamState state
);
339 void jabber_register_parse(JabberStream
*js
, const char *from
,
340 JabberIqType type
, const char *id
, PurpleXmlNode
*query
);
341 void jabber_register_start(JabberStream
*js
);
343 char *jabber_get_next_id(JabberStream
*js
);
345 /** Parse an error into a human-readable string and optionally a disconnect
347 * @param js the stream on which the error occurred.
348 * @param packet the error packet
349 * @param reason where to store the disconnection reason, or @c NULL if you
350 * don't care or you don't intend to close the connection.
352 char *jabber_parse_error(JabberStream
*js
, PurpleXmlNode
*packet
, PurpleConnectionError
*reason
);
355 * Add a feature to the list of features advertised via disco#info. If you
356 * call this while accounts are connected, Bad Things(TM) will happen because
357 * the Entity Caps hash will be out-of-date (which should be fixed :/)
359 * @param namespace The namespace of the feature
360 * @param cb A callback determining whether or not this feature
361 * will advertised; may be NULL.
363 void jabber_add_feature(const gchar
*namespace, JabberFeatureEnabled cb
);
364 void jabber_remove_feature(const gchar
*namespace);
366 /** Adds an identity to this jabber library instance. For list of valid values
367 * visit the website of the XMPP Registrar
368 * (http://xmpp.org/registrar/disco-categories.html#client)
370 * Like with jabber_add_feature, if you call this while accounts are connected,
371 * Bad Things will happen.
373 * @param category the category of the identity.
374 * @param type the type of the identity.
375 * @param language the language localization of the name. Can be NULL.
376 * @param name the name of the identity.
378 void jabber_add_identity(const gchar
*category
, const gchar
*type
, const gchar
*lang
, const gchar
*name
);
381 * GCompareFunc for JabberIdentity structs.
383 gint
jabber_identity_compare(gconstpointer a
, gconstpointer b
);
386 * Returns true if this connection is over a secure (SSL) stream. Use this
387 * instead of checking js->gsc because BOSH stores its PurpleSslConnection
388 * members in its own data structure.
390 gboolean
jabber_stream_is_ssl(JabberStream
*js
);
393 * Restart the "we haven't sent anything in a while and should send
394 * something or the server will kick us off" timer (obviously
395 * called when sending something. It's exposed for BOSH.)
397 void jabber_stream_restart_inactivity_timer(JabberStream
*js
);
399 /** Protocol functions */
400 const char *jabber_list_icon(PurpleAccount
*a
, PurpleBuddy
*b
);
401 const char* jabber_list_emblem(PurpleBuddy
*b
);
402 char *jabber_status_text(PurpleBuddy
*b
);
403 void jabber_tooltip_text(PurpleBuddy
*b
, PurpleNotifyUserInfo
*user_info
, gboolean full
);
404 GList
*jabber_status_types(PurpleAccount
*account
);
405 void jabber_login(PurpleAccount
*account
);
406 void jabber_close(PurpleConnection
*gc
);
407 void jabber_idle_set(PurpleConnection
*gc
, int idle
);
408 void jabber_blocklist_parse_push(JabberStream
*js
, const char *from
,
409 JabberIqType type
, const char *id
,
410 PurpleXmlNode
*child
);
411 void jabber_request_block_list(JabberStream
*js
);
412 void jabber_add_deny(PurpleConnection
*gc
, const char *who
);
413 void jabber_rem_deny(PurpleConnection
*gc
, const char *who
);
414 void jabber_keepalive(PurpleConnection
*gc
);
415 void jabber_register_gateway(JabberStream
*js
, const char *gateway
);
416 void jabber_register_account(PurpleAccount
*account
);
417 void jabber_unregister_account(PurpleAccount
*account
, PurpleAccountUnregistrationCb cb
, void *user_data
);
418 gboolean
jabber_send_attention(PurpleProtocolAttention
*attn
, PurpleConnection
*gc
, const char *username
, guint code
);
419 GList
*jabber_attention_types(PurpleProtocolAttention
*attn
, PurpleAccount
*account
);
420 void jabber_convo_closed(PurpleConnection
*gc
, const char *who
);
421 PurpleChat
*jabber_find_blist_chat(PurpleAccount
*account
, const char *name
);
422 gboolean
jabber_offline_message(const PurpleBuddy
*buddy
);
423 int jabber_protocol_send_raw(PurpleConnection
*gc
, const char *buf
, int len
);
424 GList
*jabber_get_actions(PurpleConnection
*gc
);
426 gboolean
jabber_audio_enabled(JabberStream
*js
, const char *unused
);
427 gboolean
jabber_video_enabled(JabberStream
*js
, const char *unused
);
428 gboolean
jabber_initiate_media(PurpleAccount
*account
, const char *who
,
429 PurpleMediaSessionType type
);
430 PurpleMediaCaps
jabber_get_media_caps(PurpleAccount
*account
, const char *who
);
431 gboolean
jabber_can_receive_file(PurpleProtocolXfer
*xfer
, PurpleConnection
*gc
, const gchar
*who
);
433 #endif /* PURPLE_JABBER_JABBER_H */