Wed Jan 8 2020 09:50:18

Asterisk developer's documentation


res_jabber.c File Reference

A resource for interfacing Asterisk directly as a client or a component to a XMPP/Jabber compliant server. More...

#include "asterisk.h"
#include <ctype.h>
#include <iksemel.h>
#include "asterisk/channel.h"
#include "asterisk/jabber.h"
#include "asterisk/file.h"
#include "asterisk/config.h"
#include "asterisk/callerid.h"
#include "asterisk/lock.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/pbx.h"
#include "asterisk/md5.h"
#include "asterisk/acl.h"
#include "asterisk/utils.h"
#include "asterisk/module.h"
#include "asterisk/astobj.h"
#include "asterisk/astdb.h"
#include "asterisk/manager.h"
#include "asterisk/event.h"
#include "asterisk/devicestate.h"

Go to the source code of this file.

Macros

#define JABBER_CONFIG   "jabber.conf"
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static int acf_jabberreceive_read (struct ast_channel *chan, const char *name, char *data, char *buf, size_t buflen)
 
static int acf_jabberstatus_read (struct ast_channel *chan, const char *name, char *data, char *buf, size_t buflen)
 
static int aji_act_hook (void *data, int type, iks *node)
 
static iks * aji_build_node_config (iks *pubsub, const char *node_type, const char *collection_name)
 
static iks * aji_build_node_request (struct aji_client *client, const char *collection)
 Build the a node request. More...
 
static iks * aji_build_publish_skeleton (struct aji_client *client, const char *node, const char *event_type, unsigned int cachable)
 Build the skeleton of a publish. More...
 
