[asterisk-commits] phsultan: branch phsultan/jabberreceive r164796 - in /team/phsultan/jabberrec...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Dec 16 13:20:16 CST 2008
Author: phsultan
Date: Tue Dec 16 13:20:16 2008
New Revision: 164796
URL: http://svn.digium.com/view/asterisk?view=rev&rev=164796
Log:
Several changes to the implentation of the new XMPP messages reception functionality. The new approach is the result of discussions on the -dev mailing list and the code review board.
1) Implement a function (JABBER_RECEIVE) rather than an application.
2) Store all messages in a list, and pull them when calling JABBER_RECEIVE.
When an XMPP messages comes in, all messages stored longer than a
configured value (default : 2 seconds) are removed.
3) Document all functions and applications with XML.
Modified:
team/phsultan/jabberreceive/channels/chan_gtalk.c
team/phsultan/jabberreceive/channels/chan_jingle.c
team/phsultan/jabberreceive/configs/jabber.conf.sample
team/phsultan/jabberreceive/doc/jabber.txt
team/phsultan/jabberreceive/res/res_jabber.c
Modified: team/phsultan/jabberreceive/channels/chan_gtalk.c
URL: http://svn.digium.com/view/asterisk/team/phsultan/jabberreceive/channels/chan_gtalk.c?view=diff&rev=164796&r1=164795&r2=164796
==============================================================================
--- team/phsultan/jabberreceive/channels/chan_gtalk.c (original)
+++ team/phsultan/jabberreceive/channels/chan_gtalk.c Tue Dec 16 13:20:16 2008
@@ -1468,7 +1468,6 @@
int res = 0;
struct aji_client *client = NULL;
struct gtalk_pvt *p = chan->tech_pvt;
-
if (!p->parent) {
ast_log(LOG_ERROR, "Parent channel not found\n");
Modified: team/phsultan/jabberreceive/channels/chan_jingle.c
URL: http://svn.digium.com/view/asterisk/team/phsultan/jabberreceive/channels/chan_jingle.c?view=diff&rev=164796&r1=164795&r2=164796
==============================================================================
--- team/phsultan/jabberreceive/channels/chan_jingle.c (original)
+++ team/phsultan/jabberreceive/channels/chan_jingle.c Tue Dec 16 13:20:16 2008
@@ -1295,12 +1295,12 @@
}
if (!p->parent->connection) {
ast_log(LOG_ERROR, "XMPP client not found\n");
- return -1;
+ return -1;
}
client = p->parent->connection;
ast_aji_send_chat(client, p->them, text);
return res;
-}
+}
static int jingle_digit(struct ast_channel *ast, char digit, unsigned int duration)
{
Modified: team/phsultan/jabberreceive/configs/jabber.conf.sample
URL: http://svn.digium.com/view/asterisk/team/phsultan/jabberreceive/configs/jabber.conf.sample?view=diff&rev=164796&r1=164795&r2=164796
==============================================================================
--- team/phsultan/jabberreceive/configs/jabber.conf.sample (original)
+++ team/phsultan/jabberreceive/configs/jabber.conf.sample Tue Dec 16 13:20:16 2008
@@ -20,4 +20,4 @@
;; xaway, or dnd
;statusmessage="I am available" ;;Have custom status message for
;;Asterisk.
-;timeout=100 ;;Timeout on the message stack.
+;timeout=2 ;;Timeout (in seconds) on the message stack, defaults to 2.
Modified: team/phsultan/jabberreceive/doc/jabber.txt
URL: http://svn.digium.com/view/asterisk/team/phsultan/jabberreceive/doc/jabber.txt?view=diff&rev=164796&r1=164795&r2=164796
==============================================================================
--- team/phsultan/jabberreceive/doc/jabber.txt (original)
+++ team/phsultan/jabberreceive/doc/jabber.txt Tue Dec 16 13:20:16 2008
@@ -1,39 +1,20 @@
XMPP (Jabber) is an xml based protocol primarily for presence and messaging.
It is an open standard and there are several open server implementations,
-ejabberd, jabberd(2), wildfire, and many others, as well as several open source
+ejabberd, jabberd(2), openfire, and many others, as well as several open source
clients, Psi, gajim, gaim etc. XMPP differs from other IM applications as it
-is immensly extendable. This allows us to easily integrate Asterisk with
+is immensly extendable. This allows us to easily integrate Asterisk with
XMPP. The Asterisk XMPP Interface is provided by res_jabber.so.
res_jabber allows for Asterisk to connect to any XMPP (Jabber) server and
is also used to provide the connection interface for chan_jingle and
chan_gtalk.
-A function (JABBER_STATUS) and two applications (JabberSend and
-JabberReceive) are exposed to the dialplan.
+Functions (JABBER_STATUS, JABBER_RECEIVE) and applications (JabberSend)
+are exposed to the dialplan.
-You'll find examples of how to use these function/applications
+You'll find examples of how to use these functions/applications
hereafter. We assume that 'asterisk-xmpp' is properly configured in
jabber.conf.
-
-**** JABBER_STATUS ****
-
-Note : as of version 1.6, the corresponding application JabberStatus is still
-available, but marked as deprecated in favor of this function.
-
-JABBER_STATUS stores the status of a buddy in a dialplan variable for
-further use. Here is an AEL example of how to use it :
-
-1234 => {
- JabberStatus(asterisk-xmpp,buddy at gmail.com,STATUS);
- if (${STATUS}=1) {
- NoOp(User is online and active, ring his Gtalk client.);
- Dial(Gtalk/asterisk-xmpp/buddy at gmail.com);
- } else {
- NoOp(Prefer the SIP phone);
- Dial(SIP/1234);
- }
-}
**** JabberSend ****
@@ -47,19 +28,38 @@
}
}
-**** JabberReceive ****
+**** JABBER_STATUS ****
-JabberReceive waits (up to X seconds) for a message from buddy and stores
-it to a dialplan variable. Used along with JabberSend (or SendText,
+Note : as of version 1.6, the corresponding application JabberStatus is still
+available, but marked as deprecated in favor of this function.
+
+JABBER_STATUS stores the status of a buddy in a dialplan variable for
+further use. Here is an AEL example of how to use it :
+
+1234 => {
+ Set(STATUS=${JABBER_STATUS(asterisk-xmpp,buddy at gmail.com)});
+ if (${STATUS}=1) {
+ NoOp(User is online and active, ring his Gtalk client.);
+ Dial(Gtalk/asterisk-xmpp/buddy at gmail.com);
+ } else {
+ NoOp(Prefer the SIP phone);
+ Dial(SIP/1234);
+ }
+}
+
+**** JABBER_RECEIVE ****
+
+JABBER_RECEIVE waits (up to X seconds) for a XMPP message and returns
+its content. Used along with JabberSend (or SendText,
provided it's implemented in the corresponding channel type),
-JabberReceive helps Asterisk interact with users while calls flow
+JABBER_RECEIVE helps Asterisk interact with users while calls flow
through the dialplan.
-JabberReceive/JabberSend are not tied to the XMPP media modules
+JABBER_RECEIVE/JabberSend are not tied to the XMPP media modules
chan_gtalk and chan_jingle, and can be used anywhere in the dialplan.
-In the following example, calls targeted to extension 1234 (be it
+In the following example, calls targeted to extension 1234 (be it
accessed from SIP, DAHDI or whatever channel type) are controlled by
-user bob at jabber.org. Asterisk notifies him that a call is coming, and
+user bob at domain.com. Asterisk notifies him that a call is coming, and
asks him to take an action. This dialog takes place over an XMPP chat.
context from-ext {
@@ -69,10 +69,10 @@
JabberSend(asterisk-xmpp,bob at jabber.org,1 : forward to cellphone);
JabberSend(asterisk-xmpp,bob at jabber.org,2 : forward to work phone);
JabberSend(asterisk-xmpp,bob at jabber.org,Default action : forward to your voicemail);
- JabberReceive(bob at jabber.org,OPTION,20);
+ Set(OPTION=${JABBER_RECEIVE(asterisk-xmpp,bob at jabber.org,20)});
switch (${OPTION}) {
case 1:
- JabberSend(asterisk-xmpp,bob at jabber.org,(Calling cellphone...);
+ JabberSend(asterisk-xmpp,bob at jabber.org,(Calling cellphone...);
Dial(SIP/987654321);
break;
case 2:
@@ -85,11 +85,11 @@
}
}
-When calling from a GoogleTalk or Jingle client, the CALLERID(name)
-is set to the XMPP id of the caller (i.e. his JID). In the
-following example, Asterisk chats back with the caller identified by the
-caller id. We also take advantage of the SendText implementation in
-chan_gtalk (available in chan_jingle, and chan_sip as well), to
+When calling from a GoogleTalk or Jingle client, the CALLERID(name)
+is set to the XMPP id of the caller (i.e. his JID). In the
+following example, Asterisk chats back with the caller identified by the
+caller id. We also take advantage of the SendText implementation in
+chan_gtalk (available in chan_jingle, and chan_sip as well), to
allow the caller to establish SIP calls from his GoogleTalk client :
context gtalk-in {
@@ -97,10 +97,10 @@
NoOp(Caller id : ${CALLERID(all)});
Answer();
SendText(Please enter the number you wish to call);
- JabberReceive(${CALLERID(name)},NEWEXTEN);
+ Set(NEWEXTEN=${JABBER_RECEIVE(asterisk-xmpp,${CALLERID(name)})});
SendText(Calling ${NEWEXTEN} ...);
Dial(SIP/${NEWEXTEN);
- Hangup();
+ Hangup();
}
}
Modified: team/phsultan/jabberreceive/res/res_jabber.c
URL: http://svn.digium.com/view/asterisk/team/phsultan/jabberreceive/res/res_jabber.c?view=diff&rev=164796&r1=164795&r2=164796
==============================================================================
--- team/phsultan/jabberreceive/res/res_jabber.c (original)
+++ team/phsultan/jabberreceive/res/res_jabber.c Tue Dec 16 13:20:16 2008
@@ -34,6 +34,97 @@
<depend>iksemel</depend>
<use>openssl</use>
***/
+/*** DOCUMENTATION
+ <application name="JabberSend" language="en_US">
+ <synopsis>
+ Sends an XMPP message to a buddy.
+ </synopsis>
+ <syntax>
+ <parameter name="account" required="true">
+ <para>The local named account to listen on (specified in
+ jabber.conf)</para>
+ </parameter>
+ <parameter name="jid" required="true">
+ <para>Jabber ID of the buddy to send the message to. It can be a
+ bare JID (username at domain) or a full JID (username at domain/resource).</para>
+ </parameter>
+ <parameter name="message" required="true">
+ <para>The message to send.</para>
+ </parameter>
+ </syntax>
+ <description>
+ <para>Sends the content of <replaceable>message</replaceable> as text message
+ from the given <replaceable>account</replaceable> to the buddy identified by
+ <replaceable>jid</replaceable></para>
+ <para>Example: JabberSend(asterisk,bob at domain.com,Hello world) sends "Hello world"
+ to <replaceable>bob at domain.com</replaceable> as an XMPP message from the account
+ <replaceable>asterisk</replaceable>, configured in jabber.conf.</para>
+ </description>
+ <see-also>
+ <ref type="function">JABBER_STATUS</ref>
+ <ref type="function">JABBER_RECEIVE</ref>
+ </see-also>
+ </application>
+ <function name="JABBER_RECEIVE" language="en_US">
+ <synopsis>
+ Reads XMPP messages.
+ </synopsis>
+ <syntax>
+ <parameter name="account" required="true">
+ <para>The local named account to listen on (specified in
+ jabber.conf)</para>
+ </parameter>
+ <parameter name="jid" required="true">
+ <para>Jabber ID of the buddy to receive message from. It can be a
+ bare JID (username at domain) or a full JID (username at domain/resource).</para>
+ </parameter>
+ <parameter name="timeout">
+ <para>In seconds, defaults to <literal>20</literal>.</para>
+ </parameter>
+ </syntax>
+ <description>
+ <para>Receives a text message on the given <replaceable>account</replaceable>
+ from the buddy identified by <replaceable>jid</replaceable> and returns the contents.</para>
+ <para>Example: ${JABBER_RECEIVE(asterisk,bob at domain.com)} returns an XMPP message
+ sent from <replaceable>bob at domain.com</replaceable> (or nothing in case of a time out), to
+ the <replaceable>asterisk</replaceable> XMPP account configured in jabber.conf.</para>
+ </description>
+ <see-also>
+ <ref type="function">JABBER_STATUS</ref>
+ <ref type="application">JabberSend</ref>
+ </see-also>
+ </function>
+ <function name="JABBER_STATUS" language="en_US">
+ <synopsis>
+ Retrieves a buddy's status.
+ </synopsis>
+ <syntax>
+ <parameter name="account" required="true">
+ <para>The local named account to listen on (specified in
+ jabber.conf)</para>
+ </parameter>
+ <parameter name="jid" required="true">
+ <para>Jabber ID of the buddy to receive message from. It can be a
+ bare JID (username at domain) or a full JID (username at domain/resource).</para>
+ </parameter>
+ </syntax>
+ <description>
+ <para>Retrieves the numeric status associated with the buddy identified
+ by <replaceable>jid</replaceable>.
+ If the buddy does not exist in the buddylist, returns 7.</para>
+ <para>Status will be 1-7.</para>
+ <para>1=Online, 2=Chatty, 3=Away, 4=XAway, 5=DND, 6=Offline</para>
+ <para>If not in roster variable will be set to 7.</para>
+ <para>Example: ${JABBER_STATUS(asterisk,bob at domain.com)} returns 1 if
+ <replaceable>bob at domain.com</replaceable> is online. <replaceable>asterisk</replaceable> is
+ the associated XMPP account configured in jabber.conf.</para>
+ </description>
+ <see-also>
+ <ref type="function">JABBER_RECEIVE</ref>
+ <ref type="application">JabberSend</ref>
+ </see-also>
+ </function>
+ ***/
#include "asterisk.h"
@@ -74,9 +165,9 @@
/*-- Forward declarations */
static void aji_buddy_destroy(struct aji_buddy *obj);
static void aji_client_destroy(struct aji_client *obj);
+static int delete_old_messages(struct aji_client *client);
static int aji_send_exec(struct ast_channel *chan, void *data);
static int aji_status_exec(struct ast_channel *chan, void *data);
-static int aji_recv_exec(struct ast_channel *chan, void *data);
static int aji_is_secure(struct aji_client *client);
#ifdef HAVE_OPENSSL
static int aji_start_tls(struct aji_client *client);
@@ -133,14 +224,6 @@
static char *app_ajisend = "JabberSend";
-static char *ajisend_synopsis = "JabberSend(Jabber,JID,Message)";
-
-static char *ajisend_descrip =
-"JabberSend(Jabber,JID,Message)\n"
-" Jabber - Client or transport Asterisk uses to connect to Jabber\n"
-" JID - XMPP/Jabber JID (Name) of recipient\n"
-" Message - Message to be sent to the buddy\n";
-
static char *app_ajistatus = "JabberStatus";
static char *ajistatus_synopsis = "JabberStatus(Jabber,JID,Variable)";
@@ -153,16 +236,6 @@
" In order, 1=Online, 2=Chatty, 3=Away, 4=XAway, 5=DND, 6=Offline\n"
" If not in roster variable will be set to 7\n\n"
"Note: This application is deprecated. Please use the JABBER_STATUS() function instead.\n";
-
-static char *app_ajirecv = "JabberReceive";
-
-static char *ajirecv_synopsis = "JabberReceive(Variable)";
-
-static char *ajirecv_descrip =
-"JabberReceive(JID,Variable[,timeout])\n"
-" JID - Jabber ID of the buddy to receive message from\n"
-" Variable - Variable to store message in\n"
-" timeout - Defaults to 20s\n" ;
struct aji_client_container clients;
struct aji_capabilities *capabilities = NULL;
@@ -457,16 +530,164 @@
static struct ast_custom_function jabberstatus_function = {
.name = "JABBER_STATUS",
- .synopsis = "Retrieve buddy status",
- .syntax = "JABBER_STATUS(<sender>,<buddy>[/<resource>])",
.read = acf_jabberstatus_read,
- .desc =
-"Retrieves the numeric status associated with the specified buddy (jid). If the\n"
-"buddy does not exist in the buddylist, returns 7.\n"
-"Status will be 1-7.\n"
-" 1=Online, 2=Chatty, 3=Away, 4=XAway, 5=DND, 6=Offline\n"
-" If not in roster variable will be set to 7\n\n",
};
+
+ /*!
+ * \brief Dial plan function to receive a message.
+ * \param channel, and data, data is account, JID and optional
+ * timeout.
+ * \return 0 on success, -1 on failure.
+ */
+static int acf_jabberreceive_read (struct ast_channel *chan, const char *name, char *data, char *buf, size_t buflen)
+{
+ char *aux = NULL, *parse = NULL;
+ int timeout;
+ time_t triggered;
+ struct aji_client *client = NULL;
+ int found = 0;
+ struct aji_message *tmp = NULL;
+ iksid *id = NULL;
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(account);
+ AST_APP_ARG(jid);
+ AST_APP_ARG(timeout);
+ );
+
+ time(&triggered);
+ if (ast_strlen_zero(data)) {
+ ast_log(LOG_WARNING, "%s requires arguments (account,jid[,timeout])\n", name);
+ return -1;
+ }
+
+ parse = ast_strdupa(data);
+ AST_STANDARD_APP_ARGS(args, parse);
+
+ if (args.argc < 2 || args.argc > 3) {
+ ast_log(LOG_WARNING, "%s requires arguments (account,jid[,timeout])\n", name);
+ return -1;
+ }
+
+ client = ast_aji_get_client(args.account);
+ if (!client) {
+ ast_log(LOG_WARNING, "Could not find client %s, exiting\n", args.account);
+ return -1;
+ }
+
+ id = iks_id_new(client->stack, args.jid);
+ if (!id) {
+ ast_log(LOG_WARNING, "Could not build a valid Jabber Identifier from %s, exiting\n", args.jid);
+ return -1;
+ }
+
+ if (ast_strlen_zero(args.timeout)) {
+ timeout = 20;
+ } else {
+ timeout = atoi(args.timeout);
+ if (timeout <= 0) {
+ ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
+ return -1;
+ }
+ }
+
+ ast_debug(3, "Waiting for an XMPP message from %s\n", args.jid);
+
+ /* search the messages list, grab the first message that matches with
+ * the from JID we're expecting, remove it from the messages list */
+ while (difftime(time(NULL), triggered) < timeout) {
+ AST_LIST_LOCK(&client->messages);
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&client->messages, tmp, list) {
+ iksid *from = iks_id_new(client->stack, tmp->from);
+ if (!from) {
+ ast_log(LOG_WARNING, "Could not build a valid Jabber Identifier from %s, exiting\n", tmp->from);
+ return -1;
+ }
+ if (strchr(args.jid, '/')) {
+ if (iks_id_cmp(from, id, IKS_ID_RESOURCE | IKS_ID_USER | IKS_ID_SERVER)) {
+ continue;
+ }
+ } else {
+ if (iks_id_cmp(from, id, IKS_ID_USER | IKS_ID_SERVER)) {
+ continue;
+ }
+ }
+ found = 1;
+ aux = ast_strdupa(tmp->message);
+ AST_LIST_REMOVE_CURRENT(list);
+ if (tmp->from) {
+ ast_free(tmp->from);
+ }
+ if (tmp->message) {
+ ast_free(tmp->message);
+ }
+ break;
+ }
+ AST_LIST_TRAVERSE_SAFE_END;
+ AST_LIST_UNLOCK(&client->messages);
+ if (found) {
+ break;
+ }
+ ast_safe_sleep(chan, 500);
+ }
+ /* return if we timed out */
+ if (!found) {
+ ast_log(LOG_NOTICE, "Timed out : no message received from %s\n", args.jid);
+ return -1;
+ }
+ ast_copy_string(buf, aux, buflen);
+ return 0;
+}
+
+static struct ast_custom_function jabberreceive_function = {
+ .name = "JABBER_RECEIVE",
+ .read = acf_jabberreceive_read,
+};
+
+/*!
+ * \brief Delete old messages
+ * Messages stored during more than client->message_timeout are deleted
+ * \param client Asterisk's XMPP client
+ * \return the number of deleted messages, or -1 in case of failure
+ */
+static int delete_old_messages(struct aji_client *client) {
+ int deleted = 0;
+ int flag = 0;
+ struct aji_message *tmp = NULL;
+ if (!client) {
+ ast_log(LOG_ERROR, "Cannot find our XMPP client\n");
+ return -1;
+ }
+
+ /* remove old messages */
+ AST_LIST_LOCK(&client->messages);
+ if (AST_LIST_EMPTY(&client->messages)) {
+ AST_LIST_UNLOCK(&client->messages);
+ return 0;
+ }
+
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&client->messages, tmp, list) {
+ if (flag) {
+ AST_LIST_REMOVE_CURRENT(list);
+ if (tmp->from)
+ ast_free(tmp->from);
+ if (tmp->message)
+ ast_free(tmp->message);
+ deleted ++;
+ } else if (difftime(time(NULL), tmp->arrived) >= client->message_timeout) {
+ flag = 1;
+ AST_LIST_REMOVE_CURRENT(list);
+ if (tmp->from)
+ ast_free(tmp->from);
+ if (tmp->message)
+ ast_free(tmp->message);
+ deleted ++;
+ }
+ }
+ AST_LIST_TRAVERSE_SAFE_END;
+ AST_LIST_UNLOCK(&client->messages);
+
+ return deleted;
+}
/*!
* \brief Dial plan function to send a message.
@@ -485,14 +706,14 @@
);
if (!data) {
- ast_log(LOG_ERROR, "Usage: JabberSend(<sender>,<recipient>,<message>)\n");
- return 0;
+ ast_log(LOG_WARNING, "%s requires arguments (account,jid,message)\n", app_ajisend);
+ return -1;
}
s = ast_strdupa(data);
AST_STANDARD_APP_ARGS(args, s);
if (args.argc < 3) {
- ast_log(LOG_ERROR, "JabberSend requires 3 arguments: '%s'\n", (char *) data);
+ ast_log(LOG_WARNING, "%s requires arguments (account,jid,message)\n", app_ajisend);
return -1;
}
@@ -500,8 +721,9 @@
ast_log(LOG_WARNING, "Could not find sender connection: '%s'\n", args.sender);
return -1;
}
- if (strchr(args.recipient, '@') && !ast_strlen_zero(args.message))
+ if (strchr(args.recipient, '@') && !ast_strlen_zero(args.message)) {
ast_aji_send_chat(client, args.recipient, args.message);
+ }
return 0;
}
@@ -774,61 +996,6 @@
return ret;
return IKS_OK;
-}
-
- /*!
- * \brief Dial plan function to receive a message.
- * \param channel, and data, data is sender, variable.
- * \return 1 on success, -1 on failure.
- */
-static int aji_recv_exec(struct ast_channel *chan, void *data)
-{
- char message[AST_MAX_EXTENSION];
- char *buf, *parse, *variable = NULL;
- int to; /* timeout */
-
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(sender);
- AST_APP_ARG(variable);
- AST_APP_ARG(timeout);
- );
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "%s requires arguments (sender,variable[,timeout])\n", app_ajirecv);
- return -1;
- }
-
- parse = ast_strdupa(data);
- AST_STANDARD_APP_ARGS(args, parse);
-
- if (args.argc < 2 || args.argc > 3) {
- ast_log(LOG_WARNING, "%s requires arguments (sender,variable[,timeout])\n", app_ajirecv);
- return -1;
- }
-
- if (ast_strlen_zero(args.timeout)) {
- to = 20000;
- } else {
- to = atoi(args.timeout);
- if (to > 0) {
- to *= 1000;
- } else {
- ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
- return -1;
- }
- }
-
- ast_debug(3, "Waiting for an XMPP message from %s\n", args.sender);
- buf = ast_recvtext(chan, to);
- /* return if we timed out */
- if (!buf) {
- return -1;
- }
- ast_copy_string(message, buf, sizeof(message));
- variable = ast_skip_blanks(args.variable);
- ast_trim_blanks(variable);
- pbx_builtin_setvar_helper(chan, variable, message);
- return 1;
}
/*!
@@ -1536,25 +1703,22 @@
/*!
* \brief Handles presence packets.
+ * Adds the incoming message to the client's message list.
* \param client the configured XMPP client we use to connect to a XMPP server
* \param pak ikspak the node
*/
static void aji_handle_message(struct aji_client *client, ikspak *pak)
{
- struct aji_message *insert, *tmp;
- struct ast_channel *chan = NULL;
- char *parse = NULL;
- struct ast_frame f = { AST_FRAME_TEXT, };
- int flag = 0;
- AST_DECLARE_APP_ARGS(args,
- AST_APP_ARG(sender);
- AST_APP_ARG(variable);
- );
+ struct aji_message *insert;
+ int deleted = 0;
ast_debug(3, "client %s received a message\n", client->name);
-
- if (!(insert = ast_calloc(1, sizeof(*insert))))
+
+ if (!(insert = ast_calloc(1, sizeof(*insert)))) {
+ ast_log(LOG_ERROR, "Out of memory.\n");
return;
+ }
+
time(&insert->arrived);
if (iks_find_cdata(pak->x, "body")) {
insert->message = ast_strdup(iks_find_cdata(pak->x, "body"));
@@ -1564,58 +1728,14 @@
}
if (pak->from){
/* insert will furtherly be added to message list */
- insert->from = ast_strdup(pak->from->full);
- }
- /* if we receive a message from a buddy, try to pass it to
- a channel waiting for JabberReceive to return */
- if (pak->from && iks_find_cdata(pak->x, "body")) {
+ insert->from = ast_strdup(pak->from->full);
ast_debug(3, "message comes from %s\n", insert->from);
-
- /* build the text frame from received message */
- if (insert->message) {
- f.datalen = strlen(insert->message);
- f.data.ptr = (void *) insert->message;
- }
-
- while ((chan = ast_channel_walk_locked(chan))) {
- if (!chan->data) {
- continue;
- }
- parse = ast_strdupa(chan->data);
- AST_STANDARD_APP_ARGS(args, parse);
-
- /* now queue the text frame only if the channel is
- under control of the JabberReceive app *and* the
- XMPP message comes from the configured JID */
- if (!strcasecmp(chan->appl, "JabberReceive") && !strncmp(args.sender, pak->from->partial, strlen(pak->from->partial))) {
- ast_debug(3, "Queuing text frame to %s\n", chan->name);
- ast_queue_frame(chan, &f);
- }
- ast_channel_unlock(chan);
- if (chan) {
- break;
- }
- }
- }
-
+ }
+
+ /* remove old messages, and insert received message */
+ deleted = delete_old_messages(client);
+ ast_debug(3, "Deleted %d messages for client %s\n", deleted, client->name);
AST_LIST_LOCK(&client->messages);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&client->messages, tmp, list) {
- if (flag) {
- AST_LIST_REMOVE_CURRENT(list);
- if (tmp->from)
- ast_free(tmp->from);
- if (tmp->message)
- ast_free(tmp->message);
- } else if (difftime(time(NULL), tmp->arrived) >= client->message_timeout) {
- flag = 1;
- AST_LIST_REMOVE_CURRENT(list);
- if (tmp->from)
- ast_free(tmp->from);
- if (tmp->message)
- ast_free(tmp->message);
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
AST_LIST_INSERT_HEAD(&client->messages, insert, list);
AST_LIST_UNLOCK(&client->messages);
}
@@ -2714,7 +2834,7 @@
client->forcessl = 0;
client->keepalive = 1;
client->timeout = 50;
- client->message_timeout = 100;
+ client->message_timeout = 2;
AST_LIST_HEAD_INIT(&client->messages);
client->component = 0;
ast_copy_string(client->statusmessage, "Online and Available", sizeof(client->statusmessage));
@@ -3087,9 +3207,9 @@
ast_cli_unregister_multiple(aji_cli, ARRAY_LEN(aji_cli));
ast_unregister_application(app_ajisend);
ast_unregister_application(app_ajistatus);
- ast_unregister_application(app_ajirecv);
ast_manager_unregister("JabberSend");
ast_custom_function_unregister(&jabberstatus_function);
+ ast_custom_function_unregister(&jabberreceive_function);
ASTOBJ_CONTAINER_TRAVERSE(&clients, 1, {
ASTOBJ_RDLOCK(iterator);
@@ -3113,11 +3233,11 @@
return AST_MODULE_LOAD_DECLINE;
ast_manager_register2("JabberSend", EVENT_FLAG_SYSTEM, manager_jabber_send,
"Sends a message to a Jabber Client", mandescr_jabber_send);
- ast_register_application(app_ajisend, aji_send_exec, ajisend_synopsis, ajisend_descrip);
+ ast_register_application_xml(app_ajisend, aji_send_exec);
ast_register_application(app_ajistatus, aji_status_exec, ajistatus_synopsis, ajistatus_descrip);
- ast_register_application(app_ajirecv, aji_recv_exec, ajirecv_synopsis, ajirecv_descrip);
ast_cli_register_multiple(aji_cli, ARRAY_LEN(aji_cli));
ast_custom_function_register(&jabberstatus_function);
+ ast_custom_function_register(&jabberreceive_function);
return 0;
}
More information about the asterisk-commits
mailing list