mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-16 14:58:25 +00:00
- Formatting
- Changing debug messages from VERBOSE to DEBUG channel - Adding a few todo's - Adding a few more "XMPP"'s to compliment Jabber... git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@136005 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -17,12 +17,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \file
|
/*! \file
|
||||||
* \brief A resource for interfacing asterisk directly as a client
|
* \brief A resource for interfacing Asterisk directly as a client
|
||||||
* or a component to a jabber compliant server.
|
* or a component to a XMPP/Jabber compliant server.
|
||||||
|
*
|
||||||
|
* References:
|
||||||
|
* - http://www.xmpp.org - The XMPP standards foundation
|
||||||
*
|
*
|
||||||
* \extref Iksemel http://code.google.com/p/iksemel/
|
* \extref Iksemel http://code.google.com/p/iksemel/
|
||||||
*
|
*
|
||||||
* \todo If you unload this module, chan_gtalk/jingle will be dead. How do we handle that?
|
* \todo If you unload this module, chan_gtalk/jingle will be dead. How do we handle that?
|
||||||
|
* \todo Dialplan applications need RETURN variable, like JABBERSENDSTATUS
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -55,6 +59,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|||||||
#include "asterisk/astdb.h"
|
#include "asterisk/astdb.h"
|
||||||
#include "asterisk/manager.h"
|
#include "asterisk/manager.h"
|
||||||
|
|
||||||
|
/*! \todo This should really be renamed to xmpp.conf. For backwards compatibility, we
|
||||||
|
need to read both files */
|
||||||
#define JABBER_CONFIG "jabber.conf"
|
#define JABBER_CONFIG "jabber.conf"
|
||||||
|
|
||||||
#ifndef FALSE
|
#ifndef FALSE
|
||||||
@@ -133,8 +139,8 @@ static char *ajisend_synopsis = "JabberSend(jabber,screenname,message)";
|
|||||||
static char *ajisend_descrip =
|
static char *ajisend_descrip =
|
||||||
"JabberSend(Jabber,ScreenName,Message)\n"
|
"JabberSend(Jabber,ScreenName,Message)\n"
|
||||||
" Jabber - Client or transport Asterisk uses to connect to Jabber\n"
|
" Jabber - Client or transport Asterisk uses to connect to Jabber\n"
|
||||||
" ScreenName - User Name to message.\n"
|
" ScreenName - XMPP/Jabber JID (Name) of recipient\n"
|
||||||
" Message - Message to be sent to the buddy\n";
|
" Message - Message to be sent to the budd (UTF8)y\n";
|
||||||
|
|
||||||
static char *app_ajistatus = "JabberStatus";
|
static char *app_ajistatus = "JabberStatus";
|
||||||
|
|
||||||
@@ -145,8 +151,9 @@ static char *ajistatus_descrip =
|
|||||||
" Jabber - Client or transport Asterisk uses to connect to Jabber\n"
|
" Jabber - Client or transport Asterisk uses to connect to Jabber\n"
|
||||||
" ScreenName - User Name to retrieve status from.\n"
|
" ScreenName - User Name to retrieve status from.\n"
|
||||||
" Variable - Variable to store presence in will be 1-6.\n"
|
" Variable - Variable to store presence in will be 1-6.\n"
|
||||||
" In order, Online, Chatty, Away, XAway, DND, Offline\n"
|
" In order, 1=Online, 2=Chatty, 3=Away, 4=XAway, 5=DND, 6=Offline\n"
|
||||||
" If not in roster variable will = 7\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";
|
||||||
|
|
||||||
struct aji_client_container clients;
|
struct aji_client_container clients;
|
||||||
struct aji_capabilities *capabilities = NULL;
|
struct aji_capabilities *capabilities = NULL;
|
||||||
@@ -407,13 +414,13 @@ static int acf_jabberstatus_read(struct ast_channel *chan, const char *name, cha
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
ast_log(LOG_ERROR, "Usage: JABBER_STATUS(<sender>,<screenname>[/<resource>])\n");
|
ast_log(LOG_ERROR, "Usage: JABBER_STATUS(<sender>,<jid>[/<resource>])\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
AST_STANDARD_APP_ARGS(args, data);
|
AST_STANDARD_APP_ARGS(args, data);
|
||||||
|
|
||||||
if (args.argc != 2) {
|
if (args.argc != 2) {
|
||||||
ast_log(LOG_ERROR, "JABBER_STATUS requires 2 arguments.\n");
|
ast_log(LOG_ERROR, "JABBER_STATUS requires 2 arguments: sender and jid.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,8 +452,11 @@ static struct ast_custom_function jabberstatus_function = {
|
|||||||
.syntax = "JABBER_STATUS(<sender>,<buddy>[/<resource>])",
|
.syntax = "JABBER_STATUS(<sender>,<buddy>[/<resource>])",
|
||||||
.read = acf_jabberstatus_read,
|
.read = acf_jabberstatus_read,
|
||||||
.desc =
|
.desc =
|
||||||
"Retrieves the numeric status associated with the specified buddy. If the\n"
|
"Retrieves the numeric status associated with the specified buddy (jid). If the\n"
|
||||||
"buddy does not exist in the buddylist, returns 7.\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",
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -776,8 +786,9 @@ static void aji_log_hook(void *data, const char *xmpp, size_t size, int is_incom
|
|||||||
ast_verbose("\nJABBER: %s INCOMING: %s\n", client->name, xmpp);
|
ast_verbose("\nJABBER: %s INCOMING: %s\n", client->name, xmpp);
|
||||||
else {
|
else {
|
||||||
if( strlen(xmpp) == 1) {
|
if( strlen(xmpp) == 1) {
|
||||||
if(option_debug > 2 && xmpp[0] == ' ')
|
if(option_debug > 2 && xmpp[0] == ' ') {
|
||||||
ast_verbose("\nJABBER: Keep alive packet\n");
|
ast_verbose("\nJABBER: Keep alive packet\n");
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
ast_verbose("\nJABBER: %s OUTGOING: %s\n", client->name, xmpp);
|
ast_verbose("\nJABBER: %s OUTGOING: %s\n", client->name, xmpp);
|
||||||
}
|
}
|
||||||
@@ -1040,7 +1051,7 @@ static int aji_act_hook(void *data, int type, iks *node)
|
|||||||
return IKS_OK;
|
return IKS_OK;
|
||||||
}
|
}
|
||||||
/*!
|
/*!
|
||||||
* \brief Uknown
|
* \brief Unknown
|
||||||
* \param data void
|
* \param data void
|
||||||
* \param pak ikspak
|
* \param pak ikspak
|
||||||
* \return IKS_FILTER_EAT.
|
* \return IKS_FILTER_EAT.
|
||||||
@@ -1083,7 +1094,7 @@ static int aji_register_approve_handler(void *data, ikspak *pak)
|
|||||||
return IKS_FILTER_EAT;
|
return IKS_FILTER_EAT;
|
||||||
}
|
}
|
||||||
/*!
|
/*!
|
||||||
* \brief register query
|
* \brief register handler for incoming querys (IQ's)
|
||||||
* \param data incoming aji_client request
|
* \param data incoming aji_client request
|
||||||
* \param pak ikspak
|
* \param pak ikspak
|
||||||
* \return IKS_FILTER_EAT.
|
* \return IKS_FILTER_EAT.
|
||||||
@@ -1093,14 +1104,15 @@ static int aji_register_query_handler(void *data, ikspak *pak)
|
|||||||
struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
|
struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
|
||||||
struct aji_buddy *buddy = NULL;
|
struct aji_buddy *buddy = NULL;
|
||||||
char *node = NULL;
|
char *node = NULL;
|
||||||
|
iks *iq = NULL, *query = NULL;
|
||||||
|
|
||||||
client = (struct aji_client *) data;
|
client = (struct aji_client *) data;
|
||||||
|
|
||||||
buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
|
buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
|
||||||
if (!buddy) {
|
if (!buddy) {
|
||||||
iks *iq = NULL, *query = NULL, *error = NULL, *notacceptable = NULL;
|
iks *error = NULL, *notacceptable = NULL;
|
||||||
|
|
||||||
ast_verbose("Someone.... %s tried to register but they aren't allowed\n", pak->from->partial);
|
ast_log(LOG_ERROR, "Someone.... %s tried to register but they aren't allowed\n", pak->from->partial);
|
||||||
iq = iks_new("iq");
|
iq = iks_new("iq");
|
||||||
query = iks_new("query");
|
query = iks_new("query");
|
||||||
error = iks_new("error");
|
error = iks_new("error");
|
||||||
@@ -1122,12 +1134,10 @@ static int aji_register_query_handler(void *data, ikspak *pak)
|
|||||||
ast_log(LOG_ERROR, "Out of memory.\n");
|
ast_log(LOG_ERROR, "Out of memory.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
iks_delete(iq);
|
|
||||||
iks_delete(query);
|
|
||||||
iks_delete(error);
|
iks_delete(error);
|
||||||
iks_delete(notacceptable);
|
iks_delete(notacceptable);
|
||||||
} else if (!(node = iks_find_attrib(pak->query, "node"))) {
|
} else if (!(node = iks_find_attrib(pak->query, "node"))) {
|
||||||
iks *iq = NULL, *query = NULL, *instructions = NULL;
|
iks *instructions = NULL;
|
||||||
char *explain = "Welcome to Asterisk - the Open Source PBX.\n";
|
char *explain = "Welcome to Asterisk - the Open Source PBX.\n";
|
||||||
iq = iks_new("iq");
|
iq = iks_new("iq");
|
||||||
query = iks_new("query");
|
query = iks_new("query");
|
||||||
@@ -1146,10 +1156,10 @@ static int aji_register_query_handler(void *data, ikspak *pak)
|
|||||||
ast_log(LOG_ERROR, "Out of memory.\n");
|
ast_log(LOG_ERROR, "Out of memory.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
iks_delete(iq);
|
|
||||||
iks_delete(query);
|
|
||||||
iks_delete(instructions);
|
iks_delete(instructions);
|
||||||
}
|
}
|
||||||
|
iks_delete(iq);
|
||||||
|
iks_delete(query);
|
||||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||||
return IKS_FILTER_EAT;
|
return IKS_FILTER_EAT;
|
||||||
}
|
}
|
||||||
@@ -1686,35 +1696,35 @@ static void aji_handle_presence(struct aji_client *client, ikspak *pak)
|
|||||||
}
|
}
|
||||||
switch (pak->subtype) {
|
switch (pak->subtype) {
|
||||||
case IKS_TYPE_AVAILABLE:
|
case IKS_TYPE_AVAILABLE:
|
||||||
ast_verb(5, "JABBER: I am available ^_* %i\n", pak->subtype);
|
ast_debug(3, "JABBER: I am available ^_* %i\n", pak->subtype);
|
||||||
break;
|
break;
|
||||||
case IKS_TYPE_UNAVAILABLE:
|
case IKS_TYPE_UNAVAILABLE:
|
||||||
ast_verb(5, "JABBER: I am unavailable ^_* %i\n", pak->subtype);
|
ast_debug(3, "JABBER: I am unavailable ^_* %i\n", pak->subtype);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ast_verb(5, "JABBER: Ohh sexy and the wrong type: %i\n", pak->subtype);
|
ast_debug(3, "JABBER: Ohh sexy and the wrong type: %i\n", pak->subtype);
|
||||||
}
|
}
|
||||||
switch (pak->show) {
|
switch (pak->show) {
|
||||||
case IKS_SHOW_UNAVAILABLE:
|
case IKS_SHOW_UNAVAILABLE:
|
||||||
ast_verb(5, "JABBER: type: %i subtype %i\n", pak->subtype, pak->show);
|
ast_debug(3, "JABBER: type: %i subtype %i\n", pak->subtype, pak->show);
|
||||||
break;
|
break;
|
||||||
case IKS_SHOW_AVAILABLE:
|
case IKS_SHOW_AVAILABLE:
|
||||||
ast_verb(5, "JABBER: type is available\n");
|
ast_debug(3, "JABBER: type is available\n");
|
||||||
break;
|
break;
|
||||||
case IKS_SHOW_CHAT:
|
case IKS_SHOW_CHAT:
|
||||||
ast_verb(5, "JABBER: type: %i subtype %i\n", pak->subtype, pak->show);
|
ast_debug(3, "JABBER: type: %i subtype %i\n", pak->subtype, pak->show);
|
||||||
break;
|
break;
|
||||||
case IKS_SHOW_AWAY:
|
case IKS_SHOW_AWAY:
|
||||||
ast_verb(5, "JABBER: type is away\n");
|
ast_debug(3, "JABBER: type is away\n");
|
||||||
break;
|
break;
|
||||||
case IKS_SHOW_XA:
|
case IKS_SHOW_XA:
|
||||||
ast_verb(5, "JABBER: type: %i subtype %i\n", pak->subtype, pak->show);
|
ast_debug(3, "JABBER: type: %i subtype %i\n", pak->subtype, pak->show);
|
||||||
break;
|
break;
|
||||||
case IKS_SHOW_DND:
|
case IKS_SHOW_DND:
|
||||||
ast_verb(5, "JABBER: type: %i subtype %i\n", pak->subtype, pak->show);
|
ast_debug(3, "JABBER: type: %i subtype %i\n", pak->subtype, pak->show);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ast_verb(5, "JABBER: Kinky! how did that happen %i\n", pak->show);
|
ast_debug(3, "JABBER: Kinky! how did that happen %i\n", pak->show);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1893,7 +1903,7 @@ static void *aji_recv_loop(void *data)
|
|||||||
int res = IKS_HOOK;
|
int res = IKS_HOOK;
|
||||||
|
|
||||||
while(res != IKS_OK) {
|
while(res != IKS_OK) {
|
||||||
ast_verb(4, "JABBER: Connecting.\n");
|
ast_debug(3, "JABBER: Connecting.\n");
|
||||||
res = aji_reconnect(client);
|
res = aji_reconnect(client);
|
||||||
sleep(4);
|
sleep(4);
|
||||||
}
|
}
|
||||||
@@ -1901,7 +1911,7 @@ static void *aji_recv_loop(void *data)
|
|||||||
do {
|
do {
|
||||||
if (res == IKS_NET_RWERR || client->timeout == 0) {
|
if (res == IKS_NET_RWERR || client->timeout == 0) {
|
||||||
while(res != IKS_OK) {
|
while(res != IKS_OK) {
|
||||||
ast_verb(4, "JABBER: reconnecting.\n");
|
ast_debug(3, "JABBER: reconnecting.\n");
|
||||||
res = aji_reconnect(client);
|
res = aji_reconnect(client);
|
||||||
sleep(4);
|
sleep(4);
|
||||||
}
|
}
|
||||||
@@ -1921,7 +1931,7 @@ static void *aji_recv_loop(void *data)
|
|||||||
if (res == IKS_HOOK)
|
if (res == IKS_HOOK)
|
||||||
ast_log(LOG_WARNING, "JABBER: Got hook event.\n");
|
ast_log(LOG_WARNING, "JABBER: Got hook event.\n");
|
||||||
else if (res == IKS_NET_TLSFAIL)
|
else if (res == IKS_NET_TLSFAIL)
|
||||||
ast_log(LOG_WARNING, "JABBER: Failure in TLS.\n");
|
ast_log(LOG_ERROR, "JABBER: Failure in TLS.\n");
|
||||||
else if (client->timeout == 0 && client->state == AJI_CONNECTED) {
|
else if (client->timeout == 0 && client->state == AJI_CONNECTED) {
|
||||||
res = client->keepalive ? aji_send_raw(client, " ") : IKS_OK;
|
res = client->keepalive ? aji_send_raw(client, " ") : IKS_OK;
|
||||||
if(res == IKS_OK)
|
if(res == IKS_OK)
|
||||||
@@ -2046,6 +2056,7 @@ static int aji_register_transport2(void *data, ikspak *pak)
|
|||||||
* \brief goes through roster and prunes users not needed in list, or adds them accordingly.
|
* \brief goes through roster and prunes users not needed in list, or adds them accordingly.
|
||||||
* \param client the configured XMPP client we use to connect to a XMPP server
|
* \param client the configured XMPP client we use to connect to a XMPP server
|
||||||
* \return void.
|
* \return void.
|
||||||
|
* \note The messages here should be configurable.
|
||||||
*/
|
*/
|
||||||
static void aji_pruneregister(struct aji_client *client)
|
static void aji_pruneregister(struct aji_client *client)
|
||||||
{
|
{
|
||||||
@@ -2067,10 +2078,10 @@ static void aji_pruneregister(struct aji_client *client)
|
|||||||
* be called at the same time */
|
* be called at the same time */
|
||||||
if (ast_test_flag(&iterator->flags, AJI_AUTOPRUNE)) {
|
if (ast_test_flag(&iterator->flags, AJI_AUTOPRUNE)) {
|
||||||
res = ast_aji_send(client, iks_make_s10n(IKS_TYPE_UNSUBSCRIBE, iterator->name,
|
res = ast_aji_send(client, iks_make_s10n(IKS_TYPE_UNSUBSCRIBE, iterator->name,
|
||||||
"GoodBye your status is no longer needed by Asterisk the Open Source PBX"
|
"GoodBye. Your status is no longer needed by Asterisk the Open Source PBX"
|
||||||
" so I am no longer subscribing to your presence.\n"));
|
" so I am no longer subscribing to your presence.\n"));
|
||||||
res = ast_aji_send(client, iks_make_s10n(IKS_TYPE_UNSUBSCRIBED, iterator->name,
|
res = ast_aji_send(client, iks_make_s10n(IKS_TYPE_UNSUBSCRIBED, iterator->name,
|
||||||
"GoodBye you are no longer in the asterisk config file so I am removing"
|
"GoodBye. You are no longer in the Asterisk config file so I am removing"
|
||||||
" your access to my presence.\n"));
|
" your access to my presence.\n"));
|
||||||
iks_insert_attrib(removeiq, "from", client->jid->full);
|
iks_insert_attrib(removeiq, "from", client->jid->full);
|
||||||
iks_insert_attrib(removeiq, "type", "set");
|
iks_insert_attrib(removeiq, "type", "set");
|
||||||
@@ -2080,7 +2091,7 @@ static void aji_pruneregister(struct aji_client *client)
|
|||||||
res = ast_aji_send(client, removeiq);
|
res = ast_aji_send(client, removeiq);
|
||||||
} else if (ast_test_flag(&iterator->flags, AJI_AUTOREGISTER)) {
|
} else if (ast_test_flag(&iterator->flags, AJI_AUTOREGISTER)) {
|
||||||
res = ast_aji_send(client, iks_make_s10n(IKS_TYPE_SUBSCRIBE, iterator->name,
|
res = ast_aji_send(client, iks_make_s10n(IKS_TYPE_SUBSCRIBE, iterator->name,
|
||||||
"Greetings I am the Asterisk Open Source PBX and I want to subscribe to your presence\n"));
|
"Greetings! I am the Asterisk Open Source PBX and I want to subscribe to your presence\n"));
|
||||||
ast_clear_flag(&iterator->flags, AJI_AUTOREGISTER);
|
ast_clear_flag(&iterator->flags, AJI_AUTOREGISTER);
|
||||||
}
|
}
|
||||||
ASTOBJ_UNLOCK(iterator);
|
ASTOBJ_UNLOCK(iterator);
|
||||||
@@ -2178,6 +2189,7 @@ static int aji_filter_roster(void *data, ikspak *pak)
|
|||||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||||
return IKS_FILTER_EAT;
|
return IKS_FILTER_EAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief reconnect to jabber server
|
* \brief reconnect to jabber server
|
||||||
* \param client the configured XMPP client we use to connect to a XMPP server
|
* \param client the configured XMPP client we use to connect to a XMPP server
|
||||||
@@ -2199,6 +2211,7 @@ static int aji_reconnect(struct aji_client *client)
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Get the roster of jabber users
|
* \brief Get the roster of jabber users
|
||||||
* \param client the configured XMPP client we use to connect to a XMPP server
|
* \param client the configured XMPP client we use to connect to a XMPP server
|
||||||
@@ -2348,7 +2361,7 @@ static char *aji_do_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_a
|
|||||||
e->command = "jabber set debug {on|off}";
|
e->command = "jabber set debug {on|off}";
|
||||||
e->usage =
|
e->usage =
|
||||||
"Usage: jabber set debug {on|off}\n"
|
"Usage: jabber set debug {on|off}\n"
|
||||||
" Enables/disables dumping of Jabber packets for debugging purposes.\n";
|
" Enables/disables dumping of XMPP/Jabber packets for debugging purposes.\n";
|
||||||
return NULL;
|
return NULL;
|
||||||
case CLI_GENERATE:
|
case CLI_GENERATE:
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
Reference in New Issue
Block a user