1034 lines
32 KiB
C++
1034 lines
32 KiB
C++
/**
|
|
* yatejabber.h
|
|
* Yet Another Jabber Component Protocol Stack
|
|
* This file is part of the YATE Project http://YATE.null.ro
|
|
*
|
|
* Yet Another Telephony Engine - a fully featured software PBX and IVR
|
|
* Copyright (C) 2004-2006 Null Team
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#ifndef __YATEJABBER_H
|
|
#define __YATEJABBER_H
|
|
|
|
#include <xmpputils.h>
|
|
#include <xmlparser.h>
|
|
|
|
/**
|
|
* Holds all Telephony Engine related classes.
|
|
*/
|
|
namespace TelEngine {
|
|
|
|
class JBEvent;
|
|
class JBComponentStream;
|
|
class JBServerInfo;
|
|
class JBEngine;
|
|
class JBClient;
|
|
class JBPresence;
|
|
|
|
/**
|
|
* This class holds a Jabber Component stream event.
|
|
* @short A Jabber Component event.
|
|
*/
|
|
class YJINGLE_API JBEvent : public RefObject
|
|
{
|
|
friend class JBComponentStream;
|
|
public:
|
|
enum Type {
|
|
// Stream events
|
|
Terminated = 1, // Stream terminated. Try to connect
|
|
Destroy = 2, // Stream is destroying
|
|
// Result events
|
|
WriteFail = 10, // Write failed
|
|
// m_element is the element
|
|
// m_id is the id set by the sender
|
|
// Stanza events
|
|
Presence = 20, // m_element is a 'presence' stanza
|
|
Message = 30, // m_element is a 'message' stanza
|
|
Iq = 50, // m_element is an unknown 'iq' element
|
|
// m_child may be an unexpected element
|
|
IqError = 51, // m_element is an 'iq' error
|
|
// m_child is the 'error' child if any
|
|
IqResult = 52, // m_element is an 'iq' result
|
|
IqDiscoGet = 60, // m_element is an 'iq' get
|
|
// m_child is a 'query' element qualified by
|
|
// XMPPNamespace::DiscoInfo namespace
|
|
IqDiscoSet = 61, // m_element is an 'iq' set
|
|
// m_child is a 'query' element qualified by
|
|
// XMPPNamespace::DiscoInfo namespace
|
|
IqDiscoRes = 62, // m_element is an 'iq' result
|
|
// m_child is a 'query' element qualified by
|
|
// XMPPNamespace::DiscoInfo namespace
|
|
IqJingleGet = 100, // m_element is an 'iq' get
|
|
// m_child is a 'jingle' element
|
|
IqJingleSet = 101, // m_element is an 'iq' set
|
|
// m_child is a 'jingle' element
|
|
// Invalid
|
|
Unhandled = 200, // m_element is an unhandled element
|
|
Invalid = 500, // m_element is 0
|
|
};
|
|
|
|
/**
|
|
* Destructor.
|
|
* Delete the XML element if valid.
|
|
*/
|
|
virtual ~JBEvent();
|
|
|
|
/**
|
|
* Get the event type.
|
|
* @return the type of this event as enumeration.
|
|
*/
|
|
inline Type type() const
|
|
{ return m_type; }
|
|
|
|
/**
|
|
* Get the element's 'type' attribute if any.
|
|
* @return The element's 'type' attribute.
|
|
*/
|
|
inline const String& stanzaType() const
|
|
{ return m_stanzaType; }
|
|
|
|
/**
|
|
* Get the 'from' data.
|
|
* @return The 'from' data.
|
|
*/
|
|
inline const String& from() const
|
|
{ return m_from; }
|
|
|
|
/**
|
|
* Get the 'to' data.
|
|
* @return The 'to' data.
|
|
*/
|
|
inline const String& to() const
|
|
{ return m_to; }
|
|
|
|
/**
|
|
* Get the 'id' data.
|
|
* @return The 'id' data.
|
|
*/
|
|
inline const String& id() const
|
|
{ return m_id; }
|
|
|
|
/**
|
|
* Get the stream.
|
|
* @return The stream.
|
|
*/
|
|
inline JBComponentStream* stream() const
|
|
{ return m_stream; }
|
|
|
|
/**
|
|
* Get the underlying XMLElement.
|
|
* @return XMLElement pointer or 0.
|
|
*/
|
|
inline XMLElement* element() const
|
|
{ return m_element; }
|
|
|
|
/**
|
|
* Get the first child of the underlying element if any.
|
|
* @return XMLElement pointer or 0.
|
|
*/
|
|
inline XMLElement* child() const
|
|
{ return m_child; }
|
|
|
|
/**
|
|
* Get the underlying XMLElement. Release the ownership.
|
|
* The caller is responsable of returned pointer.
|
|
* @return XMLElement pointer or 0.
|
|
*/
|
|
inline XMLElement* releaseXML() {
|
|
XMLElement* tmp = m_element;
|
|
m_element = 0;
|
|
return tmp;
|
|
}
|
|
|
|
/**
|
|
* Release the link with the stream to let the stream continue with events.
|
|
*/
|
|
void releaseStream();
|
|
|
|
protected:
|
|
/**
|
|
* Constructor.
|
|
* Constructs an internal stream event.
|
|
* @param type Type of this event.
|
|
* @param stream The stream that generated the event.
|
|
*/
|
|
JBEvent(Type type, JBComponentStream* stream);
|
|
|
|
/**
|
|
* Constructor.
|
|
* Constructs an event from a stream.
|
|
* @param type Type of this event.
|
|
* @param stream The stream that generated the event.
|
|
* @param element Element that generated the event.
|
|
* @param child Optional type depending element's child.
|
|
*/
|
|
JBEvent(Type type, JBComponentStream* stream,
|
|
XMLElement* element, XMLElement* child = 0);
|
|
|
|
/**
|
|
* Constructor.
|
|
* Constructs a WriteSuccess/WriteFail event from a stream.
|
|
* @param type Type of this event.
|
|
* @param stream The stream that generated the event.
|
|
* @param element Element that generated the event.
|
|
* @param senderID Sender's id.
|
|
*/
|
|
JBEvent(Type type, JBComponentStream* stream, XMLElement* element,
|
|
const String& senderID);
|
|
|
|
private:
|
|
JBEvent() {} // Don't use it!
|
|
bool init(JBComponentStream* stream, XMLElement* element);
|
|
|
|
Type m_type; // Type of this event
|
|
JBComponentStream* m_stream; // The stream that generated this event
|
|
bool m_link; // Stream link state
|
|
XMLElement* m_element; // Received XML element, if any
|
|
XMLElement* m_child; // The first child element for 'iq' elements
|
|
String m_stanzaType; // Stanza's 'type' attribute
|
|
String m_from; // Stanza's 'from' attribute
|
|
String m_to; // Stanza's 'to' attribute
|
|
String m_id; // Sender's id for Write... events
|
|
// 'id' attribute if the received stanza has one
|
|
};
|
|
|
|
/**
|
|
* This class holds a Jabber Component stream (implements the Jabber Component Protocol).
|
|
* @short A Jabber Component stream.
|
|
*/
|
|
class YJINGLE_API JBComponentStream : public RefObject, public Mutex
|
|
{
|
|
public:
|
|
friend class JBEngine;
|
|
public:
|
|
/**
|
|
* Stream state enumeration.
|
|
*/
|
|
enum State {
|
|
WaitToConnect, // Outgoing stream is waiting for the socket to connect
|
|
Started, // Stream start sent
|
|
Auth, // Authentication (handshake) sent
|
|
Running, // Authenticated. Allow any XML element to pass over the stream
|
|
Terminated, // Stream is terminated. Wait to be restarted or destroyed
|
|
Destroy, // Stream is destroying. No more traffic allowed
|
|
};
|
|
|
|
/**
|
|
* Values returned by send() methods.
|
|
*/
|
|
enum Error {
|
|
ErrorNone = 0, // No error
|
|
ErrorContext, // Invalid stream context (state) or parameters.
|
|
ErrorPending, // The operation is pending in the stream's queue.
|
|
ErrorNoSocket, // Unrecoverable socket error.
|
|
// The stream will be terminated.
|
|
};
|
|
|
|
/**
|
|
* Destructor.
|
|
* Close the stream and the socket.
|
|
*/
|
|
virtual ~JBComponentStream();
|
|
|
|
/**
|
|
* Get the stream state.
|
|
* @return The stream state as enumeration.
|
|
*/
|
|
inline State state() const
|
|
{ return m_state; }
|
|
|
|
/**
|
|
* Get the local name.
|
|
* @return The local name.
|
|
*/
|
|
inline const String& localName() const
|
|
{ return m_localName; }
|
|
|
|
/**
|
|
* Get the remote server name.
|
|
* @return The remote server name.
|
|
*/
|
|
inline const String& remoteName() const
|
|
{ return m_remoteName; }
|
|
|
|
/**
|
|
* Get the local name.
|
|
* @return The local name.
|
|
*/
|
|
inline const SocketAddr& remoteAddr() const
|
|
{ return m_remoteAddr; }
|
|
|
|
/**
|
|
* Get the stream id.
|
|
* @return The stream id.
|
|
*/
|
|
inline const String& id() const
|
|
{ return m_id; }
|
|
|
|
/**
|
|
* Get the stream's connection.
|
|
* @return The stream connection's pointer.
|
|
*/
|
|
inline JBEngine* engine() const
|
|
{ return m_engine; }
|
|
|
|
/**
|
|
* Check if the caller of connect() should wait before.
|
|
* @return True to wait.
|
|
*/
|
|
inline bool waitBeforeConnect() const
|
|
{ return m_waitBeforeConnect; }
|
|
|
|
/**
|
|
* Connect the stream to the server.
|
|
*/
|
|
void connect();
|
|
|
|
/**
|
|
* Cleanup the stream. Terminate/Destroy it. Raise the appropriate event.
|
|
* This method is thread safe.
|
|
* @param destroy True to destroy. False to terminate.
|
|
* @param sendEnd True to send stream termination tag.
|
|
* @param error Optional XML element to send before termination tag.
|
|
* @param sendError True to send the error element.
|
|
*/
|
|
void terminate(bool destroy, bool sendEnd = false,
|
|
XMLElement* error = 0, bool sendError = false);
|
|
|
|
/**
|
|
* Read data from socket and pass it to the parser.
|
|
* Raise event on bad XML.
|
|
* This method is thread safe.
|
|
* @return True if data was received.
|
|
*/
|
|
bool receive();
|
|
|
|
/**
|
|
* Send a stanza.
|
|
* This method is thread safe.
|
|
* @param stanza Element to send.
|
|
* @param senderId Optional sender's id. Used for notification events.
|
|
* @return The result of posting the stanza.
|
|
*/
|
|
Error sendStanza(XMLElement* stanza, const char* senderId = 0);
|
|
|
|
/**
|
|
* Extract an element from parser and construct an event.
|
|
* This method is thread safe.
|
|
* @param time Current time.
|
|
* @return XMPPEvent pointer or 0.
|
|
*/
|
|
JBEvent* getEvent(u_int64_t time);
|
|
|
|
/**
|
|
* Cancel pending outgoing elements.
|
|
* @param raise True to raise WriteFail events.
|
|
* @param id Optional 'id' to cancel. 0 to cancel all elements without id.
|
|
*/
|
|
void cancelPending(bool raise, const String* id = 0);
|
|
|
|
/**
|
|
* Event termination notification.
|
|
* @param event The notifier. Must be m_lastEvent.
|
|
*/
|
|
void eventTerminated(const JBEvent* event);
|
|
|
|
protected:
|
|
/**
|
|
* Constructor.
|
|
* Constructs an outgoing stream.
|
|
* @param connection The engine that owns this stream.
|
|
* @param remoteName The remote domain name.
|
|
* @param remoteAddr The remote address to connect.
|
|
*/
|
|
JBComponentStream(JBEngine* engine, const String& remoteName,
|
|
const SocketAddr& remoteAddr);
|
|
|
|
/**
|
|
* Send data without passing it through the outgoing queue.
|
|
* Change state if operation succeeds. Terminate stream if it fails.
|
|
* This method is thread safe.
|
|
* @param element The XML element to send.
|
|
* @param newState The new state if the operation succeeds.
|
|
* @param newState Optional XML element to send before element.
|
|
* @return False if the write operation fails.
|
|
*/
|
|
bool sendStreamXML(XMLElement* element, State newState,
|
|
XMLElement* before = 0);
|
|
|
|
/**
|
|
* Send a 'stream:error' element. Terminate the stream.
|
|
* @param error The XMPP defined condition.
|
|
* @param text Optional text to add to the error.
|
|
*/
|
|
inline void sendStreamError(XMPPError::Type error, const char* text = 0)
|
|
{ terminate(false,true,XMPPUtils::createStreamError(error,text)); }
|
|
|
|
/**
|
|
* Send an 'iq' of type 'error'.
|
|
* @param stanza Element that generated the error.
|
|
* @param eType The error type.
|
|
* @param eCond The error condition.
|
|
* @param eText Optional text to add to the error stanza.
|
|
* @return The result of posting the stanza.
|
|
*/
|
|
Error sendIqError(XMLElement* stanza, XMPPError::ErrorType eType,
|
|
XMPPError::Type eCond, const char* eText = 0);
|
|
/**
|
|
* Cleanup stream.
|
|
* Remove the first element from the outgoing list if partially sent.
|
|
* Send stream termination tag if requested.
|
|
* Cancel all outgoing elements without id. Destroy the socket.
|
|
* This method is thread safe.
|
|
* @param endStream True to send stream termination tag.
|
|
* @param element Optional element to send before.
|
|
*/
|
|
void cleanup(bool endStream, XMLElement* element = 0);
|
|
|
|
/**
|
|
* Post an XMLElement in the outgoing queue. Send the first element in the queue.
|
|
* This method is thread safe.
|
|
* @param element The XMLElementOut to post.
|
|
* @return ErrorNone, ErrorContext, ErrorPending, ErrorNoSocket.
|
|
*/
|
|
Error postXML(XMLElementOut* element);
|
|
|
|
/**
|
|
* Send the first element from the outgoing queue if state is Running.
|
|
* Raise WriteFail event if operation fails. Adjust buffer on partial writes.
|
|
* @return ErrorNone, ErrorContext, ErrorPending, ErrorNoSocket.
|
|
*/
|
|
Error sendXML();
|
|
|
|
/**
|
|
* Process the received XML elements. Validate them. Add events.
|
|
* @return True if generated any event(s).
|
|
*/
|
|
bool processIncomingXML();
|
|
|
|
/**
|
|
* Process a received element in state Started.
|
|
* @param e The element to process.
|
|
* @return True if generated any event(s).
|
|
*/
|
|
bool processStateStarted(XMLElement* e);
|
|
|
|
/**
|
|
* Process a received element in state Auth.
|
|
* @param e The element to process.
|
|
* @return True if generated any event(s).
|
|
*/
|
|
bool processStateAuth(XMLElement* e);
|
|
|
|
/**
|
|
* Process a received element in state Running.
|
|
* @param e The element to process.
|
|
* @return True if generated any event(s).
|
|
*/
|
|
bool processStateRunning(XMLElement* e);
|
|
|
|
/**
|
|
* Process a received 'iq' element.
|
|
* @param e The element to process.
|
|
* @return True if generated any event(s).
|
|
*/
|
|
bool processIncomingIq(XMLElement* e);
|
|
|
|
/**
|
|
* Add an event to the list.
|
|
* @param type Event type.
|
|
* @param element Optional XML element.
|
|
* @param child Optional child element.
|
|
* @return The added event.
|
|
*/
|
|
JBEvent* addEvent(JBEvent::Type type, XMLElement* element = 0,
|
|
XMLElement* child = 0);
|
|
|
|
/**
|
|
* Add a notification event to the list if the element has an id.
|
|
* Remove the element from the outgoing queue.
|
|
* @param type Event type.
|
|
* @param element XMLElementOut element that generated the event.
|
|
* @return True if the event was added.
|
|
*/
|
|
bool addEventNotify(JBEvent::Type type, XMLElementOut* element);
|
|
|
|
/**
|
|
* Actions to take when an invalid element is received.
|
|
* Delete element. Send a stream error to remote peer. Raise a Terminated event.
|
|
* @param e The invalid element.
|
|
* @param type Stream error type.
|
|
* @param text Optional text to add to the stream error.
|
|
* @return True.
|
|
*/
|
|
bool invalidElement(XMLElement* e, XMPPError::Type type,
|
|
const char* text = 0);
|
|
|
|
/**
|
|
* Actions to take when an unexpected element is received.
|
|
* Delete element.
|
|
* @param e The unexpected element.
|
|
* @return False.
|
|
*/
|
|
bool unexpectedElement(XMLElement* e);
|
|
|
|
/**
|
|
* Check if a given element is a termination one (stream error or stream end).
|
|
* Raise a Terminated event if so.
|
|
* If true is returned the element is still valid.
|
|
* @param e The element to check.
|
|
* @return True if a Terminated event was raised.
|
|
*/
|
|
bool isStreamEnd(XMLElement* e);
|
|
|
|
/**
|
|
* Read data from socket and pass it to the parser. Terminate on error.
|
|
* @param data The destination buffer.
|
|
* @param len The maximum number of bytes to read. Bytes read on exit.
|
|
* @return True if data was received.
|
|
*/
|
|
bool readSocket(char* data, u_int32_t& len);
|
|
|
|
/**
|
|
* Write data to socket. Terminate on error.
|
|
* @param data The source buffer.
|
|
* @param len The buffer length on input. Bytes written on output.
|
|
* @return False on socket error. State is Terminated on unrecoverable socket error.
|
|
*/
|
|
bool writeSocket(const char* data, u_int32_t& len);
|
|
|
|
private:
|
|
JBComponentStream() {} // Don't use it!
|
|
|
|
// State
|
|
State m_state; // Stream state
|
|
// Info
|
|
String m_id; // Stream id
|
|
String m_localName; // Local name received from the remote peer
|
|
String m_remoteName; // Remote peer's domain name
|
|
SocketAddr m_remoteAddr; // Socket's address
|
|
String m_password; // Password used for authentication
|
|
// Data
|
|
JBEngine* m_engine; // The owner of this stream
|
|
Socket* m_socket; // The socket used by this stream
|
|
XMLParser m_parser; // XML parser
|
|
Mutex m_receiveMutex; // Ensure serialization of received data
|
|
ObjList m_outXML; // Outgoing XML elements
|
|
ObjList m_events; // Event queue
|
|
JBEvent* m_lastEvent; // Last generated event
|
|
JBEvent* m_terminateEvent; // Destroy/Terminate event
|
|
int m_partialRestart; // Partial outgoing stream restart attempts counter
|
|
int m_totalRestart; // Total outgoing stream restart attempts counter
|
|
bool m_waitBeforeConnect; // Wait before trying to connect
|
|
};
|
|
|
|
/**
|
|
* This class holds info about a component server used by the Jabber engine.
|
|
* @short Server info.
|
|
*/
|
|
class YJINGLE_API JBServerInfo : public RefObject
|
|
{
|
|
public:
|
|
inline JBServerInfo(const char* name, const char* address, int port,
|
|
const char* password, const char* identity)
|
|
: m_name(name), m_address(address),
|
|
m_port(port), m_password(password), m_identity(identity)
|
|
{}
|
|
virtual ~JBServerInfo() {}
|
|
inline const String& address() const
|
|
{ return m_address; }
|
|
inline const String& name() const
|
|
{ return m_name; }
|
|
inline const int port() const
|
|
{ return m_port; }
|
|
inline const String& password() const
|
|
{ return m_password; }
|
|
inline const String& identity() const
|
|
{ return m_identity; }
|
|
private:
|
|
String m_name; // Domain name
|
|
String m_address; // IP address
|
|
int m_port; // Port
|
|
String m_password; // Authentication data
|
|
String m_identity; // Identity. Used for Jabber Component protocol
|
|
};
|
|
|
|
/**
|
|
* This class holds a Jabber engine.
|
|
* @short A Jabber engine.
|
|
*/
|
|
class YJINGLE_API JBEngine : public DebugEnabler, public Mutex, public RefObject
|
|
{
|
|
friend class JBEvent;
|
|
friend class JBComponentStream;
|
|
friend class JBClient;
|
|
friend class JBPresence;
|
|
public:
|
|
/**
|
|
* Jabber protocol type.
|
|
*/
|
|
enum Protocol {
|
|
Component, // Use Jabber Component protocol
|
|
};
|
|
|
|
/**
|
|
* Constructor.
|
|
* Constructs a Jabber engine.
|
|
*/
|
|
JBEngine();
|
|
|
|
/**
|
|
* Destructor.
|
|
*/
|
|
virtual ~JBEngine();
|
|
|
|
/**
|
|
* Get the Jabber protocol this engine is using.
|
|
* @return The Jabber protocol as enumeration.
|
|
*/
|
|
inline Protocol jabberProtocol() const
|
|
{ return Component; }
|
|
|
|
/**
|
|
* Initialize the engine's parameters.
|
|
* Parameters:
|
|
* stream_partialrestart : int Partial stream restart counter for outgoing streams. Defaults to 3.
|
|
* stream_totalrestart : int Total stream restart counter for outgoing streams. Defaults to -1 (no limit).
|
|
* xmlparser_maxbuffer : int The maximum allowed xml buffer length. Defaults to 8192.
|
|
* @param params Engine's parameters.
|
|
*/
|
|
void initialize(const NamedList& params);
|
|
|
|
/**
|
|
* Terminate all stream.
|
|
*/
|
|
void cleanup();
|
|
|
|
/**
|
|
* Set the default component server to use.
|
|
* The domain must be in the server list.
|
|
* Choose the first one from the server list if the given one doesn't exists.
|
|
* @param domain Domain name of the server.
|
|
*/
|
|
void setComponentServer(const char* domain);
|
|
|
|
/**
|
|
* Get the default component server.
|
|
* @return The default component server.
|
|
*/
|
|
const String& componentServer()
|
|
{ return m_componentDomain; }
|
|
|
|
/**
|
|
* Get the partial stream restart attempts counter.
|
|
* @return The partial stream restart attempts counter.
|
|
*/
|
|
inline int partialStreamRestartAttempts() const
|
|
{ return m_partialStreamRestart; }
|
|
|
|
/**
|
|
* Get the total stream restart attempts counter.
|
|
* @return The total stream restart attempts counter.
|
|
*/
|
|
inline int totalStreamRestartAttempts() const
|
|
{ return m_totalStreamRestart; }
|
|
|
|
/**
|
|
* Get the time to wait after m_partialStreamRestart reaches 0.
|
|
* @return time to wait after m_partialStreamRestart reaches 0.
|
|
*/
|
|
inline u_int32_t waitStreamRestart() const
|
|
{ return m_waitStreamRestart; }
|
|
|
|
/**
|
|
* Check if a stream to the given server exists.
|
|
* If the stream doesn't exists creates it.
|
|
* This method is thread safe.
|
|
* @param domain The domain name to check. 0 to use the default server.
|
|
* @param create True to create a stream to the specified domain if none exists.
|
|
* @return Pointer to a JBComponentStream or 0.
|
|
*/
|
|
JBComponentStream* getStream(const char* domain = 0, bool create = true);
|
|
|
|
/**
|
|
* Keep calling receive() for each stream until no data is received.
|
|
* @return True if data was received.
|
|
*/
|
|
bool receive();
|
|
|
|
/**
|
|
* Keep calling receive().
|
|
*/
|
|
void runReceive();
|
|
|
|
/**
|
|
* Get events from the streams owned by this engine.
|
|
* This method is thread safe.
|
|
* @param time Current time.
|
|
* @return JBEvent pointer or 0.
|
|
*/
|
|
JBEvent* getEvent(u_int64_t time);
|
|
|
|
/**
|
|
* Check if an outgoing stream exists with the same id and remote peer.
|
|
* @param connection The calling stream.
|
|
* @return True if found.
|
|
*/
|
|
bool remoteIdExists(const JBComponentStream* stream);
|
|
|
|
/**
|
|
* Create an SHA1 value from 'id' + 'password'.
|
|
* @param sha Destination string.
|
|
* @param id First element (stream id).
|
|
* @param password The second element (stream password).
|
|
*/
|
|
void createSHA1(String& sha, const String& id, const String& password);
|
|
|
|
/**
|
|
* Check if a received value is correct.
|
|
* @param sha Destination string.
|
|
* @param id First element (stream id).
|
|
* @param password The second element (stream password).
|
|
* @return True if equal.
|
|
*/
|
|
bool checkSHA1(const String& sha, const String& id, const String& password);
|
|
|
|
/**
|
|
* Call the connect method of the given stream.
|
|
* @param stream The stream to connect.
|
|
* @return False if stream is 0.
|
|
*/
|
|
virtual bool connect(JBComponentStream* stream);
|
|
|
|
/**
|
|
* Return a non processed event to this engine.
|
|
* @param event The returned event.
|
|
*/
|
|
virtual void returnEvent(JBEvent* event);
|
|
|
|
/**
|
|
* Accept an outgoing stream. If accepted, deliver a password.
|
|
* @param remoteAddr The remote address.
|
|
* @param password Password to use.
|
|
* @return True if accepted. False to terminate the stream.
|
|
*/
|
|
virtual bool acceptOutgoing(const String& remoteAddr, String& password);
|
|
|
|
/**
|
|
* Deliver a port for an outgoing connection.
|
|
* @param remoteAddr The remote address.
|
|
* @return True if accepted. False to terminate the stream.
|
|
*/
|
|
virtual int getPort(const String& remoteAddr);
|
|
|
|
/**
|
|
* Append a servr info element to the list.
|
|
* @param server The object to add.
|
|
* @param open True to open the stream.
|
|
*/
|
|
void appendServer(JBServerInfo* server, bool open);
|
|
|
|
/**
|
|
* Get the identity of the given server for a component server.
|
|
* @param destination The destination.
|
|
* @param token The search string. If 0 the default server will be used.
|
|
* @param domain True to find by domain name. False to find by address.
|
|
* @return False if server doesn't exists.
|
|
*/
|
|
bool getServerIdentity(String& destination, const char* token = 0,
|
|
bool domain = true);
|
|
|
|
/**
|
|
* Get the full identity of the given server.
|
|
* @param destination The destination.
|
|
* @param token The search string. If 0 the default server will be used.
|
|
* @param domain True to find by domain name. False to find by address.
|
|
* @return False if server doesn't exists.
|
|
*/
|
|
bool getFullServerIdentity(String& destination, const char* token = 0,
|
|
bool domain = true);
|
|
|
|
protected:
|
|
/**
|
|
* Process a DiscoInfo event.
|
|
* @param event The received event.
|
|
* @return True if processed.
|
|
*/
|
|
bool processDiscoInfo(JBEvent* event);
|
|
|
|
/**
|
|
* Check if a stream with a given remote address exists.
|
|
* @param remoteName The remote address to find.
|
|
* @return Stream pointer or 0.
|
|
*/
|
|
JBComponentStream* findStream(const String& remoteName);
|
|
|
|
/**
|
|
* Remove a stream from the list.
|
|
* @param stream The stream to remove.
|
|
* @param del Delete flag. If true the stream will be deleted.
|
|
*/
|
|
void removeStream(JBComponentStream* stream, bool del);
|
|
|
|
/**
|
|
* Add a client to this engine if not in it.
|
|
* @param client The client to add.
|
|
*/
|
|
void addClient(JBClient* client);
|
|
|
|
/**
|
|
* Remove a client to this engine if not in it.
|
|
* @param client The client to remove.
|
|
*/
|
|
void removeClient(JBClient* client);
|
|
|
|
/**
|
|
* Find server info object.
|
|
* @param token The search string. If 0 the default server will be used.
|
|
* @param domain True to find by domain name. False to find by address.
|
|
* @return JBServerInfo pointer or 0.
|
|
*/
|
|
JBServerInfo* getServer(const char* token = 0, bool domain = true);
|
|
|
|
/**
|
|
* Clear the server list.
|
|
*/
|
|
inline void clearServerList()
|
|
{ Lock lock(m_serverMutex); m_server.clear(); }
|
|
|
|
/**
|
|
* Process a message event.
|
|
* @param event The event to process. Always a valid message event.
|
|
* @return True if the event was processed (kept). False to destroy it.
|
|
*/
|
|
virtual bool processMessage(JBEvent* event);
|
|
|
|
private:
|
|
void processEventNew(JBEvent* event);
|
|
void processEventAuth(JBEvent* event);
|
|
bool getServerPassword(String& destination, const char* token = 0,
|
|
bool domain = true);
|
|
bool getServerPort(int& destination, const char* token = 0,
|
|
bool domain = true);
|
|
void setPresenceServer(JBPresence* presence);
|
|
void unsetPresenceServer(JBPresence* presence);
|
|
|
|
ObjList m_streams; // Streams belonging to this engine
|
|
Mutex m_clientsMutex; // Lock clients list
|
|
ObjList m_clients; // XMPP clients list
|
|
JBPresence* m_presence; // The presence server
|
|
Mutex m_featuresMutex; // Lock m_feature
|
|
ObjList m_features; // Remote peers' features
|
|
int m_partialStreamRestart; // Partial outgoing stream restart attempts counter
|
|
int m_totalStreamRestart; // Total outgoing stream restart attempts counter
|
|
u_int32_t m_waitStreamRestart; // How much time to wait after m_partialStreamRestart reaches 0
|
|
// ID generation data
|
|
u_int64_t m_streamID; // Stream id counter
|
|
// Server list
|
|
String m_componentDomain; // Default server domain name
|
|
String m_componentAddr; // Default server address
|
|
ObjList m_server; // Server list
|
|
Mutex m_serverMutex; // Lock server list
|
|
};
|
|
|
|
/**
|
|
* This class is the base class for a Jabber client who wants
|
|
* to deliver protocol specific data to the engine.
|
|
* @short An Jabber client.
|
|
*/
|
|
class YJINGLE_API JBClient : public RefObject
|
|
{
|
|
public:
|
|
/**
|
|
* Constructor.
|
|
* @param engine The Jabber engine.
|
|
*/
|
|
JBClient(JBEngine* engine);
|
|
|
|
/**
|
|
* Destructor.
|
|
*/
|
|
virtual ~JBClient();
|
|
|
|
/**
|
|
* Get the Jabber engine.
|
|
* @return The Jabber engine.
|
|
*/
|
|
JBEngine* engine()
|
|
{ return m_engine; }
|
|
|
|
protected:
|
|
JBEngine* m_engine; // The Jabber Component engine
|
|
|
|
private:
|
|
inline JBClient() {} // Don't use it !
|
|
};
|
|
|
|
/**
|
|
* This class is the presence server for Jabber.
|
|
* @short A Jabber presence server.
|
|
*/
|
|
class YJINGLE_API JBPresence : public DebugEnabler, public JBClient, public Mutex
|
|
{
|
|
public:
|
|
/**
|
|
* Presence enumeration.
|
|
*/
|
|
enum Presence {
|
|
Error, // error
|
|
Probe, // probe
|
|
Subscribe, // subscribe request
|
|
Subscribed, // subscribe accepted
|
|
Unavailable, // unavailable
|
|
Unsubscribe, // unsubscribe request
|
|
Unsubscribed, // unsubscribe accepted
|
|
None,
|
|
};
|
|
|
|
/**
|
|
* Constructor.
|
|
* Constructs an Jabber Component presence server.
|
|
* @param engine The Jabber Component engine.
|
|
*/
|
|
JBPresence(JBEngine* engine);
|
|
|
|
/**
|
|
* Destructor.
|
|
*/
|
|
virtual ~JBPresence();
|
|
|
|
/**
|
|
* Add an event to the list.
|
|
* This method is thread safe.
|
|
* @param event The event to add.
|
|
* @return False if the event is not a Presence one.
|
|
*/
|
|
bool receive(JBEvent* event);
|
|
|
|
/**
|
|
* Process an event from the receiving list.
|
|
* This method is thread safe.
|
|
* @return False if the list is empty.
|
|
*/
|
|
bool process();
|
|
|
|
/**
|
|
* Keep calling process().
|
|
*/
|
|
void runProcess();
|
|
|
|
/**
|
|
* Process disco info elements.
|
|
* @param event The event with the element.
|
|
*/
|
|
virtual void processDisco(JBEvent* event);
|
|
|
|
/**
|
|
* Process a presence error element.
|
|
* @param event The event with the element.
|
|
*/
|
|
virtual void processError(JBEvent* event);
|
|
|
|
/**
|
|
* Process a presence probe element.
|
|
* @param event The event with the element.
|
|
*/
|
|
virtual void processProbe(JBEvent* event);
|
|
|
|
/**
|
|
* Process a presence subscribe element.
|
|
* @param event The event with the element.
|
|
*/
|
|
virtual void processSubscribe(JBEvent* event);
|
|
|
|
/**
|
|
* Process a presence subscribed element.
|
|
* @param event The event with the element.
|
|
*/
|
|
virtual void processSubscribed(JBEvent* event);
|
|
|
|
/**
|
|
* Process a presence unsubscribe element.
|
|
* @param event The event with the element.
|
|
*/
|
|
virtual void processUnsubscribe(JBEvent* event);
|
|
|
|
/**
|
|
* Process a presence unsubscribed element.
|
|
* @param event The event with the element.
|
|
*/
|
|
virtual void processUnsubscribed(JBEvent* event);
|
|
|
|
/**
|
|
* Process a presence unavailable element.
|
|
* @param event The event with the element.
|
|
*/
|
|
virtual void processUnavailable(JBEvent* event);
|
|
|
|
/**
|
|
* Process a presence element.
|
|
* @param event The event with the element.
|
|
*/
|
|
virtual void processUnknown(JBEvent* event);
|
|
|
|
/**
|
|
* Create an 'presence' element.
|
|
* @param from The 'from' attribute.
|
|
* @param to The 'to' attribute.
|
|
* @param type Presence type as enumeration.
|
|
* @return A valid XMLElement pointer.
|
|
*/
|
|
static XMLElement* createPresence(const char* from,
|
|
const char* to, Presence type = None);
|
|
|
|
/**
|
|
* Decode an error element.
|
|
* @param element The XML element.
|
|
* @param code The 'code' attribute.
|
|
* @param type The 'type' attribute.
|
|
* @param error The name of the 'error' child.
|
|
* @return False if 'element' is 0 or is not a presence one.
|
|
*/
|
|
static bool decodeError(const XMLElement* element,
|
|
String& code, String& type, String& error);
|
|
|
|
/**
|
|
* Get the type of a 'presence' stanza as enumeration.
|
|
* @param text The text to check.
|
|
* @return Presence type as enumeration.
|
|
*/
|
|
static inline Presence presenceType(const char* txt)
|
|
{ return (Presence)lookup(txt,s_presence,None); }
|
|
/**
|
|
* Get the text from a presence type.
|
|
* @param presence The presence type.
|
|
* @return The associated text or 0.
|
|
*/
|
|
static inline const char* presenceText(Presence presence)
|
|
{ return lookup(presence,s_presence,0); }
|
|
|
|
protected:
|
|
ObjList m_events; // Incoming events from Jabber engine
|
|
static TokenDict s_presence[]; // Keep the types of 'presence'
|
|
};
|
|
|
|
};
|
|
|
|
#endif /* __YATEJABBER_H */
|
|
|
|
/* vi: set ts=8 sw=4 sts=4 noet: */
|