static char * aji_cli_create_collection (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Method to expose PubSub collection node creation via CLI. More...
 
static char * aji_cli_create_leafnode (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Method to expose PubSub leaf node creation via CLI. More...
 
static char * aji_cli_delete_pubsub_node (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Method to expose PubSub node deletion via CLI. More...
 
static char * aji_cli_list_pubsub_nodes (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Method to expose PubSub node list via CLI. More...
 
static char * aji_cli_purge_pubsub_nodes (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Method to purge PubSub nodes via CLI. More...
 
static int aji_client_connect (void *data, ikspak *pak)
 
static int aji_client_info_handler (void *data, ikspak *pak)
 
static void aji_create_affiliations (struct aji_client *client, const char *node)
 Add Owner affiliations for pubsub node. More...
 
static int aji_create_buddy (char *label, struct aji_client *client)
 
static int aji_create_client (char *label, struct ast_variable *var, int debug)
 
static void aji_create_pubsub_collection (struct aji_client *client, const char *collection_name)
 Create a PubSub collection node. More...
 
static void aji_create_pubsub_leaf (struct aji_client *client, const char *collection_name, const char *leaf_name)
 Create a PubSub leaf node. More...
 
static iks * aji_create_pubsub_node (struct aji_client *client, const char *node_type, const char *name, const char *collection_name)
 Create a pubsub node. More...
 
static int aji_delete_node_list (void *data, ikspak *pak)
 Delete pubsub item lists. More...
 
static void aji_delete_pubsub_node (struct aji_client *client, const char *node_name)
 Delete a PubSub node. More...
 
static void aji_devstate_cb (const struct ast_event *ast_event, void *data)
 Callback function for device state events. More...
 
static int aji_dinfo_handler (void *data, ikspak *pak)
 
static int aji_ditems_handler (void *data, ikspak *pak)
 
static char * aji_do_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * aji_do_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int aji_filter_roster (void *data, ikspak *pak)
 
static struct aji_resourceaji_find_resource (struct aji_buddy *buddy, char *name)
 
static struct aji_versionaji_find_version (char *node, char *version, ikspak *pak)
 
static int aji_get_roster (struct aji_client *client)
 
static void aji_handle_iq (struct aji_client *client, iks *node)
 
static void aji_handle_message (struct aji_client *client, ikspak *pak)
 
static void aji_handle_presence (struct aji_client *client, ikspak *pak)
 
static int aji_handle_pubsub_error (void *data, ikspak *pak)
 
static int aji_handle_pubsub_event (void *data, ikspak *pak)
 Callback for handling PubSub events. More...
 
static void aji_handle_subscribe (struct aji_client *client, ikspak *pak)
 
static void aji_init_event_distribution (struct aji_client *client)
 Initialize collections for event distribution. More...
 
static int aji_initialize (struct aji_client *client)
 
static int aji_io_recv (struct aji_client *client, char *buffer, size_t buf_len, int timeout)
 
static int aji_is_secure (struct aji_client *client)
 
static int aji_join_exec (struct ast_channel *chan, const char *data)
 Application to join a chat room. More...
 
static int aji_leave_exec (struct ast_channel *chan, const char *data)
 Application to leave a chat room. More...
 
static int aji_load_config (int reload)
 
static void aji_log_hook (void *data, const char *xmpp, size_t size, int is_incoming)
 
static void aji_message_destroy (struct aji_message *obj)
 
static void aji_mwi_cb (const struct ast_event *ast_event, void *data)
 Callback function for MWI events. More...
 
static void aji_pruneregister (struct aji_client *client)
 
static void aji_publish_device_state (struct aji_client *client, const char *device, const char *device_state, unsigned int cachable)
 Publish device state to a PubSub node. More...
 
static void aji_publish_mwi (struct aji_client *client, const char *mailbox, const char *context, const char *oldmsgs, const char *newmsgs)
 Publish MWI to a PubSub node. More...
 
static iks * aji_pubsub_iq_create (struct aji_client *client, const char *type)
 Create an IQ packet. More...
 
static void aji_pubsub_purge_nodes (struct aji_client *client, const char *collection_name)
 
static void aji_pubsub_subscribe (struct aji_client *client, const char *node)
 Subscribe to a PubSub node. More...
 
static int aji_receive_node_list (void *data, ikspak *pak)
 Receive pubsub item lists. More...
 
static int aji_reconnect (struct aji_client *client)
 
static int aji_recv (struct aji_client *client, int timeout)
 
static void * aji_recv_loop (void *data)
 
static int aji_register_approve_handler (void *data, ikspak *pak)
 
static int aji_register_query_handler (void *data, ikspak *pak)
 
static int aji_reload (int reload)
 
static void aji_request_pubsub_nodes (struct aji_client *client, const char *collection)
 Request item list from pubsub. More...
 
static int aji_send_exec (struct ast_channel *chan, const char *data)
 
static int aji_send_header (struct aji_client *client, const char *to)
 
static int aji_send_raw (struct aji_client *client, const char *xmlstr)
 
static int aji_send_raw_chat (struct aji_client *client, int groupchat, const char *nick, const char *address, const char *message)
 sends messages. More...
 
static int aji_sendgroup_exec (struct ast_channel *chan, const char *data)
 Application to send a message to a groupchat. More...
 
static int aji_set_group_presence (struct aji_client *client, char *room, int level, char *nick, char *desc)
 
static void aji_set_presence (struct aji_client *client, char *to, char *from, int level, char *desc)
 
static char * aji_show_buddies (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * aji_show_clients (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int aji_start_sasl (struct aji_client *client, enum ikssasltype type, char *username, char *pass)
 
static int aji_start_tls (struct aji_client *client)
 
static int aji_status_exec (struct ast_channel *chan, const char *data)
 
static int aji_tls_handshake (struct aji_client *client)
 
void ast_aji_buddy_destroy (struct aji_buddy *obj)
 
void ast_aji_client_destroy (struct aji_client *obj)
 
int ast_aji_create_chat (struct aji_client *client, char *room, char *server, char *topic)
 create a chatroom. More...
 
int ast_aji_disconnect (struct aji_client *client)
 disconnect from jabber server. More...
 
struct aji_clientast_aji_get_client (const char *name)
 grab a aji_client structure by label name or JID. Bumps the refcount. (without the resource string) More...
 
struct aji_client_containerast_aji_get_clients (void)
 
void ast_aji_increment_mid (char *mid)
 increments the mid field for messages and other events. More...
 
int ast_aji_invite_chat (struct aji_client *client, char *user, char *room, char *message)
 invite to a chatroom. More...
 
int ast_aji_join_chat (struct aji_client *client, char *room, char *nick)
 join a chatroom. More...
 
int ast_aji_leave_chat (struct aji_client *client, char *room, char *nick)
 leave a chatroom. More...
 
int ast_aji_send (struct aji_client *client, iks *x)
 Wraps raw sending. More...
 
int ast_aji_send_chat (struct aji_client *client, const char *address, const char *message)
 sends messages. More...
 
int ast_aji_send_groupchat (struct aji_client *client, const char *nick, const char *address, const char *message)
 sends message to a groupchat Prior to sending messages to a groupchat, one must be connected to it. More...
 
static int delete_old_messages (struct aji_client *client, char *from)
 
static int delete_old_messages_all (struct aji_client *client)
 
static int gtalk_yuck (iks *node)
 
static iks * jabber_make_auth (iksid *id, const char *pass, const char *sid)
 
static int load_module (void)
 
static int manager_jabber_send (struct mansession *s, const struct message *m)
 
static int reload (void)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "AJI - Asterisk Jabber Interface" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DEPEND, }
 
static struct ast_cli_entry aji_cli []
 
static char * app_ajijoin = "JabberJoin"
 
static char * app_ajileave = "JabberLeave"
 
static char * app_ajisend = "JabberSend"
 
static char * app_ajisendgroup = "JabberSendGroup"
 
static char * app_ajistatus = "JabberStatus"
 
static struct ast_module_infoast_module_info = &__mod_info
 
static struct aji_capabilitiescapabilities = NULL
 
static struct aji_client_container clients
 
static struct ast_event_subdevice_state_sub = NULL
 
static struct ast_flags globalflags = { AJI_AUTOREGISTER | AJI_AUTOACCEPT }
 Global flags, initialized to default values. More...
 
static struct ast_custom_function jabberreceive_function
 
static struct ast_custom_function jabberstatus_function
 
static ast_cond_t message_received_condition
 
static ast_mutex_t messagelock
 
static struct ast_event_submwi_sub = NULL
 
static struct ast_flags pubsubflags = { 0 }
 PubSub flags, initialized to default values. More...
 

Detailed Description

A resource for interfacing Asterisk directly as a client or a component to a XMPP/Jabber compliant server.

References:

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?

Dialplan applications need RETURN variable, like JABBERSENDSTATUS

Definition in file res_jabber.c.

Macro Definition Documentation

#define JABBER_CONFIG   "jabber.conf"
Todo:
This should really be renamed to xmpp.conf. For backwards compatibility, we need to read both files

Definition at line 285 of file res_jabber.c.

Referenced by aji_load_config().

Function Documentation

static void __reg_module ( void  )
static

Definition at line 4764 of file res_jabber.c.

static void __unreg_module ( void  )
static

Definition at line 4764 of file res_jabber.c.

static int acf_jabberreceive_read ( struct ast_channel chan,
const char *  name,
char *  data,
char *  buf,
size_t  buflen 
)
static

Definition at line 767 of file res_jabber.c.

References AJI_MAX_JIDLEN, aji_message_destroy(), args, aji_message::arrived, ast_aji_client_destroy(), ast_aji_get_client(), AST_APP_ARG, ast_autoservice_start(), ast_autoservice_stop(), ast_cond_timedwait, ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_NONSTANDARD_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_tv(), ast_tvadd(), ast_tvdiff_ms(), ast_tvdiff_sec(), ast_tvnow(), ASTOBJ_UNREF, aji_message::from, LOG_NOTICE, LOG_WARNING, aji_message::message, aji_client::message_timeout, aji_client::messages, ast_channel::name, and parse().

768 {
769  char *parse = NULL;
770  int timeout;
771  int jidlen, resourcelen;
772  struct timeval start;
773  long diff = 0;
774  struct aji_client *client = NULL;
775  int found = 0;
776  struct aji_message *tmp = NULL;
778  AST_APP_ARG(account);
779  AST_APP_ARG(jid);
780  AST_APP_ARG(timeout);
781  );
783  AST_APP_ARG(screenname);
784  AST_APP_ARG(resource);
785  );
786 
787  if (ast_strlen_zero(data)) {
788  ast_log(LOG_WARNING, "%s requires arguments (account,jid[,timeout])\n", name);
789  return -1;
790  }
791 
792  parse = ast_strdupa(data);
793  AST_STANDARD_APP_ARGS(args, parse);
794 
795  if (args.argc < 2 || args.argc > 3) {
796  ast_log(LOG_WARNING, "%s requires arguments (account,jid[,timeout])\n", name);
797  return -1;
798  }
799 
800  parse = ast_strdupa(args.jid);
801  AST_NONSTANDARD_APP_ARGS(jid, parse, '/');
802  if (jid.argc < 1 || jid.argc > 2 || strlen(args.jid) > AJI_MAX_JIDLEN) {
803  ast_log(LOG_WARNING, "Invalid JID : %s\n", parse);
804  return -1;
805  }
806 
807  if (ast_strlen_zero(args.timeout)) {
808  timeout = 20;
809  } else {
810  sscanf(args.timeout, "%d", &timeout);
811  if (timeout <= 0) {
812  ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
813  return -1;
814  }
815  }
816 
817  jidlen = strlen(jid.screenname);
818  resourcelen = ast_strlen_zero(jid.resource) ? 0 : strlen(jid.resource);
819 
820  client = ast_aji_get_client(args.account);
821  if (!client) {
822  ast_log(LOG_WARNING, "Could not find client %s, exiting\n", args.account);
823  return -1;
824  }
825 
826  ast_debug(3, "Waiting for an XMPP message from %s\n", args.jid);
827 
828  start = ast_tvnow();
829 
830  if (chan && ast_autoservice_start(chan) < 0) {
831  ast_log(LOG_WARNING, "Cannot start autoservice for channel %s\n", chan->name);
833  return -1;
834  }
835 
836  /* search the messages list, grab the first message that matches with
837  * the from JID we're expecting, and remove it from the messages list */
838  while (diff < timeout) {
839  struct timespec ts = { 0, };
840  struct timeval wait;
841  int res;
842 
843  wait = ast_tvadd(start, ast_tv(timeout, 0));
844  ts.tv_sec = wait.tv_sec;
845  ts.tv_nsec = wait.tv_usec * 1000;
846 
847  /* wait up to timeout seconds for an incoming message */
851  if (res == ETIMEDOUT) {
852  ast_debug(3, "No message received from %s in %d seconds\n", args.jid, timeout);
853  break;
854  }
855 
856  AST_LIST_LOCK(&client->messages);
857  AST_LIST_TRAVERSE_SAFE_BEGIN(&client->messages, tmp, list) {
858  if (jid.argc == 1) {
859  /* no resource provided, compare bare JIDs */
860  if (strncasecmp(jid.screenname, tmp->from, jidlen)) {
861  continue;
862  }
863  } else {
864  /* resource appended, compare bare JIDs and resources */
865  char *resource = strchr(tmp->from, '/');
866  if (!resource || strlen(resource) == 0) {
867  ast_log(LOG_WARNING, "Remote JID has no resource : %s\n", tmp->from);
868  if (strncasecmp(jid.screenname, tmp->from, jidlen)) {
869  continue;
870  }
871  } else {
872  resource ++;
873  if (strncasecmp(jid.screenname, tmp->from, jidlen) || strncmp(jid.resource, resource, resourcelen)) {
874  continue;
875  }
876  }
877  }
878  /* check if the message is not too old */
879  if (ast_tvdiff_sec(ast_tvnow(), tmp->arrived) >= client->message_timeout) {
880  ast_debug(3, "Found old message from %s, deleting it\n", tmp->from);
882  aji_message_destroy(tmp);
883  continue;
884  }
885  found = 1;
886  ast_copy_string(buf, tmp->message, buflen);
888  aji_message_destroy(tmp);
889  break;
890  }
892  AST_LIST_UNLOCK(&client->messages);
893  if (found) {
894  break;
895  }
896 
897  /* check timeout */
898  diff = ast_tvdiff_ms(ast_tvnow(), start);
899  }
900 
902  if (chan && ast_autoservice_stop(chan) < 0) {
903  ast_log(LOG_WARNING, "Cannot stop autoservice for channel %s\n", chan->name);
904  }
905 
906  /* return if we timed out */
907  if (!found) {
908  ast_log(LOG_NOTICE, "Timed out : no message received from %s\n", args.jid);
909  return -1;
910  }
911 
912  return 0;
913 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:179
#define LOG_WARNING
Definition: logger.h:144
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
int64_t ast_tvdiff_sec(struct timeval end, struct timeval start)
Computes the difference (in seconds) between two struct timeval instances.
Definition: time.h:56
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
int message_timeout
Definition: jabber.h:179
char * message
Definition: jabber.h:128
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define ast_mutex_lock(a)
Definition: lock.h:155
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:90
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
static ast_cond_t message_received_condition
Definition: res_jabber.c:396
char * from
Definition: jabber.h:127
static void aji_message_destroy(struct aji_message *obj)
Definition: res_jabber.c:451
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:238
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static struct @350 args
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: utils.c:1587
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AJI_MAX_JIDLEN
Definition: jabber.h:73
#define LOG_NOTICE
Definition: logger.h:133
struct aji_client * ast_aji_get_client(const char *name)
grab a aji_client structure by label name or JID. Bumps the refcount. (without the resource string) ...
Definition: res_jabber.c:4575
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1858
static const char name[]
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:179
static ast_mutex_t messagelock
Definition: res_jabber.c:397
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
Definition: app.h:619
struct timeval arrived
Definition: jabber.h:130
struct aji_client::messages messages
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:172
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int acf_jabberstatus_read ( struct ast_channel chan,
const char *  name,
char *  data,
char *  buf,
size_t  buflen 
)
static

Definition at line 696 of file res_jabber.c.

References aji_find_resource(), args, ast_aji_buddy_destroy(), ast_aji_client_destroy(), ast_aji_get_client(), AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_NONSTANDARD_APP_ARGS, AST_STANDARD_APP_ARGS, ASTOBJ_CONTAINER_FIND, ASTOBJ_UNREF, aji_client::buddies, LOG_ERROR, LOG_NOTICE, LOG_WARNING, aji_resource::resource, aji_buddy::resources, and aji_resource::status.

697 {
698  struct aji_client *client = NULL;
699  struct aji_buddy *buddy = NULL;
700  struct aji_resource *r = NULL;
701  int stat = 7;
703  AST_APP_ARG(sender);
704  AST_APP_ARG(jid);
705  );
707  AST_APP_ARG(screenname);
709  );
710 
711  if (!data) {
712  ast_log(LOG_ERROR, "Usage: JABBER_STATUS(<sender>,<jid>[/<resource>])\n");
713  return 0;
714  }
716 
717  if (args.argc != 2) {
718  ast_log(LOG_ERROR, "JABBER_STATUS requires 2 arguments: sender and jid.\n");
719  return -1;
720  }
721 
722  AST_NONSTANDARD_APP_ARGS(jid, args.jid, '/');
723  if (jid.argc < 1 || jid.argc > 2) {
724  ast_log(LOG_WARNING, "Wrong JID %s, exiting\n", args.jid);
725  return -1;
726  }
727 
728  if (!(client = ast_aji_get_client(args.sender))) {
729  ast_log(LOG_WARNING, "Could not find sender connection: '%s'\n", args.sender);
730  return -1;
731  }
732  buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, jid.screenname);
733  if (!buddy) {
734  ast_log(LOG_WARNING, "Could not find buddy in list: '%s'\n", jid.screenname);
736  return -1;
737  }
738  r = aji_find_resource(buddy, jid.resource);
739  if (!r && buddy->resources) {
740  r = buddy->resources;
741  }
744  if (!r) {
745  ast_log(LOG_NOTICE, "Resource %s of buddy %s was not found.\n", jid.resource, jid.screenname);
746  } else {
747  stat = r->status;
748  }
749  snprintf(buf, buflen, "%d", stat);
750  return 0;
751 }
int status
Definition: jabber.h:118
void ast_aji_buddy_destroy(struct aji_buddy *obj)
Definition: res_jabber.c:432
#define LOG_WARNING
Definition: logger.h:144
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
char resource[AJI_MAX_RESJIDLEN]
Definition: jabber.h:119
struct aji_buddy_container buddies
Definition: jabber.h:184
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
#define LOG_ERROR
Definition: logger.h:155
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
struct aji_client * ast_aji_get_client(const char *name)
grab a aji_client structure by label name or JID. Bumps the refcount. (without the resource string) ...
Definition: res_jabber.c:4575
#define ASTOBJ_CONTAINER_FIND(container, namestr)
Find an object in a container.
Definition: astobj.h:401
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
static struct aji_resource * aji_find_resource(struct aji_buddy *buddy, char *name)
Definition: res_jabber.c:544
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
Definition: app.h:619
struct aji_resource * resources
Definition: jabber.h:137
static int aji_act_hook ( void *  data,
int  type,
iks *  node 
)
static

Definition at line 1572 of file res_jabber.c.

References aji_client_connect(), AJI_CONNECTED, AJI_CONNECTING, AJI_DISCONNECTED, AJI_DISCONNECTING, aji_handle_iq(), aji_handle_message(), aji_handle_presence(), aji_handle_subscribe(), aji_is_secure(), AJI_MAX_ATTRLEN, aji_recv(), aji_send_header(), aji_send_raw(), aji_start_sasl(), aji_start_tls(), aji_tls_handshake(), ast_aji_client_destroy(), ast_aji_increment_mid(), ast_aji_send(), ast_asprintf, ast_debug, ast_free, ast_log(), ast_sha1_hash(), ASTOBJ_REF, ASTOBJ_UNREF, aji_client::authorized, aji_client::component, aji_client::f, jabber_make_auth(), aji_client::jid, LOG_ERROR, LOG_WARNING, aji_client::mid, aji_client::password, secret, aji_client::state, aji_client::stream_flags, aji_client::usesasl, and aji_client::usetls.

Referenced by aji_create_client().

1573 {
1574  struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
1575  ikspak *pak = NULL;
1576  iks *auth = NULL;
1577  int features = 0;
1578 
1579  if (!node) {
1580  ast_log(LOG_ERROR, "aji_act_hook was called with out a packet\n"); /* most likely cause type is IKS_NODE_ERROR lost connection */
1582  return IKS_HOOK;
1583  }
1584 
1585  if (client->state == AJI_DISCONNECTING) {
1587  return IKS_HOOK;
1588  }
1589 
1590  pak = iks_packet(node);
1591 
1592  /* work around iksemel's impossibility to recognize node names
1593  * containing a semicolon. Set the namespace of the corresponding
1594  * node accordingly. */
1595  if (iks_has_children(node) && strchr(iks_name(iks_child(node)), ':')) {
1596  char *node_ns = NULL;
1597  char attr[AJI_MAX_ATTRLEN];
1598  char *node_name = iks_name(iks_child(node));
1599  char *aux = strchr(node_name, ':') + 1;
1600  snprintf(attr, strlen("xmlns:") + (strlen(node_name) - strlen(aux)), "xmlns:%s", node_name);
1601  node_ns = iks_find_attrib(iks_child(node), attr);
1602  if (node_ns) {
1603  pak->ns = node_ns;
1604  pak->query = iks_child(node);
1605  }
1606  }
1607 
1608 
1609  if (!client->component) { /*client */
1610  switch (type) {
1611  case IKS_NODE_START:
1612  if (client->usetls && !aji_is_secure(client)) {
1613 #ifndef HAVE_OPENSSL
1614  ast_log(LOG_ERROR, "TLS connection cannot be established. Please install OpenSSL and its development libraries on this system, or disable the TLS option in your configuration file\n");
1616  return IKS_HOOK;
1617 #else
1618  if (aji_start_tls(client) == IKS_NET_TLSFAIL) {
1619  ast_log(LOG_ERROR, "Could not start TLS\n");
1621  return IKS_HOOK;
1622  }
1623 #endif
1624  break;
1625  }
1626  if (!client->usesasl) {
1627  iks_filter_add_rule(client->f, aji_client_connect, client, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID, client->mid, IKS_RULE_DONE);
1628  auth = jabber_make_auth(client->jid, client->password, iks_find_attrib(node, "id"));
1629  if (auth) {
1630  iks_insert_attrib(auth, "id", client->mid);
1631  iks_insert_attrib(auth, "to", client->jid->server);
1632  ast_aji_increment_mid(client->mid);
1633  ast_aji_send(client, auth);
1634  iks_delete(auth);
1635  } else {
1636  ast_log(LOG_ERROR, "Out of memory.\n");
1637  }
1638  }
1639  break;
1640 
1641  case IKS_NODE_NORMAL:
1642 #ifdef HAVE_OPENSSL
1643  if (client->stream_flags & TRY_SECURE) {
1644  if (!strcmp("proceed", iks_name(node))) {
1645  return aji_tls_handshake(client);
1646  }
1647  }
1648 #endif
1649  if (!strcmp("stream:features", iks_name(node))) {
1650  features = iks_stream_features(node);
1651  if (client->usesasl) {
1652  if (client->usetls && !aji_is_secure(client)) {
1653  break;
1654  }
1655  if (client->authorized) {
1656  if (features & IKS_STREAM_BIND) {
1657  iks_filter_add_rule(client->f, aji_client_connect, client, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_DONE);
1658  auth = iks_make_resource_bind(client->jid);
1659  if (auth) {
1660  iks_insert_attrib(auth, "id", client->mid);
1661  ast_aji_increment_mid(client->mid);
1662  ast_aji_send(client, auth);
1663  iks_delete(auth);
1664  } else {
1665  ast_log(LOG_ERROR, "Out of memory.\n");
1666  break;
1667  }
1668  }
1669  if (features & IKS_STREAM_SESSION) {
1670  iks_filter_add_rule (client->f, aji_client_connect, client, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID, "auth", IKS_RULE_DONE);
1671  auth = iks_make_session();
1672  if (auth) {
1673  iks_insert_attrib(auth, "id", "auth");
1674  ast_aji_increment_mid(client->mid);
1675  ast_aji_send(client, auth);
1676  iks_delete(auth);
1677  } else {
1678  ast_log(LOG_ERROR, "Out of memory.\n");
1679  }
1680  }
1681  } else {
1682  int ret;
1683  if (!client->jid->user) {
1684  ast_log(LOG_ERROR, "Malformed Jabber ID : %s (domain missing?)\n", client->jid->full);
1685  break;
1686  }
1687 
1688  ret = aji_start_sasl(client, features, client->jid->user, client->password);
1689  if (ret != IKS_OK) {
1691  return IKS_HOOK;
1692  }
1693  break;
1694  }
1695  }
1696  } else if (!strcmp("failure", iks_name(node))) {
1697  ast_log(LOG_ERROR, "JABBER: encryption failure. possible bad password.\n");
1698  } else if (!strcmp("success", iks_name(node))) {
1699  client->authorized = 1;
1700  aji_send_header(client, client->jid->server);
1701  }
1702  break;
1703  case IKS_NODE_ERROR:
1704  ast_log(LOG_ERROR, "JABBER: Node Error\n");
1706  return IKS_HOOK;
1707  break;
1708  case IKS_NODE_STOP:
1709  ast_log(LOG_WARNING, "JABBER: Disconnected\n");
1711  return IKS_HOOK;
1712  break;
1713  }
1714  } else if (client->state != AJI_CONNECTED && client->component) {
1715  switch (type) {
1716  case IKS_NODE_START:
1717  if (client->state == AJI_DISCONNECTED) {
1718  char secret[160], shasum[320], *handshake;
1719 
1720  sprintf(secret, "%s%s", pak->id, client->password);
1721  ast_sha1_hash(shasum, secret);
1722  if (ast_asprintf(&handshake, "<handshake>%s</handshake>", shasum) >= 0) {
1723  aji_send_raw(client, handshake);
1724  ast_free(handshake);
1725  }
1726  client->state = AJI_CONNECTING;
1727  if (aji_recv(client, 1) == 2) /*XXX proper result for iksemel library on iks_recv of <handshake/> XXX*/
1728  client->state = AJI_CONNECTED;
1729  else
1730  ast_log(LOG_WARNING, "Jabber didn't seem to handshake, failed to authenticate.\n");
1731  break;
1732  }
1733  break;
1734 
1735  case IKS_NODE_NORMAL:
1736  break;
1737 
1738  case IKS_NODE_ERROR:
1739  ast_log(LOG_ERROR, "JABBER: Node Error\n");
1741  return IKS_HOOK;
1742 
1743  case IKS_NODE_STOP:
1744  ast_log(LOG_WARNING, "JABBER: Disconnected\n");
1746  return IKS_HOOK;
1747  }
1748  }
1749 
1750  switch (pak->type) {
1751  case IKS_PAK_NONE:
1752  ast_debug(1, "JABBER: I don't know what to do with paktype NONE.\n");
1753  break;
1754  case IKS_PAK_MESSAGE:
1755  aji_handle_message(client, pak);
1756  ast_debug(1, "JABBER: Handling paktype MESSAGE.\n");
1757  break;
1758  case IKS_PAK_PRESENCE:
1759  aji_handle_presence(client, pak);
1760  ast_debug(1, "JABBER: Handling paktype PRESENCE\n");
1761  break;
1762  case IKS_PAK_S10N:
1763  aji_handle_subscribe(client, pak);
1764  ast_debug(1, "JABBER: Handling paktype S10N\n");
1765  break;
1766  case IKS_PAK_IQ:
1767  ast_debug(1, "JABBER: Handling paktype IQ\n");
1768  aji_handle_iq(client, node);
1769  break;
1770  default:
1771  ast_debug(1, "JABBER: I don't know anything about paktype '%u'\n", pak->type);
1772  break;
1773  }
1774 
1775  iks_filter_packet(client->f, pak);
1776 
1777  if (node)
1778  iks_delete(node);
1779 
1781  return IKS_OK;
1782 }
static int aji_send_raw(struct aji_client *client, const char *xmlstr)
Definition: res_jabber.c:1453
static int aji_start_sasl(struct aji_client *client, enum ikssasltype type, char *username, char *pass)
Definition: res_jabber.c:1522
static int aji_client_connect(void *data, ikspak *pak)
Definition: res_jabber.c:3090
int authorized
Definition: jabber.h:180
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
#define LOG_WARNING
Definition: logger.h:144
int usetls
Definition: jabber.h:173
static void aji_handle_subscribe(struct aji_client *client, ikspak *pak)
Definition: res_jabber.c:2531
enum aji_state state
Definition: jabber.h:170
static void aji_handle_message(struct aji_client *client, ikspak *pak)
Definition: res_jabber.c:2237
int usesasl
Definition: jabber.h:175
static int aji_is_secure(struct aji_client *client)
Definition: res_jabber.c:1203
#define AJI_MAX_ATTRLEN
Definition: jabber.h:75
int component
Definition: jabber.h:183
#define ast_asprintf(a, b, c...)
Definition: astmm.h:121
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
unsigned int stream_flags
Definition: jabber.h:168
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
void ast_sha1_hash(char *output, const char *input)
Produces SHA1 hash based on input string.
Definition: utils.c:261
#define LOG_ERROR
Definition: logger.h:155
static void aji_handle_presence(struct aji_client *client, ikspak *pak)
Definition: res_jabber.c:2287
iksid * jid
Definition: jabber.h:160
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
static const char type[]
Definition: chan_nbs.c:57
static iks * jabber_make_auth(iksid *id, const char *pass, const char *sid)
Definition: res_jabber.c:590
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
static char secret[50]
Definition: chan_h323.c:148
static int aji_recv(struct aji_client *client, int timeout)
Definition: res_jabber.c:1341
char password[160]
Definition: jabber.h:151
static int aji_tls_handshake(struct aji_client *client)
Definition: res_jabber.c:1239
#define ASTOBJ_REF(object)
Increment an object reference count.
Definition: astobj.h:201
char mid[6]
Definition: jabber.h:159
static int aji_send_header(struct aji_client *client, const char *to)
Definition: res_jabber.c:1413
iksfilter * f
Definition: jabber.h:162
static void aji_handle_iq(struct aji_client *client, iks *node)
Definition: res_jabber.c:2225
void ast_aji_increment_mid(char *mid)
increments the mid field for messages and other events.
Definition: res_jabber.c:2790
static int aji_start_tls(struct aji_client *client)
Definition: res_jabber.c:1220
static iks * aji_build_node_config ( iks *  pubsub,
const char *  node_type,
const char *  collection_name 
)
static

Definition at line 3856 of file res_jabber.c.

Referenced by aji_create_pubsub_node().

3857 {
3858  iks *configure, *x, *field_owner, *field_node_type, *field_node_config,
3859  *field_deliver_payload, *field_persist_items, *field_access_model,
3860  *field_pubsub_collection;
3861  configure = iks_insert(pubsub, "configure");
3862  x = iks_insert(configure, "x");
3863  iks_insert_attrib(x, "xmlns", "jabber:x:data");
3864  iks_insert_attrib(x, "type", "submit");
3865  field_owner = iks_insert(x, "field");
3866  iks_insert_attrib(field_owner, "var", "FORM_TYPE");
3867  iks_insert_attrib(field_owner, "type", "hidden");
3868  iks_insert_cdata(iks_insert(field_owner, "value"),
3869  "http://jabber.org/protocol/pubsub#owner", 39);
3870  if (node_type) {
3871  field_node_type = iks_insert(x, "field");
3872  iks_insert_attrib(field_node_type, "var", "pubsub#node_type");
3873  iks_insert_cdata(iks_insert(field_node_type, "value"), node_type, strlen(node_type));
3874  }
3875  field_node_config = iks_insert(x, "field");
3876  iks_insert_attrib(field_node_config, "var", "FORM_TYPE");
3877  iks_insert_attrib(field_node_config, "type", "hidden");
3878  iks_insert_cdata(iks_insert(field_node_config, "value"),
3879  "http://jabber.org/protocol/pubsub#node_config", 45);
3880  field_deliver_payload = iks_insert(x, "field");
3881  iks_insert_attrib(field_deliver_payload, "var", "pubsub#deliver_payloads");
3882  iks_insert_cdata(iks_insert(field_deliver_payload, "value"), "1", 1);
3883  field_persist_items = iks_insert(x, "field");
3884  iks_insert_attrib(field_persist_items, "var", "pubsub#persist_items");
3885  iks_insert_cdata(iks_insert(field_persist_items, "value"), "1", 1);
3886  field_access_model = iks_insert(x, "field");
3887  iks_insert_attrib(field_access_model, "var", "pubsub#access_model");
3888  iks_insert_cdata(iks_insert(field_access_model, "value"), "whitelist", 9);
3889  if (node_type && !strcasecmp(node_type, "leaf")) {
3890  field_pubsub_collection = iks_insert(x, "field");
3891  iks_insert_attrib(field_pubsub_collection, "var", "pubsub#collection");
3892  iks_insert_cdata(iks_insert(field_pubsub_collection, "value"), collection_name,
3893  strlen(collection_name));
3894  }
3895  return configure;
3896 }
node_type
Definition: ast_expr2.c:333
static iks * aji_build_node_request ( struct aji_client client,
const char *  collection 
)
static

Build the a node request.

Parameters
clientthe configured XMPP client we use to connect to a XMPP server
collectionname of the collection for request
Returns
iks*

Definition at line 3586 of file res_jabber.c.

References aji_pubsub_iq_create().

Referenced by aji_pubsub_purge_nodes(), and aji_request_pubsub_nodes().

3587 {
3588  iks *request = aji_pubsub_iq_create(client, "get");
3589  iks *query;
3590  query = iks_insert(request, "query");
3591  iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items");
3592  if (collection) {
3593  iks_insert_attrib(query, "node", collection);
3594  }
3595  return request;
3596 }
static iks * aji_pubsub_iq_create(struct aji_client *client, const char *type)
Create an IQ packet.
Definition: res_jabber.c:3493
static iks * aji_build_publish_skeleton ( struct aji_client client,
const char *  node,
const char *  event_type,
unsigned int  cachable 
)
static

Build the skeleton of a publish.

Parameters
clientthe configured XMPP client we use to connect to a XMPP server
nodeName of the node that will be published to
event_type
Returns
iks *

Definition at line 3396 of file res_jabber.c.

References aji_pubsub_iq_create(), AJI_XEP0248, AST_DEVSTATE_NOT_CACHABLE, and ast_test_flag.

Referenced by aji_publish_device_state(), and aji_publish_mwi().

3398 {
3399  iks *request = aji_pubsub_iq_create(client, "set");
3400  iks *pubsub, *publish, *item;
3401  pubsub = iks_insert(request, "pubsub");
3402  iks_insert_attrib(pubsub, "xmlns", "http://jabber.org/protocol/pubsub");
3403  publish = iks_insert(pubsub, "publish");
3405  iks_insert_attrib(publish, "node", node);
3406  } else {
3407  iks_insert_attrib(publish, "node", event_type);
3408  }
3409  item = iks_insert(publish, "item");
3410  iks_insert_attrib(item, "id", node);
3411 
3412  if (cachable == AST_DEVSTATE_NOT_CACHABLE) {
3413  iks *options, *x, *field_form_type, *field_persist;
3414 
3415  options = iks_insert(pubsub, "publish-options");
3416  x = iks_insert(options, "x");
3417  iks_insert_attrib(x, "xmlns", "jabber:x:data");
3418  iks_insert_attrib(x, "type", "submit");
3419  field_form_type = iks_insert(x, "field");
3420  iks_insert_attrib(field_form_type, "var", "FORM_TYPE");
3421  iks_insert_attrib(field_form_type, "type", "hidden");
3422  iks_insert_cdata(iks_insert(field_form_type, "value"), "http://jabber.org/protocol/pubsub#publish-options", 0);
3423  field_persist = iks_insert(x, "field");
3424  iks_insert_attrib(field_persist, "var", "pubsub#persist_items");
3425  iks_insert_cdata(iks_insert(field_persist, "value"), "0", 1);
3426  }
3427 
3428  return item;
3429 }
static iks * aji_pubsub_iq_create(struct aji_client *client, const char *type)
Create an IQ packet.
Definition: res_jabber.c:3493
#define ast_test_flag(p, flag)
Definition: utils.h:63
static struct ast_flags globalflags
Global flags, initialized to default values.
Definition: res_jabber.c:400
static char * aji_cli_create_collection ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Method to expose PubSub collection node creation via CLI.

Returns
char *.

Definition at line 3904 of file res_jabber.c.

References aji_create_pubsub_collection(), ast_cli_args::argc, ast_cli_args::argv, ast_aji_client_destroy(), ast_cli(), ASTOBJ_CONTAINER_FIND, ASTOBJ_UNREF, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, clients, ast_cli_entry::command, ast_cli_args::fd, name, and ast_cli_entry::usage.

3905 {
3906  struct aji_client *client;
3907  const char *name;
3908  const char *collection_name;
3909 
3910  switch (cmd) {
3911  case CLI_INIT:
3912  e->command = "jabber create collection";
3913  e->usage =
3914  "Usage: jabber create collection <connection> <collection>\n"
3915  " Creates a PubSub collection node using the account\n"
3916  " as configured in jabber.conf.\n";
3917  return NULL;
3918  case CLI_GENERATE:
3919  return NULL;
3920  }
3921 
3922  if (a->argc != 5) {
3923  return CLI_SHOWUSAGE;
3924  }
3925  name = a->argv[3];
3926  collection_name = a->argv[4];
3927 
3928  if (!(client = ASTOBJ_CONTAINER_FIND(&clients, name))) {
3929  ast_cli(a->fd, "Unable to find client '%s'!\n", name);
3930  return CLI_FAILURE;
3931  }
3932 
3933  ast_cli(a->fd, "Creating test PubSub node collection.\n");
3934  aji_create_pubsub_collection(client, collection_name);
3936  return CLI_SUCCESS;
3937 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
static void aji_create_pubsub_collection(struct aji_client *client, const char *collection_name)
Create a PubSub collection node.
Definition: res_jabber.c:3812
#define CLI_FAILURE
Definition: cli.h:45
static const char name[]
char * command
Definition: cli.h:180
#define ASTOBJ_CONTAINER_FIND(container, namestr)
Find an object in a container.
Definition: astobj.h:401
static struct aji_client_container clients
Definition: res_jabber.c:392
const char * usage
Definition: cli.h:171
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
#define CLI_SUCCESS
Definition: cli.h:43
static char * aji_cli_create_leafnode ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Method to expose PubSub leaf node creation via CLI.

Returns
char *.

Definition at line 3943 of file res_jabber.c.

References aji_create_pubsub_leaf(), ast_cli_args::argc, ast_cli_args::argv, ast_aji_client_destroy(), ast_cli(), ASTOBJ_CONTAINER_FIND, ASTOBJ_UNREF, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, clients, ast_cli_entry::command, ast_cli_args::fd, name, and ast_cli_entry::usage.

3944 {
3945  struct aji_client *client;
3946  const char *name;
3947  const char *collection_name;
3948  const char *leaf_name;
3949 
3950  switch (cmd) {
3951  case CLI_INIT:
3952  e->command = "jabber create leaf";
3953  e->usage =
3954  "Usage: jabber create leaf <connection> <collection> <leaf>\n"
3955  " Creates a PubSub leaf node using the account\n"
3956  " as configured in jabber.conf.\n";
3957  return NULL;
3958  case CLI_GENERATE:
3959  return NULL;
3960  }
3961 
3962  if (a->argc != 6) {
3963  return CLI_SHOWUSAGE;
3964  }
3965  name = a->argv[3];
3966  collection_name = a->argv[4];
3967  leaf_name = a->argv[5];
3968 
3969  if (!(client = ASTOBJ_CONTAINER_FIND(&clients, name))) {
3970  ast_cli(a->fd, "Unable to find client '%s'!\n", name);
3971  return CLI_FAILURE;
3972  }
3973 
3974  ast_cli(a->fd, "Creating test PubSub node collection.\n");
3975  aji_create_pubsub_leaf(client, collection_name, leaf_name);
3977  return CLI_SUCCESS;
3978 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define CLI_FAILURE
Definition: cli.h:45
static const char name[]
char * command
Definition: cli.h:180
#define ASTOBJ_CONTAINER_FIND(container, namestr)
Find an object in a container.
Definition: astobj.h:401
static struct aji_client_container clients
Definition: res_jabber.c:392
const char * usage
Definition: cli.h:171
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
#define CLI_SUCCESS
Definition: cli.h:43
static void aji_create_pubsub_leaf(struct aji_client *client, const char *collection_name, const char *leaf_name)
Create a PubSub leaf node.
Definition: res_jabber.c:3825
static char * aji_cli_delete_pubsub_node ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Method to expose PubSub node deletion via CLI.

Parameters
epointer to ast_cli_entry structure
cmd
apointer to ast_cli_args structure
Returns
char *

Definition at line 3757 of file res_jabber.c.

References aji_delete_pubsub_node(), ast_cli_args::argc, ast_cli_args::argv, ast_aji_client_destroy(), ast_cli(), ASTOBJ_CONTAINER_FIND, ASTOBJ_UNREF, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, clients, ast_cli_entry::command, ast_cli_args::fd, name, and ast_cli_entry::usage.

3759 {
3760  struct aji_client *client;
3761  const char *name;
3762 
3763  switch (cmd) {
3764  case CLI_INIT:
3765  e->command = "jabber delete node";
3766  e->usage =
3767  "Usage: jabber delete node <connection> <node>\n"
3768  " Deletes a node on PubSub server\n"
3769  " as configured in jabber.conf.\n";
3770  return NULL;
3771  case CLI_GENERATE:
3772  return NULL;
3773  }
3774 
3775  if (a->argc != 5) {
3776  return CLI_SHOWUSAGE;
3777  }
3778  name = a->argv[3];
3779 
3780  if (!(client = ASTOBJ_CONTAINER_FIND(&clients, name))) {
3781  ast_cli(a->fd, "Unable to find client '%s'!\n", name);
3782  return CLI_FAILURE;
3783  }
3784  aji_delete_pubsub_node(client, a->argv[4]);
3786  return CLI_SUCCESS;
3787 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
static void aji_delete_pubsub_node(struct aji_client *client, const char *node_name)
Delete a PubSub node.
Definition: res_jabber.c:3795
const int fd
Definition: cli.h:153
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define CLI_FAILURE
Definition: cli.h:45
static const char name[]
char * command
Definition: cli.h:180
#define ASTOBJ_CONTAINER_FIND(container, namestr)
Find an object in a container.
Definition: astobj.h:401
static struct aji_client_container clients
Definition: res_jabber.c:392
const char * usage
Definition: cli.h:171
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
#define CLI_SUCCESS
Definition: cli.h:43
static char * aji_cli_list_pubsub_nodes ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Method to expose PubSub node list via CLI.

Parameters
epointer to ast_cli_entry structure
cmd
apointer to ast_cli_args structure
Returns
char *

Definition at line 3632 of file res_jabber.c.

References aji_request_pubsub_nodes(), ast_cli_args::argc, ast_cli_args::argv, ast_aji_client_destroy(), ast_cli(), ASTOBJ_CONTAINER_FIND, ASTOBJ_UNREF, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, clients, ast_cli_entry::command, ast_cli_args::fd, name, and ast_cli_entry::usage.

3634 {
3635  struct aji_client *client;
3636  const char *name = NULL;
3637  const char *collection = NULL;
3638 
3639  switch (cmd) {
3640  case CLI_INIT:
3641  e->command = "jabber list nodes";
3642  e->usage =
3643  "Usage: jabber list nodes <connection> [collection]\n"
3644  " Lists the user's nodes on the respective connection\n"
3645  " ([connection] as configured in jabber.conf.)\n";
3646  return NULL;
3647  case CLI_GENERATE:
3648  return NULL;
3649  }
3650 
3651  if (a->argc > 5 || a->argc < 4) {
3652  return CLI_SHOWUSAGE;
3653  } else if (a->argc == 4 || a->argc == 5) {
3654  name = a->argv[3];
3655  }
3656  if (a->argc == 5) {
3657  collection = a->argv[4];
3658  }
3659  if (!(client = ASTOBJ_CONTAINER_FIND(&clients, name))) {
3660  ast_cli(a->fd, "Unable to find client '%s'!\n", name);
3661  return CLI_FAILURE;
3662  }
3663 
3664  ast_cli(a->fd, "Listing pubsub nodes.\n");
3665  aji_request_pubsub_nodes(client, collection);
3667  return CLI_SUCCESS;
3668 }
static void aji_request_pubsub_nodes(struct aji_client *client, const char *collection)
Request item list from pubsub.
Definition: res_jabber.c:3568
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define CLI_FAILURE
Definition: cli.h:45
static const char name[]
char * command
Definition: cli.h:180
#define ASTOBJ_CONTAINER_FIND(container, namestr)
Find an object in a container.
Definition: astobj.h:401
static struct aji_client_container clients
Definition: res_jabber.c:392
const char * usage
Definition: cli.h:171
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
#define CLI_SUCCESS
Definition: cli.h:43
static char * aji_cli_purge_pubsub_nodes ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Method to purge PubSub nodes via CLI.

Parameters
epointer to ast_cli_entry structure
cmd
apointer to ast_cli_args structure
Returns
char *

Definition at line 3677 of file res_jabber.c.

References aji_delete_pubsub_node(), aji_pubsub_purge_nodes(), AJI_XEP0248, ast_cli_args::argc, ast_cli_args::argv, ast_aji_client_destroy(), ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_FIND, ASTOBJ_UNREF, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, clients, ast_cli_entry::command, ast_cli_args::fd, name, and ast_cli_entry::usage.

3679 {
3680  struct aji_client *client;
3681  const char *name;
3682 
3683  switch (cmd) {
3684  case CLI_INIT:
3685  e->command = "jabber purge nodes";
3686  e->usage =
3687  "Usage: jabber purge nodes <connection> <node>\n"
3688  " Purges nodes on PubSub server\n"
3689  " as configured in jabber.conf.\n";
3690  return NULL;
3691  case CLI_GENERATE:
3692  return NULL;
3693  }
3694 
3695  if (a->argc != 5) {
3696  return CLI_SHOWUSAGE;
3697  }
3698  name = a->argv[3];
3699 
3700  if (!(client = ASTOBJ_CONTAINER_FIND(&clients, name))) {
3701  ast_cli(a->fd, "Unable to find client '%s'!\n", name);
3702  return CLI_FAILURE;
3703  }
3705  aji_pubsub_purge_nodes(client, a->argv[4]);
3706  } else {
3707  aji_delete_pubsub_node(client, a->argv[4]);
3708  }
3710  return CLI_SUCCESS;
3711 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
const int argc
Definition: cli.h:154
Definition: cli.h:146
static struct ast_flags pubsubflags
PubSub flags, initialized to default values.
Definition: res_jabber.c:403
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
static void aji_pubsub_purge_nodes(struct aji_client *client, const char *collection_name)
Definition: res_jabber.c:3713
static void aji_delete_pubsub_node(struct aji_client *client, const char *node_name)
Delete a PubSub node.
Definition: res_jabber.c:3795
const int fd
Definition: cli.h:153
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define CLI_FAILURE
Definition: cli.h:45
static const char name[]
char * command
Definition: cli.h:180
#define ASTOBJ_CONTAINER_FIND(container, namestr)
Find an object in a container.
Definition: astobj.h:401
static struct aji_client_container clients
Definition: res_jabber.c:392
const char * usage
Definition: cli.h:171
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
#define CLI_SUCCESS
Definition: cli.h:43
static int aji_client_connect ( void *  data,
ikspak *  pak 
)
static

Definition at line 3090 of file res_jabber.c.

References AJI_CONNECTING, AJI_DISCONNECTED, aji_filter_roster(), aji_get_roster(), aji_init_event_distribution(), ast_aji_client_destroy(), ast_log(), ASTOBJ_REF, ASTOBJ_UNREF, aji_client::component, aji_client::distribute_events, aji_client::f, if(), aji_client::jid, LOG_ERROR, aji_client::stack, and aji_client::state.

Referenced by aji_act_hook().

3091 {
3092  struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
3093  int res = IKS_FILTER_PASS;
3094 
3095  if (client) {
3096  if (client->state == AJI_DISCONNECTED) {
3097  iks_filter_add_rule(client->f, aji_filter_roster, client, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID, "roster", IKS_RULE_DONE);
3098  client->state = AJI_CONNECTING;
3099  client->jid = (iks_find_cdata(pak->query, "jid")) ? iks_id_new(client->stack, iks_find_cdata(pak->query, "jid")) : client->jid;
3100  if (!client->component) { /*client*/
3101  aji_get_roster(client);
3102  }
3103  if (client->distribute_events) {
3105  }
3106 
3107  iks_filter_remove_hook(client->f, aji_client_connect);
3108  /* Once we remove the hook for this routine, we must return EAT or we will crash or corrupt memory */
3109  res = IKS_FILTER_EAT;
3110  }
3111  } else {
3112  ast_log(LOG_ERROR, "Out of memory.\n");
3113  }
3114 
3116  return res;
3117 }
static int aji_client_connect(void *data, ikspak *pak)
Definition: res_jabber.c:3090
static void aji_init_event_distribution(struct aji_client *client)
Initialize collections for event distribution.
Definition: res_jabber.c:3235
enum aji_state state
Definition: jabber.h:170
int component
Definition: jabber.h:183
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
#define LOG_ERROR
Definition: logger.h:155
static int aji_get_roster(struct aji_client *client)
Definition: res_jabber.c:3067
iksid * jid
Definition: jabber.h:160
int distribute_events
Definition: jabber.h:181
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
if(yyss+yystacksize-1<=yyssp)
Definition: ast_expr2.c:1874
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
static int aji_filter_roster(void *data, ikspak *pak)
Definition: res_jabber.c:2953
#define ASTOBJ_REF(object)
Increment an object reference count.
Definition: astobj.h:201
ikstack * stack
Definition: jabber.h:163
iksfilter * f
Definition: jabber.h:162
static int aji_client_info_handler ( void *  data,
ikspak *  pak 
)
static

Definition at line 2003 of file res_jabber.c.

References aji_find_resource(), ast_aji_buddy_destroy(), ast_aji_client_destroy(), ast_aji_send(), ast_log(), ASTOBJ_CONTAINER_FIND, ASTOBJ_REF, ASTOBJ_UNREF, aji_client::buddies, aji_resource::cap, aji_client::jid, aji_version::jingle, LOG_ERROR, LOG_NOTICE, and aji_resource::resource.

Referenced by aji_create_client().

2004 {
2005  struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
2006  struct aji_resource *resource = NULL;
2007  struct aji_buddy *buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
2008 
2009  if (!buddy) {
2010  ast_log(LOG_NOTICE, "JABBER: Received client info from unknown buddy: %s.\n", pak->from->full);
2012  return IKS_FILTER_EAT;
2013  }
2014 
2015  resource = aji_find_resource(buddy, pak->from->resource);
2016  if (pak->subtype == IKS_TYPE_RESULT) {
2017  if (!resource) {
2018  ast_log(LOG_NOTICE, "JABBER: Received client info from %s when not requested.\n", pak->from->full);
2021  return IKS_FILTER_EAT;
2022  }
2023  if (iks_find_with_attrib(pak->query, "feature", "var", "http://www.google.com/xmpp/protocol/voice/v1")) {
2024  resource->cap->jingle = 1;
2025  } else {
2026  resource->cap->jingle = 0;
2027  }
2028  } else if (pak->subtype == IKS_TYPE_GET) {
2029  iks *iq, *disco, *ident, *google, *query;
2030  iq = iks_new("iq");
2031  query = iks_new("query");
2032  ident = iks_new("identity");
2033  disco = iks_new("feature");
2034  google = iks_new("feature");
2035  if (iq && ident && disco && google) {
2036  iks_insert_attrib(iq, "from", client->jid->full);
2037  iks_insert_attrib(iq, "to", pak->from->full);
2038  iks_insert_attrib(iq, "type", "result");
2039  iks_insert_attrib(iq, "id", pak->id);
2040  iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info");
2041  iks_insert_attrib(ident, "category", "client");
2042  iks_insert_attrib(ident, "type", "pc");
2043  iks_insert_attrib(ident, "name", "asterisk");
2044  iks_insert_attrib(disco, "var", "http://jabber.org/protocol/disco#info");
2045  iks_insert_attrib(google, "var", "http://www.google.com/xmpp/protocol/voice/v1");
2046  iks_insert_node(iq, query);
2047  iks_insert_node(query, ident);
2048  iks_insert_node(query, google);
2049  iks_insert_node(query, disco);
2050  ast_aji_send(client, iq);
2051  } else {
2052  ast_log(LOG_ERROR, "Out of Memory.\n");
2053  }
2054 
2055  iks_delete(iq);
2056  iks_delete(query);
2057  iks_delete(ident);
2058  iks_delete(google);
2059  iks_delete(disco);
2060  } else if (pak->subtype == IKS_TYPE_ERROR) {
2061  ast_log(LOG_NOTICE, "User %s does not support discovery.\n", pak->from->full);
2062  }
2065  return IKS_FILTER_EAT;
2066 }
void ast_aji_buddy_destroy(struct aji_buddy *obj)
Definition: res_jabber.c:432
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
char resource[AJI_MAX_RESJIDLEN]
Definition: jabber.h:119
struct aji_buddy_container buddies
Definition: jabber.h:184
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
#define LOG_ERROR
Definition: logger.h:155
iksid * jid
Definition: jabber.h:160
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#define ASTOBJ_CONTAINER_FIND(container, namestr)
Find an object in a container.
Definition: astobj.h:401
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
struct aji_version * cap
Definition: jabber.h:121
static struct aji_resource * aji_find_resource(struct aji_buddy *buddy, char *name)
Definition: res_jabber.c:544
#define ASTOBJ_REF(object)
Increment an object reference count.
Definition: astobj.h:201
int jingle
Definition: jabber.h:106
static void aji_create_affiliations ( struct aji_client client,
const char *  node 
)
static

Add Owner affiliations for pubsub node.

Parameters
clientthe configured XMPP client we use to connect to a XMPP server
nodethe name of the node to which to add affiliations
Returns
void

Definition at line 3332 of file res_jabber.c.

References aji_pubsub_iq_create(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, and aji_client::buddies.

Referenced by aji_create_pubsub_node().

3333 {
3334  iks *modify_affiliates = aji_pubsub_iq_create(client, "set");
3335  iks *pubsub, *affiliations, *affiliate;
3336  pubsub = iks_insert(modify_affiliates, "pubsub");
3337  iks_insert_attrib(pubsub, "xmlns", "http://jabber.org/protocol/pubsub#owner");
3338  affiliations = iks_insert(pubsub, "affiliations");
3339  iks_insert_attrib(affiliations, "node", node);
3340  ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, {
3341  ASTOBJ_RDLOCK(iterator);
3342  affiliate = iks_insert(affiliations, "affiliation");
3343  iks_insert_attrib(affiliate, "jid", iterator->name);
3344  iks_insert_attrib(affiliate, "affiliation", "owner");
3345  ASTOBJ_UNLOCK(iterator);
3346  });
3347  ast_aji_send(client, modify_affiliates);
3348  iks_delete(modify_affiliates);
3349 }
static iks * aji_pubsub_iq_create(struct aji_client *client, const char *type)
Create an IQ packet.
Definition: res_jabber.c:3493
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
struct aji_buddy_container buddies
Definition: jabber.h:184
#define ASTOBJ_CONTAINER_TRAVERSE(container, continue, eval)
Iterate through the objects in a container.
Definition: astobj.h:376
#define ASTOBJ_UNLOCK(object)
Unlock a locked object.
Definition: astobj.h:109
#define ASTOBJ_RDLOCK(object)
Lock an ASTOBJ for reading.
Definition: astobj.h:100
static int aji_create_buddy ( char *  label,
struct aji_client client 
)
static
static int aji_create_client ( char *  label,
struct ast_variable var,
int  debug 
)
static

Definition at line 4236 of file res_jabber.c.

References aji_act_hook(), AJI_AUTOACCEPT, AJI_AUTOPRUNE, AJI_AUTOREGISTER, aji_client_info_handler(), aji_create_buddy(), aji_dinfo_handler(), AJI_DISCONNECTED, aji_ditems_handler(), aji_log_hook(), AJI_PUBSUB, aji_register_approve_handler(), aji_register_query_handler(), ast_aji_client_destroy(), ast_asprintf, ast_calloc, ast_clear_flag, ast_copy_flags, ast_copy_string(), ast_false(), AST_FLAGS_ALL, ast_free, AST_LIST_HEAD_INIT, ast_log(), ast_set2_flag, ast_set_flag, ast_test_flag, ast_true(), ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_INIT, ASTOBJ_CONTAINER_LINK, ASTOBJ_CONTAINER_MARKALL, ASTOBJ_INIT, ASTOBJ_UNLOCK, ASTOBJ_UNMARK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, aji_client::authorized, aji_client::buddies, clients, aji_client::component, aji_client::debug, aji_client::distribute_events, aji_client::f, aji_client::flags, aji_client::forcessl, aji_client::jid, aji_client::keepalive, LOG_ERROR, LOG_WARNING, aji_client::message_timeout, aji_client::messages, aji_client::mid, ast_variable::name, aji_client::name, aji_client::name_space, ast_variable::next, aji_client::p, aji_client::password, aji_client::port, aji_client::priority, aji_client::pubsub_node, aji_client::serverhost, aji_client::stack, aji_client::state, aji_client::status, aji_client::statusmessage, aji_client::timeout, aji_client::user, aji_client::usesasl, aji_client::usetls, and ast_variable::value.

Referenced by aji_load_config().

4237 {
4238  char *resource;
4239  struct aji_client *client = NULL;
4240  int flag = 0;
4241 
4242  client = ASTOBJ_CONTAINER_FIND(&clients, label);
4243  if (!client) {
4244  flag = 1;
4245  client = ast_calloc(1, sizeof(*client));
4246  if (!client) {
4247  ast_log(LOG_ERROR, "Out of memory!\n");
4248  return 0;
4249  }
4250  ASTOBJ_INIT(client);
4251  ASTOBJ_WRLOCK(client);
4252  ASTOBJ_CONTAINER_INIT(&client->buddies);
4253  } else {
4254  ASTOBJ_WRLOCK(client);
4255  ASTOBJ_UNMARK(client);
4256  }
4258  ast_copy_string(client->name, label, sizeof(client->name));
4259  ast_copy_string(client->mid, "aaaaa", sizeof(client->mid));
4260 
4261  /* Set default values for the client object */
4262  client->debug = debug;
4264  client->port = 5222;
4265  client->usetls = 1;
4266  client->usesasl = 1;
4267  client->forcessl = 0;
4268  client->keepalive = 1;
4269  client->timeout = 50;
4270  client->message_timeout = 5;
4271  client->distribute_events = 0;
4272  AST_LIST_HEAD_INIT(&client->messages);
4273  client->component = 0;
4274  ast_copy_string(client->statusmessage, "Online and Available", sizeof(client->statusmessage));
4275  client->priority = 0;
4276  client->status = IKS_SHOW_AVAILABLE;
4277 
4278  if (flag) {
4279  client->authorized = 0;
4280  client->state = AJI_DISCONNECTED;
4281  }
4282  while (var) {
4283  if (!strcasecmp(var->name, "username")) {
4284  ast_copy_string(client->user, var->value, sizeof(client->user));
4285  } else if (!strcasecmp(var->name, "serverhost")) {
4286  ast_copy_string(client->serverhost, var->value, sizeof(client->serverhost));
4287  } else if (!strcasecmp(var->name, "secret")) {
4288  ast_copy_string(client->password, var->value, sizeof(client->password));
4289  } else if (!strcasecmp(var->name, "statusmessage")) {
4290  ast_copy_string(client->statusmessage, var->value, sizeof(client->statusmessage));
4291  } else if (!strcasecmp(var->name, "port")) {
4292  client->port = atoi(var->value);
4293  } else if (!strcasecmp(var->name, "timeout")) {
4294  client->message_timeout = atoi(var->value);
4295  } else if (!strcasecmp(var->name, "debug")) {
4296  client->debug = (ast_false(var->value)) ? 0 : 1;
4297  } else if (!strcasecmp(var->name, "type")) {
4298  if (!strcasecmp(var->value, "component")) {
4299  client->component = 1;
4300  if (client->distribute_events) {
4301  ast_log(LOG_ERROR, "Client cannot be configured to be both a component and to distribute events! Event distribution will be disabled.\n");
4302  client->distribute_events = 0;
4303  }
4304  }
4305  } else if (!strcasecmp(var->name, "distribute_events")) {
4306  if (ast_true(var->value)) {
4307  if (client->component) {
4308  ast_log(LOG_ERROR, "Client cannot be configured to be both a component and to distribute events! Event distribution will be disabled.\n");
4309  } else {
4311  ast_log(LOG_ERROR, "Only one connection can be configured for distributed events.\n");
4312  } else {
4314  client->distribute_events = 1;
4315  }
4316  }
4317  }
4318  } else if (!strcasecmp(var->name, "pubsub_node")) {
4319  ast_copy_string(client->pubsub_node, var->value, sizeof(client->pubsub_node));
4320  } else if (!strcasecmp(var->name, "usetls")) {
4321  client->usetls = (ast_false(var->value)) ? 0 : 1;
4322  } else if (!strcasecmp(var->name, "usesasl")) {
4323  client->usesasl = (ast_false(var->value)) ? 0 : 1;
4324  } else if (!strcasecmp(var->name, "forceoldssl")) {
4325  client->forcessl = (ast_false(var->value)) ? 0 : 1;
4326  } else if (!strcasecmp(var->name, "keepalive")) {
4327  client->keepalive = (ast_false(var->value)) ? 0 : 1;
4328  } else if (!strcasecmp(var->name, "autoprune")) {
4329  ast_set2_flag(&client->flags, ast_true(var->value), AJI_AUTOPRUNE);
4330  } else if (!strcasecmp(var->name, "autoregister")) {
4332  } else if (!strcasecmp(var->name, "auth_policy")) {
4333  if (!strcasecmp(var->value, "accept")) {
4334  ast_set_flag(&client->flags, AJI_AUTOACCEPT);
4335  } else {
4336  ast_clear_flag(&client->flags, AJI_AUTOACCEPT);
4337  }
4338  } else if (!strcasecmp(var->name, "buddy")) {
4339  aji_create_buddy((char *)var->value, client);
4340  } else if (!strcasecmp(var->name, "priority")) {
4341  client->priority = atoi(var->value);
4342  } else if (!strcasecmp(var->name, "status")) {
4343  if (!strcasecmp(var->value, "unavailable")) {
4344  client->status = IKS_SHOW_UNAVAILABLE;
4345  } else if (!strcasecmp(var->value, "available")
4346  || !strcasecmp(var->value, "online")) {
4347  client->status = IKS_SHOW_AVAILABLE;
4348  } else if (!strcasecmp(var->value, "chat")
4349  || !strcasecmp(var->value, "chatty")) {
4350  client->status = IKS_SHOW_CHAT;
4351  } else if (!strcasecmp(var->value, "away")) {
4352  client->status = IKS_SHOW_AWAY;
4353  } else if (!strcasecmp(var->value, "xa")
4354  || !strcasecmp(var->value, "xaway")) {
4355  client->status = IKS_SHOW_XA;
4356  } else if (!strcasecmp(var->value, "dnd")) {
4357  client->status = IKS_SHOW_DND;
4358  } else if (!strcasecmp(var->value, "invisible")) {
4359  #ifdef IKS_SHOW_INVISIBLE
4360  client->status = IKS_SHOW_INVISIBLE;
4361  #else
4362  ast_log(LOG_WARNING, "Your iksemel doesn't support invisible status: falling back to DND\n");
4363  client->status = IKS_SHOW_DND;
4364  #endif
4365  } else {
4366  ast_log(LOG_WARNING, "Unknown presence status: %s\n", var->value);
4367  }
4368  }
4369  /* no transport support in this version */
4370  /* else if (!strcasecmp(var->name, "transport"))
4371  aji_create_transport(var->value, client);
4372  */
4373  var = var->next;
4374  }
4375  if (!flag) {
4376  ASTOBJ_UNLOCK(client);
4378  return 1;
4379  }
4380 
4381  ast_copy_string(client->name_space, (client->component) ? "jabber:component:accept" : "jabber:client", sizeof(client->name_space));
4382  client->p = iks_stream_new(client->name_space, client, aji_act_hook);
4383  if (!client->p) {
4384  ast_log(LOG_ERROR, "Failed to create stream for client '%s'!\n", client->name);
4385  return 0;
4386  }
4387  client->stack = iks_stack_new(8192, 8192);
4388  if (!client->stack) {
4389  ast_log(LOG_ERROR, "Failed to allocate stack for client '%s'\n", client->name);
4390  return 0;
4391  }
4392  client->f = iks_filter_new();
4393  if (!client->f) {
4394  ast_log(LOG_ERROR, "Failed to create filter for client '%s'\n", client->name);
4395  return 0;
4396  }
4397  if (!strchr(client->user, '/') && !client->component) { /*client */
4398  if (ast_asprintf(&resource, "%s/asterisk", client->user) >= 0) {
4399  client->jid = iks_id_new(client->stack, resource);
4400  ast_free(resource);
4401  }
4402  } else {
4403  client->jid = iks_id_new(client->stack, client->user);
4404  }
4405  if (client->component) {
4406  iks_filter_add_rule(client->f, aji_dinfo_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#info", IKS_RULE_DONE);
4407  iks_filter_add_rule(client->f, aji_ditems_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#items", IKS_RULE_DONE);
4408  iks_filter_add_rule(client->f, aji_register_query_handler, client, IKS_RULE_SUBTYPE, IKS_TYPE_GET, IKS_RULE_NS, "jabber:iq:register", IKS_RULE_DONE);
4409  iks_filter_add_rule(client->f, aji_register_approve_handler, client, IKS_RULE_SUBTYPE, IKS_TYPE_SET, IKS_RULE_NS, "jabber:iq:register", IKS_RULE_DONE);
4410  } else {
4411  iks_filter_add_rule(client->f, aji_client_info_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#info", IKS_RULE_DONE);
4412  }
4413 
4414  iks_set_log_hook(client->p, aji_log_hook);
4415  ASTOBJ_UNLOCK(client);
4416  ASTOBJ_CONTAINER_LINK(&clients, client);
4417  return 1;
4418 }
static int aji_act_hook(void *data, int type, iks *node)
Definition: res_jabber.c:1572
char statusmessage[256]
Definition: jabber.h:156
int authorized
Definition: jabber.h:180
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:144
int usetls
Definition: jabber.h:173
int keepalive
Definition: jabber.h:176
static struct ast_flags globalflags
Global flags, initialized to default values.
Definition: res_jabber.c:400
#define ASTOBJ_UNMARK(object)
Unmark an ASTOBJ by subtracting the ASTOBJ_FLAG_MARKED flag from its objflags mask.
Definition: astobj.h:251
enum aji_state state
Definition: jabber.h:170
iksparser * p
Definition: jabber.h:161
int message_timeout
Definition: jabber.h:179
int usesasl
Definition: jabber.h:175
static struct ast_flags pubsubflags
PubSub flags, initialized to default values.
Definition: res_jabber.c:403
#define ASTOBJ_WRLOCK(object)
Lock an ASTOBJ for writing.
Definition: astobj.h:104
char serverhost[AJI_MAX_RESJIDLEN]
Definition: jabber.h:154
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
struct ast_flags flags
Definition: jabber.h:182
int component
Definition: jabber.h:183
#define ASTOBJ_CONTAINER_INIT(container)
Initialize a container.
Definition: astobj.h:752
#define ast_asprintf(a, b, c...)
Definition: astmm.h:121
static int aji_client_info_handler(void *data, ikspak *pak)
Definition: res_jabber.c:2003
static void aji_log_hook(void *data, const char *xmpp, size_t size, int is_incoming)
Definition: res_jabber.c:1487
const char * value
Definition: config.h:79
struct aji_buddy_container buddies
Definition: jabber.h:184
static int aji_register_query_handler(void *data, ikspak *pak)
Definition: res_jabber.c:1833
static int aji_ditems_handler(void *data, ikspak *pak)
Definition: res_jabber.c:1906
#define ASTOBJ_INIT(object)
Initialize an object.
Definition: astobj.h:264
int port
Definition: jabber.h:171
const char * name
Definition: config.h:77
char name[80]
Definition: jabber.h:151
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
#define LOG_ERROR
Definition: logger.h:155
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
char user[AJI_MAX_JIDLEN]
Definition: jabber.h:153
#define ASTOBJ_CONTAINER_LINK(container, newobj)
Add an object to a container.
Definition: astobj.h:776
iksid * jid
Definition: jabber.h:160
int distribute_events
Definition: jabber.h:181
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
enum ikshowtype status
Definition: jabber.h:189
#define ASTOBJ_UNLOCK(object)
Unlock a locked object.
Definition: astobj.h:109
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
Definition: linkedlists.h:611
#define ast_free(a)
Definition: astmm.h:97
#define ASTOBJ_CONTAINER_FIND(container, namestr)
Find an object in a container.
Definition: astobj.h:401
#define AST_FLAGS_ALL
Definition: utils.h:196
int debug
Definition: jabber.h:172
static struct aji_client_container clients
Definition: res_jabber.c:392
#define ast_clear_flag(p, flag)
Definition: utils.h:77
char pubsub_node[AJI_MAX_RESJIDLEN]
Definition: jabber.h:155
static int aji_dinfo_handler(void *data, ikspak *pak)
Definition: res_jabber.c:2075
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
static int aji_register_approve_handler(void *data, ikspak *pak)
Definition: res_jabber.c:1790
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int aji_create_buddy(char *label, struct aji_client *client)
Definition: res_jabber.c:4490
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is &quot;false&quot;...
Definition: utils.c:1550
char password[160]
Definition: jabber.h:151
int timeout
Definition: jabber.h:178
#define ASTOBJ_CONTAINER_MARKALL(container)
Mark all the objects in a container.
Definition: astobj.h:782
struct ast_variable * next
Definition: config.h:82
char name_space[256]
Definition: jabber.h:157
ikstack * stack
Definition: jabber.h:163
struct aji_client::messages messages
char mid[6]
Definition: jabber.h:159
int priority
Definition: jabber.h:188
int forcessl
Definition: jabber.h:174
iksfilter * f
Definition: jabber.h:162
static void aji_create_pubsub_collection ( struct aji_client client,
const char *  collection_name 
)
static

Create a PubSub collection node.

Parameters
clientthe configured XMPP client we use to connect to a XMPP server
collection_nameThe name to use for this collection
Returns
void.

Definition at line 3812 of file res_jabber.c.

References aji_create_pubsub_node().

Referenced by aji_cli_create_collection(), and aji_handle_pubsub_error().

3814 {
3815  aji_create_pubsub_node(client, "collection", collection_name, NULL);
3816 }
static iks * aji_create_pubsub_node(struct aji_client *client, const char *node_type, const char *name, const char *collection_name)
Create a pubsub node.
Definition: res_jabber.c:3838
static void aji_create_pubsub_leaf ( struct aji_client client,
const char *  collection_name,
const char *  leaf_name 
)
static

Create a PubSub leaf node.

Parameters
clientthe configured XMPP client we use to connect to a XMPP server
leaf_nameThe name to use for this collection
Returns
void.

Definition at line 3825 of file res_jabber.c.

References aji_create_pubsub_node().

Referenced by aji_cli_create_leafnode(), and aji_handle_pubsub_error().

3827 {
3828  aji_create_pubsub_node(client, "leaf", leaf_name, collection_name);
3829 }
static iks * aji_create_pubsub_node(struct aji_client *client, const char *node_type, const char *name, const char *collection_name)
Create a pubsub node.
Definition: res_jabber.c:3838
static iks * aji_create_pubsub_node ( struct aji_client client,
const char *  node_type,
const char *  name,
const char *  collection_name 
)
static

Create a pubsub node.

Parameters
clientthe configured XMPP client we use to connect to a XMPP server
node_typethe type of node to create
namethe name of the node to create
Returns
iks*

Definition at line 3838 of file res_jabber.c.

References aji_build_node_config(), aji_create_affiliations(), aji_pubsub_iq_create(), and ast_aji_send().

Referenced by aji_create_pubsub_collection(), aji_create_pubsub_leaf(), aji_handle_pubsub_error(), and aji_publish_device_state().

3840 {
3841  iks *node = aji_pubsub_iq_create(client, "set");
3842  iks *pubsub, *create;
3843  pubsub = iks_insert(node, "pubsub");
3844  iks_insert_attrib(pubsub, "xmlns", "http://jabber.org/protocol/pubsub");
3845  create = iks_insert(pubsub, "create");
3846  iks_insert_attrib(create, "node", name);
3847  aji_build_node_config(pubsub, node_type, collection_name);
3848  ast_aji_send(client, node);
3849  aji_create_affiliations(client, name);
3850  iks_delete(node);
3851  return 0;
3852 }
static iks * aji_pubsub_iq_create(struct aji_client *client, const char *type)
Create an IQ packet.
Definition: res_jabber.c:3493
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
static iks * aji_build_node_config(iks *pubsub, const char *node_type, const char *collection_name)
Definition: res_jabber.c:3856
node_type
Definition: ast_expr2.c:333
static const char name[]
static void aji_create_affiliations(struct aji_client *client, const char *node)
Add Owner affiliations for pubsub node.
Definition: res_jabber.c:3332
static int aji_delete_node_list ( void *  data,
ikspak *  pak 
)
static

Delete pubsub item lists.

Parameters
datapointer to aji_client structure
pakresponse from pubsub diso::items query
Returns
IKS_FILTER_EAT

Definition at line 3730 of file res_jabber.c.

References aji_delete_pubsub_node(), ast_log(), ASTOBJ_REF, aji_client::jid, and LOG_WARNING.

Referenced by aji_pubsub_purge_nodes().

3731 {
3732 
3733  struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
3734  iks *item = NULL;
3735  if (iks_has_children(pak->query)) {
3736  item = iks_first_tag(pak->query);
3737  ast_log(LOG_WARNING, "Connection: %s Node name: %s\n", client->jid->partial,
3738  iks_find_attrib(item, "node"));
3739  while ((item = iks_next_tag(item))) {
3740  aji_delete_pubsub_node(client, iks_find_attrib(item, "node"));
3741  }
3742  }
3743  if (item) {
3744  iks_delete(item);
3745  }
3746  return IKS_FILTER_EAT;
3747 }
#define LOG_WARNING
Definition: logger.h:144
static void aji_delete_pubsub_node(struct aji_client *client, const char *node_name)
Delete a PubSub node.
Definition: res_jabber.c:3795
iksid * jid
Definition: jabber.h:160
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ASTOBJ_REF(object)
Increment an object reference count.
Definition: astobj.h:201
static void aji_delete_pubsub_node ( struct aji_client client,
const char *  node_name 
)
static

Delete a PubSub node.

Parameters
clientthe configured XMPP client we use to connect to a XMPP server
node_namethe name of the node to delete return void

Definition at line 3795 of file res_jabber.c.

References aji_pubsub_iq_create(), and ast_aji_send().

Referenced by aji_cli_delete_pubsub_node(), aji_cli_purge_pubsub_nodes(), and aji_delete_node_list().

3796 {
3797  iks *request = aji_pubsub_iq_create(client, "set");
3798  iks *pubsub, *delete;
3799  pubsub = iks_insert(request, "pubsub");
3800  iks_insert_attrib(pubsub, "xmlns", "http://jabber.org/protocol/pubsub#owner");
3801  delete = iks_insert(pubsub, "delete");
3802  iks_insert_attrib(delete, "node", node_name);
3803  ast_aji_send(client, request);
3804 }
static iks * aji_pubsub_iq_create(struct aji_client *client, const char *type)
Create an IQ packet.
Definition: res_jabber.c:3493
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
static void aji_devstate_cb ( const struct ast_event ast_event,
void *  data 
)
static

Callback function for device state events.

Parameters
ast_event
datavoid pointer to ast_client structure
Returns
void

Definition at line 3209 of file res_jabber.c.

References aji_publish_device_state(), ast_aji_client_destroy(), ast_devstate_str(), ast_eid_cmp(), ast_eid_default, ast_event_get_ie_raw(), ast_event_get_ie_str(), ast_event_get_ie_uint(), AST_EVENT_IE_CACHABLE, AST_EVENT_IE_DEVICE, AST_EVENT_IE_EID, AST_EVENT_IE_STATE, ast_log(), ASTOBJ_REF, ASTOBJ_UNREF, and LOG_DEBUG.

Referenced by aji_init_event_distribution().

3210 {
3211  const char *device;
3212  const char *device_state;
3213  unsigned int cachable;
3214  struct aji_client *client;
3216  {
3217  /* If the event didn't originate from this server, don't send it back out. */
3218  ast_log(LOG_DEBUG, "Returning here\n");
3219  return;
3220  }
3221 
3222  client = ASTOBJ_REF((struct aji_client *) data);
3223  device = ast_event_get_ie_str(ast_event, AST_EVENT_IE_DEVICE);
3224  device_state = ast_devstate_str(ast_event_get_ie_uint(ast_event, AST_EVENT_IE_STATE));
3225  cachable = ast_event_get_ie_uint(ast_event, AST_EVENT_IE_CACHABLE);
3226  aji_publish_device_state(client, device, device_state, cachable);
3228 }
#define LOG_DEBUG
Definition: logger.h:122
Entity ID Used by All events Payload type: RAW This IE indicates which server the event originated fr...
Definition: event_defs.h:266
int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2)
Compare two EIDs.
Definition: netsock.c:320
Event non-cachability flag Used by: All events Payload type: UINT.
Definition: event_defs.h:291
const void * ast_event_get_ie_raw(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has a raw payload.
Definition: event.c:1111
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
const char * ast_devstate_str(enum ast_device_state devstate) attribute_pure
Convert device state to text string that is easier to parse.
Definition: devicestate.c:239
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void aji_publish_device_state(struct aji_client *client, const char *device, const char *device_state, unsigned int cachable)
Publish device state to a PubSub node.
Definition: res_jabber.c:3438
uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has an integer payload.
Definition: event.c:1075
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
struct ast_eid ast_eid_default
Global EID.
Definition: asterisk.c:192
Generic State IE Used by AST_EVENT_DEVICE_STATE_CHANGE Payload type: UINT The actual state values dep...
Definition: event_defs.h:115
const char * ast_event_get_ie_str(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has a string payload.
Definition: event.c:1102
#define ASTOBJ_REF(object)
Increment an object reference count.
Definition: astobj.h:201
Device Name Used by AST_EVENT_DEVICE_STATE_CHANGE Payload type: STR.
Definition: event_defs.h:107
static int aji_dinfo_handler ( void *  data,
ikspak *  pak 
)
static

Definition at line 2075 of file res_jabber.c.

References aji_find_resource(), ast_aji_buddy_destroy(), ast_aji_client_destroy(), ast_aji_send(), ast_log(), ASTOBJ_CONTAINER_FIND, ASTOBJ_REF, ASTOBJ_UNREF, aji_client::buddies, aji_resource::cap, commands, aji_version::jingle, LOG_ERROR, LOG_NOTICE, LOG_WARNING, aji_resource::resource, aji_client::user, and version.

Referenced by aji_create_client().

2076 {
2077  struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
2078  char *node = NULL;
2079  struct aji_resource *resource = NULL;
2080  struct aji_buddy *buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
2081 
2082  if (!buddy) {
2083  ast_log(LOG_NOTICE, "JABBER: Received client info from unknown buddy: %s.\n", pak->from->full);
2085  return IKS_FILTER_EAT;
2086  }
2087 
2088  if (pak->subtype == IKS_TYPE_ERROR) {
2089  ast_log(LOG_WARNING, "Received error from a client, turn on jabber debug!\n");
2091  return IKS_FILTER_EAT;
2092  }
2093  resource = aji_find_resource(buddy, pak->from->resource);
2094  if (pak->subtype == IKS_TYPE_RESULT) {
2095  if (!resource) {
2096  ast_log(LOG_NOTICE, "JABBER: Received client info from %s when not requested.\n", pak->from->full);
2099  return IKS_FILTER_EAT;
2100  }
2101  if (iks_find_with_attrib(pak->query, "feature", "var", "http://www.google.com/xmpp/protocol/voice/v1")) {
2102  resource->cap->jingle = 1;
2103  } else {
2104  resource->cap->jingle = 0;
2105  }
2106  } else if (pak->subtype == IKS_TYPE_GET && !(node = iks_find_attrib(pak->query, "node"))) {
2107  iks *iq, *query, *identity, *disco, *reg, *commands, *gateway, *version, *vcard, *search;
2108 
2109  iq = iks_new("iq");
2110  query = iks_new("query");
2111  identity = iks_new("identity");
2112  disco = iks_new("feature");
2113  reg = iks_new("feature");
2114  commands = iks_new("feature");
2115  gateway = iks_new("feature");
2116  version = iks_new("feature");
2117  vcard = iks_new("feature");
2118  search = iks_new("feature");
2119  if (iq && query && identity && disco && reg && commands && gateway && version && vcard && search && client) {
2120  iks_insert_attrib(iq, "from", client->user);
2121  iks_insert_attrib(iq, "to", pak->from->full);
2122  iks_insert_attrib(iq, "id", pak->id);
2123  iks_insert_attrib(iq, "type", "result");
2124  iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info");
2125  iks_insert_attrib(identity, "category", "gateway");
2126  iks_insert_attrib(identity, "type", "pstn");
2127  iks_insert_attrib(identity, "name", "Asterisk The Open Source PBX");
2128  iks_insert_attrib(disco, "var", "http://jabber.org/protocol/disco");
2129  iks_insert_attrib(reg, "var", "jabber:iq:register");
2130  iks_insert_attrib(commands, "var", "http://jabber.org/protocol/commands");
2131  iks_insert_attrib(gateway, "var", "jabber:iq:gateway");
2132  iks_insert_attrib(version, "var", "jabber:iq:version");
2133  iks_insert_attrib(vcard, "var", "vcard-temp");
2134  iks_insert_attrib(search, "var", "jabber:iq:search");
2135 
2136  iks_insert_node(iq, query);
2137  iks_insert_node(query, identity);
2138  iks_insert_node(query, disco);
2139  iks_insert_node(query, reg);
2140  iks_insert_node(query, commands);
2141  iks_insert_node(query, gateway);
2142  iks_insert_node(query, version);
2143  iks_insert_node(query, vcard);
2144  iks_insert_node(query, search);
2145  ast_aji_send(client, iq);
2146  } else {
2147  ast_log(LOG_ERROR, "Out of memory.\n");
2148  }
2149 
2150  iks_delete(iq);
2151  iks_delete(query);
2152  iks_delete(identity);
2153  iks_delete(disco);
2154  iks_delete(reg);
2155  iks_delete(commands);
2156  iks_delete(gateway);
2157  iks_delete(version);
2158  iks_delete(vcard);
2159  iks_delete(search);
2160  } else if (pak->subtype == IKS_TYPE_GET && !strcasecmp(node, "http://jabber.org/protocol/commands")) {
2161  iks *iq, *query, *confirm;
2162  iq = iks_new("iq");
2163  query = iks_new("query");
2164  confirm = iks_new("item");
2165 
2166  if (iq && query && confirm && client) {
2167  iks_insert_attrib(iq, "from", client->user);
2168  iks_insert_attrib(iq, "to", pak->from->full);
2169  iks_insert_attrib(iq, "id", pak->id);
2170  iks_insert_attrib(iq, "type", "result");
2171  iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items");
2172  iks_insert_attrib(query, "node", "http://jabber.org/protocol/commands");
2173  iks_insert_attrib(confirm, "node", "confirmaccount");
2174  iks_insert_attrib(confirm, "name", "Confirm AIM account");
2175  iks_insert_attrib(confirm, "jid", client->user);
2176  iks_insert_node(iq, query);
2177  iks_insert_node(query, confirm);
2178  ast_aji_send(client, iq);
2179  } else {
2180  ast_log(LOG_ERROR, "Out of memory.\n");
2181  }
2182 
2183  iks_delete(iq);
2184  iks_delete(query);
2185  iks_delete(confirm);
2186 
2187  } else if (pak->subtype == IKS_TYPE_GET && !strcasecmp(node, "confirmaccount")) {
2188  iks *iq, *query, *feature;
2189 
2190  iq = iks_new("iq");
2191  query = iks_new("query");
2192  feature = iks_new("feature");
2193 
2194  if (iq && query && feature && client) {
2195  iks_insert_attrib(iq, "from", client->user);
2196  iks_insert_attrib(iq, "to", pak->from->full);
2197  iks_insert_attrib(iq, "id", pak->id);
2198  iks_insert_attrib(iq, "type", "result");
2199  iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info");
2200  iks_insert_attrib(feature, "var", "http://jabber.org/protocol/commands");
2201  iks_insert_node(iq, query);
2202  iks_insert_node(query, feature);
2203  ast_aji_send(client, iq);
2204  } else {
2205  ast_log(LOG_ERROR, "Out of memory.\n");
2206  }
2207 
2208  iks_delete(iq);
2209  iks_delete(query);
2210  iks_delete(feature);
2211  }
2212 
2215  return IKS_FILTER_EAT;
2216 }
uint32_t version
void ast_aji_buddy_destroy(struct aji_buddy *obj)
Definition: res_jabber.c:432
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
#define LOG_WARNING
Definition: logger.h:144
char resource[AJI_MAX_RESJIDLEN]
Definition: jabber.h:119
struct aji_buddy_container buddies
Definition: jabber.h:184
static struct agi_command commands[]
AGI commands list.
Definition: res_agi.c:3046
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
#define LOG_ERROR
Definition: logger.h:155
char user[AJI_MAX_JIDLEN]
Definition: jabber.h:153
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#define ASTOBJ_CONTAINER_FIND(container, namestr)
Find an object in a container.
Definition: astobj.h:401
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
struct aji_version * cap
Definition: jabber.h:121
static struct aji_resource * aji_find_resource(struct aji_buddy *buddy, char *name)
Definition: res_jabber.c:544
#define ASTOBJ_REF(object)
Increment an object reference count.
Definition: astobj.h:201
int jingle
Definition: jabber.h:106
static int aji_ditems_handler ( void *  data,
ikspak *  pak 
)
static

Definition at line 1906 of file res_jabber.c.

References ast_aji_client_destroy(), ast_aji_send(), ast_log(), ASTOBJ_REF, ASTOBJ_UNREF, LOG_ERROR, and aji_client::user.

Referenced by aji_create_client().

1907 {
1908  struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
1909  char *node = NULL;
1910 
1911  if (!(node = iks_find_attrib(pak->query, "node"))) {
1912  iks *iq = NULL, *query = NULL, *item = NULL;
1913  iq = iks_new("iq");
1914  query = iks_new("query");
1915  item = iks_new("item");
1916 
1917  if (iq && query && item) {
1918  iks_insert_attrib(iq, "from", client->user);
1919  iks_insert_attrib(iq, "to", pak->from->full);
1920  iks_insert_attrib(iq, "id", pak->id);
1921  iks_insert_attrib(iq, "type", "result");
1922  iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items");
1923  iks_insert_attrib(item, "node", "http://jabber.org/protocol/commands");
1924  iks_insert_attrib(item, "name", "Million Dollar Asterisk Commands");
1925  iks_insert_attrib(item, "jid", client->user);
1926 
1927  iks_insert_node(iq, query);
1928  iks_insert_node(query, item);
1929  ast_aji_send(client, iq);
1930  } else {
1931  ast_log(LOG_ERROR, "Out of memory.\n");
1932  }
1933 
1934  iks_delete(iq);
1935  iks_delete(query);
1936  iks_delete(item);
1937 
1938  } else if (!strcasecmp(node, "http://jabber.org/protocol/commands")) {
1939  iks *iq, *query, *confirm;
1940  iq = iks_new("iq");
1941  query = iks_new("query");
1942  confirm = iks_new("item");
1943  if (iq && query && confirm && client) {
1944  iks_insert_attrib(iq, "from", client->user);
1945  iks_insert_attrib(iq, "to", pak->from->full);
1946  iks_insert_attrib(iq, "id", pak->id);
1947  iks_insert_attrib(iq, "type", "result");
1948  iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items");
1949  iks_insert_attrib(query, "node", "http://jabber.org/protocol/commands");
1950  iks_insert_attrib(confirm, "node", "confirmaccount");
1951  iks_insert_attrib(confirm, "name", "Confirm AIM account");
1952  iks_insert_attrib(confirm, "jid", "blog.astjab.org");
1953 
1954  iks_insert_node(iq, query);
1955  iks_insert_node(query, confirm);
1956  ast_aji_send(client, iq);
1957  } else {
1958  ast_log(LOG_ERROR, "Out of memory.\n");
1959  }
1960 
1961  iks_delete(iq);
1962  iks_delete(query);
1963  iks_delete(confirm);
1964 
1965  } else if (!strcasecmp(node, "confirmaccount")) {
1966  iks *iq = NULL, *query = NULL, *feature = NULL;
1967 
1968  iq = iks_new("iq");
1969  query = iks_new("query");
1970  feature = iks_new("feature");
1971 
1972  if (iq && query && feature && client) {
1973  iks_insert_attrib(iq, "from", client->user);
1974  iks_insert_attrib(iq, "to", pak->from->full);
1975  iks_insert_attrib(iq, "id", pak->id);
1976  iks_insert_attrib(iq, "type", "result");
1977  iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items");
1978  iks_insert_attrib(feature, "var", "http://jabber.org/protocol/commands");
1979  iks_insert_node(iq, query);
1980  iks_insert_node(query, feature);
1981  ast_aji_send(client, iq);
1982  } else {
1983  ast_log(LOG_ERROR, "Out of memory.\n");
1984  }
1985 
1986  iks_delete(iq);
1987  iks_delete(query);
1988  iks_delete(feature);
1989  }
1990 
1992  return IKS_FILTER_EAT;
1993 
1994 }
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
#define LOG_ERROR
Definition: logger.h:155
char user[AJI_MAX_JIDLEN]
Definition: jabber.h:153
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
#define ASTOBJ_REF(object)
Increment an object reference count.
Definition: astobj.h:201
static char * aji_do_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 4117 of file res_jabber.c.

References aji_reload(), ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

4118 {
4119  switch (cmd) {
4120  case CLI_INIT:
4121  e->command = "jabber reload";
4122  e->usage =
4123  "Usage: jabber reload\n"
4124  " Reloads the Jabber module.\n";
4125  return NULL;
4126  case CLI_GENERATE:
4127  return NULL;
4128  }
4129 
4130  aji_reload(1);
4131  ast_cli(a->fd, "Jabber Reloaded.\n");
4132  return CLI_SUCCESS;
4133 }
Definition: cli.h:146
static int aji_reload(int reload)
Definition: res_jabber.c:4654
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char * aji_do_set_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 4075 of file res_jabber.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, clients, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

4076 {
4077  switch (cmd) {
4078  case CLI_INIT:
4079  e->command = "jabber set debug {on|off}";
4080  e->usage =
4081  "Usage: jabber set debug {on|off}\n"
4082  " Enables/disables dumping of XMPP/Jabber packets for debugging purposes.\n";
4083  return NULL;
4084  case CLI_GENERATE:
4085  return NULL;
4086  }
4087 
4088  if (a->argc != e->args) {
4089  return CLI_SHOWUSAGE;
4090  }
4091 
4092  if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
4094  ASTOBJ_RDLOCK(iterator);
4095  iterator->debug = 1;
4096  ASTOBJ_UNLOCK(iterator);
4097  });
4098  ast_cli(a->fd, "Jabber Debugging Enabled.\n");
4099  return CLI_SUCCESS;
4100  } else if (!strncasecmp(a->argv[e->args - 1], "off", 3)) {
4102  ASTOBJ_RDLOCK(iterator);
4103  iterator->debug = 0;
4104  ASTOBJ_UNLOCK(iterator);
4105  });
4106  ast_cli(a->fd, "Jabber Debugging Disabled.\n");
4107  return CLI_SUCCESS;
4108  }
4109  return CLI_SHOWUSAGE; /* defaults to invalid */
4110 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
int args
This gets set in ast_cli_register()
Definition: cli.h:179
const int fd
Definition: cli.h:153
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define ASTOBJ_CONTAINER_TRAVERSE(container, continue, eval)
Iterate through the objects in a container.
Definition: astobj.h:376
#define ASTOBJ_UNLOCK(object)
Unlock a locked object.
Definition: astobj.h:109
char * command
Definition: cli.h:180
static struct aji_client_container clients
Definition: res_jabber.c:392
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
#define ASTOBJ_RDLOCK(object)
Lock an ASTOBJ for reading.
Definition: astobj.h:100
static int aji_filter_roster ( void *  data,
ikspak *  pak 
)
static

Definition at line 2953 of file res_jabber.c.

References AJI_AUTOPRUNE, AJI_AUTOREGISTER, AJI_CONNECTED, ast_clear_flag, ast_copy_flags, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_REF, ASTOBJ_UNLOCK, aji_client::buddies, aji_client::flags, and aji_client::state.

Referenced by aji_client_connect().

2954 {
2955  struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
2956  int flag = 0;
2957  iks *x = NULL;
2958  struct aji_buddy *buddy;
2959 
2960  client->state = AJI_CONNECTED;
2961  ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, {
2962  ASTOBJ_RDLOCK(iterator);
2963  x = iks_child(pak->query);
2964  flag = 0;
2965  while (x) {
2966  if (!iks_strcmp(iks_name(x), "item")) {
2967  if (!strcasecmp(iterator->name, iks_find_attrib(x, "jid"))) {
2968  flag = 1;
2969  ast_clear_flag(&iterator->flags, AJI_AUTOPRUNE | AJI_AUTOREGISTER);
2970  }
2971  }
2972  x = iks_next(x);
2973  }
2974  if (!flag) {
2975  ast_copy_flags(&iterator->flags, &client->flags, AJI_AUTOREGISTER);
2976  }
2977  iks_delete(x);
2978 
2979  ASTOBJ_UNLOCK(iterator);
2980  });
2981 
2982  x = iks_child(pak->query);
2983  while (x) {
2984  flag = 0;
2985  if (iks_strcmp(iks_name(x), "item") == 0) {
2986  ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, {
2987  ASTOBJ_RDLOCK(iterator);
2988  if (!strcasecmp(iterator->name, iks_find_attrib(x, "jid")))
2989  flag = 1;
2990  ASTOBJ_UNLOCK(iterator);
2991  });
2992 
2993  if (flag) {
2994  /* found buddy, don't create a new one */
2995  x = iks_next(x);
2996  continue;
2997  }
2998 
2999  buddy = ast_calloc(1, sizeof(*buddy));
3000  if (!buddy) {
3001  ast_log(LOG_WARNING, "Out of memory\n");
3003  return 0;
3004  }
3005  ASTOBJ_INIT(buddy);
3006  ASTOBJ_WRLOCK(buddy);
3007  ast_copy_string(buddy->name, iks_find_attrib(x, "jid"), sizeof(buddy->name));
3009  if (ast_test_flag(&client->flags, AJI_AUTOPRUNE)) {
3010  ast_set_flag(&buddy->flags, AJI_AUTOPRUNE);
3011  ASTOBJ_MARK(buddy);
3012  } else if (ast_test_flag(&client->flags, AJI_AUTOREGISTER)) {
3013  if (!iks_strcmp(iks_find_attrib(x, "subscription"), "none") || !iks_strcmp(iks_find_attrib(x, "subscription"), "from")) {
3014  /* subscribe to buddy's presence only
3015  if we really need to */
3017  }
3018  }
3019  ASTOBJ_UNLOCK(buddy);
3020  if (buddy) {
3021  ASTOBJ_CONTAINER_LINK(&client->buddies, buddy);
3023  }
3024  }
3025  x = iks_next(x);
3026  }
3027 
3028  iks_delete(x);
3029  aji_pruneregister(client);
3030 
3032  return IKS_FILTER_EAT;
3033 }
void ast_aji_buddy_destroy(struct aji_buddy *obj)
Definition: res_jabber.c:432
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define ASTOBJ_MARK(object)
Mark an ASTOBJ by adding the ASTOBJ_FLAG_MARKED flag to its objflags mask.
Definition: astobj.h:241
#define LOG_WARNING
Definition: logger.h:144
char name[3071]
Definition: jabber.h:135
enum aji_state state
Definition: jabber.h:170
#define ASTOBJ_WRLOCK(object)
Lock an ASTOBJ for writing.
Definition: astobj.h:104
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
struct ast_flags flags
Definition: jabber.h:182
struct aji_buddy_container buddies
Definition: jabber.h:184
#define ASTOBJ_INIT(object)
Initialize an object.
Definition: astobj.h:264
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
#define ASTOBJ_CONTAINER_LINK(container, newobj)
Add an object to a container.
Definition: astobj.h:776
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ASTOBJ_CONTAINER_TRAVERSE(container, continue, eval)
Iterate through the objects in a container.
Definition: astobj.h:376
#define ASTOBJ_UNLOCK(object)
Unlock a locked object.
Definition: astobj.h:109
#define AST_FLAGS_ALL
Definition: utils.h:196
#define ast_clear_flag(p, flag)
Definition: utils.h:77
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
#define ASTOBJ_RDLOCK(object)
Lock an ASTOBJ for reading.
Definition: astobj.h:100
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define ASTOBJ_REF(object)
Increment an object reference count.
Definition: astobj.h:201
struct ast_flags flags
Definition: jabber.h:139
static void aji_pruneregister(struct aji_client *client)
Definition: res_jabber.c:2899
static struct aji_resource* aji_find_resource ( struct aji_buddy buddy,
char *  name 
)
static

Definition at line 544 of file res_jabber.c.

References aji_resource::next, aji_resource::resource, and aji_buddy::resources.

Referenced by acf_jabberstatus_read(), aji_client_info_handler(), aji_dinfo_handler(), and aji_status_exec().

545 {
546  struct aji_resource *res = NULL;
547  if (!buddy || !name) {
548  return res;
549  }
550  res = buddy->resources;
551  while (res) {
552  if (!strcasecmp(res->resource, name)) {
553  break;
554  }
555  res = res->next;
556  }
557  return res;
558 }
char resource[AJI_MAX_RESJIDLEN]
Definition: jabber.h:119
struct aji_resource * next
Definition: jabber.h:123
static const char name[]
struct aji_resource * resources
Definition: jabber.h:137
static struct aji_version* aji_find_version ( char *  node,
char *  version,
ikspak *  pak 
)
static

Definition at line 472 of file res_jabber.c.

References ast_copy_string(), ast_free, ast_log(), ast_malloc, capabilities, aji_version::jingle, LOG_ERROR, aji_version::next, aji_capabilities::next, aji_capabilities::node, aji_version::parent, aji_version::version, and aji_capabilities::versions.

Referenced by aji_handle_presence().

473 {
474  struct aji_capabilities *list = NULL;
475  struct aji_version *res = NULL;
476 
477  list = capabilities;
478 
479  if (!node) {
480  node = pak->from->full;
481  }
482  if (!version) {
483  version = "none supplied.";
484  }
485  while (list) {
486  if (!strcasecmp(list->node, node)) {
487  res = list->versions;
488  while(res) {
489  if (!strcasecmp(res->version, version)) {
490  return res;
491  }
492  res = res->next;
493  }
494  /* Specified version not found. Let's add it to
495  this node in our capabilities list */
496  if (!res) {
497  res = ast_malloc(sizeof(*res));
498  if (!res) {
499  ast_log(LOG_ERROR, "Out of memory!\n");
500  return NULL;
501  }
502  res->jingle = 0;
503  res->parent = list;
504  ast_copy_string(res->version, version, sizeof(res->version));
505  res->next = list->versions;
506  list->versions = res;
507  return res;
508  }
509  }
510  list = list->next;
511  }
512  /* Specified node not found. Let's add it our capabilities list */
513  if (!list) {
514  list = ast_malloc(sizeof(*list));
515  if (!list) {
516  ast_log(LOG_ERROR, "Out of memory!\n");
517  return NULL;
518  }
519  res = ast_malloc(sizeof(*res));
520  if (!res) {
521  ast_log(LOG_ERROR, "Out of memory!\n");
522  ast_free(list);
523  return NULL;
524  }
525  ast_copy_string(list->node, node, sizeof(list->node));
526  ast_copy_string(res->version, version, sizeof(res->version));
527  res->jingle = 0;
528  res->parent = list;
529  res->next = NULL;
530  list->versions = res;
531  list->next = capabilities;
532  capabilities = list;
533  }
534  return res;
535 }
char version[50]
Definition: jabber.h:105
uint32_t version
struct aji_version * next
Definition: jabber.h:108
static struct aji_capabilities * capabilities
Definition: res_jabber.c:393
char node[200]
Definition: jabber.h:112
struct aji_capabilities * next
Definition: jabber.h:114
struct aji_version * versions
Definition: jabber.h:113
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define ast_malloc(a)
Definition: astmm.h:91
struct aji_capabilities * parent
Definition: jabber.h:107
int jingle
Definition: jabber.h:106
static int aji_get_roster ( struct aji_client client)
static

Definition at line 3067 of file res_jabber.c.

References aji_set_presence(), ast_aji_send(), aji_client::jid, aji_client::status, and aji_client::statusmessage.

Referenced by aji_client_connect(), and aji_reload().

3068 {
3069  iks *roster = NULL;
3070  roster = iks_make_iq(IKS_TYPE_GET, IKS_NS_ROSTER);
3071 
3072  if (roster) {
3073  iks_insert_attrib(roster, "id", "roster");
3074  aji_set_presence(client, NULL, client->jid->full, client->status, client->statusmessage);
3075  ast_aji_send(client, roster);
3076  }
3077 
3078  iks_delete(roster);
3079 
3080  return 1;
3081 }
char statusmessage[256]
Definition: jabber.h:156
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
static void aji_set_presence(struct aji_client *client, char *to, char *from, int level, char *desc)
Definition: res_jabber.c:3992
iksid * jid
Definition: jabber.h:160
enum ikshowtype status
Definition: jabber.h:189
static void aji_handle_iq ( struct aji_client client,
iks *  node 
)
static

Definition at line 2225 of file res_jabber.c.

Referenced by aji_act_hook().

2226 {
2227  /*Nothing to see here */
2228 }
static void aji_handle_message ( struct aji_client client,
ikspak *  pak 
)
static

Definition at line 2237 of file res_jabber.c.

References aji_message::arrived, ast_calloc, ast_cond_broadcast, ast_copy_string(), ast_debug, ast_free, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_strdup, ast_tvnow(), delete_old_messages(), aji_message::from, aji_message::id, aji_message::list, LOG_ERROR, aji_message::message, aji_client::messages, and aji_client::name.

Referenced by aji_act_hook().

2238 {
2239  struct aji_message *insert;
2240  int deleted = 0;
2241 
2242  ast_debug(3, "client %s received a message\n", client->name);
2243 
2244  if (!(insert = ast_calloc(1, sizeof(*insert)))) {
2245  return;
2246  }
2247 
2248  insert->arrived = ast_tvnow();
2249 
2250  /* wake up threads waiting for messages */
2254 
2255  if (iks_find_cdata(pak->x, "body")) {
2256  insert->message = ast_strdup(iks_find_cdata(pak->x, "body"));
2257  }
2258  if (pak->id) {
2259  ast_copy_string(insert->id, pak->id, sizeof(insert->id));
2260  }
2261  if (pak->from){
2262  /* insert will furtherly be added to message list */
2263  insert->from = ast_strdup(pak->from->full);
2264  if (!insert->from) {
2265  ast_free(insert);
2266  ast_log(LOG_ERROR, "Memory allocation failure\n");
2267  return;
2268  }
2269  ast_debug(3, "message comes from %s\n", insert->from);
2270  }
2271 
2272  /* remove old messages received from this JID
2273  * and insert received message */
2274  deleted = delete_old_messages(client, pak->from->partial);
2275  ast_debug(3, "Deleted %d messages for client %s from JID %s\n", deleted, client->name, pak->from->partial);
2276  AST_LIST_LOCK(&client->messages);
2277  AST_LIST_INSERT_HEAD(&client->messages, insert, list);
2278  AST_LIST_UNLOCK(&client->messages);
2279 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define ast_strdup(a)
Definition: astmm.h:109
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char id[25]
Definition: jabber.h:129
char * message
Definition: jabber.h:128
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define ast_mutex_lock(a)
Definition: lock.h:155
static ast_cond_t message_received_condition
Definition: res_jabber.c:396
char * from
Definition: jabber.h:127
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static int delete_old_messages(struct aji_client *client, char *from)
Definition: res_jabber.c:929
#define ast_cond_broadcast(cond)
Definition: lock.h:170
char name[80]
Definition: jabber.h:151
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:696
#define ast_free(a)
Definition: astmm.h:97
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct aji_message::@188 list
static ast_mutex_t messagelock
Definition: res_jabber.c:397
struct timeval arrived
Definition: jabber.h:130
struct aji_client::messages messages
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void aji_handle_presence ( struct aji_client client,
ikspak *  pak 
)
static

Definition at line 2287 of file res_jabber.c.

References AJI_CONNECTED, aji_create_buddy(), aji_find_version(), aji_set_presence(), ast_aji_buddy_destroy(), ast_aji_increment_mid(), ast_aji_send(), ast_calloc, ast_copy_string(), ast_debug, ast_free, ast_log(), ast_strdup, ast_verbose(), ASTOBJ_CONTAINER_FIND, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, aji_client::buddies, aji_client::component, aji_resource::description, EVENT_FLAG_USER, gtalk_yuck(), aji_client::jid, last, LOG_ERROR, LOG_NOTICE, manager_event, aji_client::mid, aji_client::name, aji_resource::next, aji_resource::priority, aji_resource::resource, aji_buddy::resources, S_OR, aji_client::state, aji_resource::status, status, aji_client::status, aji_client::statusmessage, and type.

Referenced by aji_act_hook().

2288 {
2289  int status, priority;
2290  struct aji_buddy *buddy;
2291  struct aji_resource *tmp = NULL, *last = NULL, *found = NULL;
2292  char *ver, *node, *descrip, *type;
2293 
2294  if (client->state != AJI_CONNECTED)
2295  aji_create_buddy(pak->from->partial, client);
2296 
2297  buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
2298  if (!buddy && pak->from->partial) {
2299  /* allow our jid to be used to log in with another resource */
2300  if (!strcmp((const char *)pak->from->partial, (const char *)client->jid->partial))
2301  aji_create_buddy(pak->from->partial, client);
2302  else
2303  ast_log(LOG_NOTICE, "Got presence packet from %s, someone not in our roster!!!!\n", pak->from->partial);
2304  return;
2305  }
2306  type = iks_find_attrib(pak->x, "type");
2307  if (client->component && type &&!strcasecmp("probe", type)) {
2308  aji_set_presence(client, pak->from->full, iks_find_attrib(pak->x, "to"), client->status, client->statusmessage);
2309  ast_verbose("what i was looking for \n");
2310  }
2311  ASTOBJ_WRLOCK(buddy);
2312  status = (pak->show) ? pak->show : 6;
2313  priority = atoi((iks_find_cdata(pak->x, "priority")) ? iks_find_cdata(pak->x, "priority") : "0");
2314  tmp = buddy->resources;
2315  descrip = ast_strdup(iks_find_cdata(pak->x, "status"));
2316 
2317  while (tmp && pak->from->resource) {
2318  if (!strcasecmp(tmp->resource, pak->from->resource)) {
2319  tmp->status = status;
2320  if (tmp->description) {
2321  ast_free(tmp->description);
2322  }
2323  tmp->description = descrip;
2324  found = tmp;
2325  if (status == 6) { /* Sign off Destroy resource */
2326  if (last && found->next) {
2327  last->next = found->next;
2328  } else if (!last) {
2329  if (found->next) {
2330  buddy->resources = found->next;
2331  } else {
2332  buddy->resources = NULL;
2333  }
2334  } else if (!found->next) {
2335  if (last) {
2336  last->next = NULL;
2337  } else {
2338  buddy->resources = NULL;
2339  }
2340  }
2341  ast_free(found);
2342  found = NULL;
2343  break;
2344  }
2345  /* resource list is sorted by descending priority */
2346  if (tmp->priority != priority) {
2347  found->priority = priority;
2348  if (!last && !found->next) {
2349  /* resource was found to be unique,
2350  leave loop */
2351  break;
2352  }
2353  /* search for resource in our list
2354  and take it out for the moment */
2355  if (last) {
2356  last->next = found->next;
2357  } else {
2358  buddy->resources = found->next;
2359  }
2360 
2361  last = NULL;
2362  tmp = buddy->resources;
2363  if (!buddy->resources) {
2364  buddy->resources = found;
2365  }
2366  /* priority processing */
2367  while (tmp) {
2368  /* insert resource back according to
2369  its priority value */
2370  if (found->priority > tmp->priority) {
2371  if (last) {
2372  /* insert within list */
2373  last->next = found;
2374  }
2375  found->next = tmp;
2376  if (!last) {
2377  /* insert on top */
2378  buddy->resources = found;
2379  }
2380  break;
2381  }
2382  if (!tmp->next) {
2383  /* insert at the end of the list */
2384  tmp->next = found;
2385  found->next = NULL;
2386  break;
2387  }
2388  last = tmp;
2389  tmp = tmp->next;
2390  }
2391  }
2392  break;
2393  }
2394  last = tmp;
2395  tmp = tmp->next;
2396  }
2397 
2398  /* resource not found in our list, create it */
2399  if (!found && status != 6 && pak->from->resource) {
2400  found = ast_calloc(1, sizeof(*found));
2401 
2402  if (!found) {
2403  ast_log(LOG_ERROR, "Out of memory!\n");
2404  ASTOBJ_UNLOCK(buddy);
2406  return;
2407  }
2408  ast_copy_string(found->resource, pak->from->resource, sizeof(found->resource));
2409  found->status = status;
2410  found->description = descrip;
2411  found->priority = priority;
2412  found->next = NULL;
2413  last = NULL;
2414  tmp = buddy->resources;
2415  while (tmp) {
2416  if (found->priority > tmp->priority) {
2417  if (last) {
2418  last->next = found;
2419  }
2420  found->next = tmp;
2421  if (!last) {
2422  buddy->resources = found;
2423  }
2424  break;
2425  }
2426  if (!tmp->next) {
2427  tmp->next = found;
2428  break;
2429  }
2430  last = tmp;
2431  tmp = tmp->next;
2432  }
2433  if (!tmp) {
2434  buddy->resources = found;
2435  }
2436  }
2437 
2438  ASTOBJ_UNLOCK(buddy);
2440 
2441  node = iks_find_attrib(iks_find(pak->x, "c"), "node");
2442  ver = iks_find_attrib(iks_find(pak->x, "c"), "ver");
2443 
2444  /* handle gmail client's special caps:c tag */
2445  if (!node && !ver) {
2446  node = iks_find_attrib(iks_find(pak->x, "caps:c"), "node");
2447  ver = iks_find_attrib(iks_find(pak->x, "caps:c"), "ver");
2448  }
2449 
2450  /* retrieve capabilites of the new resource */
2451  if (status != 6 && found && !found->cap) {
2452  found->cap = aji_find_version(node, ver, pak);
2453  if (gtalk_yuck(pak->x)) { /* gtalk should do discover */
2454  found->cap->jingle = 1;
2455  }
2456  if (found->cap->jingle) {
2457  ast_debug(1, "Special case for google till they support discover.\n");
2458  } else {
2459  iks *iq, *query;
2460  iq = iks_new("iq");
2461  query = iks_new("query");
2462  if (query && iq) {
2463  iks_insert_attrib(iq, "type", "get");
2464  iks_insert_attrib(iq, "to", pak->from->full);
2465  iks_insert_attrib(iq, "from", client->jid->full);
2466  iks_insert_attrib(iq, "id", client->mid);
2467  ast_aji_increment_mid(client->mid);
2468  iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info");
2469  iks_insert_node(iq, query);
2470  ast_aji_send(client, iq);
2471  } else {
2472  ast_log(LOG_ERROR, "Out of memory.\n");
2473  }
2474  iks_delete(query);
2475  iks_delete(iq);
2476  }
2477  }
2478  switch (pak->subtype) {
2479  case IKS_TYPE_AVAILABLE:
2480  ast_debug(3, "JABBER: I am available ^_* %u\n", pak->subtype);
2481  break;
2482  case IKS_TYPE_UNAVAILABLE:
2483  ast_debug(3, "JABBER: I am unavailable ^_* %u\n", pak->subtype);
2484  break;
2485  default:
2486  ast_debug(3, "JABBER: Ohh sexy and the wrong type: %u\n", pak->subtype);
2487  }
2488  switch (pak->show) {
2489  case IKS_SHOW_UNAVAILABLE:
2490  ast_debug(3, "JABBER: type: %u subtype %u\n", pak->subtype, pak->show);
2491  break;
2492  case IKS_SHOW_AVAILABLE:
2493  ast_debug(3, "JABBER: type is available\n");
2494  break;
2495  case IKS_SHOW_CHAT:
2496  ast_debug(3, "JABBER: type: %u subtype %u\n", pak->subtype, pak->show);
2497  break;
2498  case IKS_SHOW_AWAY:
2499  ast_debug(3, "JABBER: type is away\n");
2500  break;
2501  case IKS_SHOW_XA:
2502  ast_debug(3, "JABBER: type: %u subtype %u\n", pak->subtype, pak->show);
2503  break;
2504  case IKS_SHOW_DND:
2505  ast_debug(3, "JABBER: type: %u subtype %u\n", pak->subtype, pak->show);
2506  break;
2507  default:
2508  ast_debug(3, "JABBER: Kinky! how did that happen %u\n", pak->show);
2509  }
2510 
2511  if (found) {
2512  manager_event(EVENT_FLAG_USER, "JabberStatus",
2513  "Account: %s\r\nJID: %s\r\nResource: %s\r\nStatus: %d\r\nPriority: %d"
2514  "\r\nDescription: %s\r\n",
2515  client->name, pak->from->partial, found->resource, found->status,
2516  found->priority, S_OR(found->description, ""));
2517  } else {
2518  manager_event(EVENT_FLAG_USER, "JabberStatus",
2519  "Account: %s\r\nJID: %s\r\nStatus: %u\r\n",
2520  client->name, pak->from->partial, pak->show ? pak->show : IKS_SHOW_UNAVAILABLE);
2521  }
2522 }
int status
Definition: jabber.h:118
char * description
Definition: jabber.h:120
void ast_aji_buddy_destroy(struct aji_buddy *obj)
Definition: res_jabber.c:432
char statusmessage[256]
Definition: jabber.h:156
#define ast_strdup(a)
Definition: astmm.h:109
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
enum aji_state state
Definition: jabber.h:170
#define ASTOBJ_WRLOCK(object)
Lock an ASTOBJ for writing.
Definition: astobj.h:104
static void aji_set_presence(struct aji_client *client, char *to, char *from, int level, char *desc)
Definition: res_jabber.c:3992
int component
Definition: jabber.h:183
char resource[AJI_MAX_RESJIDLEN]
Definition: jabber.h:119
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct aji_buddy_container buddies
Definition: jabber.h:184
struct sla_ringing_trunk * last
Definition: app_meetme.c:965
struct aji_resource * next
Definition: jabber.h:123
char name[80]
Definition: jabber.h:151
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
#define LOG_ERROR
Definition: logger.h:155
iksid * jid
Definition: jabber.h:160
#define EVENT_FLAG_USER
Definition: manager.h:77
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
int priority
Definition: jabber.h:122
enum ikshowtype status
Definition: jabber.h:189
#define ASTOBJ_UNLOCK(object)
Unlock a locked object.
Definition: astobj.h:109
#define ast_free(a)
Definition: astmm.h:97
#define ASTOBJ_CONTAINER_FIND(container, namestr)
Find an object in a container.
Definition: astobj.h:401
static struct aji_version * aji_find_version(char *node, char *version, ikspak *pak)
Definition: res_jabber.c:472
static const char type[]
Definition: chan_nbs.c:57
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int aji_create_buddy(char *label, struct aji_client *client)
Definition: res_jabber.c:4490
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
static int gtalk_yuck(iks *node)
Definition: res_jabber.c:566
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:219
char mid[6]
Definition: jabber.h:159
struct aji_resource * resources
Definition: jabber.h:137
void ast_aji_increment_mid(char *mid)
increments the mid field for messages and other events.
Definition: res_jabber.c:2790
jack_status_t status
Definition: app_jack.c:143
static int aji_handle_pubsub_error ( void *  data,
ikspak *  pak 
)
static

Definition at line 3505 of file res_jabber.c.

References aji_create_pubsub_collection(), aji_create_pubsub_leaf(), aji_create_pubsub_node(), aji_pubsub_iq_create(), AJI_XEP0248, ast_aji_client_destroy(), ast_aji_send(), ast_debug, ast_log(), ast_test_flag, ASTOBJ_REF, ASTOBJ_UNREF, and LOG_ERROR.

Referenced by aji_init_event_distribution().

3506 {
3507  char *node_name;
3508  char *error;
3509  int error_num;
3510  iks *orig_request;
3511  iks *orig_pubsub = iks_find(pak->x, "pubsub");
3512  struct aji_client *client;
3513  if (!orig_pubsub) {
3514  ast_debug(1, "Error isn't a PubSub error, why are we here?\n");
3515  return IKS_FILTER_EAT;
3516  }
3517  orig_request = iks_child(orig_pubsub);
3518  error = iks_find_attrib(iks_find(pak->x, "error"), "code");
3519  node_name = iks_find_attrib(orig_request, "node");
3520  if (!sscanf(error, "%30d", &error_num)) {
3521  return IKS_FILTER_EAT;
3522  }
3523  if (error_num > 399 && error_num < 500 && error_num != 404) {
3525  "Error performing operation on PubSub node %s, %s.\n", node_name, error);
3526  return IKS_FILTER_EAT;
3527  } else if (error_num > 499 && error_num < 600) {
3528  ast_log(LOG_ERROR, "PubSub Server error, %s\n", error);
3529  return IKS_FILTER_EAT;
3530  }
3531 
3532  client = ASTOBJ_REF((struct aji_client *) data);
3533 
3534  if (!strcasecmp(iks_name(orig_request), "publish")) {
3535  iks *request;
3537  if (iks_find(iks_find(orig_request, "item"), "state")) {
3538  aji_create_pubsub_leaf(client, "device_state", node_name);
3539  } else if (iks_find(iks_find(orig_request, "item"), "mailbox")) {
3540  aji_create_pubsub_leaf(client, "message_waiting", node_name);
3541  }
3542  } else {
3543  aji_create_pubsub_node(client, NULL, node_name, NULL);
3544  }
3545  request = aji_pubsub_iq_create(client, "set");
3546  iks_insert_node(request, orig_pubsub);
3547  ast_aji_send(client, request);
3548  iks_delete(request);
3550  return IKS_FILTER_EAT;
3551  } else if (!strcasecmp(iks_name(orig_request), "subscribe")) {
3553  aji_create_pubsub_collection(client, node_name);
3554  } else {
3555  aji_create_pubsub_node(client, NULL, node_name, NULL);
3556  }
3557  }
3559  return IKS_FILTER_EAT;
3560 }
static iks * aji_pubsub_iq_create(struct aji_client *client, const char *type)
Create an IQ packet.
Definition: res_jabber.c:3493
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
#define ast_test_flag(p, flag)
Definition: utils.h:63
static struct ast_flags pubsubflags
PubSub flags, initialized to default values.
Definition: res_jabber.c:403
static iks * aji_create_pubsub_node(struct aji_client *client, const char *node_type, const char *name, const char *collection_name)
Create a pubsub node.
Definition: res_jabber.c:3838
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void aji_create_pubsub_collection(struct aji_client *client, const char *collection_name)
Create a PubSub collection node.
Definition: res_jabber.c:3812
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
#define ASTOBJ_REF(object)
Increment an object reference count.
Definition: astobj.h:201
static void aji_create_pubsub_leaf(struct aji_client *client, const char *collection_name, const char *leaf_name)
Create a PubSub leaf node.
Definition: res_jabber.c:3825
static int aji_handle_pubsub_event ( void *  data,
ikspak *  pak 
)
static

