001/**
002 *
003 * Copyright 2009 Jive Software.
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.jivesoftware.smack;
018
019import org.jivesoftware.smack.SmackException.NoResponseException;
020import org.jivesoftware.smack.SmackException.NotConnectedException;
021import org.jivesoftware.smack.filter.IQReplyFilter;
022import org.jivesoftware.smack.filter.StanzaFilter;
023import org.jivesoftware.smack.iqrequest.IQRequestHandler;
024import org.jivesoftware.smack.packet.ExtensionElement;
025import org.jivesoftware.smack.packet.IQ;
026import org.jivesoftware.smack.packet.Nonza;
027import org.jivesoftware.smack.packet.Stanza;
028
029import org.jxmpp.jid.DomainBareJid;
030import org.jxmpp.jid.EntityFullJid;
031
032/**
033 * The XMPPConnection interface provides an interface for connections to an XMPP server and
034 * implements shared methods which are used by the different types of connections (e.g.
035 * <code>XMPPTCPConnection</code> or <code>XMPPBOSHConnection</code>). To create a connection to an XMPP server
036 * a simple usage of this API might look like the following:
037 * 
038 * <pre>
039 * // Create a connection to the igniterealtime.org XMPP server.
040 * XMPPTCPConnection con = new XMPPTCPConnection("igniterealtime.org");
041 * // Connect to the server
042 * con.connect();
043 * // Most servers require you to login before performing other tasks.
044 * con.login("jsmith", "mypass");
045 * // Start a new conversation with John Doe and send him a message.
046 * ChatManager chatManager = ChatManager.getInstanceFor(con);
047 * chatManager.addIncomingListener(new IncomingChatMessageListener() {
048 *     public void newIncomingMessage(EntityBareJid from, Message message, Chat chat) {
049 *         // Print out any messages we get back to standard out.
050 *         System.out.println("Received message: " + message);
051 *     }
052 * });
053 * Chat chat = chatManager.chatWith("jdoe@igniterealtime.org");
054 * chat.send("Howdy!");
055 * // Disconnect from the server
056 * con.disconnect();
057 * </pre>
058 * <p>
059 * Note that the XMPPConnection interface does intentionally not declare any methods that manipulate
060 * the connection state, e.g. <code>connect()</code>, <code>disconnect()</code>. You should use the
061 * most specific connection type, e.g. <code>XMPPTCPConnection</code> as declared type and use the
062 * XMPPConnection interface when you don't need to manipulate the connection state.
063 * </p>
064 * <p>
065 * XMPPConnections can be reused between connections. This means that an Connection may be connected,
066 * disconnected and then connected again. Listeners of the XMPPConnection will be retained across
067 * connections.
068 * </p>
069 *
070 * @author Matt Tucker
071 * @author Guenther Niess
072 */
073public interface XMPPConnection {
074
075    /**
076     * Returns the name of the service provided by the XMPP server for this connection.
077     * This is also called XMPP domain of the connected server. After
078     * authenticating with the server the returned value may be different.
079     * 
080     * @return the name of the service provided by the XMPP server.
081     // TODO remove this once the java bugs are fixed, causing a warning
082//     * @deprecated use {@link #getXMPPServiceDomain()} instead.
083     */
084//    @Deprecated
085    public DomainBareJid getServiceName();
086
087    /**
088     * Returns the XMPP Domain of the service provided by the XMPP server and used for this connection. After
089     * authenticating with the server the returned value may be different.
090     * 
091     * @return the XMPP domain of this XMPP session.
092     */
093    public DomainBareJid getXMPPServiceDomain();
094
095    /**
096     * Returns the host name of the server where the XMPP server is running. This would be the
097     * IP address of the server or a name that may be resolved by a DNS server.
098     * 
099     * @return the host name of the server where the XMPP server is running or null if not yet connected.
100     */
101    public String getHost();
102
103    /**
104     * Returns the port number of the XMPP server for this connection. The default port
105     * for normal connections is 5222.
106     * 
107     * @return the port number of the XMPP server or 0 if not yet connected.
108     */
109    public int getPort();
110
111    /**
112     * Returns the full XMPP address of the user that is logged in to the connection or
113     * <tt>null</tt> if not logged in yet. An XMPP address is in the form
114     * username@server/resource.
115     * 
116     * @return the full XMPP address of the user logged in.
117     */
118    public EntityFullJid getUser();
119
120    /**
121     * Returns the stream ID for this connection, which is the value set by the server
122     * when opening an XMPP stream. This value will be <tt>null</tt> if not connected to the server.
123     * 
124     * @return the ID of this connection returned from the XMPP server or <tt>null</tt> if
125     *      not connected to the server.
126     * @see <a href="http://xmpp.org/rfcs/rfc6120.html#streams-attr-id">RFC 6120 ยง 4.7.3. id</a>
127     */
128    public String getStreamId();
129
130    /**
131     * Returns true if currently connected to the XMPP server.
132     * 
133     * @return true if connected.
134     */
135    public boolean isConnected();
136
137    /**
138     * Returns true if currently authenticated by successfully calling the login method.
139     * 
140     * @return true if authenticated.
141     */
142    public boolean isAuthenticated();
143
144    /**
145     * Returns true if currently authenticated anonymously.
146     * 
147     * @return true if authenticated anonymously.
148     */
149    public boolean isAnonymous();
150
151    /**
152     * Returns true if the connection to the server has successfully negotiated encryption. 
153     * 
154     * @return true if a secure connection to the server.
155     */
156    public boolean isSecureConnection();
157
158    /**
159     * Returns true if network traffic is being compressed. When using stream compression network
160     * traffic can be reduced up to 90%. Therefore, stream compression is ideal when using a slow
161     * speed network connection. However, the server will need to use more CPU time in order to
162     * un/compress network data so under high load the server performance might be affected.
163     * 
164     * @return true if network traffic is being compressed.
165     */
166    public boolean isUsingCompression();
167
168    /**
169     * Sends the specified stanza(/packet) to the server.
170     * 
171     * @param packet the stanza(/packet) to send.
172     * @throws NotConnectedException 
173     * @throws InterruptedException 
174     * @deprecated use {@link #sendStanza(Stanza)} instead.
175     */
176    @Deprecated
177    public void sendPacket(Stanza packet) throws NotConnectedException, InterruptedException;
178
179    /**
180     * Sends the specified stanza to the server.
181     *
182     * @param stanza the stanza to send.
183     * @throws NotConnectedException if the connection is not connected.
184     * @throws InterruptedException
185     * */
186    public void sendStanza(Stanza stanza) throws NotConnectedException, InterruptedException;
187
188    /**
189     * Send a Nonza.
190     * <p>
191     * <b>This method is not meant for end-user usage!</b> It allows sending plain stream elements, which should not be
192     * done by a user manually. <b>Doing so may result in a unstable or unusable connection.</b> Certain Smack APIs use
193     * this method to send plain stream elements.
194     * </p>
195     *
196     * @param nonza the Nonza to send.
197     * @throws NotConnectedException
198     * @throws InterruptedException 
199     */
200    public void sendNonza(Nonza nonza) throws NotConnectedException, InterruptedException;
201
202    /**
203     * Adds a connection listener to this connection that will be notified when
204     * the connection closes or fails.
205     * 
206     * @param connectionListener a connection listener.
207     */
208    public void addConnectionListener(ConnectionListener connectionListener);
209
210    /**
211     * Removes a connection listener from this connection.
212     * 
213     * @param connectionListener a connection listener.
214     */
215    public void removeConnectionListener(ConnectionListener connectionListener);
216
217    /**
218     * Creates a new stanza(/packet) collector collecting packets that are replies to <code>packet</code>.
219     * Does also send <code>packet</code>. The stanza(/packet) filter for the collector is an
220     * {@link IQReplyFilter}, guaranteeing that stanza(/packet) id and JID in the 'from' address have
221     * expected values.
222     *
223     * @param packet the stanza(/packet) to filter responses from
224     * @return a new stanza(/packet) collector.
225     * @throws NotConnectedException 
226     * @throws InterruptedException 
227     */
228    public StanzaCollector createStanzaCollectorAndSend(IQ packet) throws NotConnectedException, InterruptedException;
229
230    /**
231     * Creates a new stanza(/packet) collector for this connection. A stanza(/packet) filter determines
232     * which packets will be accumulated by the collector. A StanzaCollector is
233     * more suitable to use than a {@link StanzaListener} when you need to wait for
234     * a specific result.
235     * 
236     * @param packetFilter the stanza(/packet) filter to use.
237     * @param packet the packet to send right after the collector got created
238     * @return a new stanza(/packet) collector.
239     * @throws InterruptedException 
240     * @throws NotConnectedException 
241     */
242    public StanzaCollector createStanzaCollectorAndSend(StanzaFilter packetFilter, Stanza packet)
243                    throws NotConnectedException, InterruptedException;
244
245    /**
246     * Creates a new stanza(/packet) collector for this connection. A stanza(/packet) filter
247     * determines which packets will be accumulated by the collector. A
248     * StanzaCollector is more suitable to use than a {@link StanzaListener}
249     * when you need to wait for a specific result.
250     * <p>
251     * <b>Note:</b> If you send a Stanza(/Packet) right after using this method, then
252     * consider using
253     * {@link #createStanzaCollectorAndSend(StanzaFilter, Stanza)} instead.
254     * Otherwise make sure cancel the StanzaCollector in every case, e.g. even
255     * if an exception is thrown, or otherwise you may leak the StanzaCollector.
256     * </p>
257     * 
258     * @param packetFilter the stanza(/packet) filter to use.
259     * @return a new stanza(/packet) collector.
260     */
261    public StanzaCollector createStanzaCollector(StanzaFilter packetFilter);
262
263    /**
264     * Create a new stanza(/packet) collector with the given stanza(/packet) collector configuration.
265     * <p>
266     * Please make sure to cancel the collector when it is no longer required. See also
267     * {@link #createStanzaCollector(StanzaFilter)}.
268     * </p>
269     * 
270     * @param configuration the stanza(/packet) collector configuration.
271     * @return a new stanza(/packet) collector.
272     * @since 4.1
273     */
274    public StanzaCollector createStanzaCollector(StanzaCollector.Configuration configuration);
275
276    /**
277     * Remove a stanza(/packet) collector of this connection.
278     * 
279     * @param collector a stanza(/packet) collectors which was created for this connection.
280     */
281    public void removeStanzaCollector(StanzaCollector collector);
282
283    /**
284     * Registers a stanza(/packet) listener with this connection.
285     * <p>
286     * This method has been deprecated. It is important to differentiate between using an asynchronous stanza(/packet) listener
287     * (preferred where possible) and a synchronous stanza(/packet) lister. Refer
288     * {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)} and
289     * {@link #addSyncStanzaListener(StanzaListener, StanzaFilter)} for more information.
290     * </p>
291     *
292     * @param packetListener the stanza(/packet) listener to notify of new received packets.
293     * @param packetFilter the stanza(/packet) filter to use.
294     * @deprecated use {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)} or
295     *             {@link #addSyncStanzaListener(StanzaListener, StanzaFilter)}.
296     */
297    @Deprecated
298    public void addPacketListener(StanzaListener packetListener, StanzaFilter packetFilter);
299
300    /**
301     * Removes a stanza(/packet) listener for received packets from this connection.
302     * 
303     * @param packetListener the stanza(/packet) listener to remove.
304     * @return true if the stanza(/packet) listener was removed
305     * @deprecated use {@link #removeAsyncStanzaListener(StanzaListener)} or {@link #removeSyncStanzaListener(StanzaListener)}.
306     */
307    @Deprecated
308    public boolean removePacketListener(StanzaListener packetListener);
309
310    /**
311     * Registers a <b>synchronous</b> stanza(/packet) listener with this connection. A stanza(/packet) listener will be invoked only when
312     * an incoming stanza(/packet) is received. A stanza(/packet) filter determines which packets will be delivered to the listener. If
313     * the same stanza(/packet) listener is added again with a different filter, only the new filter will be used.
314     * <p>
315     * <b>Important:</b> This stanza(/packet) listeners will be called in the same <i>single</i> thread that processes all
316     * incoming stanzas. Only use this kind of stanza(/packet) filter if it does not perform any XMPP activity that waits for a
317     * response. Consider using {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)} when possible, i.e. when
318     * the invocation order doesn't have to be the same as the order of the arriving packets. If the order of the
319     * arriving packets, consider using a {@link StanzaCollector} when possible.
320     * </p>
321     *
322     * @param packetListener the stanza(/packet) listener to notify of new received packets.
323     * @param packetFilter the stanza(/packet) filter to use.
324     * @see #addStanzaInterceptor(StanzaListener, StanzaFilter)
325     * @since 4.1
326     */
327    public void addSyncStanzaListener(StanzaListener packetListener, StanzaFilter packetFilter);
328
329    /**
330     * Removes a stanza(/packet) listener for received packets from this connection.
331     *
332     * @param packetListener the stanza(/packet) listener to remove.
333     * @return true if the stanza(/packet) listener was removed
334     * @since 4.1
335     */
336    public boolean removeSyncStanzaListener(StanzaListener packetListener);
337
338    /**
339     * Registers an <b>asynchronous</b> stanza(/packet) listener with this connection. A stanza(/packet) listener will be invoked only
340     * when an incoming stanza(/packet) is received. A stanza(/packet) filter determines which packets will be delivered to the listener.
341     * If the same stanza(/packet) listener is added again with a different filter, only the new filter will be used.
342     * <p>
343     * Unlike {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)} stanza(/packet) listeners added with this method will be
344     * invoked asynchronously in their own thread. Use this method if the order of the stanza(/packet) listeners must not depend
345     * on the order how the stanzas where received.
346     * </p>
347     * 
348     * @param packetListener the stanza(/packet) listener to notify of new received packets.
349     * @param packetFilter the stanza(/packet) filter to use.
350     * @see #addStanzaInterceptor(StanzaListener, StanzaFilter)
351     * @since 4.1
352    */
353    public void addAsyncStanzaListener(StanzaListener packetListener, StanzaFilter packetFilter);
354
355    /**
356     * Removes an <b>asynchronous</b> stanza(/packet) listener for received packets from this connection.
357     * 
358     * @param packetListener the stanza(/packet) listener to remove.
359     * @return true if the stanza(/packet) listener was removed
360     * @since 4.1
361     */
362    public boolean removeAsyncStanzaListener(StanzaListener packetListener);
363
364    /**
365     * Registers a stanza(/packet) listener with this connection. The listener will be
366     * notified of every stanza(/packet) that this connection sends. A stanza(/packet) filter determines
367     * which packets will be delivered to the listener. Note that the thread
368     * that writes packets will be used to invoke the listeners. Therefore, each
369     * stanza(/packet) listener should complete all operations quickly or use a different
370     * thread for processing.
371     * 
372     * @param packetListener the stanza(/packet) listener to notify of sent packets.
373     * @param packetFilter   the stanza(/packet) filter to use.
374     * @deprecated use {@link #addStanzaSendingListener} instead
375     */
376    // TODO Remove in Smack 4.4
377    @Deprecated
378    public void addPacketSendingListener(StanzaListener packetListener, StanzaFilter packetFilter);
379
380    /**
381     * Registers a stanza(/packet) listener with this connection. The listener will be
382     * notified of every stanza(/packet) that this connection sends. A stanza(/packet) filter determines
383     * which packets will be delivered to the listener. Note that the thread
384     * that writes packets will be used to invoke the listeners. Therefore, each
385     * stanza(/packet) listener should complete all operations quickly or use a different
386     * thread for processing.
387     *
388     * @param packetListener the stanza(/packet) listener to notify of sent packets.
389     * @param packetFilter   the stanza(/packet) filter to use.
390     */
391    public void addStanzaSendingListener(StanzaListener packetListener, StanzaFilter packetFilter);
392
393    /**
394     * Removes a stanza(/packet) listener for sending packets from this connection.
395     * 
396     * @param packetListener the stanza(/packet) listener to remove.
397     * @deprecated use {@link #removeStanzaSendingListener} instead
398     */
399    // TODO Remove in Smack 4.4
400    @Deprecated
401    public void removePacketSendingListener(StanzaListener packetListener);
402
403    /**
404     * Removes a stanza(/packet) listener for sending packets from this connection.
405     *
406     * @param packetListener the stanza(/packet) listener to remove.
407     */
408    public void removeStanzaSendingListener(StanzaListener packetListener);
409
410    /**
411     * Registers a stanza(/packet) interceptor with this connection. The interceptor will be
412     * invoked every time a stanza(/packet) is about to be sent by this connection. Interceptors
413     * may modify the stanza(/packet) to be sent. A stanza(/packet) filter determines which packets
414     * will be delivered to the interceptor.
415     * 
416     * <p>
417     * NOTE: For a similar functionality on incoming packets, see {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}.
418     * </p>
419     *
420     * @param packetInterceptor the stanza(/packet) interceptor to notify of packets about to be sent.
421     * @param packetFilter      the stanza(/packet) filter to use.
422     * @deprecated use {@link #addStanzaInterceptor} instead
423     */
424    // TODO Remove in Smack 4.4
425    @Deprecated
426    public void addPacketInterceptor(StanzaListener packetInterceptor, StanzaFilter packetFilter);
427
428    /**
429     * Registers a stanza(/packet) interceptor with this connection. The interceptor will be
430     * invoked every time a stanza(/packet) is about to be sent by this connection. Interceptors
431     * may modify the stanza(/packet) to be sent. A stanza(/packet) filter determines which packets
432     * will be delivered to the interceptor.
433     *
434     * <p>
435     * NOTE: For a similar functionality on incoming packets, see {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}.
436     * </p>
437     *
438     * @param packetInterceptor the stanza(/packet) interceptor to notify of packets about to be sent.
439     * @param packetFilter      the stanza(/packet) filter to use.
440     */
441    public void addStanzaInterceptor(StanzaListener packetInterceptor, StanzaFilter packetFilter);
442
443    /**
444     * Removes a stanza(/packet) interceptor.
445     *
446     * @param packetInterceptor the stanza(/packet) interceptor to remove.
447     * @deprecated user {@link #removeStanzaInterceptor} instead
448     */
449    // TODO Remove in Smack 4.4
450    @Deprecated
451    public void removePacketInterceptor(StanzaListener packetInterceptor);
452
453    /**
454     * Removes a stanza(/packet) interceptor.
455     *
456     * @param packetInterceptor the stanza(/packet) interceptor to remove.
457     */
458    public void removeStanzaInterceptor(StanzaListener packetInterceptor);
459
460    /**
461     * Returns the current value of the reply timeout in milliseconds for request for this
462     * XMPPConnection instance.
463     *
464     * @return the stanza(/packet) reply timeout in milliseconds
465     * @deprecated use {@link #getReplyTimeout()} instead.
466     */
467    @Deprecated
468    // TODO Remove in Smack 4.3
469    public long getPacketReplyTimeout();
470
471    /**
472     * Set the stanza(/packet) reply timeout in milliseconds. In most cases, Smack will throw a
473     * {@link NoResponseException} if no reply to a request was received within the timeout period.
474     *
475     * @param timeout the stanza(/packet) reply timeout in milliseconds
476     * @deprecated use {@link #setReplyTimeout(long)} instead.
477     */
478    @Deprecated
479    // TODO Remove in Smack 4.3
480    public void setPacketReplyTimeout(long timeout);
481
482    /**
483     * Returns the current value of the reply timeout in milliseconds for request for this
484     * XMPPConnection instance.
485     *
486     * @return the reply timeout in milliseconds
487     */
488    public long getReplyTimeout();
489
490    /**
491     * Set the stanza(/packet) reply timeout in milliseconds. In most cases, Smack will throw a
492     * {@link NoResponseException} if no reply to a request was received within the timeout period.
493     *
494     * @param timeout for a reply in milliseconds
495     */
496    public void setReplyTimeout(long timeout);
497
498    /**
499     * Get the connection counter of this XMPPConnection instance. Those can be used as ID to
500     * identify the connection, but beware that the ID may not be unique if you create more then
501     * <tt>2*Integer.MAX_VALUE</tt> instances as the counter could wrap.
502     *
503     * @return the connection counter of this XMPPConnection
504     */
505    public int getConnectionCounter();
506
507    public static enum FromMode {
508        /**
509         * Leave the 'from' attribute unchanged. This is the behavior of Smack &lt; 4.0
510         */
511        UNCHANGED,
512        /**
513         * Omit the 'from' attribute. According to RFC 6120 8.1.2.1 1. XMPP servers "MUST (...)
514         * override the 'from' attribute specified by the client". It is therefore safe to specify
515         * FromMode.OMITTED here.
516         */
517        OMITTED,
518        /**
519         * Set the from to the clients full JID. This is usually not required.
520         */
521        USER
522    }
523
524    /**
525     * Set the FromMode for this connection instance. Defines how the 'from' attribute of outgoing
526     * stanzas should be populated by Smack.
527     * 
528     * @param fromMode
529     */
530    public void setFromMode(FromMode fromMode);
531
532    /**
533     * Get the currently active FromMode.
534     *
535     * @return the currently active {@link FromMode}
536     */
537    public FromMode getFromMode();
538
539    /**
540     * Get the feature stanza(/packet) extensions for a given stream feature of the
541     * server, or <code>null</code> if the server doesn't support that feature.
542     *
543     * @param <F> {@link ExtensionElement} type of the feature.
544     * @param element
545     * @param namespace
546     * @return a stanza(/packet) extensions of the feature or <code>null</code>
547     */
548    public <F extends ExtensionElement> F getFeature(String element, String namespace);
549
550    /**
551     * Return true if the server supports the given stream feature.
552     * 
553     * @param element
554     * @param namespace
555     * @return true if the server supports the stream feature.
556     */
557    public boolean hasFeature(String element, String namespace);
558
559    /**
560     * Send a stanza and wait asynchronously for a response by using <code>replyFilter</code>.
561     * <p>
562     * If there is a response, then <code>callback</code> will be invoked. The callback will be
563     * invoked at most once and it will be not invoked after the connections default reply timeout
564     * has been elapsed.
565     * </p>
566     * 
567     * @param stanza the stanza to send (required)
568     * @param replyFilter the filter used to determine response stanza (required)
569     * @param callback the callback invoked if there is a response (required)
570     * @throws NotConnectedException
571     * @throws InterruptedException 
572     */
573    public void sendStanzaWithResponseCallback(Stanza stanza, StanzaFilter replyFilter,
574                    StanzaListener callback) throws NotConnectedException, InterruptedException;
575
576    /**
577     * Send a stanza and wait asynchronously for a response by using <code>replyFilter</code>.
578     * <p>
579     * If there is a response, then <code>callback</code> will be invoked. If there is no response
580     * after the connections default reply timeout, then <code>exceptionCallback</code> will be invoked
581     * with a {@link SmackException.NoResponseException}. The callback will be invoked at most once.
582     * </p>
583     * 
584     * @param stanza the stanza to send (required)
585     * @param replyFilter the filter used to determine response stanza (required)
586     * @param callback the callback invoked if there is a response (required)
587     * @param exceptionCallback the callback invoked if there is an exception (optional)
588     * @throws NotConnectedException
589     * @throws InterruptedException 
590     */
591    public void sendStanzaWithResponseCallback(Stanza stanza, StanzaFilter replyFilter, StanzaListener callback,
592                    ExceptionCallback exceptionCallback) throws NotConnectedException, InterruptedException;
593
594    /**
595     * Send a stanza and wait asynchronously for a response by using <code>replyFilter</code>.
596     * <p>
597     * If there is a response, then <code>callback</code> will be invoked. If there is no response
598     * after <code>timeout</code> milliseconds, then <code>exceptionCallback</code> will be invoked
599     * with a {@link SmackException.NoResponseException}. The callback will be invoked at most once.
600     * </p>
601     * 
602     * @param stanza the stanza to send (required)
603     * @param replyFilter the filter used to determine response stanza (required)
604     * @param callback the callback invoked if there is a response (required)
605     * @param exceptionCallback the callback invoked if there is an exception (optional)
606     * @param timeout the timeout in milliseconds to wait for a response
607     * @throws NotConnectedException
608     * @throws InterruptedException 
609     */
610    public void sendStanzaWithResponseCallback(Stanza stanza, StanzaFilter replyFilter,
611                    final StanzaListener callback, final ExceptionCallback exceptionCallback,
612                    long timeout) throws NotConnectedException, InterruptedException;
613
614    /**
615     * Send a IQ stanza and invoke <code>callback</code> if there is a result of
616     * {@link org.jivesoftware.smack.packet.IQ.Type#result} with that result IQ. The callback will
617     * not be invoked after the connections default reply timeout has been elapsed.
618     * 
619     * @param iqRequest the IQ stanza to send (required)
620     * @param callback the callback invoked if there is result response (required)
621     * @throws NotConnectedException
622     * @throws InterruptedException 
623     */
624    public void sendIqWithResponseCallback(IQ iqRequest, StanzaListener callback) throws NotConnectedException, InterruptedException;
625
626    /**
627     * Send a IQ stanza and invoke <code>callback</code> if there is a result of
628     * {@link org.jivesoftware.smack.packet.IQ.Type#result} with that result IQ. If there is an
629     * error response <code>exceptionCallback</code> will be invoked, if not null, with the received
630     * error as {@link XMPPException.XMPPErrorException}. If there is no response after the
631     * connections default reply timeout, then <code>exceptionCallback</code> will be invoked with a
632     * {@link SmackException.NoResponseException}.
633     * 
634     * @param iqRequest the IQ stanza to send (required)
635     * @param callback the callback invoked if there is result response (required)
636     * @param exceptionCallback the callback invoked if there is an Exception optional
637     * @throws NotConnectedException
638     * @throws InterruptedException 
639     */
640    public void sendIqWithResponseCallback(IQ iqRequest, StanzaListener callback,
641                    ExceptionCallback exceptionCallback) throws NotConnectedException, InterruptedException;
642
643    /**
644     * Send a IQ stanza and invoke <code>callback</code> if there is a result of
645     * {@link org.jivesoftware.smack.packet.IQ.Type#result} with that result IQ. If there is an
646     * error response <code>exceptionCallback</code> will be invoked, if not null, with the received
647     * error as {@link XMPPException.XMPPErrorException}. If there is no response after
648     * <code>timeout</code>, then <code>exceptionCallback</code> will be invoked with a
649     * {@link SmackException.NoResponseException}.
650     * 
651     * @param iqRequest the IQ stanza to send (required)
652     * @param callback the callback invoked if there is result response (required)
653     * @param exceptionCallback the callback invoked if there is an Exception optional
654     * @param timeout the timeout in milliseconds to wait for a response
655     * @throws NotConnectedException
656     * @throws InterruptedException 
657     */
658    public void sendIqWithResponseCallback(IQ iqRequest, final StanzaListener callback,
659                    final ExceptionCallback exceptionCallback, long timeout)
660                    throws NotConnectedException, InterruptedException;
661
662    /**
663     * Add a callback that is called exactly once and synchronously with the incoming stanza that matches the given
664     * stanza(/packet) filter.
665     * 
666     * @param callback the callback invoked once the stanza(/packet) filter matches a stanza.
667     * @param packetFilter the filter to match stanzas or null to match all.
668     */
669    public void addOneTimeSyncCallback(StanzaListener callback, StanzaFilter packetFilter);
670
671    /**
672     * Register an IQ request handler with this connection.
673     * <p>
674     * IQ request handler process incoming IQ requests, i.e. incoming IQ stanzas of type 'get' or 'set', and return a result.
675     * </p>
676     * @param iqRequestHandler the IQ request handler to register.
677     * @return the previously registered IQ request handler or null.
678     */
679    public IQRequestHandler registerIQRequestHandler(IQRequestHandler iqRequestHandler);
680
681    /**
682     * Convenience method for {@link #unregisterIQRequestHandler(String, String, org.jivesoftware.smack.packet.IQ.Type)}.
683     *
684     * @param iqRequestHandler
685     * @return the previously registered IQ request handler or null.
686     */
687    public IQRequestHandler unregisterIQRequestHandler(IQRequestHandler iqRequestHandler);
688
689    /**
690     * Unregister an IQ request handler with this connection.
691     * 
692     * @param element the IQ element the IQ request handler is responsible for.
693     * @param namespace the IQ namespace the IQ request handler is responsible for.
694     * @param type the IQ type the IQ request handler is responsible for.
695     * @return the previously registered IQ request handler or null.
696     */
697    public IQRequestHandler unregisterIQRequestHandler(String element, String namespace, IQ.Type type);
698
699    /**
700     * Returns the timestamp in milliseconds when the last stanza was received.
701     * 
702     * @return the timestamp in milliseconds
703     */
704    public long getLastStanzaReceived();
705
706}