00001 /* 00002 * Asterisk -- An open source telephony toolkit. 00003 * 00004 * Copyright (C) 2012, Digium, Inc. 00005 * 00006 * Joshua Colp <jcolp@digium.com> 00007 * 00008 * See http://www.asterisk.org for more information about 00009 * the Asterisk project. Please do not directly contact 00010 * any of the maintainers of this project for assistance; 00011 * the project provides a web site, mailing lists and IRC 00012 * channels for your use. 00013 * 00014 * This program is free software, distributed under the terms of 00015 * the GNU General Public License Version 2. See the LICENSE file 00016 * at the top of the source tree. 00017 */ 00018 00019 /*! \file 00020 * \brief XMPP Interface 00021 * \author Joshua Colp <jcolp@digium.com> 00022 * \extref IKSEMEL http://iksemel.jabberstudio.org 00023 */ 00024 00025 #ifndef _ASTERISK_XMPP_H 00026 #define _ASTERISK_XMPP_H 00027 00028 #ifdef HAVE_OPENSSL 00029 00030 #include <openssl/ssl.h> 00031 #include <openssl/err.h> 00032 #define TRY_SECURE 2 00033 #define SECURE 4 00034 00035 #endif /* HAVE_OPENSSL */ 00036 00037 /* file is read by blocks with this size */ 00038 #define NET_IO_BUF_SIZE 16384 00039 00040 /* Return value for timeout connection expiration */ 00041 #define IKS_NET_EXPIRED 12 00042 00043 #include <iksemel.h> 00044 00045 #include "asterisk/utils.h" 00046 #include "asterisk/astobj2.h" 00047 #include "asterisk/linkedlists.h" 00048 #include "asterisk/stringfields.h" 00049 #include "asterisk/pbx.h" 00050 00051 /* 00052 * As per RFC 3920 - section 3.1, the maximum length for a full Jabber ID 00053 * is 3071 bytes. 00054 * The ABNF syntax for jid : 00055 * jid = [node "@" ] domain [ "/" resource ] 00056 * Each allowable portion of a JID (node identifier, domain identifier, 00057 * and resource identifier) MUST NOT be more than 1023 bytes in length, 00058 * resulting in a maximum total size (including the '@' and '/' separators) 00059 * of 3071 bytes. 00060 */ 00061 #define XMPP_MAX_JIDLEN 3071 00062 00063 /*! \brief Maximum size of a resource JID */ 00064 #define XMPP_MAX_RESJIDLEN 1023 00065 00066 /*! \brief Maximum size of an attribute */ 00067 #define XMPP_MAX_ATTRLEN 256 00068 00069 /*! \brief Client connection states */ 00070 enum xmpp_state { 00071 XMPP_STATE_DISCONNECTING, /*!< Client is disconnecting */ 00072 XMPP_STATE_DISCONNECTED, /*!< Client is disconnected */ 00073 XMPP_STATE_CONNECTING, /*!< Client is connecting */ 00074 XMPP_STATE_REQUEST_TLS, /*!< Client should request TLS */ 00075 XMPP_STATE_REQUESTED_TLS, /*!< Client has requested TLS */ 00076 XMPP_STATE_AUTHENTICATE, /*!< Client needs to authenticate */ 00077 XMPP_STATE_AUTHENTICATING, /*!< Client is authenticating */ 00078 XMPP_STATE_ROSTER, /*!< Client is currently getting the roster */ 00079 XMPP_STATE_CONNECTED, /*!< Client is fully connected */ 00080 }; 00081 00082 /*! \brief Resource capabilities */ 00083 struct ast_xmpp_capabilities { 00084 char node[200]; /*!< Node string from the capabilities stanza in presence notification */ 00085 char version[50]; /*!< Version string from the capabilities stanza in presence notification */ 00086 unsigned int jingle:1; /*!< Set if the resource supports Jingle */ 00087 unsigned int google:1; /*!< Set if the resource supports Google Talk */ 00088 }; 00089 00090 /*! \brief XMPP Resource */ 00091 struct ast_xmpp_resource { 00092 char resource[XMPP_MAX_RESJIDLEN]; /*!< JID of the resource */ 00093 int status; /*!< Current status of the resource */ 00094 char *description; /*!< Description of the resource */ 00095 int priority; /*!< Priority, used for deciding what resource to use */ 00096 struct ast_xmpp_capabilities caps; /*!< Capabilities of the resource */ 00097 }; 00098 00099 /*! \brief XMPP Message */ 00100 struct ast_xmpp_message { 00101 char *from; /*!< Who the message is from */ 00102 char *message; /*!< Message contents */ 00103 char id[25]; /*!< Identifier for the message */ 00104 struct timeval arrived; /*!< When the message arrived */ 00105 AST_LIST_ENTRY(ast_xmpp_message) list; /*!< Linked list information */ 00106 }; 00107 00108 /*! \brief XMPP Buddy */ 00109 struct ast_xmpp_buddy { 00110 char id[XMPP_MAX_JIDLEN]; /*!< JID of the buddy */ 00111 struct ao2_container *resources; /*!< Resources for the buddy */ 00112 unsigned int subscribe:1; /*!< Need to subscribe to get their status */ 00113 }; 00114 00115 /*! \brief XMPP Client Connection */ 00116 struct ast_xmpp_client { 00117 AST_DECLARE_STRING_FIELDS( 00118 AST_STRING_FIELD(name); /*!< Name of the client configuration */ 00119 ); 00120 char mid[6]; /* Message ID */ 00121 iksid *jid; 00122 iksparser *parser; 00123 iksfilter *filter; 00124 ikstack *stack; 00125 #ifdef HAVE_OPENSSL 00126 SSL_CTX *ssl_context; 00127 SSL *ssl_session; 00128 const SSL_METHOD *ssl_method; 00129 unsigned int stream_flags; 00130 #endif /* HAVE_OPENSSL */ 00131 enum xmpp_state state; 00132 struct ao2_container *buddies; 00133 AST_LIST_HEAD(, ast_xmpp_message) messages; 00134 pthread_t thread; 00135 int timeout; 00136 unsigned int reconnect:1; /*!< Reconnect this client */ 00137 struct ast_event_sub *mwi_sub; /*!< If distributing event information the MWI subscription */ 00138 struct ast_event_sub *device_state_sub; /*!< If distributing event information the device state subscription */ 00139 }; 00140 00141 /*! 00142 * \brief Find an XMPP client connection using a given name 00143 * 00144 * \param name Name of the client connection 00145 * 00146 * \retval non-NULL on success 00147 * \retval NULL on failure 00148 * 00149 * \note This will return the client connection with the reference count incremented by one. 00150 */ 00151 struct ast_xmpp_client *ast_xmpp_client_find(const char *name); 00152 00153 /*! 00154 * \brief Disconnect an XMPP client connection 00155 * 00156 * \param client Pointer to the client 00157 * 00158 * \retval 0 on success 00159 * \retval -1 on failure 00160 */ 00161 int ast_xmpp_client_disconnect(struct ast_xmpp_client *client); 00162 00163 /*! 00164 * \brief Release XMPP client connection reference 00165 * 00166 * \param client Pointer to the client 00167 */ 00168 void ast_xmpp_client_unref(struct ast_xmpp_client *client); 00169 00170 /*! 00171 * \brief Lock an XMPP client connection 00172 * 00173 * \param client Pointer to the client 00174 */ 00175 void ast_xmpp_client_lock(struct ast_xmpp_client *client); 00176 00177 /*! 00178 * \brief Unlock an XMPP client connection 00179 * 00180 * \param client Pointer to the client 00181 */ 00182 void ast_xmpp_client_unlock(struct ast_xmpp_client *client); 00183 00184 /*! 00185 * \brief Send an XML stanza out using an established XMPP client connection 00186 * 00187 * \param client Pointer to the client 00188 * \param stanza Pointer to the Iksemel stanza 00189 * 00190 * \retval 0 on success 00191 * \retval -1 on failure 00192 */ 00193 int ast_xmpp_client_send(struct ast_xmpp_client *client, iks *stanza); 00194 00195 /*! 00196 * \brief Send a message to a given user using an established XMPP client connection 00197 * 00198 * \param client Pointer to the client 00199 * \param user User the message should be sent to 00200 * \param message The message to send 00201 * 00202 * \retval 0 on success 00203 * \retval -1 on failure 00204 */ 00205 int ast_xmpp_client_send_message(struct ast_xmpp_client *client, const char *user, const char *message); 00206 00207 /*! 00208 * \brief Invite a user to an XMPP multi-user chatroom 00209 * 00210 * \param client Pointer to the client 00211 * \param user JID of the user 00212 * \param room Name of the chatroom 00213 * \param message Message to send with the invitation 00214 * 00215 * \retval 0 on success 00216 * \retval -1 on failure 00217 */ 00218 int ast_xmpp_chatroom_invite(struct ast_xmpp_client *client, const char *user, const char *room, const char *message); 00219 00220 /*! 00221 * \brief Join an XMPP multi-user chatroom 00222 * 00223 * \param client Pointer to the client 00224 * \param room Name of the chatroom 00225 * \param nickname Nickname to use 00226 * 00227 * \retval 0 on success 00228 * \retval -1 on failure 00229 */ 00230 int ast_xmpp_chatroom_join(struct ast_xmpp_client *client, const char *room, const char *nickname); 00231 00232 /*! 00233 * \brief Send a message to an XMPP multi-user chatroom 00234 * 00235 * \param client Pointer to the client 00236 * \param nickname Nickname to use 00237 * \param Address Address of the room 00238 * \param message Message itself 00239 * 00240 * \retval 0 on success 00241 * \retval -1 on failure 00242 */ 00243 int ast_xmpp_chatroom_send(struct ast_xmpp_client *client, const char *nickname, const char *address, const char *message); 00244 00245 /*! 00246 * \brief Leave an XMPP multi-user chatroom 00247 * 00248 * \param client Pointer to the client 00249 * \param room Name of the chatroom 00250 * \param nickname Nickname being used 00251 * 00252 * \retval 0 on success 00253 * \retval -1 on failure 00254 */ 00255 int ast_xmpp_chatroom_leave(struct ast_xmpp_client *client, const char *room, const char *nickname); 00256 00257 /*! 00258 * \brief Helper function which increments the message identifier 00259 * 00260 * \param mid Pointer to a string containing the message identifier 00261 */ 00262 void ast_xmpp_increment_mid(char *mid); 00263 00264 #endif