Callback for handling PubSub events.

Parameters
datavoid pointer to aji_client structure
Returns
IKS_FILTER_EAT

Definition at line 3264 of file res_jabber.c.

References AST_DEVSTATE_CACHABLE, ast_devstate_val(), ast_eid_cmp(), ast_eid_default, AST_EVENT_DEVICE_STATE_CHANGE, AST_EVENT_IE_CACHABLE, AST_EVENT_IE_CONTEXT, AST_EVENT_IE_DEVICE, AST_EVENT_IE_EID, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_RAW, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_IE_STATE, AST_EVENT_MWI, ast_event_new(), ast_event_queue(), ast_event_queue_and_cache(), ast_log(), ast_str_to_eid(), LOG_DEBUG, LOG_ERROR, mailbox, and strsep().

Referenced by aji_init_event_distribution().

3265 {
3266  char *item_id, *device_state, *mailbox, *cachable_str;
3267  int oldmsgs, newmsgs;
3268  iks *item, *item_content;
3269  struct ast_eid pubsub_eid;
3270  struct ast_event *event;
3271  unsigned int cachable = AST_DEVSTATE_CACHABLE;
3272 
3273  item = iks_find(iks_find(iks_find(pak->x, "event"), "items"), "item");
3274  if (!item) {
3275  ast_log(LOG_ERROR, "Could not parse incoming PubSub event\n");
3276  return IKS_FILTER_EAT;
3277  }
3278  item_id = iks_find_attrib(item, "id");
3279  item_content = iks_child(item);
3280  ast_str_to_eid(&pubsub_eid, iks_find_attrib(item_content, "eid"));
3281  if (!ast_eid_cmp(&ast_eid_default, &pubsub_eid)) {
3282  ast_log(LOG_DEBUG, "Returning here, eid of incoming event matches ours!\n");
3283  return IKS_FILTER_EAT;
3284  }
3285  if (!strcasecmp(iks_name(item_content), "state")) {
3286  if ((cachable_str = iks_find_attrib(item_content, "cachable"))) {
3287  sscanf(cachable_str, "%30u", &cachable);
3288  }
3289  device_state = iks_find_cdata(item, "state");
3293  AST_EVENT_IE_PLTYPE_RAW, &pubsub_eid, sizeof(pubsub_eid),
3295  AST_EVENT_IE_END))) {
3296  return IKS_FILTER_EAT;
3297  }
3298  } else if (!strcasecmp(iks_name(item_content), "mailbox")) {
3299  mailbox = strsep(&item_id, "@");
3300  sscanf(iks_find_cdata(item_content, "OLDMSGS"), "%10d", &oldmsgs);
3301  sscanf(iks_find_cdata(item_content, "NEWMSGS"), "%10d", &newmsgs);
3302  if (!(event = ast_event_new(AST_EVENT_MWI,
3307  AST_EVENT_IE_EID, AST_EVENT_IE_PLTYPE_RAW, &pubsub_eid, sizeof(pubsub_eid),
3308  AST_EVENT_IE_END))) {
3309  return IKS_FILTER_EAT;
3310  }
3311  } else {
3312  ast_log(LOG_DEBUG, "Don't know how to handle PubSub event of type %s\n",
3313  iks_name(item_content));
3314  return IKS_FILTER_EAT;
3315  }
3316 
3317  if (cachable == AST_DEVSTATE_CACHABLE) {
3319  } else {
3320  ast_event_queue(event);
3321  }
3322 
3323  return IKS_FILTER_EAT;
3324 }
An event.
Definition: event.c:85
char * strsep(char **str, const char *delims)
int ast_event_queue_and_cache(struct ast_event *event)
Queue and cache an event.
Definition: event.c:1465
Number of new messages Used by: AST_EVENT_MWI Payload type: UINT.
Definition: event_defs.h:71
Number of Used by: AST_EVENT_MWI Payload type: UINT.
Definition: event_defs.h:77
#define LOG_DEBUG
Definition: logger.h:122
An Entity ID is essentially a MAC address, brief and unique.
Definition: utils.h:808
Entity ID Used by All events Payload type: RAW This IE indicates which server the event originated fr...
Definition: event_defs.h:266
int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2)
Compare two EIDs.
Definition: netsock.c:320
int ast_event_queue(struct ast_event *event)
Queue an event.
Definition: event.c:1517
Context IE Used by AST_EVENT_MWI Payload type: str.
Definition: event_defs.h:121
enum ast_device_state ast_devstate_val(const char *val)
Convert device state from text to integer value.
Definition: devicestate.c:244
int ast_str_to_eid(struct ast_eid *eid, const char *s)
Convert a string into an EID.
Definition: netsock.c:305
Event non-cachability flag Used by: All events Payload type: UINT.
Definition: event_defs.h:291
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct ast_eid ast_eid_default
Global EID.
Definition: asterisk.c:192
struct ast_event * ast_event_new(enum ast_event_type event_type,...)
Create a new event.
Definition: event.c:1202
Generic State IE Used by AST_EVENT_DEVICE_STATE_CHANGE Payload type: UINT The actual state values dep...
Definition: event_defs.h:115
Device Name Used by AST_EVENT_DEVICE_STATE_CHANGE Payload type: STR.
Definition: event_defs.h:107
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
Mailbox name.
Definition: event_defs.h:83
static void aji_handle_subscribe ( struct aji_client client,
ikspak *  pak 
)
static

Definition at line 2531 of file res_jabber.c.

References AJI_AUTOACCEPT, aji_create_buddy(), aji_set_presence(), ast_aji_buddy_destroy(), ast_aji_send(), ast_log(), ast_test_flag, ast_verbose(), ASTOBJ_CONTAINER_FIND, ASTOBJ_UNREF, aji_client::buddies, aji_client::component, aji_client::flags, aji_client::jid, LOG_ERROR, option_verbose, status, aji_client::status, aji_client::statusmessage, and VERBOSE_PREFIX_3.

Referenced by aji_act_hook().

2532 {
2533  iks *presence = NULL, *status = NULL;
2534  struct aji_buddy* buddy = NULL;
2535 
2536  switch (pak->subtype) {
2537  case IKS_TYPE_SUBSCRIBE:
2538  if (ast_test_flag(&client->flags, AJI_AUTOACCEPT)) {
2539  presence = iks_new("presence");
2540  status = iks_new("status");
2541  if (presence && status) {
2542  iks_insert_attrib(presence, "type", "subscribed");
2543  iks_insert_attrib(presence, "to", pak->from->full);
2544  iks_insert_attrib(presence, "from", client->jid->full);
2545  if (pak->id)
2546  iks_insert_attrib(presence, "id", pak->id);
2547  iks_insert_cdata(status, "Asterisk has approved subscription", 0);
2548  iks_insert_node(presence, status);
2549  ast_aji_send(client, presence);
2550  } else {
2551  ast_log(LOG_ERROR, "Unable to allocate nodes\n");
2552  }
2553 
2554  iks_delete(presence);
2555  iks_delete(status);
2556  }
2557 
2558  if (client->component)
2559  aji_set_presence(client, pak->from->full, iks_find_attrib(pak->x, "to"), client->status, client->statusmessage);
2560  case IKS_TYPE_SUBSCRIBED:
2561  buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
2562  if (!buddy && pak->from->partial) {
2563  aji_create_buddy(pak->from->partial, client);
2564  } else if (buddy) {
2566  }
2567  default:
2568  if (option_verbose > 4) {
2569  ast_verbose(VERBOSE_PREFIX_3 "JABBER: This is a subcription of type %u\n", pak->subtype);
2570  }
2571  }
2572 }
void ast_aji_buddy_destroy(struct aji_buddy *obj)
Definition: res_jabber.c:432
char statusmessage[256]
Definition: jabber.h:156
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define VERBOSE_PREFIX_3
Definition: logger.h:43
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
int option_verbose
Definition: asterisk.c:181
struct ast_flags flags
Definition: jabber.h:182
static void aji_set_presence(struct aji_client *client, char *to, char *from, int level, char *desc)
Definition: res_jabber.c:3992
int component
Definition: jabber.h:183
struct aji_buddy_container buddies
Definition: jabber.h:184
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
#define LOG_ERROR
Definition: logger.h:155
iksid * jid
Definition: jabber.h:160
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
enum ikshowtype status
Definition: jabber.h:189
#define ASTOBJ_CONTAINER_FIND(container, namestr)
Find an object in a container.
Definition: astobj.h:401
static int aji_create_buddy(char *label, struct aji_client *client)
Definition: res_jabber.c:4490
jack_status_t status
Definition: app_jack.c:143
static void aji_init_event_distribution ( struct aji_client client)
static

Initialize collections for event distribution.

Parameters
clientthe configured XMPP client we use to connect to a XMPP server
Returns
void

Definition at line 3235 of file res_jabber.c.

References aji_devstate_cb(), aji_handle_pubsub_error(), aji_handle_pubsub_event(), aji_mwi_cb(), aji_pubsub_subscribe(), ast_enable_distributed_devstate(), AST_EVENT_DEVICE_STATE_CHANGE, ast_event_dump_cache(), AST_EVENT_IE_END, AST_EVENT_MWI, ast_event_subscribe(), aji_client::f, and aji_client::pubsub_node.

Referenced by aji_client_connect(), and aji_reload().

3236 {
3237  if (!mwi_sub) {
3238  mwi_sub = ast_event_subscribe(AST_EVENT_MWI, aji_mwi_cb, "aji_mwi_subscription",
3239  client, AST_EVENT_IE_END);
3240  }
3241  if (!device_state_sub) {
3243  return;
3244  }
3246  aji_devstate_cb, "aji_devstate_subscription", client, AST_EVENT_IE_END);
3248  }
3249 
3250  aji_pubsub_subscribe(client, "device_state");
3251  aji_pubsub_subscribe(client, "message_waiting");
3252  iks_filter_add_rule(client->f, aji_handle_pubsub_event, client, IKS_RULE_TYPE,
3253  IKS_PAK_MESSAGE, IKS_RULE_FROM, client->pubsub_node, IKS_RULE_DONE);
3254  iks_filter_add_rule(client->f, aji_handle_pubsub_error, client, IKS_RULE_TYPE,
3255  IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_ERROR, IKS_RULE_DONE);
3256 
3257 }
An MWI subscription.
int ast_enable_distributed_devstate(void)
Enable distributed device state processing.
Definition: devicestate.c:796
static void aji_pubsub_subscribe(struct aji_client *client, const char *node)
Subscribe to a PubSub node.
Definition: res_jabber.c:3357
static int aji_handle_pubsub_event(void *data, ikspak *pak)
Callback for handling PubSub events.
Definition: res_jabber.c:3264
void ast_event_dump_cache(const struct ast_event_sub *event_sub)
Dump the event cache for the subscriber.
Definition: event.c:654
static struct ast_event_sub * device_state_sub
Definition: res_jabber.c:395
char pubsub_node[AJI_MAX_RESJIDLEN]
Definition: jabber.h:155
static void aji_devstate_cb(const struct ast_event *ast_event, void *data)
Callback function for device state events.
Definition: res_jabber.c:3209
static void aji_mwi_cb(const struct ast_event *ast_event, void *data)
Callback function for MWI events.
Definition: res_jabber.c:3178
struct ast_event_sub * ast_event_subscribe(enum ast_event_type event_type, ast_event_cb_t cb, const char *description, void *userdata,...)
Subscribe to events.
Definition: event.c:909
static int aji_handle_pubsub_error(void *data, ikspak *pak)
Definition: res_jabber.c:3505
iksfilter * f
Definition: jabber.h:162
static int aji_initialize ( struct aji_client client)
static

Definition at line 3125 of file res_jabber.c.

References ast_log(), aji_client::component, connected, aji_client::jid, LOG_ERROR, aji_client::name, aji_client::p, aji_client::port, S_OR, aji_client::serverhost, aji_client::stream_flags, and aji_client::user.

Referenced by aji_reconnect().

3126 {
3127  int connected = IKS_NET_NOCONN;
3128 
3129 #ifdef HAVE_OPENSSL
3130  /* reset stream flags */
3131  client->stream_flags = 0;
3132 #endif
3133  /* If it's a component, connect to user, otherwise, connect to server */
3134  connected = iks_connect_via(client->p, S_OR(client->serverhost, client->jid->server), client->port, client->component ? client->user : client->jid->server);
3135 
3136  if (connected == IKS_NET_NOCONN) {
3137  ast_log(LOG_ERROR, "JABBER ERROR: No Connection\n");
3138  return IKS_HOOK;
3139  } else if (connected == IKS_NET_NODNS) {
3140  ast_log(LOG_ERROR, "JABBER ERROR: No DNS %s for client to %s\n", client->name,
3141  S_OR(client->serverhost, client->jid->server));
3142  return IKS_HOOK;
3143  }
3144 
3145  return IKS_OK;
3146 }
iksparser * p
Definition: jabber.h:161
char serverhost[AJI_MAX_RESJIDLEN]
Definition: jabber.h:154
int component
Definition: jabber.h:183
unsigned int stream_flags
Definition: jabber.h:168
int port
Definition: jabber.h:171
char name[80]
Definition: jabber.h:151
#define LOG_ERROR
Definition: logger.h:155
char user[AJI_MAX_JIDLEN]
Definition: jabber.h:153
iksid * jid
Definition: jabber.h:160
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
static int connected
Definition: cdr_pgsql.c:57
static int aji_io_recv ( struct aji_client client,
char *  buffer,
size_t  buf_len,
int  timeout 
)
static

Definition at line 1296 of file res_jabber.c.

References aji_is_secure(), ast_poll, len(), aji_client::p, and aji_client::ssl_session.

Referenced by aji_recv().

1297 {
1298  struct pollfd pfd = { .events = POLLIN };
1299  int len, res;
1300 
1301 #ifdef HAVE_OPENSSL
1302  if (aji_is_secure(client)) {
1303  pfd.fd = SSL_get_fd(client->ssl_session);
1304  if (pfd.fd < 0) {
1305  return -1;
1306  }
1307  } else
1308 #endif /* HAVE_OPENSSL */
1309  pfd.fd = iks_fd(client->p);
1310 
1311  res = ast_poll(&pfd, 1, timeout > 0 ? timeout * 1000 : -1);
1312  if (res > 0) {
1313 #ifdef HAVE_OPENSSL
1314  if (aji_is_secure(client)) {
1315  len = SSL_read(client->ssl_session, buffer, buf_len);
1316  } else
1317 #endif /* HAVE_OPENSSL */
1318  len = recv(pfd.fd, buffer, buf_len, 0);
1319 
1320  if (len > 0) {
1321  return len;
1322  } else if (len <= 0) {
1323  return -1;
1324  }
1325  }
1326  return res;
1327 }
iksparser * p
Definition: jabber.h:161
static int aji_is_secure(struct aji_client *client)
Definition: res_jabber.c:1203
#define ast_poll(a, b, c)
Definition: poll-compat.h:88
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
SSL * ssl_session
Definition: jabber.h:166
static int aji_is_secure ( struct aji_client client)
static

Definition at line 1203 of file res_jabber.c.

References aji_client::stream_flags.

Referenced by aji_act_hook(), aji_io_recv(), aji_send_raw(), and aji_start_sasl().

1204 {
1205 #ifdef HAVE_OPENSSL
1206  return client->stream_flags & SECURE;
1207 #else
1208  return 0;
1209 #endif
1210 }
unsigned int stream_flags
Definition: jabber.h:168
static int aji_join_exec ( struct ast_channel chan,
const char *  data 
)
static

Application to join a chat room.

Parameters
chanast_channel
dataData is sender|jid|nickname.
Return values
0success
-1error

Definition at line 988 of file res_jabber.c.

References AJI_MAX_RESJIDLEN, args, ast_aji_client_destroy(), ast_aji_get_client(), ast_aji_join_chat(), AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ASTOBJ_UNREF, aji_client::component, aji_client::jid, and LOG_ERROR.

Referenced by load_module().

989 {
990  struct aji_client *client = NULL;
991  char *s;
992  char nick[AJI_MAX_RESJIDLEN];
993 
995  AST_APP_ARG(sender);
996  AST_APP_ARG(jid);
997  AST_APP_ARG(nick);
998  );
999 
1000  if (!data) {
1001  ast_log(LOG_ERROR, "%s requires arguments (sender,jid[,nickname])\n", app_ajijoin);
1002  return -1;
1003  }
1004  s = ast_strdupa(data);
1005 
1007  if (args.argc < 2 || args.argc > 3) {
1008  ast_log(LOG_ERROR, "%s requires arguments (sender,jid[,nickname])\n", app_ajijoin);
1009  return -1;
1010  }
1011 
1012  if (strchr(args.jid, '/')) {
1013  ast_log(LOG_ERROR, "Invalid room name : resource must not be appended\n");
1014  return -1;
1015  }
1016 
1017  if (!(client = ast_aji_get_client(args.sender))) {
1018  ast_log(LOG_ERROR, "Could not find sender connection: '%s'\n", args.sender);
1019  return -1;
1020  }
1021 
1022  if (!ast_strlen_zero(args.nick)) {
1023  snprintf(nick, AJI_MAX_RESJIDLEN, "%s", args.nick);
1024  } else {
1025  if (client->component) {
1026  sprintf(nick, "asterisk");
1027  } else {
1028  snprintf(nick, AJI_MAX_RESJIDLEN, "%s", client->jid->user);
1029  }
1030  }
1031 
1032  if (!ast_strlen_zero(args.jid) && strchr(args.jid, '@')) {
1033  ast_aji_join_chat(client, args.jid, nick);
1034  } else {
1035  ast_log(LOG_ERROR, "Problem with specified jid of '%s'\n", args.jid);
1036  }
1037 
1039  return 0;
1040 }
static char * app_ajijoin
Definition: res_jabber.c:389
#define AJI_MAX_RESJIDLEN
Definition: jabber.h:74
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
int ast_aji_join_chat(struct aji_client *client, char *room, char *nick)
join a chatroom.
Definition: res_jabber.c:2674
int component
Definition: jabber.h:183
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
static struct @350 args
iksid * jid
Definition: jabber.h:160
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct aji_client * ast_aji_get_client(const char *name)
grab a aji_client structure by label name or JID. Bumps the refcount. (without the resource string) ...
Definition: res_jabber.c:4575
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
static int aji_leave_exec ( struct ast_channel chan,
const char *  data 
)
static

Application to leave a chat room.

Parameters
chanast_channel
dataData is sender|jid|nickname.
Return values
0success
-1error

Definition at line 1049 of file res_jabber.c.

References AJI_MAX_RESJIDLEN, args, ast_aji_client_destroy(), ast_aji_get_client(), ast_aji_leave_chat(), AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ASTOBJ_UNREF, aji_client::component, aji_client::jid, and LOG_ERROR.

Referenced by load_module().

1050 {
1051  struct aji_client *client = NULL;
1052  char *s;
1053  char nick[AJI_MAX_RESJIDLEN];
1055  AST_APP_ARG(sender);
1056  AST_APP_ARG(jid);
1057  AST_APP_ARG(nick);
1058  );
1059 
1060  if (!data) {
1061  ast_log(LOG_ERROR, "%s requires arguments (sender,jid[,nickname])\n", app_ajileave);
1062  return -1;
1063  }
1064  s = ast_strdupa(data);
1065 
1067  if (args.argc < 2 || args.argc > 3) {
1068  ast_log(LOG_ERROR, "%s requires arguments (sender,jid[,nickname])\n", app_ajileave);
1069  return -1;
1070  }
1071 
1072  if (strchr(args.jid, '/')) {
1073  ast_log(LOG_ERROR, "Invalid room name, resource must not be appended\n");
1074  return -1;
1075  }
1076 
1077  if (!(client = ast_aji_get_client(args.sender))) {
1078  ast_log(LOG_ERROR, "Could not find sender connection: '%s'\n", args.sender);
1079  return -1;
1080  }
1081 
1082  if (!ast_strlen_zero(args.nick)) {
1083  snprintf(nick, AJI_MAX_RESJIDLEN, "%s", args.nick);
1084  } else {
1085  if (client->component) {
1086  sprintf(nick, "asterisk");
1087  } else {
1088  snprintf(nick, AJI_MAX_RESJIDLEN, "%s", client->jid->user);
1089  }
1090  }
1091 
1092  if (!ast_strlen_zero(args.jid) && strchr(args.jid, '@')) {
1093  ast_aji_leave_chat(client, args.jid, nick);
1094  }
1096  return 0;
1097 }
#define AJI_MAX_RESJIDLEN
Definition: jabber.h:74
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
static char * app_ajileave
Definition: res_jabber.c:390
int component
Definition: jabber.h:183
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
static struct @350 args
int ast_aji_leave_chat(struct aji_client *client, char *room, char *nick)
leave a chatroom.
Definition: res_jabber.c:2686
iksid * jid
Definition: jabber.h:160
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct aji_client * ast_aji_get_client(const char *name)
grab a aji_client structure by label name or JID. Bumps the refcount. (without the resource string) ...
Definition: res_jabber.c:4575
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
static int aji_load_config ( int  reload)
static

Definition at line 4517 of file res_jabber.c.

References AJI_AUTOACCEPT, AJI_AUTOPRUNE, AJI_AUTOREGISTER, aji_create_client(), AJI_PUBSUB_AUTOCREATE, AJI_XEP0248, ast_category_browse(), ast_clear_flag, ast_config_destroy(), ast_config_load, ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), ast_variable_browse(), ast_variable_retrieve(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, JABBER_CONFIG, LOG_WARNING, ast_variable::name, ast_variable::next, ast_variable::value, and var.

Referenced by aji_reload().

4518 {
4519  char *cat = NULL;
4520  int debug = 0;
4521  struct ast_config *cfg = NULL;
4522  struct ast_variable *var = NULL;
4523  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
4524 
4525  if ((cfg = ast_config_load(JABBER_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
4526  return -1;
4527  }
4528 
4529  /* Reset flags to default value */
4531 
4533  ast_log(LOG_WARNING, "No such configuration file %s\n", JABBER_CONFIG);
4534  return 0;
4535  }
4536 
4537  cat = ast_category_browse(cfg, NULL);
4538  for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
4539  if (!strcasecmp(var->name, "debug")) {
4540  debug = (ast_false(ast_variable_retrieve(cfg, "general", "debug"))) ? 0 : 1;
4541  } else if (!strcasecmp(var->name, "autoprune")) {
4543  } else if (!strcasecmp(var->name, "autoregister")) {
4545  } else if (!strcasecmp(var->name, "collection_nodes")) {
4547  } else if (!strcasecmp(var->name, "pubsub_autocreate")) {
4549  } else if (!strcasecmp(var->name, "auth_policy")) {
4550  if (!strcasecmp(var->value, "accept")) {
4552  } else {
4554  }
4555  }
4556  }
4557 
4558  while (cat) {
4559  if (strcasecmp(cat, "general")) {
4560  var = ast_variable_browse(cfg, cat);
4561  aji_create_client(cat, var, debug);
4562  }
4563  cat = ast_category_browse(cfg, cat);
4564  }
4565  ast_config_destroy(cfg); /* or leak memory */
4566  return 1;
4567 }
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
#define JABBER_CONFIG
Definition: res_jabber.c:285
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:144
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
static struct ast_flags globalflags
Global flags, initialized to default values.
Definition: res_jabber.c:400
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
static struct ast_flags pubsubflags
PubSub flags, initialized to default values.
Definition: res_jabber.c:403
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
static int reload(void)
Definition: res_jabber.c:4753
#define CONFIG_STATUS_FILEMISSING
Definition: config.h:50
static int aji_create_client(char *label, struct ast_variable *var, int debug)
Definition: res_jabber.c:4236
const char * value
Definition: config.h:79
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
Definition: config.c:810
const char * name
Definition: config.h:77
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int debug
Definition: jabber.h:172
Structure used to handle boolean flags.
Definition: utils.h:200
#define ast_clear_flag(p, flag)
Definition: utils.h:77
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is &quot;false&quot;...
Definition: utils.c:1550
struct ast_variable * next
Definition: config.h:82
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
#define CONFIG_STATUS_FILEUNCHANGED
Definition: config.h:51
static void aji_log_hook ( void *  data,
const char *  xmpp,
size_t  size,
int  is_incoming 
)
static

Definition at line 1487 of file res_jabber.c.

References ast_aji_client_destroy(), ast_strlen_zero(), ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, aji_client::debug, EVENT_FLAG_USER, manager_event, aji_client::name, and option_debug.

Referenced by aji_create_client(), aji_recv(), and aji_send_raw().

1488 {
1489  struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
1490 
1491  if (!ast_strlen_zero(xmpp)) {
1492  manager_event(EVENT_FLAG_USER, "JabberEvent", "Account: %s\r\nPacket: %s\r\n", client->name, xmpp);
1493  }
1494 
1495  if (client->debug) {
1496  if (is_incoming) {
1497  ast_verbose("\nJABBER: %s INCOMING: %s\n", client->name, xmpp);
1498  } else {
1499  if (strlen(xmpp) == 1) {
1500  if (option_debug > 2 && xmpp[0] == ' ') {
1501  ast_verbose("\nJABBER: Keep alive packet\n");
1502  }
1503  } else {
1504  ast_verbose("\nJABBER: %s OUTGOING: %s\n", client->name, xmpp);
1505  }
1506  }
1507 
1508  }
1510 }
int option_debug
Definition: asterisk.c:182
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char name[80]
Definition: jabber.h:151
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
#define EVENT_FLAG_USER
Definition: manager.h:77
int debug
Definition: jabber.h:172
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:219
#define ASTOBJ_REF(object)
Increment an object reference count.
Definition: astobj.h:201
static void aji_message_destroy ( struct aji_message obj)
static

Definition at line 451 of file res_jabber.c.

References ast_free, aji_message::from, and aji_message::message.

Referenced by acf_jabberreceive_read(), ast_aji_client_destroy(), and delete_old_messages().

452 {
453  if (obj->from) {
454  ast_free(obj->from);
455  }
456  if (obj->message) {
457  ast_free(obj->message);
458  }
459  ast_free(obj);
460 }
char * message
Definition: jabber.h:128
char * from
Definition: jabber.h:127
#define ast_free(a)
Definition: astmm.h:97
static void aji_mwi_cb ( const struct ast_event ast_event,
void *  data 
)
static

Callback function for MWI events.

Parameters
ast_event
datavoid pointer to ast_client structure
Returns
void

Definition at line 3178 of file res_jabber.c.

References aji_publish_mwi(), ast_aji_client_destroy(), ast_eid_cmp(), ast_eid_default, ast_event_get_ie_raw(), ast_event_get_ie_str(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_EID, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, ast_log(), ASTOBJ_REF, ASTOBJ_UNREF, context, LOG_DEBUG, and mailbox.

Referenced by aji_init_event_distribution().

3179 {
3180  const char *mailbox;
3181  const char *context;
3182  char oldmsgs[10];
3183  char newmsgs[10];
3184  struct aji_client *client;
3186  {
3187  /* If the event didn't originate from this server, don't send it back out. */
3188  ast_log(LOG_DEBUG, "Returning here\n");
3189  return;
3190  }
3191 
3192  client = ASTOBJ_REF((struct aji_client *) data);
3193  mailbox = ast_event_get_ie_str(ast_event, AST_EVENT_IE_MAILBOX);
3194  context = ast_event_get_ie_str(ast_event, AST_EVENT_IE_CONTEXT);
3195  snprintf(oldmsgs, sizeof(oldmsgs), "%u",
3197  snprintf(newmsgs, sizeof(newmsgs), "%u",
3199  aji_publish_mwi(client, mailbox, context, oldmsgs, newmsgs);
3201 
3202 }
Number of new messages Used by: AST_EVENT_MWI Payload type: UINT.
Definition: event_defs.h:71
Number of Used by: AST_EVENT_MWI Payload type: UINT.
Definition: event_defs.h:77
#define LOG_DEBUG
Definition: logger.h:122
Entity ID Used by All events Payload type: RAW This IE indicates which server the event originated fr...
Definition: event_defs.h:266
int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2)
Compare two EIDs.
Definition: netsock.c:320
Context IE Used by AST_EVENT_MWI Payload type: str.
Definition: event_defs.h:121
const void * ast_event_get_ie_raw(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has a raw payload.
Definition: event.c:1111
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has an integer payload.
Definition: event.c:1075
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
struct ast_eid ast_eid_default
Global EID.
Definition: asterisk.c:192
static void aji_publish_mwi(struct aji_client *client, const char *mailbox, const char *context, const char *oldmsgs, const char *newmsgs)
Publish MWI to a PubSub node.
Definition: res_jabber.c:3469
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
const char * ast_event_get_ie_str(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has a string payload.
Definition: event.c:1102
#define ASTOBJ_REF(object)
Increment an object reference count.
Definition: astobj.h:201
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
Mailbox name.
Definition: event_defs.h:83
static void aji_pruneregister ( struct aji_client client)
static

Definition at line 2899 of file res_jabber.c.

References AJI_AUTOPRUNE, ast_aji_send(), ast_log(), ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, aji_client::buddies, aji_client::jid, and LOG_ERROR.

2900 {
2901  iks *removeiq = iks_new("iq");
2902  iks *removequery = iks_new("query");
2903  iks *removeitem = iks_new("item");
2904  iks *send = iks_make_iq(IKS_TYPE_GET, "http://jabber.org/protocol/disco#items");
2905  if (!client || !removeiq || !removequery || !removeitem || !send) {
2906  ast_log(LOG_ERROR, "Out of memory.\n");
2907  goto safeout;
2908  }
2909 
2910  iks_insert_node(removeiq, removequery);
2911  iks_insert_node(removequery, removeitem);
2912  ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, {
2913  ASTOBJ_RDLOCK(iterator);
2914  /* For an aji_buddy, both AUTOPRUNE and AUTOREGISTER will never
2915  * be called at the same time */
2916  if (ast_test_flag(&iterator->flags, AJI_AUTOPRUNE)) { /* If autoprune is set on jabber.conf */
2917  ast_aji_send(client, iks_make_s10n(IKS_TYPE_UNSUBSCRIBE, iterator->name,
2918  "GoodBye. Your status is no longer needed by Asterisk the Open Source PBX"
2919  " so I am no longer subscribing to your presence.\n"));
2920  ast_aji_send(client, iks_make_s10n(IKS_TYPE_UNSUBSCRIBED, iterator->name,
2921  "GoodBye. You are no longer in the Asterisk config file so I am removing"
2922  " your access to my presence.\n"));
2923  iks_insert_attrib(removeiq, "from", client->jid->full);
2924  iks_insert_attrib(removeiq, "type", "set");
2925  iks_insert_attrib(removequery, "xmlns", "jabber:iq:roster");
2926  iks_insert_attrib(removeitem, "jid", iterator->name);
2927  iks_insert_attrib(removeitem, "subscription", "remove");
2928  ast_aji_send(client, removeiq);
2929  } else if (ast_test_flag(&iterator->flags, AJI_AUTOREGISTER)) {
2930  ast_aji_send(client, iks_make_s10n(IKS_TYPE_SUBSCRIBE, iterator->name,
2931  "Greetings! I am the Asterisk Open Source PBX and I want to subscribe to your presence\n"));
2932  ast_clear_flag(&iterator->flags, AJI_AUTOREGISTER);
2933  }
2934  ASTOBJ_UNLOCK(iterator);
2935  });
2936 
2937  safeout:
2938  iks_delete(removeiq);
2939  iks_delete(removequery);
2940  iks_delete(removeitem);
2941  iks_delete(send);
2942 
2944 }
void ast_aji_buddy_destroy(struct aji_buddy *obj)
Definition: res_jabber.c:432
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct aji_buddy_container buddies
Definition: jabber.h:184
#define LOG_ERROR
Definition: logger.h:155
iksid * jid
Definition: jabber.h:160
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ASTOBJ_CONTAINER_TRAVERSE(container, continue, eval)
Iterate through the objects in a container.
Definition: astobj.h:376
#define ASTOBJ_UNLOCK(object)
Unlock a locked object.
Definition: astobj.h:109
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define ASTOBJ_RDLOCK(object)
Lock an ASTOBJ for reading.
Definition: astobj.h:100
#define ASTOBJ_CONTAINER_PRUNE_MARKED(container, destructor)
Prune marked objects from a container.
Definition: astobj.h:651
static void aji_publish_device_state ( struct aji_client client,
const char *  device,
const char *  device_state,
unsigned int  cachable 
)
static

Publish device state to a PubSub node.

Parameters
clientthe configured XMPP client we use to connect to a XMPP server
devicethe name of the device whose state to publish
device_statethe state to publish
Returns
void

Definition at line 3438 of file res_jabber.c.

References aji_build_publish_skeleton(), aji_create_pubsub_node(), AJI_PUBSUB_AUTOCREATE, AJI_XEP0248, ast_aji_send(), ast_eid_default, ast_eid_to_str(), ast_test_flag, and state.

Referenced by aji_devstate_cb().

3440 {
3441  iks *request = aji_build_publish_skeleton(client, device, "device_state", cachable);
3442  iks *state;
3443  char eid_str[20], cachable_str[2];
3446  aji_create_pubsub_node(client, "leaf", device, "device_state");
3447  } else {
3448  aji_create_pubsub_node(client, NULL, device, NULL);
3449  }
3450  }
3451  ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
3452  state = iks_insert(request, "state");
3453  iks_insert_attrib(state, "xmlns", "http://asterisk.org");
3454  iks_insert_attrib(state, "eid", eid_str);
3455  snprintf(cachable_str, sizeof(cachable_str), "%u", cachable);
3456  iks_insert_attrib(state, "cachable", cachable_str);
3457  iks_insert_cdata(state, device_state, strlen(device_state));
3458  ast_aji_send(client, iks_root(request));
3459  iks_delete(request);
3460 }
enum sip_cc_notify_state state
Definition: chan_sip.c:842
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
char * ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
Definition: netsock.c:222
#define ast_test_flag(p, flag)
Definition: utils.h:63
static struct ast_flags pubsubflags
PubSub flags, initialized to default values.
Definition: res_jabber.c:403
static iks * aji_create_pubsub_node(struct aji_client *client, const char *node_type, const char *name, const char *collection_name)
Create a pubsub node.
Definition: res_jabber.c:3838
static iks * aji_build_publish_skeleton(struct aji_client *client, const char *node, const char *event_type, unsigned int cachable)
Build the skeleton of a publish.
Definition: res_jabber.c:3396
struct ast_eid ast_eid_default
Global EID.
Definition: asterisk.c:192
static void aji_publish_mwi ( struct aji_client client,
const char *  mailbox,
const char *  context,
const char *  oldmsgs,
const char *  newmsgs 
)
static

Publish MWI to a PubSub node.

Parameters
clientthe configured XMPP client we use to connect to a XMPP server
devicethe name of the device whose state to publish
device_statethe state to publish
Returns
void

Definition at line 3469 of file res_jabber.c.

References aji_build_publish_skeleton(), ast_aji_send(), ast_eid_default, ast_eid_to_str(), AST_MAX_CONTEXT, and AST_MAX_EXTENSION.

Referenced by aji_mwi_cb().

3471 {
3472  char full_mailbox[AST_MAX_EXTENSION+AST_MAX_CONTEXT];
3473  char eid_str[20];
3474  iks *mailbox_node, *request;
3475  snprintf(full_mailbox, sizeof(full_mailbox), "%s@%s", mailbox, context);
3476  request = aji_build_publish_skeleton(client, full_mailbox, "message_waiting", 1);
3477  ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
3478  mailbox_node = iks_insert(request, "mailbox");
3479  iks_insert_attrib(mailbox_node, "xmlns", "http://asterisk.org");
3480  iks_insert_attrib(mailbox_node, "eid", eid_str);
3481  iks_insert_cdata(iks_insert(mailbox_node, "NEWMSGS"), newmsgs, strlen(newmsgs));
3482  iks_insert_cdata(iks_insert(mailbox_node, "OLDMSGS"), oldmsgs, strlen(oldmsgs));
3483  ast_aji_send(client, iks_root(request));
3484  iks_delete(request);
3485 }
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
char * ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
Definition: netsock.c:222
#define AST_MAX_EXTENSION
Definition: channel.h:135
static iks * aji_build_publish_skeleton(struct aji_client *client, const char *node, const char *event_type, unsigned int cachable)
Build the skeleton of a publish.
Definition: res_jabber.c:3396
#define AST_MAX_CONTEXT
Definition: channel.h:136
struct ast_eid ast_eid_default
Global EID.
Definition: asterisk.c:192
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
static iks * aji_pubsub_iq_create ( struct aji_client client,
const char *  type 
)
static

Create an IQ packet.

Parameters
clientthe configured XMPP client we use to connect to a XMPP server
typethe type of IQ packet to create
Returns
iks*

Definition at line 3493 of file res_jabber.c.

References ast_aji_increment_mid(), aji_client::jid, aji_client::mid, and aji_client::pubsub_node.

Referenced by aji_build_node_request(), aji_build_publish_skeleton(), aji_create_affiliations(), aji_create_pubsub_node(), aji_delete_pubsub_node(), aji_handle_pubsub_error(), and aji_pubsub_subscribe().

3494 {
3495  iks *request = iks_new("iq");
3496 
3497  iks_insert_attrib(request, "to", client->pubsub_node);
3498  iks_insert_attrib(request, "from", client->jid->full);
3499  iks_insert_attrib(request, "type", type);
3500  ast_aji_increment_mid(client->mid);
3501  iks_insert_attrib(request, "id", client->mid);
3502  return request;
3503 }
iksid * jid
Definition: jabber.h:160
static const char type[]
Definition: chan_nbs.c:57
char pubsub_node[AJI_MAX_RESJIDLEN]
Definition: jabber.h:155
char mid[6]
Definition: jabber.h:159
void ast_aji_increment_mid(char *mid)
increments the mid field for messages and other events.
Definition: res_jabber.c:2790
static void aji_pubsub_purge_nodes ( struct aji_client client,
const char *  collection_name 
)
static

Definition at line 3713 of file res_jabber.c.

References aji_build_node_request(), aji_delete_node_list(), ast_aji_send(), aji_client::f, and aji_client::mid.

Referenced by aji_cli_purge_pubsub_nodes().

3714 {
3715  iks *request = aji_build_node_request(client, collection_name);
3716  ast_aji_send(client, request);
3717  iks_filter_add_rule(client->f, aji_delete_node_list, client, IKS_RULE_TYPE,
3718  IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID, client->mid,
3719  IKS_RULE_DONE);
3720  ast_aji_send(client, request);
3721  iks_delete(request);
3722 }
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
static iks * aji_build_node_request(struct aji_client *client, const char *collection)
Build the a node request.
Definition: res_jabber.c:3586
static int aji_delete_node_list(void *data, ikspak *pak)
Delete pubsub item lists.
Definition: res_jabber.c:3730
char mid[6]
Definition: jabber.h:159
iksfilter * f
Definition: jabber.h:162
static void aji_pubsub_subscribe ( struct aji_client client,
const char *  node 
)
static

Subscribe to a PubSub node.

Parameters
clientthe configured XMPP client we use to connect to a XMPP server
nodethe name of the node to which to subscribe
Returns
void

Definition at line 3357 of file res_jabber.c.

References aji_pubsub_iq_create(), AJI_XEP0248, ast_aji_send(), ast_test_flag, and aji_client::jid.

Referenced by aji_init_event_distribution().

3358 {
3359  iks *request = aji_pubsub_iq_create(client, "set");
3360  iks *pubsub, *subscribe;
3361 
3362  pubsub = iks_insert(request, "pubsub");
3363  iks_insert_attrib(pubsub, "xmlns", "http://jabber.org/protocol/pubsub");
3364  subscribe = iks_insert(pubsub, "subscribe");
3365  iks_insert_attrib(subscribe, "jid", client->jid->partial);
3366  iks_insert_attrib(subscribe, "node", node);
3368  iks *options, *x, *sub_options, *sub_type, *sub_depth;
3369  options = iks_insert(pubsub, "options");
3370  x = iks_insert(options, "x");
3371  iks_insert_attrib(x, "xmlns", "jabber:x:data");
3372  iks_insert_attrib(x, "type", "submit");
3373  sub_options = iks_insert(x, "field");
3374  iks_insert_attrib(sub_options, "var", "FORM_TYPE");
3375  iks_insert_attrib(sub_options, "type", "hidden");
3376  iks_insert_cdata(iks_insert(sub_options, "value"),
3377  "http://jabber.org/protocol/pubsub#subscribe_options", 51);
3378  sub_type = iks_insert(x, "field");
3379  iks_insert_attrib(sub_type, "var", "pubsub#subscription_type");
3380  iks_insert_cdata(iks_insert(sub_type, "value"), "items", 5);
3381  sub_depth = iks_insert(x, "field");
3382  iks_insert_attrib(sub_type, "var", "pubsub#subscription_depth");
3383  iks_insert_cdata(iks_insert(sub_depth, "value"), "all", 3);
3384  }
3385  ast_aji_send(client, request);
3386  iks_delete(request);
3387 }
static iks * aji_pubsub_iq_create(struct aji_client *client, const char *type)
Create an IQ packet.
Definition: res_jabber.c:3493
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
#define ast_test_flag(p, flag)
Definition: utils.h:63
static struct ast_flags globalflags
Global flags, initialized to default values.
Definition: res_jabber.c:400
iksid * jid
Definition: jabber.h:160
static int aji_receive_node_list ( void *  data,
ikspak *  pak 
)
static

Receive pubsub item lists.

Parameters
datapointer to aji_client structure
pakresponse from pubsub diso::items query
Returns
IKS_FILTER_EAT

Definition at line 3604 of file res_jabber.c.

References ast_aji_client_destroy(), ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, aji_client::jid, and aji_client::name.

Referenced by aji_request_pubsub_nodes().

3605 {
3606 
3607  struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
3608  iks *item = NULL;
3609  if (iks_has_children(pak->query)) {
3610  item = iks_first_tag(pak->query);
3611  ast_verbose("Connection %s: %s\nNode name: %s\n", client->name, client->jid->partial,
3612  iks_find_attrib(item, "node"));
3613  while ((item = iks_next_tag(item))) {
3614  ast_verbose("Node name: %s\n", iks_find_attrib(item, "node"));
3615  }
3616  }
3617  if (item) {
3618  iks_delete(item);
3619  }
3621  return IKS_FILTER_EAT;
3622 }
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
char name[80]
Definition: jabber.h:151
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
iksid * jid
Definition: jabber.h:160
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
#define ASTOBJ_REF(object)
Increment an object reference count.
Definition: astobj.h:201
static int aji_reconnect ( struct aji_client client)
static

Definition at line 3041 of file res_jabber.c.

References AJI_DISCONNECTED, aji_initialize(), aji_client::authorized, aji_client::p, aji_client::state, and aji_client::timeout.

Referenced by aji_recv_loop().

3042 {
3043  int res = 0;
3044 
3045  if (client->state) {
3046  client->state = AJI_DISCONNECTED;
3047  }
3048  client->timeout = 50;
3049  if (client->p) {
3050  iks_parser_reset(client->p);
3051  }
3052  if (client->authorized) {
3053  client->authorized = 0;
3054  }
3055 
3056  res = aji_initialize(client);
3057 
3058  return res;
3059 }
static int aji_initialize(struct aji_client *client)
Definition: res_jabber.c:3125
int authorized
Definition: jabber.h:180
enum aji_state state
Definition: jabber.h:170
iksparser * p
Definition: jabber.h:161
int timeout
Definition: jabber.h:178
static int aji_recv ( struct aji_client client,
int  timeout 
)
static

Definition at line 1341 of file res_jabber.c.

References aji_io_recv(), aji_log_hook(), ast_debug, ast_log(), IKS_NET_EXPIRED, len(), LOG_WARNING, NET_IO_BUF_SIZE, and aji_client::p.

Referenced by aji_act_hook(), and aji_recv_loop().

1342 {
1343  int len, ret;
1344  char buf[NET_IO_BUF_SIZE - 1];
1345  char newbuf[NET_IO_BUF_SIZE - 1];
1346  int pos = 0;
1347  int newbufpos = 0;
1348  unsigned char c;
1349 
1350  memset(buf, 0, sizeof(buf));
1351  memset(newbuf, 0, sizeof(newbuf));
1352 
1353  while (1) {
1354  len = aji_io_recv(client, buf, NET_IO_BUF_SIZE - 2, timeout);
1355  if (len < 0) return IKS_NET_RWERR;
1356  if (len == 0) return IKS_NET_EXPIRED;
1357  buf[len] = '\0';
1358 
1359  /* our iksemel parser won't work as expected if we feed
1360  it with XML packets that contain multiple whitespace
1361  characters between tags */
1362  while (pos < len) {
1363  c = buf[pos];
1364  /* if we stumble on the ending tag character,
1365  we skip any whitespace that follows it*/
1366  if (c == '>') {
1367  while (isspace(buf[pos+1])) {
1368  pos++;
1369  }
1370  }
1371  newbuf[newbufpos] = c;
1372  newbufpos ++;
1373  pos++;
1374  }
1375  pos = 0;
1376  newbufpos = 0;
1377 
1378  /* Log the message here, because iksemel's logHook is
1379  unaccessible */
1380  aji_log_hook(client, buf, len, 1);
1381 
1382  /* let iksemel deal with the string length,
1383  and reset our buffer */
1384  ret = iks_parse(client->p, newbuf, 0, 0);
1385  memset(newbuf, 0, sizeof(newbuf));
1386 
1387  switch (ret) {
1388  case IKS_NOMEM:
1389  ast_log(LOG_WARNING, "Parsing failure: Out of memory.\n");
1390  break;
1391  case IKS_BADXML:
1392  ast_log(LOG_WARNING, "Parsing failure: Invalid XML.\n");
1393  break;
1394  case IKS_HOOK:
1395  ast_log(LOG_WARNING, "Parsing failure: Hook returned an error.\n");
1396  break;
1397  }
1398  if (ret != IKS_OK) {
1399  return ret;
1400  }
1401  ast_debug(3, "XML parsing successful\n");
1402  }
1403  return IKS_OK;
1404 }
#define LOG_WARNING
Definition: logger.h:144
iksparser * p
Definition: jabber.h:161
static void aji_log_hook(void *data, const char *xmpp, size_t size, int is_incoming)
Definition: res_jabber.c:1487
static int aji_io_recv(struct aji_client *client, char *buffer, size_t buf_len, int timeout)
Definition: res_jabber.c:1296
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define IKS_NET_EXPIRED
Definition: jabber.h:57
int timeout
Definition: jabber.h:178
#define NET_IO_BUF_SIZE
Definition: jabber.h:55
static void * aji_recv_loop ( void *  data)
static

Definition at line 2733 of file res_jabber.c.

References AJI_CONNECTED, AJI_DISCONNECTING, aji_reconnect(), aji_recv(), aji_send_raw(), ast_aji_client_destroy(), ast_debug, ast_log(), ASTOBJ_REF, ASTOBJ_UNREF, delete_old_messages_all(), IKS_NET_EXPIRED, aji_client::keepalive, LOG_ERROR, LOG_WARNING, aji_client::state, and aji_client::timeout.

Referenced by aji_reload().

2734 {
2735  struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
2736  int res = IKS_HOOK;
2737 
2738  while (res != IKS_OK) {
2739  ast_debug(3, "JABBER: Connecting.\n");
2740  res = aji_reconnect(client);
2741  sleep(4);
2742  }
2743 
2744  do {
2745  if (res == IKS_NET_RWERR || client->timeout == 0) {
2746  while (res != IKS_OK) {
2747  ast_debug(3, "JABBER: reconnecting.\n");
2748  res = aji_reconnect(client);
2749  sleep(4);
2750  }
2751  }
2752 
2753  res = aji_recv(client, 1);
2754 
2755  if (client->state == AJI_DISCONNECTING) {
2756  ast_debug(2, "Ending our Jabber client's thread due to a disconnect\n");
2757  pthread_exit(NULL);
2758  }
2759 
2760  /* Decrease timeout if no data received, and delete
2761  * old messages globally */
2762  if (res == IKS_NET_EXPIRED) {
2763  client->timeout--;
2764  delete_old_messages_all(client);
2765  }
2766  if (res == IKS_HOOK) {
2767  ast_log(LOG_WARNING, "JABBER: Got hook event.\n");
2768  } else if (res == IKS_NET_TLSFAIL) {
2769  ast_log(LOG_ERROR, "JABBER: Failure in TLS.\n");
2770  } else if (client->timeout == 0 && client->state == AJI_CONNECTED) {
2771  res = client->keepalive ? aji_send_raw(client, " ") : IKS_OK;
2772  if (res == IKS_OK) {
2773  client->timeout = 50;
2774  } else {
2775  ast_log(LOG_WARNING, "JABBER: Network Timeout\n");
2776  }
2777  } else if (res == IKS_NET_RWERR) {
2778  ast_log(LOG_WARNING, "JABBER: socket read error\n");
2779  }
2780  } while (client);
2782  return 0;
2783 }
static int aji_reconnect(struct aji_client *client)
Definition: res_jabber.c:3041
static int aji_send_raw(struct aji_client *client, const char *xmlstr)
Definition: res_jabber.c:1453
static int delete_old_messages_all(struct aji_client *client)
Definition: res_jabber.c:976
#define LOG_WARNING
Definition: logger.h:144
int keepalive
Definition: jabber.h:176
enum aji_state state
Definition: jabber.h:170
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define IKS_NET_EXPIRED
Definition: jabber.h:57
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
static int aji_recv(struct aji_client *client, int timeout)
Definition: res_jabber.c:1341
int timeout
Definition: jabber.h:178
#define ASTOBJ_REF(object)
Increment an object reference count.
Definition: astobj.h:201
static int aji_register_approve_handler ( void *  data,
ikspak *  pak 
)
static

Definition at line 1790 of file res_jabber.c.

References ast_aji_client_destroy(), ast_aji_increment_mid(), ast_aji_send(), ast_log(), ASTOBJ_REF, ASTOBJ_UNREF, aji_client::jid, LOG_ERROR, and aji_client::mid.

Referenced by aji_create_client().

1791 {
1792  struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
1793  iks *iq = NULL, *presence = NULL, *x = NULL;
1794 
1795  iq = iks_new("iq");
1796  presence = iks_new("presence");
1797  x = iks_new("x");
1798  if (client && iq && presence && x) {
1799  if (!iks_find(pak->query, "remove")) {
1800  iks_insert_attrib(iq, "from", client->jid->full);
1801  iks_insert_attrib(iq, "to", pak->from->full);
1802  iks_insert_attrib(iq, "id", pak->id);
1803  iks_insert_attrib(iq, "type", "result");
1804  ast_aji_send(client, iq);
1805 
1806  iks_insert_attrib(presence, "from", client->jid->full);
1807  iks_insert_attrib(presence, "to", pak->from->partial);
1808  iks_insert_attrib(presence, "id", client->mid);
1809  ast_aji_increment_mid(client->mid);
1810  iks_insert_attrib(presence, "type", "subscribe");
1811  iks_insert_attrib(x, "xmlns", "vcard-temp:x:update");
1812  iks_insert_node(presence, x);
1813  ast_aji_send(client, presence);
1814  }
1815  } else {
1816  ast_log(LOG_ERROR, "Out of memory.\n");
1817  }
1818 
1819  iks_delete(iq);
1820  iks_delete(presence);
1821  iks_delete(x);
1822 
1824  return IKS_FILTER_EAT;
1825 }
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
#define LOG_ERROR
Definition: logger.h:155
iksid * jid
Definition: jabber.h:160
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
#define ASTOBJ_REF(object)
Increment an object reference count.
Definition: astobj.h:201
char mid[6]
Definition: jabber.h:159
void ast_aji_increment_mid(char *mid)
increments the mid field for messages and other events.
Definition: res_jabber.c:2790
static int aji_register_query_handler ( void *  data,
ikspak *  pak 
)
static

Definition at line 1833 of file res_jabber.c.

References ast_aji_buddy_destroy(), ast_aji_client_destroy(), ast_aji_send(), ast_log(), ASTOBJ_CONTAINER_FIND, ASTOBJ_REF, ASTOBJ_UNREF, aji_client::buddies, LOG_ERROR, and aji_client::user.

Referenced by aji_create_client().

1834 {
1835  struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
1836  struct aji_buddy *buddy = NULL;
1837  char *node = NULL;
1838  iks *iq = NULL, *query = NULL;
1839 
1840  client = (struct aji_client *) data;
1841 
1842  buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, pak->from->partial);
1843  if (!buddy) {
1844  iks *error = NULL, *notacceptable = NULL;
1845 
1846  ast_log(LOG_ERROR, "Someone.... %s tried to register but they aren't allowed\n", pak->from->partial);
1847  iq = iks_new("iq");
1848  query = iks_new("query");
1849  error = iks_new("error");
1850  notacceptable = iks_new("not-acceptable");
1851  if (iq && query && error && notacceptable) {
1852  iks_insert_attrib(iq, "type", "error");
1853  iks_insert_attrib(iq, "from", client->user);
1854  iks_insert_attrib(iq, "to", pak->from->full);
1855  iks_insert_attrib(iq, "id", pak->id);
1856  iks_insert_attrib(query, "xmlns", "jabber:iq:register");
1857  iks_insert_attrib(error, "code" , "406");
1858  iks_insert_attrib(error, "type", "modify");
1859  iks_insert_attrib(notacceptable, "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas");
1860  iks_insert_node(iq, query);
1861  iks_insert_node(iq, error);
1862  iks_insert_node(error, notacceptable);
1863  ast_aji_send(client, iq);
1864  } else {
1865  ast_log(LOG_ERROR, "Out of memory.\n");
1866  }
1867 
1868  iks_delete(error);
1869  iks_delete(notacceptable);
1870  } else if (!(node = iks_find_attrib(pak->query, "node"))) {
1871  iks *instructions = NULL;
1872  char *explain = "Welcome to Asterisk - the Open Source PBX.\n";
1873  iq = iks_new("iq");
1874  query = iks_new("query");
1875  instructions = iks_new("instructions");
1876  if (iq && query && instructions && client) {
1877  iks_insert_attrib(iq, "from", client->user);
1878  iks_insert_attrib(iq, "to", pak->from->full);
1879  iks_insert_attrib(iq, "id", pak->id);
1880  iks_insert_attrib(iq, "type", "result");
1881  iks_insert_attrib(query, "xmlns", "jabber:iq:register");
1882  iks_insert_cdata(instructions, explain, 0);
1883  iks_insert_node(iq, query);
1884  iks_insert_node(query, instructions);
1885  ast_aji_send(client, iq);
1886  } else {
1887  ast_log(LOG_ERROR, "Out of memory.\n");
1888  }
1889 
1890  iks_delete(instructions);
1891  }
1892  iks_delete(iq);
1893  iks_delete(query);
1896  return IKS_FILTER_EAT;
1897 }
void ast_aji_buddy_destroy(struct aji_buddy *obj)
Definition: res_jabber.c:432
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
struct aji_buddy_container buddies
Definition: jabber.h:184
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
#define LOG_ERROR
Definition: logger.h:155
char user[AJI_MAX_JIDLEN]
Definition: jabber.h:153
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ASTOBJ_CONTAINER_FIND(container, namestr)
Find an object in a container.
Definition: astobj.h:401
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
#define ASTOBJ_REF(object)
Increment an object reference count.
Definition: astobj.h:201
static int aji_reload ( int  reload)
static

Definition at line 4654 of file res_jabber.c.

References AJI_CONNECTING, AJI_DISCONNECTED, aji_get_roster(), aji_init_event_distribution(), aji_load_config(), aji_recv_loop(), ast_aji_client_destroy(), ast_log(), ast_pthread_create_background, ASTOBJ_CONTAINER_MARKALL, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, clients, and LOG_ERROR.

Referenced by aji_do_reload(), load_module(), and reload().

4655 {
4656  int res;
4657 
4659  if (!(res = aji_load_config(reload))) {
4660  ast_log(LOG_ERROR, "JABBER: Failed to load config.\n");
4661  return 0;
4662  } else if (res == -1)
4663  return 1;
4664 
4667  ASTOBJ_RDLOCK(iterator);
4668  if (iterator->state == AJI_DISCONNECTED) {
4669  if (!iterator->thread)
4670  ast_pthread_create_background(&iterator->thread, NULL, aji_recv_loop, iterator);
4671  } else if (iterator->state == AJI_CONNECTING) {
4672  aji_get_roster(iterator);
4673  if (iterator->distribute_events) {
4674  aji_init_event_distribution(iterator);
4675  }
4676  }
4677 
4678  ASTOBJ_UNLOCK(iterator);
4679  });
4680 
4681  return 1;
4682 }
static void aji_init_event_distribution(struct aji_client *client)
Initialize collections for event distribution.
Definition: res_jabber.c:3235
static int reload(void)
Definition: res_jabber.c:4753
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:426
#define LOG_ERROR
Definition: logger.h:155
static int aji_get_roster(struct aji_client *client)
Definition: res_jabber.c:3067
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ASTOBJ_CONTAINER_TRAVERSE(container, continue, eval)
Iterate through the objects in a container.
Definition: astobj.h:376
#define ASTOBJ_UNLOCK(object)
Unlock a locked object.
Definition: astobj.h:109
static struct aji_client_container clients
Definition: res_jabber.c:392
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
static int aji_load_config(int reload)
Definition: res_jabber.c:4517
#define ASTOBJ_RDLOCK(object)
Lock an ASTOBJ for reading.
Definition: astobj.h:100
static void * aji_recv_loop(void *data)
Definition: res_jabber.c:2733
#define ASTOBJ_CONTAINER_MARKALL(container)
Mark all the objects in a container.
Definition: astobj.h:782
#define ASTOBJ_CONTAINER_PRUNE_MARKED(container, destructor)
Prune marked objects from a container.
Definition: astobj.h:651
static void aji_request_pubsub_nodes ( struct aji_client client,
const char *  collection 
)
static

Request item list from pubsub.

Parameters
clientthe configured XMPP client we use to connect to a XMPP server
collectionname of the collection for request
Returns
void

Definition at line 3568 of file res_jabber.c.

References aji_build_node_request(), aji_receive_node_list(), ast_aji_send(), aji_client::f, and aji_client::mid.

Referenced by aji_cli_list_pubsub_nodes().

3569 {
3570  iks *request = aji_build_node_request(client, collection);
3571 
3572  iks_filter_add_rule(client->f, aji_receive_node_list, client, IKS_RULE_TYPE,
3573  IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID, client->mid,
3574  IKS_RULE_DONE);
3575  ast_aji_send(client, request);
3576  iks_delete(request);
3577 
3578 }
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
static iks * aji_build_node_request(struct aji_client *client, const char *collection)
Build the a node request.
Definition: res_jabber.c:3586
static int aji_receive_node_list(void *data, ikspak *pak)
Receive pubsub item lists.
Definition: res_jabber.c:3604
char mid[6]
Definition: jabber.h:159
iksfilter * f
Definition: jabber.h:162
static int aji_send_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 1107 of file res_jabber.c.

References args, ast_aji_client_destroy(), ast_aji_get_client(), ast_aji_send_chat(), AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ASTOBJ_UNREF, and LOG_WARNING.

Referenced by load_module().

1108 {
1109  struct aji_client *client = NULL;
1110  char *s;
1112  AST_APP_ARG(sender);
1113  AST_APP_ARG(recipient);
1115  );
1116 
1117  if (!data) {
1118  ast_log(LOG_WARNING, "%s requires arguments (account,jid,message)\n", app_ajisend);
1119  return -1;
1120  }
1121  s = ast_strdupa(data);
1122 
1124  if (args.argc < 3) {
1125  ast_log(LOG_WARNING, "%s requires arguments (account,jid,message)\n", app_ajisend);
1126  return -1;
1127  }
1128 
1129  if (!(client = ast_aji_get_client(args.sender))) {
1130  ast_log(LOG_WARNING, "Could not find sender connection: '%s'\n", args.sender);
1131  return -1;
1132  }
1133  if (strchr(args.recipient, '@') && !ast_strlen_zero(args.message)) {
1134  ast_aji_send_chat(client, args.recipient, args.message);
1135  }
1137  return 0;
1138 }
#define LOG_WARNING
Definition: logger.h:144
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
int ast_aji_send_chat(struct aji_client *client, const char *address, const char *message)
sends messages.
Definition: res_jabber.c:2582
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct aji_client * ast_aji_get_client(const char *name)
grab a aji_client structure by label name or JID. Bumps the refcount. (without the resource string) ...
Definition: res_jabber.c:4575
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
static char * app_ajisend
Definition: res_jabber.c:386
static int aji_send_header ( struct aji_client client,
const char *  to 
)
static

Definition at line 1413 of file res_jabber.c.

References aji_send_raw(), len(), and aji_client::name_space.

Referenced by aji_act_hook(), and aji_tls_handshake().

1414 {
1415  char *msg;
1416  int len, err;
1417 
1418  len = 91 + strlen(client->name_space) + 6 + strlen(to) + 16 + 1;
1419  msg = iks_malloc(len);
1420  if (!msg)
1421  return IKS_NOMEM;
1422  sprintf(msg, "<?xml version='1.0'?>"
1423  "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='"
1424  "%s' to='%s' version='1.0'>", client->name_space, to);
1425  err = aji_send_raw(client, msg);
1426  iks_free(msg);
1427  if (err != IKS_OK)
1428  return err;
1429 
1430  return IKS_OK;
1431 }
static int aji_send_raw(struct aji_client *client, const char *xmlstr)
Definition: res_jabber.c:1453
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
char name_space[256]
Definition: jabber.h:157
static int aji_send_raw ( struct aji_client client,
const char *  xmlstr 
)
static

Definition at line 1453 of file res_jabber.c.

References aji_is_secure(), aji_log_hook(), len(), aji_client::p, and aji_client::ssl_session.

Referenced by aji_act_hook(), aji_recv_loop(), aji_send_header(), and ast_aji_send().

1454 {
1455  int ret;
1456 #ifdef HAVE_OPENSSL
1457  int len = strlen(xmlstr);
1458 
1459  if (aji_is_secure(client)) {
1460  ret = SSL_write(client->ssl_session, xmlstr, len);
1461  if (ret) {
1462  /* Log the message here, because iksemel's logHook is
1463  unaccessible */
1464  aji_log_hook(client, xmlstr, len, 0);
1465  return IKS_OK;
1466  }
1467  }
1468 #endif
1469  /* If needed, data will be sent unencrypted, and logHook will
1470  be called inside iks_send_raw */
1471  ret = iks_send_raw(client->p, xmlstr);
1472  if (ret != IKS_OK) {
1473  return ret;
1474  }
1475 
1476  return IKS_OK;
1477 }
iksparser * p
Definition: jabber.h:161
static int aji_is_secure(struct aji_client *client)
Definition: res_jabber.c:1203
static void aji_log_hook(void *data, const char *xmpp, size_t size, int is_incoming)
Definition: res_jabber.c:1487
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
SSL * ssl_session
Definition: jabber.h:166
static int aji_send_raw_chat ( struct aji_client client,
int  groupchat,
const char *  nick,
const char *  address,
const char *  message 
)
static

sends messages.

Parameters
clientthe configured XMPP client we use to connect to a XMPP server
groupchat
nickthe nickname we use in chatrooms
address
message
Returns
IKS_OK on success, any other value on failure

Definition at line 2609 of file res_jabber.c.

References AJI_CONNECTED, AJI_MAX_JIDLEN, ast_aji_send(), ast_log(), aji_client::component, aji_client::jid, LOG_ERROR, LOG_WARNING, and aji_client::state.

Referenced by ast_aji_send_chat(), and ast_aji_send_groupchat().

2610 {
2611  int res = 0;
2612  iks *message_packet = NULL;
2613  char from[AJI_MAX_JIDLEN];
2614  /* the nickname is used only in component mode */
2615  if (nick && client->component) {
2616  snprintf(from, AJI_MAX_JIDLEN, "%s@%s/%s", nick, client->jid->full, nick);
2617  } else {
2618  snprintf(from, AJI_MAX_JIDLEN, "%s", client->jid->full);
2619  }
2620 
2621  if (client->state != AJI_CONNECTED) {
2622  ast_log(LOG_WARNING, "JABBER: Not connected can't send\n");
2623  return -1;
2624  }
2625 
2626  message_packet = iks_make_msg(groupchat ? IKS_TYPE_GROUPCHAT : IKS_TYPE_CHAT, address, message);
2627  if (!message_packet) {
2628  ast_log(LOG_ERROR, "Out of memory.\n");
2629  return -1;
2630  }
2631  iks_insert_attrib(message_packet, "from", from);
2632  res = ast_aji_send(client, message_packet);
2633  iks_delete(message_packet);
2634 
2635  return res;
2636 }
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
#define LOG_WARNING
Definition: logger.h:144
enum aji_state state
Definition: jabber.h:170
int component
Definition: jabber.h:183
#define LOG_ERROR
Definition: logger.h:155
iksid * jid
Definition: jabber.h:160
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AJI_MAX_JIDLEN
Definition: jabber.h:73
static int aji_sendgroup_exec ( struct ast_channel chan,
const char *  data 
)
static

Application to send a message to a groupchat.

Parameters
chanast_channel
dataData is sender|groupchat|message.
Return values
0success
-1error

Definition at line 1147 of file res_jabber.c.

References AJI_MAX_RESJIDLEN, args, ast_aji_client_destroy(), ast_aji_get_client(), ast_aji_send_groupchat(), AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ASTOBJ_UNREF, aji_client::component, aji_client::jid, and LOG_ERROR.

Referenced by load_module().

1148 {
1149  struct aji_client *client = NULL;
1150  char *s;
1151  char nick[AJI_MAX_RESJIDLEN];
1152  int res = 0;
1154  AST_APP_ARG(sender);
1155  AST_APP_ARG(groupchat);
1157  AST_APP_ARG(nick);
1158  );
1159 
1160  if (!data) {
1161  ast_log(LOG_ERROR, "%s requires arguments (sender,groupchatid,message[,nickname])\n", app_ajisendgroup);
1162  return -1;
1163  }
1164  s = ast_strdupa(data);
1165 
1167  if (args.argc < 3 || args.argc > 4) {
1168  ast_log(LOG_ERROR, "%s requires arguments (sender,groupchatid,message[,nickname])\n", app_ajisendgroup);
1169  return -1;
1170  }
1171 
1172  if (!(client = ast_aji_get_client(args.sender))) {
1173  ast_log(LOG_ERROR, "Could not find sender connection: '%s'\n", args.sender);
1174  return -1;
1175  }
1176 
1177  if (ast_strlen_zero(args.nick) || args.argc == 3) {
1178  if (client->component) {
1179  sprintf(nick, "asterisk");
1180  } else {
1181  snprintf(nick, AJI_MAX_RESJIDLEN, "%s", client->jid->user);
1182  }
1183  } else {
1184  snprintf(nick, AJI_MAX_RESJIDLEN, "%s", args.nick);
1185  }
1186 
1187  if (strchr(args.groupchat, '@') && !ast_strlen_zero(args.message)) {
1188  res = ast_aji_send_groupchat(client, nick, args.groupchat, args.message);
1189  }
1190 
1192  if (res != IKS_OK) {
1193  return -1;
1194  }
1195  return 0;
1196 }
#define AJI_MAX_RESJIDLEN
Definition: jabber.h:74
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
static char * app_ajisendgroup
Definition: res_jabber.c:387
int component
Definition: jabber.h:183
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
static struct @350 args
int ast_aji_send_groupchat(struct aji_client *client, const char *nick, const char *address, const char *message)
sends message to a groupchat Prior to sending messages to a groupchat, one must be connected to it...
Definition: res_jabber.c:2596
iksid * jid
Definition: jabber.h:160
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct aji_client * ast_aji_get_client(const char *name)
grab a aji_client structure by label name or JID. Bumps the refcount. (without the resource string) ...
Definition: res_jabber.c:4575
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
static int aji_set_group_presence ( struct aji_client client,
char *  room,
int  level,
char *  nick,
char *  desc 
)
static

Definition at line 4034 of file res_jabber.c.

References AJI_MAX_JIDLEN, ast_aji_send(), ast_log(), aji_client::component, aji_client::jid, LOG_ERROR, and MUC_NS.

Referenced by ast_aji_join_chat(), and ast_aji_leave_chat().

4035 {
4036  int res = 0;
4037  iks *presence = NULL, *x = NULL;
4038  char from[AJI_MAX_JIDLEN];
4039  char roomid[AJI_MAX_JIDLEN];
4040 
4041  presence = iks_make_pres(level, NULL);
4042  x = iks_new("x");
4043 
4044  if (client->component) {
4045  snprintf(from, AJI_MAX_JIDLEN, "%s@%s/%s", nick, client->jid->full, nick);
4046  snprintf(roomid, AJI_MAX_JIDLEN, "%s/%s", room, nick);
4047  } else {
4048  snprintf(from, AJI_MAX_JIDLEN, "%s", client->jid->full);
4049  snprintf(roomid, AJI_MAX_JIDLEN, "%s/%s", room, nick ? nick : client->jid->user);
4050  }
4051 
4052  if (!presence || !x || !client) {
4053  ast_log(LOG_ERROR, "Out of memory.\n");
4054  res = -1;
4055  goto safeout;
4056  } else {
4057  iks_insert_attrib(presence, "to", roomid);
4058  iks_insert_attrib(presence, "from", from);
4059  iks_insert_attrib(x, "xmlns", MUC_NS);
4060  iks_insert_node(presence, x);
4061  res = ast_aji_send(client, presence);
4062  }
4063 
4064 safeout:
4065  iks_delete(presence);
4066  iks_delete(x);
4067  return res;
4068 }
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
int component
Definition: jabber.h:183
#define LOG_ERROR
Definition: logger.h:155
iksid * jid
Definition: jabber.h:160
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AJI_MAX_JIDLEN
Definition: jabber.h:73
#define MUC_NS
Definition: jabber.h:77
static void aji_set_presence ( struct aji_client client,
char *  to,
char *  from,
int  level,
char *  desc 
)
static

Definition at line 3992 of file res_jabber.c.

References ast_aji_send(), ast_log(), LOG_ERROR, and aji_client::priority.

Referenced by aji_get_roster(), aji_handle_presence(), and aji_handle_subscribe().

3993 {
3994  iks *presence = iks_make_pres(level, desc);
3995  iks *cnode = iks_new("c");
3996  iks *priority = iks_new("priority");
3997  char priorityS[10];
3998 
3999  if (presence && cnode && client && priority) {
4000  if (to) {
4001  iks_insert_attrib(presence, "to", to);
4002  }
4003  if (from) {
4004  iks_insert_attrib(presence, "from", from);
4005  }
4006  snprintf(priorityS, sizeof(priorityS), "%d", client->priority);
4007  iks_insert_cdata(priority, priorityS, strlen(priorityS));
4008  iks_insert_node(presence, priority);
4009  iks_insert_attrib(cnode, "node", "http://www.asterisk.org/xmpp/client/caps");
4010  iks_insert_attrib(cnode, "ver", "asterisk-xmpp");
4011  iks_insert_attrib(cnode, "ext", "voice-v1");
4012  iks_insert_attrib(cnode, "xmlns", "http://jabber.org/protocol/caps");
4013  iks_insert_node(presence, cnode);
4014  ast_aji_send(client, presence);
4015  } else {
4016  ast_log(LOG_ERROR, "Out of memory.\n");
4017  }
4018 
4019  iks_delete(cnode);
4020  iks_delete(presence);
4021  iks_delete(priority);
4022 }
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
static const char desc[]
Definition: cdr_radius.c:85
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int priority
Definition: jabber.h:188
static char * aji_show_buddies ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 4186 of file res_jabber.c.

References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, aji_client::buddies, aji_resource::cap, CLI_GENERATE, CLI_INIT, clients, ast_cli_entry::command, ast_cli_args::fd, aji_version::jingle, aji_resource::next, aji_capabilities::node, aji_version::parent, aji_resource::priority, aji_resource::resource, aji_resource::status, ast_cli_entry::usage, and aji_version::version.

4187 {
4188  struct aji_resource *resource;
4189  struct aji_client *client;
4190 
4191  switch (cmd) {
4192  case CLI_INIT:
4193  e->command = "jabber show buddies";
4194  e->usage =
4195  "Usage: jabber show buddies\n"
4196  " Shows buddy lists of our clients\n";
4197  return NULL;
4198  case CLI_GENERATE:
4199  return NULL;
4200  }
4201 
4202  ast_cli(a->fd, "Jabber buddy lists\n");
4204  ast_cli(a->fd, "Client: %s\n", iterator->user);
4205  client = iterator;
4206  ASTOBJ_CONTAINER_TRAVERSE(&client->buddies, 1, {
4207  ASTOBJ_RDLOCK(iterator);
4208  ast_cli(a->fd, "\tBuddy:\t%s\n", iterator->name);
4209  if (!iterator->resources)
4210  ast_cli(a->fd, "\t\tResource: None\n");
4211  for (resource = iterator->resources; resource; resource = resource->next) {
4212  ast_cli(a->fd, "\t\tResource: %s\n", resource->resource);
4213  if (resource->cap) {
4214  ast_cli(a->fd, "\t\t\tnode: %s\n", resource->cap->parent->node);
4215  ast_cli(a->fd, "\t\t\tversion: %s\n", resource->cap->version);
4216  ast_cli(a->fd, "\t\t\tJingle capable: %s\n", resource->cap->jingle ? "yes" : "no");
4217  }
4218  ast_cli(a->fd, "\t\tStatus: %d\n", resource->status);
4219  ast_cli(a->fd, "\t\tPriority: %d\n", resource->priority);
4220  }
4221  ASTOBJ_UNLOCK(iterator);
4222  });
4223  iterator = client;
4224  });
4225  return CLI_SUCCESS;
4226 }
int status
Definition: jabber.h:118
char version[50]
Definition: jabber.h:105
Definition: cli.h:146
char node[200]
Definition: jabber.h:112
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
char resource[AJI_MAX_RESJIDLEN]
Definition: jabber.h:119
struct aji_buddy_container buddies
Definition: jabber.h:184
const int fd
Definition: cli.h:153
struct aji_resource * next
Definition: jabber.h:123
#define ASTOBJ_CONTAINER_TRAVERSE(container, continue, eval)
Iterate through the objects in a container.
Definition: astobj.h:376
int priority
Definition: jabber.h:122
#define ASTOBJ_UNLOCK(object)
Unlock a locked object.
Definition: astobj.h:109
char * command
Definition: cli.h:180
static struct aji_client_container clients
Definition: res_jabber.c:392
const char * usage
Definition: cli.h:171
struct aji_version * cap
Definition: jabber.h:121
#define CLI_SUCCESS
Definition: cli.h:43
#define ASTOBJ_RDLOCK(object)
Lock an ASTOBJ for reading.
Definition: astobj.h:100
struct aji_capabilities * parent
Definition: jabber.h:107
int jingle
Definition: jabber.h:106
static char * aji_show_clients ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 4140 of file res_jabber.c.

References AJI_CONNECTED, AJI_CONNECTING, AJI_DISCONNECTED, ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, clients, ast_cli_entry::command, ast_cli_args::fd, status, and ast_cli_entry::usage.

4141 {
4142  char *status;
4143  int count = 0;
4144 
4145  switch (cmd) {
4146  case CLI_INIT:
4147  e->command = "jabber show connections";
4148  e->usage =
4149  "Usage: jabber show connections\n"
4150  " Shows state of client and component connections\n";
4151  return NULL;
4152  case CLI_GENERATE:
4153  return NULL;
4154  }
4155 
4156  ast_cli(a->fd, "Jabber Users and their status:\n");
4158  ASTOBJ_RDLOCK(iterator);
4159  count++;
4160  switch (iterator->state) {
4161  case AJI_DISCONNECTED:
4162  status = "Disconnected";
4163  break;
4164  case AJI_CONNECTING:
4165  status = "Connecting";
4166  break;
4167  case AJI_CONNECTED:
4168  status = "Connected";
4169  break;
4170  default:
4171  status = "Unknown";
4172  }
4173  ast_cli(a->fd, " [%s] %s - %s\n", iterator->name, iterator->user, status);
4174  ASTOBJ_UNLOCK(iterator);
4175  });
4176  ast_cli(a->fd, "----\n");
4177  ast_cli(a->fd, " Number of users: %d\n", count);
4178  return CLI_SUCCESS;
4179 }
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
#define ASTOBJ_CONTAINER_TRAVERSE(container, continue, eval)
Iterate through the objects in a container.
Definition: astobj.h:376
#define ASTOBJ_UNLOCK(object)
Unlock a locked object.
Definition: astobj.h:109
char * command
Definition: cli.h:180
static struct aji_client_container clients
Definition: res_jabber.c:392
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
#define ASTOBJ_RDLOCK(object)
Lock an ASTOBJ for reading.
Definition: astobj.h:100
jack_status_t status
Definition: app_jack.c:143
static int aji_start_sasl ( struct aji_client client,
enum ikssasltype  type,
char *  username,
char *  pass 
)
static

Definition at line 1522 of file res_jabber.c.

References aji_is_secure(), ast_aji_send(), ast_alloca, ast_base64encode(), ast_log(), base64, len(), LOG_ERROR, and aji_client::p.

Referenced by aji_act_hook().

1523 {
1524  iks *x = NULL;
1525  int len;
1526  char *s;
1527  char *base64;
1528 
1529  /* trigger SASL DIGEST-MD5 only over an unsecured connection.
1530  iks_start_sasl is an iksemel API function and relies on GnuTLS,
1531  whereas we use OpenSSL */
1532  if ((type & IKS_STREAM_SASL_MD5) && !aji_is_secure(client))
1533  return iks_start_sasl(client->p, IKS_SASL_DIGEST_MD5, username, pass);
1534  if (!(type & IKS_STREAM_SASL_PLAIN)) {
1535  ast_log(LOG_ERROR, "Server does not support SASL PLAIN authentication\n");
1536  return IKS_NET_NOTSUPP;
1537  }
1538 
1539  x = iks_new("auth");
1540  if (!x) {
1541  ast_log(LOG_ERROR, "Out of memory.\n");
1542  return IKS_NET_NOTSUPP;
1543  }
1544 
1545  iks_insert_attrib(x, "xmlns", IKS_NS_XMPP_SASL);
1546  len = strlen(username) + strlen(pass) + 3;
1547  s = ast_alloca(len);
1548  base64 = ast_alloca((len + 2) * 4 / 3);
1549  iks_insert_attrib(x, "mechanism", "PLAIN");
1550  snprintf(s, len, "%c%s%c%s", 0, username, 0, pass);
1551 
1552  /* exclude the NULL training byte from the base64 encoding operation
1553  as some XMPP servers will refuse it.
1554  The format for authentication is [authzid]\0authcid\0password
1555  not [authzid]\0authcid\0password\0 */
1556  ast_base64encode(base64, (const unsigned char *) s, len - 1, (len + 2) * 4 / 3);
1557  iks_insert_cdata(x, base64, 0);
1558  ast_aji_send(client, x);
1559  iks_delete(x);
1560 
1561  return IKS_OK;
1562 }
static char pass[512]
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: utils.h:653
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
iksparser * p
Definition: jabber.h:161
static int aji_is_secure(struct aji_client *client)
Definition: res_jabber.c:1203
static char base64[64]
Definition: utils.c:78
#define LOG_ERROR
Definition: logger.h:155
int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64.
Definition: utils.c:357
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char type[]
Definition: chan_nbs.c:57
static int aji_start_tls ( struct aji_client client)
static

Definition at line 1220 of file res_jabber.c.

References aji_client::p, and aji_client::stream_flags.

Referenced by aji_act_hook().

1221 {
1222  int ret;
1223 
1224  /* This is sent not encrypted */
1225  if ((ret = iks_send_raw(client->p, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>"))) {
1226  return ret;
1227  }
1228 
1229  client->stream_flags |= TRY_SECURE;
1230  return IKS_OK;
1231 }
iksparser * p
Definition: jabber.h:161
unsigned int stream_flags
Definition: jabber.h:168
static int aji_status_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 620 of file res_jabber.c.

References aji_find_resource(), args, ast_aji_buddy_destroy(), ast_aji_client_destroy(), ast_aji_get_client(), AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_NONSTANDARD_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, ASTOBJ_CONTAINER_FIND, ASTOBJ_UNREF, aji_client::buddies, LOG_ERROR, LOG_NOTICE, LOG_WARNING, pbx_builtin_setvar_helper(), aji_resource::resource, aji_buddy::resources, aji_resource::status, and status.

Referenced by load_module().

621 {
622  struct aji_client *client = NULL;
623  struct aji_buddy *buddy = NULL;
624  struct aji_resource *r = NULL;
625  char *s = NULL;
626  int stat = 7;
627  char status[2];
628  static int deprecation_warning = 0;
630  AST_APP_ARG(sender);
631  AST_APP_ARG(jid);
632  AST_APP_ARG(variable);
633  );
635  AST_APP_ARG(screenname);
637  );
638 
639  if (deprecation_warning++ % 10 == 0) {
640  ast_log(LOG_WARNING, "JabberStatus is deprecated. Please use the JABBER_STATUS dialplan function in the future.\n");
641  }
642 
643  if (!data) {
644  ast_log(LOG_ERROR, "Usage: JabberStatus(<sender>,<jid>[/<resource>],<varname>\n");
645  return 0;
646  }
647  s = ast_strdupa(data);
649 
650  if (args.argc != 3) {
651  ast_log(LOG_ERROR, "JabberStatus() requires 3 arguments.\n");
652  return -1;
653  }
654 
655  AST_NONSTANDARD_APP_ARGS(jid, args.jid, '/');
656  if (jid.argc < 1 || jid.argc > 2) {
657  ast_log(LOG_WARNING, "Wrong JID %s, exiting\n", args.jid);
658  return -1;
659  }
660 
661  if (!(client = ast_aji_get_client(args.sender))) {
662  ast_log(LOG_WARNING, "Could not find sender connection: '%s'\n", args.sender);
663  return -1;
664  }
665  buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, jid.screenname);
666  if (!buddy) {
667  ast_log(LOG_WARNING, "Could not find buddy in list: '%s'\n", jid.screenname);
669  return -1;
670  }
671  r = aji_find_resource(buddy, jid.resource);
672  if (!r && buddy->resources) {
673  r = buddy->resources;
674  }
677  if (!r) {
678  ast_log(LOG_NOTICE, "Resource '%s' of buddy '%s' was not found\n", jid.resource, jid.screenname);
679  } else {
680  stat = r->status;
681  }
682  snprintf(status, sizeof(status), "%d", stat);
683  pbx_builtin_setvar_helper(chan, args.variable, status);
684  return 0;
685 }
int status
Definition: jabber.h:118
void ast_aji_buddy_destroy(struct aji_buddy *obj)
Definition: res_jabber.c:432
#define LOG_WARNING
Definition: logger.h:144
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
char resource[AJI_MAX_RESJIDLEN]
Definition: jabber.h:119
struct aji_buddy_container buddies
Definition: jabber.h:184
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
struct aji_client * ast_aji_get_client(const char *name)
grab a aji_client structure by label name or JID. Bumps the refcount. (without the resource string) ...
Definition: res_jabber.c:4575
#define ASTOBJ_CONTAINER_FIND(container, namestr)
Find an object in a container.
Definition: astobj.h:401
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
static struct aji_resource * aji_find_resource(struct aji_buddy *buddy, char *name)
Definition: res_jabber.c:544
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
Definition: app.h:619
struct aji_resource * resources
Definition: jabber.h:137
jack_status_t status
Definition: app_jack.c:143
static int aji_tls_handshake ( struct aji_client client)
static

Definition at line 1239 of file res_jabber.c.

References aji_send_header(), ast_debug, aji_client::jid, aji_client::p, aji_client::ssl_context, aji_client::ssl_method, aji_client::ssl_session, and aji_client::stream_flags.

Referenced by aji_act_hook().

1240 {
1241  int ret;
1242  int sock;
1243  long ssl_opts;
1244 
1245  ast_debug(1, "Starting TLS handshake\n");
1246 
1247  /* Choose an SSL/TLS protocol version, create SSL_CTX */
1248  client->ssl_method = SSLv23_method();
1249  if (!(client->ssl_context = SSL_CTX_new((SSL_METHOD *) client->ssl_method))) {
1250  return IKS_NET_TLSFAIL;
1251  }
1252  ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
1253  SSL_CTX_set_options(client->ssl_context, ssl_opts);
1254 
1255  /* Create new SSL session */
1256  if (!(client->ssl_session = SSL_new(client->ssl_context))) {
1257  return IKS_NET_TLSFAIL;
1258  }
1259 
1260  /* Enforce TLS on our XMPP connection */
1261  sock = iks_fd(client->p);
1262  if (!(ret = SSL_set_fd(client->ssl_session, sock))) {
1263  return IKS_NET_TLSFAIL;
1264  }
1265 
1266  /* Perform SSL handshake */
1267  if (!(ret = SSL_connect(client->ssl_session))) {
1268  return IKS_NET_TLSFAIL;
1269  }
1270 
1271  client->stream_flags &= (~TRY_SECURE);
1272  client->stream_flags |= SECURE;
1273 
1274  /* Sent over the established TLS connection */
1275  if ((ret = aji_send_header(client, client->jid->server)) != IKS_OK) {
1276  return IKS_NET_TLSFAIL;
1277  }
1278 
1279  ast_debug(1, "TLS started with server\n");
1280 
1281  return IKS_OK;
1282 }
SSL_CTX * ssl_context
Definition: jabber.h:165
const SSL_METHOD * ssl_method
Definition: jabber.h:167
iksparser * p
Definition: jabber.h:161
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
unsigned int stream_flags
Definition: jabber.h:168
iksid * jid
Definition: jabber.h:160
SSL * ssl_session
Definition: jabber.h:166
static int aji_send_header(struct aji_client *client, const char *to)
Definition: res_jabber.c:1413
void ast_aji_buddy_destroy ( struct aji_buddy obj)

Destructor function for buddies to be used with ASTOBJ_UNREF

Definition at line 432 of file res_jabber.c.

References ast_free, aji_resource::description, aji_resource::next, and aji_buddy::resources.

Referenced by acf_jabberstatus_read(), aji_client_info_handler(), aji_create_buddy(), aji_dinfo_handler(), aji_handle_presence(), aji_handle_subscribe(), aji_register_query_handler(), aji_status_exec(), ast_aji_client_destroy(), gtalk_alloc(), and jingle_alloc().

433 {
434  struct aji_resource *tmp;
435 
436  while ((tmp = obj->resources)) {
437  obj->resources = obj->resources->next;
438  ast_free(tmp->description);
439  ast_free(tmp);
440  }
441 
442  ast_free(obj);
443 }
char * description
Definition: jabber.h:120
struct aji_resource * next
Definition: jabber.h:123
#define ast_free(a)
Definition: astmm.h:97
struct aji_resource * resources
Definition: jabber.h:137
void ast_aji_client_destroy ( struct aji_client obj)

Destructor function for clients to be used with ASTOBJ_UNREF after calls to ast_aji_get_client

Definition at line 410 of file res_jabber.c.

References aji_message_destroy(), ast_aji_buddy_destroy(), ast_free, AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, aji_client::buddies, aji_client::f, aji_message::list, aji_client::messages, aji_client::p, and aji_client::stack.

Referenced by acf_jabberreceive_read(), acf_jabberstatus_read(), aji_act_hook(), aji_cli_create_collection(), aji_cli_create_leafnode(), aji_cli_delete_pubsub_node(), aji_cli_list_pubsub_nodes(), aji_cli_purge_pubsub_nodes(), aji_client_connect(), aji_client_info_handler(), aji_create_client(), aji_devstate_cb(), aji_dinfo_handler(), aji_ditems_handler(), aji_handle_pubsub_error(), aji_join_exec(), aji_leave_exec(), aji_log_hook(), aji_mwi_cb(), aji_receive_node_list(), aji_recv_loop(), aji_register_approve_handler(), aji_register_query_handler(), aji_reload(), aji_send_exec(), aji_sendgroup_exec(), aji_status_exec(), ast_aji_disconnect(), gtalk_load_config(), gtalk_newcall(), gtalk_request(), jingle_load_config(), jingle_newcall(), jingle_request(), manager_jabber_send(), and unload_module().

411 {
412  struct aji_message *tmp;
415  iks_filter_delete(obj->f);
416  iks_parser_delete(obj->p);
417  iks_stack_delete(obj->stack);
418  AST_LIST_LOCK(&obj->messages);
419  while ((tmp = AST_LIST_REMOVE_HEAD(&obj->messages, list))) {
420  aji_message_destroy(tmp);
421  }
423  ast_free(obj);
424 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
void ast_aji_buddy_destroy(struct aji_buddy *obj)
Definition: res_jabber.c:432
iksparser * p
Definition: jabber.h:161
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
Definition: linkedlists.h:638
static void aji_message_destroy(struct aji_message *obj)
Definition: res_jabber.c:451
struct aji_buddy_container buddies
Definition: jabber.h:184
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
#define ASTOBJ_CONTAINER_DESTROY(container)
Destroy a container.
Definition: astobj.h:765
#define ASTOBJ_CONTAINER_DESTROYALL(container, destructor)
Empty a container.
Definition: astobj.h:453
#define ast_free(a)
Definition: astmm.h:97
struct aji_message::@188 list
ikstack * stack
Definition: jabber.h:163
struct aji_client::messages messages
iksfilter * f
Definition: jabber.h:162
int ast_aji_create_chat ( struct aji_client client,
char *  room,
char *  server,
char *  topic 
)

create a chatroom.

Parameters
clientthe configured XMPP client we use to connect to a XMPP server
roomname of room
servername of server
topictopic for the room.
Returns
0.

Definition at line 2646 of file res_jabber.c.

References ast_aji_increment_mid(), ast_aji_send(), ast_log(), LOG_ERROR, and aji_client::mid.

2647 {
2648  int res = 0;
2649  iks *iq = NULL;
2650  iq = iks_new("iq");
2651 
2652  if (iq && client) {
2653  iks_insert_attrib(iq, "type", "get");
2654  iks_insert_attrib(iq, "to", server);
2655  iks_insert_attrib(iq, "id", client->mid);
2656  ast_aji_increment_mid(client->mid);
2657  ast_aji_send(client, iq);
2658  } else {
2659  ast_log(LOG_ERROR, "Out of memory.\n");
2660  }
2661 
2662  iks_delete(iq);
2663 
2664  return res;
2665 }
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
char mid[6]
Definition: jabber.h:159
void ast_aji_increment_mid(char *mid)
increments the mid field for messages and other events.
Definition: res_jabber.c:2790
int ast_aji_disconnect ( struct aji_client client)

disconnect from jabber server.

Parameters
clientthe configured XMPP client we use to connect to a XMPP server
Returns
1.

Definition at line 3153 of file res_jabber.c.

References ast_aji_client_destroy(), ast_verb, ASTOBJ_UNREF, aji_client::p, aji_client::ssl_context, aji_client::ssl_session, and aji_client::stream_flags.

Referenced by unload_module().

3154 {
3155  if (client) {
3156  ast_verb(4, "JABBER: Disconnecting\n");
3157 #ifdef HAVE_OPENSSL
3158  if (client->stream_flags & SECURE) {
3159  SSL_shutdown(client->ssl_session);
3160  SSL_CTX_free(client->ssl_context);
3161  SSL_free(client->ssl_session);
3162  }
3163 #endif
3164  iks_disconnect(client->p);
3165  iks_parser_delete(client->p);
3167  }
3168 
3169  return 1;
3170 }
SSL_CTX * ssl_context
Definition: jabber.h:165
iksparser * p
Definition: jabber.h:161
#define ast_verb(level,...)
Definition: logger.h:243
unsigned int stream_flags
Definition: jabber.h:168
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
SSL * ssl_session
Definition: jabber.h:166
struct aji_client* ast_aji_get_client ( const char *  name)

grab a aji_client structure by label name or JID. Bumps the refcount. (without the resource string)

Parameters
namelabel or JID
Returns
aji_client.

Definition at line 4575 of file res_jabber.c.

References ast_strdupa, ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, clients, and strsep().

Referenced by acf_jabberreceive_read(), acf_jabberstatus_read(), aji_join_exec(), aji_leave_exec(), aji_send_exec(), aji_sendgroup_exec(), aji_status_exec(), gtalk_create_member(), gtalk_newcall(), gtalk_request(), jingle_create_member(), jingle_newcall(), jingle_request(), and manager_jabber_send().

4576 {
4577  struct aji_client *client = NULL;
4578  char *aux = NULL;
4579 
4580  client = ASTOBJ_CONTAINER_FIND(&clients, name);
4581  if (!client && strchr(name, '@')) {
4583  aux = ast_strdupa(iterator->user);
4584  if (strchr(aux, '/')) {
4585  /* strip resource for comparison */
4586  aux = strsep(&aux, "/");
4587  }
4588  if (!strncasecmp(aux, name, strlen(aux))) {
4589  client = ASTOBJ_REF(iterator);
4590  }
4591  });
4592  }
4593 
4594  return client;
4595 }
char * strsep(char **str, const char *delims)
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define ASTOBJ_CONTAINER_TRAVERSE(container, continue, eval)
Iterate through the objects in a container.
Definition: astobj.h:376
static const char name[]
#define ASTOBJ_CONTAINER_FIND(container, namestr)
Find an object in a container.
Definition: astobj.h:401
static struct aji_client_container clients
Definition: res_jabber.c:392
#define ASTOBJ_REF(object)
Increment an object reference count.
Definition: astobj.h:201
struct aji_client_container* ast_aji_get_clients ( void  )

Definition at line 4597 of file res_jabber.c.

References clients.

Referenced by gtalk_load_config(), and jingle_load_config().

4598 {
4599  return &clients;
4600 }
static struct aji_client_container clients
Definition: res_jabber.c:392
void ast_aji_increment_mid ( char *  mid)

increments the mid field for messages and other events.

Parameters
midchar.
Returns
void.

Definition at line 2790 of file res_jabber.c.

Referenced by aji_act_hook(), aji_handle_presence(), aji_pubsub_iq_create(), aji_register_approve_handler(), ast_aji_create_chat(), ast_aji_invite_chat(), gtalk_action(), gtalk_create_candidates(), gtalk_invite(), jingle_accept_call(), jingle_action(), jingle_create_candidates(), jingle_digit(), and jingle_transmit_invite().

2791 {
2792  int i = 0;
2793 
2794  for (i = strlen(mid) - 1; i >= 0; i--) {
2795  if (mid[i] != 'z') {
2796  mid[i] = mid[i] + 1;
2797  i = 0;
2798  } else
2799  mid[i] = 'a';
2800  }
2801 }
char mid[6]
Definition: jabber.h:159
int ast_aji_invite_chat ( struct aji_client client,
char *  user,
char *  room,
char *  message 
)

invite to a chatroom.

Parameters
clientthe configured XMPP client we use to connect to a XMPP server
user
room
message
Returns
res.

Definition at line 2698 of file res_jabber.c.

References ast_aji_increment_mid(), ast_aji_send(), ast_log(), LOG_ERROR, and aji_client::mid.

2699 {
2700  int res = 0;
2701  iks *invite, *body, *namespace;
2702 
2703  invite = iks_new("message");
2704  body = iks_new("body");
2705  namespace = iks_new("x");
2706  if (client && invite && body && namespace) {
2707  iks_insert_attrib(invite, "to", user);
2708  iks_insert_attrib(invite, "id", client->mid);
2709  ast_aji_increment_mid(client->mid);
2710  iks_insert_cdata(body, message, 0);
2711  iks_insert_attrib(namespace, "xmlns", "jabber:x:conference");
2712  iks_insert_attrib(namespace, "jid", room);
2713  iks_insert_node(invite, body);
2714  iks_insert_node(invite, namespace);
2715  res = ast_aji_send(client, invite);
2716  } else {
2717  ast_log(LOG_ERROR, "Out of memory.\n");
2718  }
2719 
2720  iks_delete(body);
2721  iks_delete(namespace);
2722  iks_delete(invite);
2723 
2724  return res;
2725 }
int ast_aji_send(struct aji_client *client, iks *x)
Wraps raw sending.
Definition: res_jabber.c:1439
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
structure to hold users read from users.conf
char mid[6]
Definition: jabber.h:159
void ast_aji_increment_mid(char *mid)
increments the mid field for messages and other events.
Definition: res_jabber.c:2790
int ast_aji_join_chat ( struct aji_client client,
char *  room,
char *  nick 
)

join a chatroom.

Parameters
clientthe configured XMPP client we use to connect to a XMPP server
roomroom to join
nickthe nickname to use in this room
Returns
IKS_OK on success, any other value on failure.

Definition at line 2674 of file res_jabber.c.

References aji_set_group_presence().

Referenced by aji_join_exec().

2675 {
2676  return aji_set_group_presence(client, room, IKS_SHOW_AVAILABLE, nick, NULL);
2677 }
static int aji_set_group_presence(struct aji_client *client, char *room, int level, char *nick, char *desc)
Definition: res_jabber.c:4034
int ast_aji_leave_chat ( struct aji_client client,
char *  room,
char *  nick 
)

leave a chatroom.

Parameters
clientthe configured XMPP client we use to connect to a XMPP server
roomroom to leave
nickthe nickname used in this room
Returns
IKS_OK on success, any other value on failure.

Definition at line 2686 of file res_jabber.c.

References aji_set_group_presence().

Referenced by aji_leave_exec().

2687 {
2688  return aji_set_group_presence(client, room, IKS_SHOW_UNAVAILABLE, nick, NULL);
2689 }
static int aji_set_group_presence(struct aji_client *client, char *room, int level, char *nick, char *desc)
Definition: res_jabber.c:4034
int ast_aji_send_chat ( struct aji_client client,
const char *  address,
const char *  message 
)

sends messages.

Parameters
clientthe configured XMPP client we use to connect to a XMPP server
address
message
Return values
IKS_OKsuccess
-1failure

Definition at line 2582 of file res_jabber.c.

References aji_send_raw_chat().

Referenced by aji_send_exec(), gtalk_sendtext(), jingle_sendtext(), and manager_jabber_send().

2583 {
2584  return aji_send_raw_chat(client, 0, NULL, address, message);
2585 }
static int aji_send_raw_chat(struct aji_client *client, int groupchat, const char *nick, const char *address, const char *message)
sends messages.
Definition: res_jabber.c:2609
int ast_aji_send_groupchat ( struct aji_client client,
const char *  nick,
const char *  address,
const char *  message 
)

sends message to a groupchat Prior to sending messages to a groupchat, one must be connected to it.

Parameters
clientthe configured XMPP client we use to connect to a XMPP server
nickthe nickname we use in the chatroom
addressthe user the messages must be sent to
messagethe message to send
Returns
IKS_OK on success, any other value on failure

Definition at line 2596 of file res_jabber.c.

References aji_send_raw_chat().

Referenced by aji_sendgroup_exec().

2596  {
2597  return aji_send_raw_chat(client, 1, nick, address, message);
2598 }
static int aji_send_raw_chat(struct aji_client *client, int groupchat, const char *nick, const char *address, const char *message)
sends messages.
Definition: res_jabber.c:2609
static int delete_old_messages ( struct aji_client client,
char *  from 
)
static

Definition at line 929 of file res_jabber.c.

References aji_message_destroy(), aji_message::arrived, AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_tvdiff_sec(), ast_tvnow(), aji_message::from, aji_message::list, LOG_ERROR, aji_client::message_timeout, and aji_client::messages.

Referenced by aji_handle_message(), and delete_old_messages_all().

930 {
931  int deleted = 0;
932  int isold = 0;
933  struct aji_message *tmp = NULL;
934  if (!client) {
935  ast_log(LOG_ERROR, "Cannot find our XMPP client\n");
936  return -1;
937  }
938 
939  /* remove old messages */
940  AST_LIST_LOCK(&client->messages);
941  if (AST_LIST_EMPTY(&client->messages)) {
942  AST_LIST_UNLOCK(&client->messages);
943  return 0;
944  }
945 
946  AST_LIST_TRAVERSE_SAFE_BEGIN(&client->messages, tmp, list) {
947  if (isold) {
948  if (!from || !strncasecmp(from, tmp->from, strlen(from))) {
950  aji_message_destroy(tmp);
951  deleted ++;
952  }
953  } else if (ast_tvdiff_sec(ast_tvnow(), tmp->arrived) >= client->message_timeout) {
954  isold = 1;
955  if (!from || !strncasecmp(from, tmp->from, strlen(from))) {
957  aji_message_destroy(tmp);
958  deleted ++;
959  }
960  }
961  }
963  AST_LIST_UNLOCK(&client->messages);
964 
965  return deleted;
966 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
int64_t ast_tvdiff_sec(struct timeval end, struct timeval start)
Computes the difference (in seconds) between two struct timeval instances.
Definition: time.h:56
int message_timeout
Definition: jabber.h:179
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
char * from
Definition: jabber.h:127
static void aji_message_destroy(struct aji_message *obj)
Definition: res_jabber.c:451
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct aji_message::@188 list
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
struct timeval arrived
Definition: jabber.h:130
struct aji_client::messages messages
static int delete_old_messages_all ( struct aji_client client)
static

Definition at line 976 of file res_jabber.c.

References delete_old_messages().

Referenced by aji_recv_loop().

977 {
978  return delete_old_messages(client, NULL);
979 }
static int delete_old_messages(struct aji_client *client, char *from)
Definition: res_jabber.c:929
static int gtalk_yuck ( iks *  node)
static

Definition at line 566 of file res_jabber.c.

References ast_debug.

Referenced by aji_handle_presence().

567 {
568  if (iks_find_with_attrib(node, "c", "node", "http://www.google.com/xmpp/client/caps")) {
569  ast_debug(1, "Found resource with Googletalk voice capabilities\n");
570  return 1;
571  } else if (iks_find_with_attrib(node, "caps:c", "ext", "pmuc-v1 sms-v1 camera-v1 video-v1 voice-v1")) {
572  ast_debug(1, "Found resource with Gmail voice/video chat capabilities\n");
573  return 1;
574  } else if (iks_find_with_attrib(node, "caps:c", "ext", "pmuc-v1 sms-v1 video-v1 voice-v1")) {
575  ast_debug(1, "Found resource with Gmail voice/video chat capabilities (no camera)\n");
576  return 1;
577  }
578 
579  return 0;
580 }
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static iks * jabber_make_auth ( iksid *  id,
const char *  pass,
const char *  sid 
)
static

Definition at line 590 of file res_jabber.c.

References ast_sha1_hash().

Referenced by aji_act_hook().

591 {
592  iks *x, *y;
593  x = iks_new("iq");
594  iks_insert_attrib(x, "type", "set");
595  y = iks_insert(x, "query");
596  iks_insert_attrib(y, "xmlns", IKS_NS_AUTH);
597  iks_insert_cdata(iks_insert(y, "username"), id->user, 0);
598  iks_insert_cdata(iks_insert(y, "resource"), id->resource, 0);
599  if (sid) {
600  char buf[41];
601  char sidpass[100];
602  snprintf(sidpass, sizeof(sidpass), "%s%s", sid, pass);
603  ast_sha1_hash(buf, sidpass);
604  iks_insert_cdata(iks_insert(y, "digest"), buf, 0);
605  } else {
606  iks_insert_cdata(iks_insert(y, "password"), pass, 0);
607  }
608  return x;
609 }
static char pass[512]
void ast_sha1_hash(char *output, const char *input)
Produces SHA1 hash based on input string.
Definition: utils.c:261
enum queue_result id
Definition: app_queue.c:1090
static int load_module ( void  )
static

Definition at line 4729 of file res_jabber.c.

References aji_join_exec(), aji_leave_exec(), aji_reload(), aji_send_exec(), aji_sendgroup_exec(), aji_status_exec(), ARRAY_LEN, ast_cli_register_multiple(), ast_cond_init, ast_custom_function_register, ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, ast_mutex_init, ast_register_application_xml, ASTOBJ_CONTAINER_INIT, clients, EVENT_FLAG_SYSTEM, and manager_jabber_send().

4730 {
4732  if (!aji_reload(0))
4733  return AST_MODULE_LOAD_DECLINE;
4743 
4746  return 0;
4747 }
static char * app_ajijoin
Definition: res_jabber.c:389
static struct ast_custom_function jabberstatus_function
Definition: res_jabber.c:753
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static int aji_send_exec(struct ast_channel *chan, const char *data)
Definition: res_jabber.c:1107
static int aji_join_exec(struct ast_channel *chan, const char *data)
Application to join a chat room.
Definition: res_jabber.c:988
static int manager_jabber_send(struct mansession *s, const struct message *m)
Definition: res_jabber.c:4609
#define ast_cond_init(cond, attr)
Definition: lock.h:167
static int aji_reload(int reload)
Definition: res_jabber.c:4654
static char * app_ajisendgroup
Definition: res_jabber.c:387
static ast_cond_t message_received_condition
Definition: res_jabber.c:396
static char * app_ajileave
Definition: res_jabber.c:390
static int aji_status_exec(struct ast_channel *chan, const char *data)
Definition: res_jabber.c:620
#define ASTOBJ_CONTAINER_INIT(container)
Initialize a container.
Definition: astobj.h:752
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
#define ast_manager_register_xml(a, b, c)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:172
static struct ast_cli_entry aji_cli[]
Definition: res_jabber.c:374
static char * app_ajistatus
Definition: res_jabber.c:388
static struct aji_client_container clients
Definition: res_jabber.c:392
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
static ast_mutex_t messagelock
Definition: res_jabber.c:397
#define ast_mutex_init(pmutex)
Definition: lock.h:152
static int aji_sendgroup_exec(struct ast_channel *chan, const char *data)
Application to send a message to a groupchat.
Definition: res_jabber.c:1147
static int aji_leave_exec(struct ast_channel *chan, const char *data)
Application to leave a chat room.
Definition: res_jabber.c:1049
static struct ast_custom_function jabberreceive_function
Definition: res_jabber.c:915
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1164
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:437
static char * app_ajisend
Definition: res_jabber.c:386
static int manager_jabber_send ( struct mansession s,
const struct message m 
)
static

Definition at line 4609 of file res_jabber.c.

References ast_aji_client_destroy(), ast_aji_get_client(), ast_aji_send_chat(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_ack(), astman_send_error(), and ASTOBJ_UNREF.

Referenced by load_module().

4610 {
4611  struct aji_client *client = NULL;
4612  const char *id = astman_get_header(m, "ActionID");
4613  const char *jabber = astman_get_header(m, "Jabber");
4614  const char *screenname = astman_get_header(m, "ScreenName");
4615  const char *message = astman_get_header(m, "Message");
4616 
4617  if (ast_strlen_zero(jabber)) {
4618  astman_send_error(s, m, "No transport specified");
4619  return 0;
4620  }
4621  if (ast_strlen_zero(screenname)) {
4622  astman_send_error(s, m, "No ScreenName specified");
4623  return 0;
4624  }
4625  if (ast_strlen_zero(message)) {
4626  astman_send_error(s, m, "No Message specified");
4627  return 0;
4628  }
4629 
4630  astman_send_ack(s, m, "Attempting to send Jabber Message");
4631  client = ast_aji_get_client(jabber);
4632  if (!client) {
4633  astman_send_error(s, m, "Could not find Sender");
4634  return 0;
4635  }
4636  if (strchr(screenname, '@') && message) {
4637  ast_aji_send_chat(client, screenname, message);
4638  astman_append(s, "Response: Success\r\n");
4639  } else {
4640  astman_append(s, "Response: Error\r\n");
4641  }
4643  if (!ast_strlen_zero(id)) {
4644  astman_append(s, "ActionID: %s\r\n", id);
4645  }
4646  astman_append(s, "\r\n");
4647  return 0;
4648 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2135
int ast_aji_send_chat(struct aji_client *client, const char *address, const char *message)
sends messages.
Definition: res_jabber.c:2582
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
struct aji_client * ast_aji_get_client(const char *name)
grab a aji_client structure by label name or JID. Bumps the refcount. (without the resource string) ...
Definition: res_jabber.c:4575
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static int reload ( void  )
static

Definition at line 4753 of file res_jabber.c.

References aji_reload().

4754 {
4755  aji_reload(1);
4756  return 0;
4757 }
static int aji_reload(int reload)
Definition: res_jabber.c:4654
static int unload_module ( void  )
static

Definition at line 4688 of file res_jabber.c.

References AJI_DISCONNECTING, ARRAY_LEN, ast_aji_client_destroy(), ast_aji_disconnect(), ast_cli_unregister_multiple(), ast_cond_destroy, ast_custom_function_unregister(), ast_debug, ast_event_unsubscribe(), ast_manager_unregister(), ast_mutex_destroy, ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, and clients.

4689 {
4690 
4697  ast_manager_unregister("JabberSend");
4699  if (mwi_sub) {
4701  }
4702  if (device_state_sub) {
4704  }
4706 
4708  ASTOBJ_WRLOCK(iterator);
4709  ast_debug(3, "JABBER: Releasing and disconnecting client: %s\n", iterator->name);
4710  iterator->state = AJI_DISCONNECTING;
4711  ASTOBJ_UNLOCK(iterator);
4712  pthread_join(iterator->thread, NULL);
4713  ast_aji_disconnect(iterator);
4714  });
4715 
4718 
4721 
4722  return 0;
4723 }
static char * app_ajijoin
Definition: res_jabber.c:389
static struct ast_custom_function jabberstatus_function
Definition: res_jabber.c:753
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: cli.c:2177
int ast_aji_disconnect(struct aji_client *client)
disconnect from jabber server.
Definition: res_jabber.c:3153
An MWI subscription.
#define ASTOBJ_WRLOCK(object)
Lock an ASTOBJ for writing.
Definition: astobj.h:104
static char * app_ajisendgroup
Definition: res_jabber.c:387
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx.c:7705
static ast_cond_t message_received_condition
Definition: res_jabber.c:396
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
Definition: pbx.c:3814
static char * app_ajileave
Definition: res_jabber.c:390
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static struct ast_cli_entry aji_cli[]
Definition: res_jabber.c:374
#define ASTOBJ_CONTAINER_DESTROY(container)
Destroy a container.
Definition: astobj.h:765
#define ASTOBJ_CONTAINER_DESTROYALL(container, destructor)
Empty a container.
Definition: astobj.h:453
#define ast_cond_destroy(cond)
Definition: lock.h:168
#define ASTOBJ_CONTAINER_TRAVERSE(container, continue, eval)
Iterate through the objects in a container.
Definition: astobj.h:376
#define ASTOBJ_UNLOCK(object)
Unlock a locked object.
Definition: astobj.h:109
static char * app_ajistatus
Definition: res_jabber.c:388
static struct aji_client_container clients
Definition: res_jabber.c:392
static struct ast_event_sub * device_state_sub
Definition: res_jabber.c:395
void ast_aji_client_destroy(struct aji_client *obj)
Definition: res_jabber.c:410
static ast_mutex_t messagelock
Definition: res_jabber.c:397
#define ast_mutex_destroy(a)
Definition: lock.h:154
static struct ast_custom_function jabberreceive_function
Definition: res_jabber.c:915
struct ast_event_sub * ast_event_unsubscribe(struct ast_event_sub *event_sub)
Un-subscribe from events.
Definition: event.c:987
int ast_manager_unregister(char *action)
Unregister a registered manager command.
Definition: manager.c:5355
static char * app_ajisend
Definition: res_jabber.c:386

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "AJI - Asterisk Jabber Interface" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DEPEND, }
static

Definition at line 4764 of file res_jabber.c.

struct ast_cli_entry aji_cli[]
static

Definition at line 374 of file res_jabber.c.

char* app_ajijoin = "JabberJoin"
static

Definition at line 389 of file res_jabber.c.

char* app_ajileave = "JabberLeave"
static

Definition at line 390 of file res_jabber.c.

char* app_ajisend = "JabberSend"
static

Definition at line 386 of file res_jabber.c.

char* app_ajisendgroup = "JabberSendGroup"
static

Definition at line 387 of file res_jabber.c.

char* app_ajistatus = "JabberStatus"
static

Definition at line 388 of file res_jabber.c.

Definition at line 4764 of file res_jabber.c.

struct aji_capabilities* capabilities = NULL
static

Definition at line 393 of file res_jabber.c.

Referenced by aji_find_version(), ast_request(), and set_peer_capabilities().

struct ast_event_sub* device_state_sub = NULL
static

Definition at line 395 of file res_jabber.c.

struct ast_flags globalflags = { AJI_AUTOREGISTER | AJI_AUTOACCEPT }
static

Global flags, initialized to default values.

Definition at line 400 of file res_jabber.c.

struct ast_custom_function jabberreceive_function
static
Initial value:
= {
.name = "JABBER_RECEIVE",
}
static int acf_jabberreceive_read(struct ast_channel *chan, const char *name, char *data, char *buf, size_t buflen)
Definition: res_jabber.c:767

Definition at line 915 of file res_jabber.c.

struct ast_custom_function jabberstatus_function
static
Initial value:
= {
.name = "JABBER_STATUS",
}
static int acf_jabberstatus_read(struct ast_channel *chan, const char *name, char *data, char *buf, size_t buflen)
Definition: res_jabber.c:696

Definition at line 753 of file res_jabber.c.

ast_cond_t message_received_condition
static

Definition at line 396 of file res_jabber.c.

ast_mutex_t messagelock
static

Definition at line 397 of file res_jabber.c.

struct ast_event_sub* mwi_sub = NULL
static

Definition at line 394 of file res_jabber.c.

Referenced by handle_subscribe(), handle_unsubscribe(), and poll_subscribed_mailboxes().

struct ast_flags pubsubflags = { 0 }
static

PubSub flags, initialized to default values.

Definition at line 403 of file res_jabber.c.