Asterisk - The Open Source Telephony Project  21.4.1
Data Structures | Macros | Enumerations | Functions | Variables
res_xmpp.c File Reference

XMPP client and component module. More...

#include "asterisk.h"
#include <ctype.h>
#include <iksemel.h>
#include "asterisk/xmpp.h"
#include "asterisk/module.h"
#include "asterisk/manager.h"
#include "asterisk/app.h"
#include "asterisk/mwi.h"
#include "asterisk/message.h"
#include "asterisk/cli.h"
#include "asterisk/config_options.h"
#include "asterisk/json.h"

Go to the source code of this file.

Data Structures

struct  ast_xmpp_client_config
 XMPP Client Configuration. More...
 
struct  ast_xmpp_global_config
 XMPP Global Configuration. More...
 
struct  xmpp_config
 
struct  xmpp_pak_handler
 Defined handlers for different PAK types. More...
 
struct  xmpp_state_handler
 Defined handlers for XMPP client states. More...
 

Macros

#define BUDDY_BUCKETS   53
 Number of buckets for buddies (per client)
 
#define BUDDY_NOT_IN_ROSTER   7
 
#define BUDDY_OFFLINE   6
 
#define CLIENT_BUCKETS   53
 Number of buckets for client connections.
 
#define RESOURCE_BUCKETS   53
 Number of buckets for resources (per buddy)
 
#define STATUS_DISAPPEAR   6
 Status for a disappearing buddy.
 
#define XMPP_TLS_NS   "urn:ietf:params:xml:ns:xmpp-tls"
 Namespace for TLS support.
 

Enumerations

enum  {
  XMPP_AUTOPRUNE = (1 << 0), XMPP_AUTOREGISTER = (1 << 1), XMPP_AUTOACCEPT = (1 << 2), XMPP_DEBUG = (1 << 3),
  XMPP_USETLS = (1 << 4), XMPP_USESASL = (1 << 5), XMPP_FORCESSL = (1 << 6), XMPP_KEEPALIVE = (1 << 7),
  XMPP_COMPONENT = (1 << 8), XMPP_SEND_TO_DIALPLAN = (1 << 9), XMPP_DISTRIBUTE_EVENTS = (1 << 10)
}
 Supported general configuration flags.
 
enum  { XMPP_XEP0248 = (1 << 0), XMPP_PUBSUB = (1 << 1), XMPP_PUBSUB_AUTOCREATE = (1 << 2) }
 Supported pubsub configuration flags.
 

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 AO2_GLOBAL_OBJ_STATIC (globals)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
int ast_xmpp_chatroom_invite (struct ast_xmpp_client *client, const char *user, const char *room, const char *message)
 Invite a user to an XMPP multi-user chatroom. More...
 
int ast_xmpp_chatroom_join (struct ast_xmpp_client *client, const char *room, const char *nickname)
 Join an XMPP multi-user chatroom. More...
 
int ast_xmpp_chatroom_leave (struct ast_xmpp_client *client, const char *room, const char *nickname)
 Leave an XMPP multi-user chatroom. More...
 
int ast_xmpp_chatroom_send (struct ast_xmpp_client *client, const char *nickname, const char *address, const char *message)
 Send a message to an XMPP multi-user chatroom. More...
 
static void * ast_xmpp_client_config_alloc (const char *cat)
 Allocator function for configuration.
 
static void ast_xmpp_client_config_destructor (void *obj)
 Destructor function for configuration.
 
int ast_xmpp_client_disconnect (struct ast_xmpp_client *client)
 Disconnect an XMPP client connection. More...
 
struct ast_xmpp_clientast_xmpp_client_find (const char *name)
 Find an XMPP client connection using a given name. More...
 
void ast_xmpp_client_lock (struct ast_xmpp_client *client)
 Lock an XMPP client connection. More...
 
int ast_xmpp_client_send (struct ast_xmpp_client *client, iks *stanza)
 Send an XML stanza out using an established XMPP client connection. More...
 
int ast_xmpp_client_send_message (struct ast_xmpp_client *client, const char *user, const char *message)
 Send a message to a given user using an established XMPP client connection. More...
 
void ast_xmpp_client_unlock (struct ast_xmpp_client *client)
 Unlock an XMPP client connection. More...
 
void ast_xmpp_client_unref (struct ast_xmpp_client *client)
 Release XMPP client connection reference. More...
 
void ast_xmpp_increment_mid (char *mid)
 Helper function which increments the message identifier. More...
 
static int cached_devstate_cb (void *obj, void *arg, int flags)
 
static int client_bitfield_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 
static int client_buddy_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 
static int client_status_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 
 CONFIG_INFO_STANDARD (cfg_info, globals, xmpp_config_alloc,.files=ACO_FILES(&res_xmpp_conf),.post_apply_config=xmpp_config_post_apply,)
 
static int delete_old_messages (struct ast_xmpp_client *client, char *from)
 
static int fetch_access_token (struct ast_xmpp_client_config *cfg)
 
static int get_buddy_status (struct ast_xmpp_client_config *clientcfg, char *screenname, char *resource)
 
static int global_bitfield_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 
static int load_module (void)
 Load the module. More...
 
static int manager_jabber_send (struct mansession *s, const struct message *m)
 
static char * openssl_error_string (void)
 
static int reload (void)
 
static void sleep_with_backoff (unsigned int *sleep_time)
 
static int unload_module (void)
 
static int xmpp_action_hook (void *data, int type, iks *node)
 Action hook for when things occur.
 
static int xmpp_buddy_cmp (void *obj, void *arg, int flags)
 Comparator function for XMPP buddy.
 
static void xmpp_buddy_destructor (void *obj)
 Destructor callback function for XMPP buddy.
 
static int xmpp_buddy_hash (const void *obj, const int flags)
 Hashing function for XMPP buddy.
 
static char * xmpp_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 * xmpp_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 * xmpp_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 * xmpp_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 * xmpp_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 struct ast_xmpp_clientxmpp_client_alloc (const char *name)
 Allocator function for ast_xmpp_client.
 
static int xmpp_client_authenticate (struct ast_xmpp_client *client, struct ast_xmpp_client_config *cfg, int type, iks *node)
 Internal function called when we need to authenticate.
 
static int xmpp_client_authenticate_digest (struct ast_xmpp_client *client, struct ast_xmpp_client_config *cfg, int type, iks *node)
 Internal function called when we need to authenticate using non-SASL.
 
static int xmpp_client_authenticate_sasl (struct ast_xmpp_client *client, struct ast_xmpp_client_config *cfg, int type, iks *node)
 Internal function called when we need to authenticate using SASL.
 
static int xmpp_client_authenticating (struct ast_xmpp_client *client, struct ast_xmpp_client_config *cfg, int type, iks *node)
 Internal function called when we are authenticating.
 
static void xmpp_client_change_state (struct ast_xmpp_client *client, int state)
 Internal function which changes the XMPP client state.
 
static int xmpp_client_config_merge_buddies (void *obj, void *arg, int flags)
 
static int xmpp_client_config_post_apply (void *obj, void *arg, int flags)
 
static struct ast_xmpp_buddyxmpp_client_create_buddy (struct ao2_container *container, const char *id)
 Internal function which creates a buddy on a client.
 
static void xmpp_client_destructor (void *obj)
 Destructor callback function for XMPP client.
 
static void * xmpp_client_find_or_create (const char *category)
 Look up existing client or create a new one.
 
static int xmpp_client_receive (struct ast_xmpp_client *client, unsigned int timeout)
 Internal function which receives data from the XMPP client connection.
 
static int xmpp_client_reconnect (struct ast_xmpp_client *client)
 Internal function used to reconnect an XMPP client to its server.
 
static int xmpp_client_request_tls (struct ast_xmpp_client *client, struct ast_xmpp_client_config *cfg, int type, iks *node)
 Internal function called when we need to request TLS support.
 
static int xmpp_client_requested_tls (struct ast_xmpp_client *client, struct ast_xmpp_client_config *cfg, int type, iks *node)
 Internal function called when we receive a response to our TLS initiation request.
 
static int xmpp_client_send_disco_info_request (struct ast_xmpp_client *client, const char *to, const char *from)
 Helper function which sends a discovery information request to a user.
 
static int xmpp_client_send_message (struct ast_xmpp_client *client, int group, const char *nick, const char *address, const char *message)
 Internal function used to send a message to a user or chatroom.
 
static int xmpp_client_send_raw_message (struct ast_xmpp_client *client, const char *message)
 Internal function which sends a raw message.
 
static int xmpp_client_service_discovery_get_hook (void *data, ikspak *pak)
 Hook function called when client receives a service discovery get message.
 
static int xmpp_client_service_discovery_result_hook (void *data, ikspak *pak)
 Hook function called when client receives a service discovery result message.
 
static int xmpp_client_set_group_presence (struct ast_xmpp_client *client, const char *room, int level, const char *nick)
 
static void xmpp_client_set_presence (struct ast_xmpp_client *client, const char *to, const char *from, int level, const char *desc)
 Internal function which changes the presence status of an XMPP client.
 
static int xmpp_client_subscribe_user (void *obj, void *arg, int flags)
 Callback function which subscribes to a user if needed.
 
static void * xmpp_client_thread (void *data)
 XMPP client connection thread.
 
static int xmpp_client_unsubscribe_user (struct ast_xmpp_client *client, const char *user)
 Helper function which unsubscribes a user and removes them from the roster.
 
static int xmpp_component_authenticate (struct ast_xmpp_client *client, struct ast_xmpp_client_config *cfg, int type, iks *node)
 Internal function called when we should authenticate as a component.
 
static int xmpp_component_authenticating (struct ast_xmpp_client *client, struct ast_xmpp_client_config *cfg, int type, iks *node)
 Internal function called when we authenticated as a component.
 
static int xmpp_component_register_get_hook (void *data, ikspak *pak)
 Hook function called when the component is queried about registration.
 
static int xmpp_component_register_set_hook (void *data, ikspak *pak)
 Hook function called when someone registers to the component.
 
static int xmpp_component_service_discovery_get_hook (void *data, ikspak *pak)
 Hook function called when component receives a service discovery get message.
 
static int xmpp_component_service_discovery_items_hook (void *data, ikspak *pak)
 Hook function called when we receive a service discovery items request.
 
static void * xmpp_config_alloc (void)
 Allocator for XMPP configuration.
 
static int xmpp_config_cmp (void *obj, void *arg, int flags)
 Comparator function for configuration.
 
static void xmpp_config_destructor (void *obj)
 Destructor for XMPP configuration.
 
static void * xmpp_config_find (struct ao2_container *tmp_container, const char *category)
 Find function for configuration.
 
static void xmpp_config_post_apply (void)
 
static int xmpp_config_prelink (void *newitem)
 
static int xmpp_connect_hook (void *data, ikspak *pak)
 Hook function called when client finishes authenticating with the server.
 
static char * xmpp_do_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static void xmpp_init_event_distribution (struct ast_xmpp_client *client)
 Initialize collections for event distribution. More...
 
static int xmpp_io_recv (struct ast_xmpp_client *client, char *buffer, size_t buf_len, int timeout)
 Internal function which polls on an XMPP client and receives data.
 
static int xmpp_is_secure (struct ast_xmpp_client *client)
 Helper function which returns whether an XMPP client connection is secure or not.
 
static int xmpp_join_exec (struct ast_channel *chan, const char *data)
 Application to join a chat room. More...
 
static int xmpp_leave_exec (struct ast_channel *chan, const char *data)
 Application to leave a chat room. More...
 
static void xmpp_log_hook (void *data, const char *xmpp, size_t size, int incoming)
 Logging hook function.
 
static void xmpp_message_destroy (struct ast_xmpp_message *message)
 Destroy function for XMPP messages.
 
static int xmpp_pak_message (struct ast_xmpp_client *client, struct ast_xmpp_client_config *cfg, iks *node, ikspak *pak)
 Internal function called when a message is received.
 
static int xmpp_pak_presence (struct ast_xmpp_client *client, struct ast_xmpp_client_config *cfg, iks *node, ikspak *pak)
 Internal function called when a presence message is received.
 
static int xmpp_pak_s10n (struct ast_xmpp_client *client, struct ast_xmpp_client_config *cfg, iks *node, ikspak *pak)
 Internal function called when a subscription message is received.
 
static int xmpp_ping_request (struct ast_xmpp_client *client, const char *to, const char *from)
 Helper function which sends a ping request to a server.
 
static iks * xmpp_pubsub_build_node_config (iks *pubsub, const char *node_type, const char *collection_name)
 
static iks * xmpp_pubsub_build_node_request (struct ast_xmpp_client *client, const char *collection)
 Build the a node request. More...
 
static iks * xmpp_pubsub_build_publish_skeleton (struct ast_xmpp_client *client, const char *node, const char *event_type, unsigned int cachable)
 Build the skeleton of a publish. More...
 
static void xmpp_pubsub_create_affiliations (struct ast_xmpp_client *client, const char *node)
 Add Owner affiliations for pubsub node. More...
 
static void xmpp_pubsub_create_collection (struct ast_xmpp_client *client, const char *collection_name)
 Create a PubSub collection node. More...
 
static void xmpp_pubsub_create_leaf (struct ast_xmpp_client *client, const char *collection_name, const char *leaf_name)
 Create a PubSub leaf node. More...
 
static void xmpp_pubsub_create_node (struct ast_xmpp_client *client, const char *node_type, const char *name, const char *collection_name)
 Create a pubsub node. More...
 
static void xmpp_pubsub_delete_node (struct ast_xmpp_client *client, const char *node_name)
 Delete a PubSub node. More...
 
static int xmpp_pubsub_delete_node_list (void *data, ikspak *pak)
 Delete pubsub item lists. More...
 
static void xmpp_pubsub_devstate_cb (void *data, struct stasis_subscription *sub, struct stasis_message *msg)
 Callback function for device state events. More...
 
static int xmpp_pubsub_handle_error (void *data, ikspak *pak)
 
static int xmpp_pubsub_handle_event (void *data, ikspak *pak)
 Callback for handling PubSub events. More...
 
static iks * xmpp_pubsub_iq_create (struct ast_xmpp_client *client, const char *type)
 Create an IQ packet. More...
 
static void xmpp_pubsub_mwi_cb (void *data, struct stasis_subscription *sub, struct stasis_message *msg)
 Callback function for MWI events. More...
 
static void xmpp_pubsub_publish_device_state (struct ast_xmpp_client *client, const char *device, const char *device_state, unsigned int cachable)
 Publish device state to a PubSub node. More...
 
static void xmpp_pubsub_publish_mwi (struct ast_xmpp_client *client, const char *mailbox, const char *oldmsgs, const char *newmsgs)
 Publish MWI to a PubSub node. More...
 
static void xmpp_pubsub_purge_nodes (struct ast_xmpp_client *client, const char *collection_name)
 
static int xmpp_pubsub_receive_node_list (void *data, ikspak *pak)
 Receive pubsub item lists. More...
 
static void xmpp_pubsub_request_nodes (struct ast_xmpp_client *client, const char *collection)
 Request item list from pubsub. More...
 
static void xmpp_pubsub_subscribe (struct ast_xmpp_client *client, const char *node)
 Subscribe to a PubSub node. More...
 
static void xmpp_pubsub_unsubscribe (struct ast_xmpp_client *client, const char *node)
 Unsubscribe from a PubSub node. More...
 
static int xmpp_resource_cmp (void *obj, void *arg, int flags)
 Comparator function for XMPP resource.
 
static void xmpp_resource_destructor (void *obj)
 Destructor callback function for XMPP resource.
 
static int xmpp_resource_hash (const void *obj, const int flags)
 Hashing function for XMPP resource.
 
static int xmpp_resource_immediate (void *obj, void *arg, int flags)
 Internal astobj2 callback function which returns the first resource, which is the highest priority one.
 
static int xmpp_resource_is_available (void *obj, void *arg, int flags)
 Callback function which returns when the resource is available.
 
static int xmpp_roster_hook (void *data, ikspak *pak)
 Hook function called when roster is received from server.
 
static int xmpp_send_cb (const struct ast_msg *msg, const char *to, const char *from)
 
static int xmpp_send_exec (struct ast_channel *chan, const char *data)
 
static int xmpp_send_stream_header (struct ast_xmpp_client *client, const struct ast_xmpp_client_config *cfg, const char *to)
 Helper function which sends an XMPP stream header to the server.
 
static int xmpp_sendgroup_exec (struct ast_channel *chan, const char *data)
 Application to send a message to a groupchat. More...
 
static char * xmpp_show_buddies (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * xmpp_show_clients (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Asterisk XMPP 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 = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DEPEND, }
 
static const char * app_ajijoin = "JabberJoin"
 
static const char * app_ajileave = "JabberLeave"
 
static const char * app_ajisend = "JabberSend"
 
static const char * app_ajisendgroup = "JabberSendGroup"
 
static const char * app_ajistatus = "JabberStatus"
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct aco_type client_option
 
struct aco_typeclient_options [] = ACO_TYPES(&client_option)
 
static int debug
 Global debug status.
 
static struct aco_type global_option
 
struct aco_typeglobal_options [] = ACO_TYPES(&global_option)
 
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 const struct ast_msg_tech msg_tech
 
struct aco_file res_xmpp_conf
 
static struct ast_cli_entry xmpp_cli []
 
static const struct xmpp_pak_handler xmpp_pak_handlers []
 
static const struct xmpp_state_handler xmpp_state_handlers []
 

Detailed Description

XMPP client and component module.

Author
Joshua Colp jcolp.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Iksemel http://code.google.com/p/iksemel/

A reference module for interfacting Asterisk directly as a client or component with an XMPP/Jabber compliant server.

This module is based upon the original res_jabber as done by Matt O'Gorman.

Definition in file res_xmpp.c.

Function Documentation

int ast_xmpp_chatroom_invite ( struct ast_xmpp_client client,
const char *  user,
const char *  room,
const char *  message 
)

Invite a user to an XMPP multi-user chatroom.

Parameters
clientPointer to the client
userJID of the user
roomName of the chatroom
messageMessage to send with the invitation
Return values
0on success
-1on failure

Definition at line 943 of file res_xmpp.c.

References ast_xmpp_client_lock(), ast_xmpp_client_send(), ast_xmpp_client_unlock(), ast_xmpp_increment_mid(), and ast_xmpp_client::mid.

944 {
945  int res = 0;
946  iks *invite, *body = NULL, *namespace = NULL;
947 
948  if (!(invite = iks_new("message")) || !(body = iks_new("body")) || !(namespace = iks_new("x"))) {
949  res = -1;
950  goto done;
951  }
952 
953  iks_insert_attrib(invite, "to", user);
954  ast_xmpp_client_lock(client);
955  iks_insert_attrib(invite, "id", client->mid);
956  ast_xmpp_increment_mid(client->mid);
957  ast_xmpp_client_unlock(client);
958  iks_insert_cdata(body, message, 0);
959  iks_insert_node(invite, body);
960  iks_insert_attrib(namespace, "xmlns", "jabber:x:conference");
961  iks_insert_attrib(namespace, "jid", room);
962  iks_insert_node(invite, namespace);
963 
964  res = ast_xmpp_client_send(client, invite);
965 
966 done:
967  iks_delete(namespace);
968  iks_delete(body);
969  iks_delete(invite);
970 
971  return res;
972 }
void ast_xmpp_increment_mid(char *mid)
Helper function which increments the message identifier.
Definition: res_xmpp.c:1025
void ast_xmpp_client_lock(struct ast_xmpp_client *client)
Lock an XMPP client connection.
Definition: res_xmpp.c:899
structure to hold users read from users.conf
char mid[6]
Definition: xmpp.h:125
void ast_xmpp_client_unlock(struct ast_xmpp_client *client)
Unlock an XMPP client connection.
Definition: res_xmpp.c:904
int ast_xmpp_client_send(struct ast_xmpp_client *client, iks *stanza)
Send an XML stanza out using an established XMPP client connection.
Definition: res_xmpp.c:2534
int ast_xmpp_chatroom_join ( struct ast_xmpp_client client,
const char *  room,
const char *  nickname 
)

Join an XMPP multi-user chatroom.

Parameters
clientPointer to the client
roomName of the chatroom
nicknameNickname to use
Return values
0on success
-1on failure

Definition at line 1010 of file res_xmpp.c.

Referenced by xmpp_join_exec().

1011 {
1012  return xmpp_client_set_group_presence(client, room, IKS_SHOW_AVAILABLE, nickname);
1013 }
int ast_xmpp_chatroom_leave ( struct ast_xmpp_client client,
const char *  room,
const char *  nickname 
)

Leave an XMPP multi-user chatroom.

Parameters
clientPointer to the client
roomName of the chatroom
nicknameNickname being used
Return values
0on success
-1on failure

Definition at line 1020 of file res_xmpp.c.

Referenced by xmpp_leave_exec().

1021 {
1022  return xmpp_client_set_group_presence(client, room, IKS_SHOW_UNAVAILABLE, nickname);
1023 }
int ast_xmpp_chatroom_send ( struct ast_xmpp_client client,
const char *  nickname,
const char *  address,
const char *  message 
)

Send a message to an XMPP multi-user chatroom.

Parameters
clientPointer to the client
nicknameNickname to use
addressAddress of the room
messageMessage itself
Return values
0on success
-1on failure

Definition at line 1015 of file res_xmpp.c.

References xmpp_client_send_message().

Referenced by xmpp_sendgroup_exec().

1016 {
1017  return xmpp_client_send_message(client, 1, nickname, address, message);
1018 }
static int xmpp_client_send_message(struct ast_xmpp_client *client, int group, const char *nick, const char *address, const char *message)
Internal function used to send a message to a user or chatroom.
Definition: res_xmpp.c:910
int ast_xmpp_client_disconnect ( struct ast_xmpp_client client)

Disconnect an XMPP client connection.

Parameters
clientPointer to the client
Return values
0on success
-1on failure

Definition at line 3525 of file res_xmpp.c.

References ast_xmpp_client::device_state_sub, ast_xmpp_client::mwi_sub, stasis_unsubscribe_and_join(), xmpp_client_change_state(), xmpp_pubsub_unsubscribe(), XMPP_STATE_DISCONNECTED, and XMPP_STATE_DISCONNECTING.

Referenced by xmpp_client_destructor(), xmpp_client_reconnect(), and xmpp_client_thread().

3526 {
3527  if ((client->thread != AST_PTHREADT_NULL) && !pthread_equal(pthread_self(), client->thread)) {
3529  pthread_cancel(client->thread);
3530  pthread_join(client->thread, NULL);
3531  client->thread = AST_PTHREADT_NULL;
3532  }
3533 
3534  if (client->mwi_sub) {
3535  client->mwi_sub = stasis_unsubscribe_and_join(client->mwi_sub);
3536  xmpp_pubsub_unsubscribe(client, "message_waiting");
3537  }
3538 
3539  if (client->device_state_sub) {
3541  xmpp_pubsub_unsubscribe(client, "device_state");
3542  }
3543 
3544 #ifdef HAVE_OPENSSL
3545  if (client->stream_flags & SECURE) {
3546  SSL_shutdown(client->ssl_session);
3547  SSL_CTX_free(client->ssl_context);
3548  SSL_free(client->ssl_session);
3549  }
3550 
3551  client->stream_flags = 0;
3552 #endif
3553 
3554  if (client->parser) {
3555  iks_disconnect(client->parser);
3556  }
3557 
3559 
3560  return 0;
3561 }
struct stasis_subscription * device_state_sub
Definition: xmpp.h:146
struct stasis_subscription * mwi_sub
Definition: xmpp.h:144
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
Definition: stasis.c:1134
static void xmpp_pubsub_unsubscribe(struct ast_xmpp_client *client, const char *node)
Unsubscribe from a PubSub node.
Definition: res_xmpp.c:1385
static void xmpp_client_change_state(struct ast_xmpp_client *client, int state)
Internal function which changes the XMPP client state.
Definition: res_xmpp.c:596
struct ast_xmpp_client* ast_xmpp_client_find ( const char *  name)

Find an XMPP client connection using a given name.

Parameters
nameName of the client connection
Return values
non-NULLon success
NULLon failure
Note
This will return the client connection with the reference count incremented by one.

Definition at line 881 of file res_xmpp.c.

References ao2_global_obj_ref, ao2_ref, ast_xmpp_client_config::client, RAII_VAR, and xmpp_config_find().

Referenced by custom_connection_handler().

882 {
883  RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
884  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
885 
886  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, name))) {
887  return NULL;
888  }
889 
890  ao2_ref(clientcfg->client, +1);
891  return clientcfg->client;
892 }
XMPP Client Configuration.
Definition: res_xmpp.c:450
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:657
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
void ast_xmpp_client_lock ( struct ast_xmpp_client client)

Lock an XMPP client connection.

Parameters
clientPointer to the client

Definition at line 899 of file res_xmpp.c.

Referenced by ast_xmpp_chatroom_invite(), xmpp_client_authenticate_digest(), xmpp_client_authenticating(), xmpp_client_send_disco_info_request(), xmpp_component_register_set_hook(), xmpp_pak_message(), xmpp_ping_request(), and xmpp_pubsub_iq_create().

900 {
901  ao2_lock(client);
902 }
int ast_xmpp_client_send ( struct ast_xmpp_client client,
iks *  stanza 
)

Send an XML stanza out using an established XMPP client connection.

Parameters
clientPointer to the client
stanzaPointer to the Iksemel stanza
Return values
0on success
-1on failure

Definition at line 2534 of file res_xmpp.c.

References xmpp_client_send_raw_message().

Referenced by ast_xmpp_chatroom_invite(), jingle_send_error_response(), jingle_send_response(), jingle_send_session_action(), jingle_send_session_info(), jingle_send_session_terminate(), jingle_send_transport_info(), xmpp_client_authenticate_digest(), xmpp_client_authenticate_sasl(), xmpp_client_authenticating(), xmpp_client_send_disco_info_request(), xmpp_client_send_message(), xmpp_client_service_discovery_get_hook(), xmpp_client_set_presence(), xmpp_client_subscribe_user(), xmpp_client_unsubscribe_user(), xmpp_component_register_get_hook(), xmpp_component_register_set_hook(), xmpp_component_service_discovery_get_hook(), xmpp_component_service_discovery_items_hook(), xmpp_connect_hook(), xmpp_pak_s10n(), xmpp_ping_request(), xmpp_pubsub_create_affiliations(), xmpp_pubsub_create_node(), xmpp_pubsub_delete_node(), xmpp_pubsub_publish_device_state(), xmpp_pubsub_publish_mwi(), xmpp_pubsub_request_nodes(), xmpp_pubsub_subscribe(), and xmpp_pubsub_unsubscribe().

2535 {
2536  return xmpp_client_send_raw_message(client, iks_string(iks_stack(stanza), stanza));
2537 }
static int xmpp_client_send_raw_message(struct ast_xmpp_client *client, const char *message)
Internal function which sends a raw message.
Definition: res_xmpp.c:2489
int ast_xmpp_client_send_message ( struct ast_xmpp_client client,
const char *  user,
const char *  message 
)

Send a message to a given user using an established XMPP client connection.

Parameters
clientPointer to the client
userUser the message should be sent to
messageThe message to send
Return values
0on success
-1on failure

Definition at line 938 of file res_xmpp.c.

References xmpp_client_send_message().

Referenced by jingle_sendtext().

939 {
940  return xmpp_client_send_message(client, 0, NULL, user, message);
941 }
structure to hold users read from users.conf
static int xmpp_client_send_message(struct ast_xmpp_client *client, int group, const char *nick, const char *address, const char *message)
Internal function used to send a message to a user or chatroom.
Definition: res_xmpp.c:910
void ast_xmpp_client_unlock ( struct ast_xmpp_client client)

Unlock an XMPP client connection.

Parameters
clientPointer to the client

Definition at line 904 of file res_xmpp.c.

Referenced by ast_xmpp_chatroom_invite(), xmpp_client_authenticate_digest(), xmpp_client_authenticating(), xmpp_client_send_disco_info_request(), xmpp_component_register_set_hook(), xmpp_pak_message(), xmpp_ping_request(), and xmpp_pubsub_iq_create().

905 {
906  ao2_unlock(client);
907 }
void ast_xmpp_client_unref ( struct ast_xmpp_client client)

Release XMPP client connection reference.

Parameters
clientPointer to the client

Definition at line 894 of file res_xmpp.c.

References ao2_ref.

Referenced by jingle_endpoint_destructor(), and jingle_session_destructor().

895 {
896  ao2_ref(client, -1);
897 }
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
void ast_xmpp_increment_mid ( char *  mid)

Helper function which increments the message identifier.

Parameters
midPointer to a string containing the message identifier

Definition at line 1025 of file res_xmpp.c.

Referenced by ast_xmpp_chatroom_invite(), jingle_send_session_action(), jingle_send_session_info(), jingle_send_session_terminate(), jingle_send_transport_info(), xmpp_client_authenticate_digest(), xmpp_client_authenticating(), xmpp_client_send_disco_info_request(), xmpp_component_register_set_hook(), xmpp_ping_request(), and xmpp_pubsub_iq_create().

1026 {
1027  int i = 0;
1028 
1029  for (i = strlen(mid) - 1; i >= 0; i--) {
1030  if (mid[i] != 'z') {
1031  mid[i] = mid[i] + 1;
1032  i = 0;
1033  } else {
1034  mid[i] = 'a';
1035  }
1036  }
1037 }
static int load_module ( void  )
static

Load the module.

Module loading including tests for configuration or dependencies. This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails tests return AST_MODULE_LOAD_FAILURE. If the module can not load the configuration file or other non-critical problem return AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.

Definition at line 4619 of file res_xmpp.c.

References aco_info_destroy(), aco_info_init(), aco_option_register, aco_option_register_custom, aco_process_config(), ACO_PROCESS_ERROR, ast_cli_register_multiple, ast_custom_function_register, ast_eid_default, ast_eid_is_empty(), ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_msg_tech_register(), ast_register_application_xml, FLDSET, OPT_STRINGFIELD_T, OPT_UINT_T, STRFLDSET, xmpp_join_exec(), xmpp_leave_exec(), and xmpp_sendgroup_exec().

4620 {
4621  if (aco_info_init(&cfg_info)) {
4622  return AST_MODULE_LOAD_DECLINE;
4623  }
4624 
4625  aco_option_register_custom(&cfg_info, "debug", ACO_EXACT, global_options, "no", global_bitfield_handler, 0);
4626  aco_option_register_custom(&cfg_info, "autoprune", ACO_EXACT, global_options, "no", global_bitfield_handler, 0);
4627  aco_option_register_custom(&cfg_info, "autoregister", ACO_EXACT, global_options, "yes", global_bitfield_handler, 0);
4628  aco_option_register_custom(&cfg_info, "collection_nodes", ACO_EXACT, global_options, "no", global_bitfield_handler, 0);
4629  aco_option_register_custom(&cfg_info, "pubsub_autocreate", ACO_EXACT, global_options, "no", global_bitfield_handler, 0);
4630  aco_option_register_custom(&cfg_info, "auth_policy", ACO_EXACT, global_options, "accept", global_bitfield_handler, 0);
4631 
4632  aco_option_register(&cfg_info, "username", ACO_EXACT, client_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_xmpp_client_config, user));
4633  aco_option_register(&cfg_info, "secret", ACO_EXACT, client_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_xmpp_client_config, password));
4634  aco_option_register(&cfg_info, "refresh_token", ACO_EXACT, client_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_xmpp_client_config, refresh_token));
4635  aco_option_register(&cfg_info, "oauth_clientid", ACO_EXACT, client_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_xmpp_client_config, oauth_clientid));
4636  aco_option_register(&cfg_info, "oauth_secret", ACO_EXACT, client_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_xmpp_client_config, oauth_secret));
4637  aco_option_register(&cfg_info, "serverhost", ACO_EXACT, client_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_xmpp_client_config, server));
4638  aco_option_register(&cfg_info, "statusmessage", ACO_EXACT, client_options, "Online and Available", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_xmpp_client_config, statusmsg));
4639  aco_option_register(&cfg_info, "pubsub_node", ACO_EXACT, client_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_xmpp_client_config, pubsubnode));
4640  aco_option_register(&cfg_info, "context", ACO_EXACT, client_options, "default", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_xmpp_client_config, context));
4641  aco_option_register(&cfg_info, "priority", ACO_EXACT, client_options, "1", OPT_UINT_T, 0, FLDSET(struct ast_xmpp_client_config, priority));
4642  aco_option_register(&cfg_info, "port", ACO_EXACT, client_options, "5222", OPT_UINT_T, 0, FLDSET(struct ast_xmpp_client_config, port));
4643  aco_option_register(&cfg_info, "timeout", ACO_EXACT, client_options, "5", OPT_UINT_T, 0, FLDSET(struct ast_xmpp_client_config, message_timeout));
4644 
4645  /* Global options that can be overridden per client must not specify a default */
4646  aco_option_register_custom(&cfg_info, "autoprune", ACO_EXACT, client_options, NULL, client_bitfield_handler, 0);
4647  aco_option_register_custom(&cfg_info, "autoregister", ACO_EXACT, client_options, NULL, client_bitfield_handler, 0);
4648  aco_option_register_custom(&cfg_info, "auth_policy", ACO_EXACT, client_options, NULL, client_bitfield_handler, 0);
4649 
4650  aco_option_register_custom(&cfg_info, "debug", ACO_EXACT, client_options, "no", client_bitfield_handler, 0);
4651  aco_option_register_custom(&cfg_info, "type", ACO_EXACT, client_options, "client", client_bitfield_handler, 0);
4652  aco_option_register_custom(&cfg_info, "distribute_events", ACO_EXACT, client_options, "no", client_bitfield_handler, 0);
4653  aco_option_register_custom(&cfg_info, "usetls", ACO_EXACT, client_options, "yes", client_bitfield_handler, 0);
4654  aco_option_register_custom(&cfg_info, "usesasl", ACO_EXACT, client_options, "yes", client_bitfield_handler, 0);
4655  aco_option_register_custom(&cfg_info, "forceoldssl", ACO_EXACT, client_options, "no", client_bitfield_handler, 0);
4656  aco_option_register_custom(&cfg_info, "keepalive", ACO_EXACT, client_options, "yes", client_bitfield_handler, 0);
4657  aco_option_register_custom(&cfg_info, "sendtodialplan", ACO_EXACT, client_options, "no", client_bitfield_handler, 0);
4658  aco_option_register_custom(&cfg_info, "status", ACO_EXACT, client_options, "available", client_status_handler, 0);
4659  aco_option_register_custom(&cfg_info, "buddy", ACO_EXACT, client_options, NULL, client_buddy_handler, 0);
4660 
4661  if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {
4662  aco_info_destroy(&cfg_info);
4663  return AST_MODULE_LOAD_DECLINE;
4664  }
4665 
4666  ast_manager_register_xml("JabberSend", EVENT_FLAG_SYSTEM, manager_jabber_send);
4667 
4668  ast_register_application_xml(app_ajisend, xmpp_send_exec);
4672 
4673  ast_cli_register_multiple(xmpp_cli, ARRAY_LEN(xmpp_cli));
4674  ast_custom_function_register(&jabberstatus_function);
4675  ast_custom_function_register(&jabberreceive_function);
4676  ast_msg_tech_register(&msg_tech);
4677 
4678  ast_mutex_init(&messagelock);
4679  ast_cond_init(&message_received_condition, NULL);
4680 
4682  ast_log(LOG_WARNING, "Entity ID is not set. The distributing device state or MWI will not work.\n");
4683  }
4684 
4685  return AST_MODULE_LOAD_SUCCESS;
4686 }
XMPP Client Configuration.
Definition: res_xmpp.c:450
#define aco_option_register_custom(info, name, matchtype, types, default_val, handler, flags)
Register a config option.
static int xmpp_leave_exec(struct ast_channel *chan, const char *data)
Application to leave a chat room.
Definition: res_xmpp.c:1777
#define aco_option_register(info, name, matchtype, types, default_val, opt_type, flags,...)
Register a config option.
int ast_msg_tech_register(const struct ast_msg_tech *tech)
Register a message technology.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
enum aco_process_status aco_process_config(struct aco_info *info, int reload)
Process a config info via the options registered with an aco_info.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
Type for default option handler for unsigned integers.
Their was an error and no changes were applied.
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
static int xmpp_sendgroup_exec(struct ast_channel *chan, const char *data)
Application to send a message to a groupchat.
Definition: res_xmpp.c:1879
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
structure to hold users read from users.conf
struct ast_eid ast_eid_default
Global EID.
Definition: options.c:93
static int xmpp_join_exec(struct ast_channel *chan, const char *data)
Application to join a chat room.
Definition: res_xmpp.c:1718
Type for default option handler for stringfields.
int ast_eid_is_empty(const struct ast_eid *eid)
Check if EID is empty.
Definition: utils.c:3099
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:191
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1558
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:640
static char* xmpp_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 4218 of file res_xmpp.c.

References ao2_global_obj_ref, ast_xmpp_client_config::client, ast_cli_entry::command, ast_xmpp_client::name, RAII_VAR, ast_cli_entry::usage, xmpp_config_find(), and xmpp_pubsub_create_collection().

4219 {
4220  RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
4221  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
4222  const char *name, *collection_name;
4223 
4224  switch (cmd) {
4225  case CLI_INIT:
4226  e->command = "xmpp create collection";
4227  e->usage =
4228  "Usage: xmpp create collection <connection> <collection>\n"
4229  " Creates a PubSub collection node using the account\n"
4230  " as configured in xmpp.conf.\n";
4231  return NULL;
4232  case CLI_GENERATE:
4233  return NULL;
4234  }
4235 
4236  if (a->argc != 5) {
4237  return CLI_SHOWUSAGE;
4238  }
4239  name = a->argv[3];
4240  collection_name = a->argv[4];
4241 
4242  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, name))) {
4243  ast_cli(a->fd, "Unable to find client '%s'!\n", name);
4244  return CLI_FAILURE;
4245  }
4246 
4247  ast_cli(a->fd, "Creating test PubSub node collection.\n");
4248 
4249  xmpp_pubsub_create_collection(clientcfg->client, collection_name);
4250 
4251  return CLI_SUCCESS;
4252 }
static void xmpp_pubsub_create_collection(struct ast_xmpp_client *client, const char *collection_name)
Create a PubSub collection node.
Definition: res_xmpp.c:1244
XMPP Client Configuration.
Definition: res_xmpp.c:450
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:657
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
static char* xmpp_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 4258 of file res_xmpp.c.

References ao2_global_obj_ref, ast_xmpp_client_config::client, ast_cli_entry::command, ast_xmpp_client::name, RAII_VAR, ast_cli_entry::usage, xmpp_config_find(), and xmpp_pubsub_create_leaf().

4259 {
4260  RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
4261  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
4262  const char *name, *collection_name, *leaf_name;
4263 
4264  switch (cmd) {
4265  case CLI_INIT:
4266  e->command = "xmpp create leaf";
4267  e->usage =
4268  "Usage: xmpp create leaf <connection> <collection> <leaf>\n"
4269  " Creates a PubSub leaf node using the account\n"
4270  " as configured in xmpp.conf.\n";
4271  return NULL;
4272  case CLI_GENERATE:
4273  return NULL;
4274  }
4275 
4276  if (a->argc != 6) {
4277  return CLI_SHOWUSAGE;
4278  }
4279  name = a->argv[3];
4280  collection_name = a->argv[4];
4281  leaf_name = a->argv[5];
4282 
4283  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, name))) {
4284  ast_cli(a->fd, "Unable to find client '%s'!\n", name);
4285  return CLI_FAILURE;
4286  }
4287 
4288  ast_cli(a->fd, "Creating test PubSub node collection.\n");
4289 
4290  xmpp_pubsub_create_leaf(clientcfg->client, collection_name, leaf_name);
4291 
4292  return CLI_SUCCESS;
4293 }
XMPP Client Configuration.
Definition: res_xmpp.c:450
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:657
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
static void xmpp_pubsub_create_leaf(struct ast_xmpp_client *client, const char *collection_name, const char *leaf_name)
Create a PubSub leaf node.
Definition: res_xmpp.c:1256
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
static char* xmpp_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 4180 of file res_xmpp.c.

References ao2_global_obj_ref, ast_xmpp_client_config::client, ast_cli_entry::command, ast_xmpp_client::name, RAII_VAR, ast_cli_entry::usage, xmpp_config_find(), and xmpp_pubsub_delete_node().

4182 {
4183  RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
4184  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
4185  const char *name;
4186 
4187  switch (cmd) {
4188  case CLI_INIT:
4189  e->command = "xmpp delete node";
4190  e->usage =
4191  "Usage: xmpp delete node <connection> <node>\n"
4192  " Deletes a node on PubSub server\n"
4193  " as configured in xmpp.conf.\n";
4194  return NULL;
4195  case CLI_GENERATE:
4196  return NULL;
4197  }
4198 
4199  if (a->argc != 5) {
4200  return CLI_SHOWUSAGE;
4201  }
4202  name = a->argv[3];
4203 
4204  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, name))) {
4205  ast_cli(a->fd, "Unable to find client '%s'!\n", name);
4206  return CLI_FAILURE;
4207  }
4208 
4209  xmpp_pubsub_delete_node(clientcfg->client, a->argv[4]);
4210 
4211  return CLI_SUCCESS;
4212 }
XMPP Client Configuration.
Definition: res_xmpp.c:450
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:657
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
static void xmpp_pubsub_delete_node(struct ast_xmpp_client *client, const char *node_name)
Delete a PubSub node.
Definition: res_xmpp.c:1222
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
static char* xmpp_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 4049 of file res_xmpp.c.

References ao2_global_obj_ref, ast_xmpp_client_config::client, ast_cli_entry::command, RAII_VAR, ast_cli_entry::usage, xmpp_config_find(), and xmpp_pubsub_request_nodes().

4051 {
4052  RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
4053  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
4054  const char *name = NULL, *collection = NULL;
4055 
4056  switch (cmd) {
4057  case CLI_INIT:
4058  e->command = "xmpp list nodes";
4059  e->usage =
4060  "Usage: xmpp list nodes <connection> [collection]\n"
4061  " Lists the user's nodes on the respective connection\n"
4062  " ([connection] as configured in xmpp.conf.)\n";
4063  return NULL;
4064  case CLI_GENERATE:
4065  return NULL;
4066  }
4067 
4068  if (a->argc > 5 || a->argc < 4) {
4069  return CLI_SHOWUSAGE;
4070  } else if (a->argc == 4 || a->argc == 5) {
4071  name = a->argv[3];
4072  }
4073 
4074  if (a->argc == 5) {
4075  collection = a->argv[4];
4076  }
4077 
4078  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, name))) {
4079  ast_cli(a->fd, "Unable to find client '%s'!\n", name);
4080  return CLI_FAILURE;
4081  }
4082 
4083  ast_cli(a->fd, "Listing pubsub nodes.\n");
4084 
4085  xmpp_pubsub_request_nodes(clientcfg->client, collection);
4086 
4087  return CLI_SUCCESS;
4088 }
XMPP Client Configuration.
Definition: res_xmpp.c:450
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:657
static void xmpp_pubsub_request_nodes(struct ast_xmpp_client *client, const char *collection)
Request item list from pubsub.
Definition: res_xmpp.c:4025
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
static char* xmpp_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 4135 of file res_xmpp.c.

References ao2_global_obj_ref, ast_xmpp_client_config::client, ast_cli_entry::command, ast_xmpp_client::name, RAII_VAR, ast_cli_entry::usage, xmpp_config_find(), and xmpp_pubsub_delete_node().

4137 {
4138  RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
4139  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
4140  const char *name;
4141 
4142  switch (cmd) {
4143  case CLI_INIT:
4144  e->command = "xmpp purge nodes";
4145  e->usage =
4146  "Usage: xmpp purge nodes <connection> <node>\n"
4147  " Purges nodes on PubSub server\n"
4148  " as configured in xmpp.conf.\n";
4149  return NULL;
4150  case CLI_GENERATE:
4151  return NULL;
4152  }
4153 
4154  if (a->argc != 5) {
4155  return CLI_SHOWUSAGE;
4156  }
4157  name = a->argv[3];
4158 
4159  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, name))) {
4160  ast_cli(a->fd, "Unable to find client '%s'!\n", name);
4161  return CLI_FAILURE;
4162  }
4163 
4164  if (ast_test_flag(&cfg->global->pubsub, XMPP_XEP0248)) {
4165  xmpp_pubsub_purge_nodes(clientcfg->client, a->argv[4]);
4166  } else {
4167  xmpp_pubsub_delete_node(clientcfg->client, a->argv[4]);
4168  }
4169 
4170  return CLI_SUCCESS;
4171 }
XMPP Client Configuration.
Definition: res_xmpp.c:450
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:657
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
static void xmpp_pubsub_delete_node(struct ast_xmpp_client *client, const char *node_name)
Delete a PubSub node.
Definition: res_xmpp.c:1222
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
static void xmpp_init_event_distribution ( struct ast_xmpp_client client)
static

Initialize collections for event distribution.

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

Definition at line 1583 of file res_xmpp.c.

References ao2_callback, ao2_global_obj_ref, ast_device_state_cache(), ast_device_state_message_type(), ast_device_state_topic_all(), ast_mwi_state_type(), ast_mwi_topic_all(), ast_xmpp_client::device_state_sub, ast_xmpp_client::mwi_sub, ast_xmpp_client::name, OBJ_NODATA, ast_xmpp_client_config::pubsubnode, RAII_VAR, stasis_cache_dump(), stasis_subscription_accept_message_type(), STASIS_SUBSCRIPTION_FILTER_SELECTIVE, stasis_subscription_set_filter(), stasis_unsubscribe(), xmpp_config_find(), xmpp_pubsub_devstate_cb(), xmpp_pubsub_handle_event(), xmpp_pubsub_mwi_cb(), xmpp_pubsub_subscribe(), and xmpp_pubsub_unsubscribe().

Referenced by xmpp_connect_hook().

1584 {
1585  RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
1586  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
1587  RAII_VAR(struct ao2_container *, cached, NULL, ao2_cleanup);
1588 
1589  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name))) {
1590  return;
1591  }
1592 
1593  xmpp_pubsub_unsubscribe(client, "device_state");
1594  xmpp_pubsub_unsubscribe(client, "message_waiting");
1595 
1596  if (!(client->mwi_sub = stasis_subscribe_pool(ast_mwi_topic_all(), xmpp_pubsub_mwi_cb, client))) {
1597  return;
1598  }
1601 
1602  if (!(client->device_state_sub = stasis_subscribe(ast_device_state_topic_all(), xmpp_pubsub_devstate_cb, client))) {
1603  client->mwi_sub = stasis_unsubscribe(client->mwi_sub);
1604  return;
1605  }
1608 
1609  cached = stasis_cache_dump(ast_device_state_cache(), NULL);
1610  ao2_callback(cached, OBJ_NODATA, cached_devstate_cb, client);
1611 
1612  xmpp_pubsub_subscribe(client, "device_state");
1613  xmpp_pubsub_subscribe(client, "message_waiting");
1614  iks_filter_add_rule(client->filter, xmpp_pubsub_handle_event, client, IKS_RULE_TYPE,
1615  IKS_PAK_MESSAGE, IKS_RULE_FROM, clientcfg->pubsubnode, IKS_RULE_DONE);
1616  iks_filter_add_rule(client->filter, xmpp_pubsub_handle_error, client, IKS_RULE_TYPE,
1617  IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_ERROR, IKS_RULE_DONE);
1618 
1619 }
XMPP Client Configuration.
Definition: res_xmpp.c:450
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:657
static void xmpp_pubsub_mwi_cb(void *data, struct stasis_subscription *sub, struct stasis_message *msg)
Callback function for MWI events.
Definition: res_xmpp.c:1335
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
Definition: astobj2.h:1693
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
Definition: stasis.c:1077
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
struct ao2_container * stasis_cache_dump(struct stasis_cache *cache, struct stasis_message_type *type)
Dump cached items to a subscription for the ast_eid_default entity.
Definition: stasis_cache.c:736
struct stasis_subscription * device_state_sub
Definition: xmpp.h:146
static void xmpp_pubsub_devstate_cb(void *data, struct stasis_subscription *sub, struct stasis_message *msg)
Callback function for device state events.
Definition: res_xmpp.c:1362
static void xmpp_pubsub_subscribe(struct ast_xmpp_client *client, const char *node)
Subscribe to a PubSub node.
Definition: res_xmpp.c:1410
struct stasis_message_type * ast_device_state_message_type(void)
Get the Stasis message type for device state messages.
static int xmpp_pubsub_handle_event(void *data, ikspak *pak)
Callback for handling PubSub events.
Definition: res_xmpp.c:1457
struct stasis_subscription * mwi_sub
Definition: xmpp.h:144
struct stasis_cache * ast_device_state_cache(void)
Backend cache for ast_device_state_topic_cached()
Definition: devicestate.c:673
struct stasis_message_type * ast_mwi_state_type(void)
Get the Stasis Message Bus API message type for MWI messages.
struct stasis_subscription * stasis_unsubscribe(struct stasis_subscription *subscription)
Cancel a subscription.
Definition: stasis.c:971
struct stasis_topic * ast_device_state_topic_all(void)
Get the Stasis topic for device state messages.
Definition: devicestate.c:668
const ast_string_field name
Definition: xmpp.h:123
static void xmpp_pubsub_unsubscribe(struct ast_xmpp_client *client, const char *node)
Unsubscribe from a PubSub node.
Definition: res_xmpp.c:1385
int stasis_subscription_accept_message_type(struct stasis_subscription *subscription, const struct stasis_message_type *type)
Indicate to a subscription that we are interested in a message type.
Definition: stasis.c:1023
Generic container type.
struct stasis_topic * ast_mwi_topic_all(void)
Get the Stasis Message Bus API topic for MWI messages.
Definition: mwi.c:89
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
static int xmpp_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 1718 of file res_xmpp.c.

References ao2_global_obj_ref, AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_xmpp_chatroom_join(), ast_xmpp_client_config::client, ast_xmpp_client_config::flags, RAII_VAR, xmpp_config_find(), and XMPP_MAX_RESJIDLEN.

Referenced by load_module().

1719 {
1720  RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
1721  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
1722  char *s, nick[XMPP_MAX_RESJIDLEN];
1723  AST_DECLARE_APP_ARGS(args,
1724  AST_APP_ARG(sender);
1725  AST_APP_ARG(jid);
1726  AST_APP_ARG(nick);
1727  );
1728 
1729  if (ast_strlen_zero(data)) {
1730  ast_log(LOG_ERROR, "%s requires arguments (sender,jid[,nickname])\n", app_ajijoin);
1731  return -1;
1732  }
1733  s = ast_strdupa(data);
1734 
1735  AST_STANDARD_APP_ARGS(args, s);
1736  if (args.argc < 2 || args.argc > 3) {
1737  ast_log(LOG_ERROR, "%s requires arguments (sender,jid[,nickname])\n", app_ajijoin);
1738  return -1;
1739  }
1740 
1741  if (strchr(args.jid, '/')) {
1742  ast_log(LOG_ERROR, "Invalid room name : resource must not be appended\n");
1743  return -1;
1744  }
1745 
1746  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, args.sender))) {
1747  ast_log(LOG_ERROR, "Could not find sender connection: '%s'\n", args.sender);
1748  return -1;
1749  }
1750 
1751  if (ast_strlen_zero(args.nick)) {
1752  if (ast_test_flag(&clientcfg->flags, XMPP_COMPONENT)) {
1753  snprintf(nick, sizeof(nick), "asterisk");
1754  } else {
1755  snprintf(nick, sizeof(nick), "%s", clientcfg->client->jid->user);
1756  }
1757  } else {
1758  snprintf(nick, sizeof(nick), "%s", args.nick);
1759  }
1760 
1761  if (!ast_strlen_zero(args.jid) && strchr(args.jid, '@')) {
1762  ast_xmpp_chatroom_join(clientcfg->client, args.jid, nick);
1763  } else {
1764  ast_log(LOG_ERROR, "Problem with specified jid of '%s'\n", args.jid);
1765  }
1766 
1767  return 0;
1768 }
XMPP Client Configuration.
Definition: res_xmpp.c:450
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:657
int ast_xmpp_chatroom_join(struct ast_xmpp_client *client, const char *room, const char *nickname)
Join an XMPP multi-user chatroom.
Definition: res_xmpp.c:1010
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
#define XMPP_MAX_RESJIDLEN
Maximum size of a resource JID.
Definition: xmpp.h:65
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_APP_ARG(name)
Define an application argument.
static int xmpp_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 1777 of file res_xmpp.c.

References ao2_global_obj_ref, AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_xmpp_chatroom_leave(), ast_xmpp_client_config::client, ast_xmpp_client_config::flags, RAII_VAR, xmpp_config_find(), and XMPP_MAX_RESJIDLEN.

Referenced by load_module().

1778 {
1779  RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
1780  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
1781  char *s, nick[XMPP_MAX_RESJIDLEN];
1782  AST_DECLARE_APP_ARGS(args,
1783  AST_APP_ARG(sender);
1784  AST_APP_ARG(jid);
1785  AST_APP_ARG(nick);
1786  );
1787 
1788  if (ast_strlen_zero(data)) {
1789  ast_log(LOG_ERROR, "%s requires arguments (sender,jid[,nickname])\n", app_ajileave);
1790  return -1;
1791  }
1792  s = ast_strdupa(data);
1793 
1794  AST_STANDARD_APP_ARGS(args, s);
1795  if (args.argc < 2 || args.argc > 3) {
1796  ast_log(LOG_ERROR, "%s requires arguments (sender,jid[,nickname])\n", app_ajileave);
1797  return -1;
1798  }
1799 
1800  if (strchr(args.jid, '/')) {
1801  ast_log(LOG_ERROR, "Invalid room name, resource must not be appended\n");
1802  return -1;
1803  }
1804 
1805  if (ast_strlen_zero(args.jid) || !strchr(args.jid, '@')) {
1806  ast_log(LOG_ERROR, "No jabber ID specified\n");
1807  return -1;
1808  }
1809 
1810  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, args.sender))) {
1811  ast_log(LOG_ERROR, "Could not find sender connection: '%s'\n", args.sender);
1812  return -1;
1813  }
1814 
1815  if (ast_strlen_zero(args.nick)) {
1816  if (ast_test_flag(&clientcfg->flags, XMPP_COMPONENT)) {
1817  snprintf(nick, sizeof(nick), "asterisk");
1818  } else {
1819  snprintf(nick, sizeof(nick), "%s", clientcfg->client->jid->user);
1820  }
1821  } else {
1822  snprintf(nick, sizeof(nick), "%s", args.nick);
1823  }
1824 
1825  ast_xmpp_chatroom_leave(clientcfg->client, args.jid, nick);
1826 
1827  return 0;
1828 }
int ast_xmpp_chatroom_leave(struct ast_xmpp_client *client, const char *room, const char *nickname)
Leave an XMPP multi-user chatroom.
Definition: res_xmpp.c:1020
XMPP Client Configuration.
Definition: res_xmpp.c:450
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:657
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
#define XMPP_MAX_RESJIDLEN
Maximum size of a resource JID.
Definition: xmpp.h:65
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_APP_ARG(name)
Define an application argument.
static iks* xmpp_pubsub_build_node_request ( struct ast_xmpp_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 3974 of file res_xmpp.c.

References xmpp_pubsub_iq_create().

Referenced by xmpp_pubsub_request_nodes().

3975 {
3976  iks *request = xmpp_pubsub_iq_create(client, "get"), *query;
3977 
3978  if (!request) {
3979  return NULL;
3980  }
3981 
3982  query = iks_insert(request, "query");
3983  iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items");
3984 
3985  if (collection) {
3986  iks_insert_attrib(query, "node", collection);
3987  }
3988 
3989  return request;
3990 }
static iks * xmpp_pubsub_iq_create(struct ast_xmpp_client *client, const char *type)
Create an IQ packet.
Definition: res_xmpp.c:1045
static iks* xmpp_pubsub_build_publish_skeleton ( struct ast_xmpp_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,cachable
Returns
iks *

Definition at line 1077 of file res_xmpp.c.

References ao2_global_obj_ref, AST_DEVSTATE_NOT_CACHABLE, RAII_VAR, and xmpp_pubsub_iq_create().

Referenced by xmpp_pubsub_publish_device_state(), and xmpp_pubsub_publish_mwi().

1079 {
1080  RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
1081  iks *request, *pubsub, *publish, *item;
1082 
1083  if (!cfg || !cfg->global || !(request = xmpp_pubsub_iq_create(client, "set"))) {
1084  return NULL;
1085  }
1086 
1087  pubsub = iks_insert(request, "pubsub");
1088  iks_insert_attrib(pubsub, "xmlns", "http://jabber.org/protocol/pubsub");
1089  publish = iks_insert(pubsub, "publish");
1090  iks_insert_attrib(publish, "node", ast_test_flag(&cfg->global->pubsub, XMPP_XEP0248) ? node : event_type);
1091  item = iks_insert(publish, "item");
1092  iks_insert_attrib(item, "id", node);
1093 
1094  if (cachable == AST_DEVSTATE_NOT_CACHABLE) {
1095  iks *options, *x, *field_form_type, *field_persist;
1096 
1097  options = iks_insert(pubsub, "publish-options");
1098  x = iks_insert(options, "x");
1099  iks_insert_attrib(x, "xmlns", "jabber:x:data");
1100  iks_insert_attrib(x, "type", "submit");
1101  field_form_type = iks_insert(x, "field");
1102  iks_insert_attrib(field_form_type, "var", "FORM_TYPE");
1103  iks_insert_attrib(field_form_type, "type", "hidden");
1104  iks_insert_cdata(iks_insert(field_form_type, "value"), "http://jabber.org/protocol/pubsub#publish-options", 0);
1105  field_persist = iks_insert(x, "field");
1106  iks_insert_attrib(field_persist, "var", "pubsub#persist_items");
1107  iks_insert_cdata(iks_insert(field_persist, "value"), "0", 1);
1108  }
1109 
1110  return item;
1111 
1112 }
Definition: test_heap.c:38
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
static iks * xmpp_pubsub_iq_create(struct ast_xmpp_client *client, const char *type)
Create an IQ packet.
Definition: res_xmpp.c:1045
static void xmpp_pubsub_create_affiliations ( struct ast_xmpp_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

Definition at line 1161 of file res_xmpp.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_ref, ast_xmpp_client_send(), ast_xmpp_buddy::id, ast_xmpp_client::name, and xmpp_pubsub_iq_create().

Referenced by xmpp_pubsub_create_node().

1162 {
1163  iks *modify_affiliates = xmpp_pubsub_iq_create(client, "set");
1164  iks *pubsub, *affiliations, *affiliate;
1165  struct ao2_iterator i;
1166  struct ast_xmpp_buddy *buddy;
1167 
1168  if (!modify_affiliates) {
1169  ast_log(LOG_ERROR, "Could not create IQ for creating affiliations on client '%s'\n", client->name);
1170  return;
1171  }
1172 
1173  pubsub = iks_insert(modify_affiliates, "pubsub");
1174  iks_insert_attrib(pubsub, "xmlns", "http://jabber.org/protocol/pubsub#owner");
1175  affiliations = iks_insert(pubsub, "affiliations");
1176  iks_insert_attrib(affiliations, "node", node);
1177 
1178  i = ao2_iterator_init(client->buddies, 0);
1179  while ((buddy = ao2_iterator_next(&i))) {
1180  affiliate = iks_insert(affiliations, "affiliation");
1181  iks_insert_attrib(affiliate, "jid", buddy->id);
1182  iks_insert_attrib(affiliate, "affiliation", "owner");
1183  ao2_ref(buddy, -1);
1184  }
1186 
1187  ast_xmpp_client_send(client, modify_affiliates);
1188  iks_delete(modify_affiliates);
1189 }
Definition: test_heap.c:38
char id[XMPP_MAX_JIDLEN]
Definition: xmpp.h:113
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
XMPP Buddy.
Definition: xmpp.h:112
const ast_string_field name
Definition: xmpp.h:123
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
static iks * xmpp_pubsub_iq_create(struct ast_xmpp_client *client, const char *type)
Create an IQ packet.
Definition: res_xmpp.c:1045
int ast_xmpp_client_send(struct ast_xmpp_client *client, iks *stanza)
Send an XML stanza out using an established XMPP client connection.
Definition: res_xmpp.c:2534
static void xmpp_pubsub_create_collection ( struct ast_xmpp_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

Definition at line 1244 of file res_xmpp.c.

References xmpp_pubsub_create_node().

Referenced by xmpp_cli_create_collection().

1245 {
1246  xmpp_pubsub_create_node(client, "collection", collection_name, NULL);
1247 }
static void xmpp_pubsub_create_node(struct ast_xmpp_client *client, const char *node_type, const char *name, const char *collection_name)
Create a pubsub node.
Definition: res_xmpp.c:1198
static void xmpp_pubsub_create_leaf ( struct ast_xmpp_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
collection_name
leaf_nameThe name to use for this collection

Definition at line 1256 of file res_xmpp.c.

References xmpp_pubsub_create_node().

Referenced by xmpp_cli_create_leafnode().

1258 {
1259  xmpp_pubsub_create_node(client, "leaf", leaf_name, collection_name);
1260 }
static void xmpp_pubsub_create_node(struct ast_xmpp_client *client, const char *node_type, const char *name, const char *collection_name)
Create a pubsub node.
Definition: res_xmpp.c:1198
static void xmpp_pubsub_create_node ( struct ast_xmpp_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
collection_name

Definition at line 1198 of file res_xmpp.c.

References ast_xmpp_client_send(), xmpp_pubsub_create_affiliations(), and xmpp_pubsub_iq_create().

Referenced by xmpp_pubsub_create_collection(), xmpp_pubsub_create_leaf(), and xmpp_pubsub_publish_device_state().

1200 {
1201  iks *node, *pubsub, *create;
1202 
1203  if (!(node = xmpp_pubsub_iq_create(client, "set"))) {
1204  return;
1205  }
1206 
1207  pubsub = iks_insert(node, "pubsub");
1208  iks_insert_attrib(pubsub, "xmlns", "http://jabber.org/protocol/pubsub");
1209  create = iks_insert(pubsub, "create");
1210  iks_insert_attrib(create, "node", name);
1211  xmpp_pubsub_build_node_config(pubsub, node_type, collection_name);
1212  ast_xmpp_client_send(client, node);
1213  xmpp_pubsub_create_affiliations(client, name);
1214  iks_delete(node);
1215 }
Definition: test_heap.c:38
static void xmpp_pubsub_create_affiliations(struct ast_xmpp_client *client, const char *node)
Add Owner affiliations for pubsub node.
Definition: res_xmpp.c:1161
static iks * xmpp_pubsub_iq_create(struct ast_xmpp_client *client, const char *type)
Create an IQ packet.
Definition: res_xmpp.c:1045
int ast_xmpp_client_send(struct ast_xmpp_client *client, iks *stanza)
Send an XML stanza out using an established XMPP client connection.
Definition: res_xmpp.c:2534
static void xmpp_pubsub_delete_node ( struct ast_xmpp_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

Definition at line 1222 of file res_xmpp.c.

References ast_xmpp_client_send(), and xmpp_pubsub_iq_create().

Referenced by xmpp_cli_delete_pubsub_node(), xmpp_cli_purge_pubsub_nodes(), and xmpp_pubsub_delete_node_list().

1223 {
1224  iks *request, *pubsub, *delete;
1225 
1226  if (!(request = xmpp_pubsub_iq_create(client, "set"))) {
1227  return;
1228  }
1229 
1230  pubsub = iks_insert(request, "pubsub");
1231  iks_insert_attrib(pubsub, "xmlns", "http://jabber.org/protocol/pubsub#owner");
1232  delete = iks_insert(pubsub, "delete");
1233  iks_insert_attrib(delete, "node", node_name);
1234  ast_xmpp_client_send(client, request);
1235 
1236  iks_delete(request);
1237 }
static iks * xmpp_pubsub_iq_create(struct ast_xmpp_client *client, const char *type)
Create an IQ packet.
Definition: res_xmpp.c:1045
int ast_xmpp_client_send(struct ast_xmpp_client *client, iks *stanza)
Send an XML stanza out using an established XMPP client connection.
Definition: res_xmpp.c:2534
static int xmpp_pubsub_delete_node_list ( void *  data,
ikspak *  pak 
)
static

Delete pubsub item lists.

Parameters
datapointer to ast_xmpp_client structure
pakresponse from pubsub diso::items query
Return values
IKS_FILTER_EAT

Definition at line 4096 of file res_xmpp.c.

References xmpp_pubsub_delete_node().

4097 {
4098  struct ast_xmpp_client *client = data;
4099  iks *item = NULL;
4100 
4101  if (iks_has_children(pak->query)) {
4102  item = iks_first_tag(pak->query);
4103  ast_log(LOG_WARNING, "Connection: %s Node name: %s\n", client->jid->partial,
4104  iks_find_attrib(item, "node"));
4105  while ((item = iks_next_tag(item))) {
4106  xmpp_pubsub_delete_node(client, iks_find_attrib(item, "node"));
4107  }
4108  }
4109 
4110  if (item) {
4111  iks_delete(item);
4112  }
4113 
4114  return IKS_FILTER_EAT;
4115 }
XMPP Client Connection.
Definition: xmpp.h:119
static void xmpp_pubsub_delete_node(struct ast_xmpp_client *client, const char *node_name)
Delete a PubSub node.
Definition: res_xmpp.c:1222
static void xmpp_pubsub_devstate_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message msg 
)
static

Callback function for device state events.

Parameters
datavoid pointer to ast_client structure
sub,msg

Definition at line 1362 of file res_xmpp.c.

References ast_device_state_message_type(), ast_devstate_str(), ast_eid_cmp(), ast_eid_default, ast_device_state_message::cachable, ast_device_state_message::device, ast_device_state_message::eid, stasis_message_data(), stasis_message_type(), stasis_subscription_is_subscribed(), ast_device_state_message::state, and xmpp_pubsub_publish_device_state().

Referenced by xmpp_init_event_distribution().

1363 {
1364  struct ast_xmpp_client *client = data;
1365  struct ast_device_state_message *dev_state;
1366 
1368  return;
1369  }
1370 
1371  dev_state = stasis_message_data(msg);
1372  if (!dev_state->eid || ast_eid_cmp(&ast_eid_default, dev_state->eid)) {
1373  /* If the event is aggregate or didn't originate from this server, don't send it out. */
1374  return;
1375  }
1376 
1377  xmpp_pubsub_publish_device_state(client, dev_state->device, ast_devstate_str(dev_state->state), dev_state->cachable);
1378 }
enum ast_device_state state
Definition: devicestate.h:248
int stasis_subscription_is_subscribed(const struct stasis_subscription *sub)
Returns whether a subscription is currently subscribed.
Definition: stasis.c:1150
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
enum ast_devstate_cache cachable
Definition: devicestate.h:250
int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2)
Compare two EIDs.
Definition: utils.c:3094
struct stasis_message_type * ast_device_state_message_type(void)
Get the Stasis message type for device state messages.
XMPP Client Connection.
Definition: xmpp.h:119
const struct ast_eid * eid
The EID of the server where this message originated.
Definition: devicestate.h:246
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:255
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
static void xmpp_pubsub_publish_device_state(struct ast_xmpp_client *client, const char *device, const char *device_state, unsigned int cachable)
Publish device state to a PubSub node.
Definition: res_xmpp.c:1300
struct ast_eid ast_eid_default
Global EID.
Definition: options.c:93
The structure that contains device state.
Definition: devicestate.h:238
static int xmpp_pubsub_handle_event ( void *  data,
ikspak *  pak 
)
static

Callback for handling PubSub events.

Parameters
datavoid pointer to ast_xmpp_client structure
pakA pak
Return values
IKS_FILTER_EAT

Definition at line 1457 of file res_xmpp.c.

References ast_debug, AST_DEVSTATE_CACHABLE, AST_DEVSTATE_NOT_CACHABLE, ast_devstate_val(), ast_eid_cmp(), ast_eid_default, ast_publish_device_state_full(), ast_publish_mwi_state_full(), and ast_str_to_eid().

Referenced by xmpp_init_event_distribution().

1458 {
1459  char *item_id, *device_state, *mailbox, *cachable_str;
1460  int oldmsgs, newmsgs;
1461  iks *item, *item_content;
1462  struct ast_eid pubsub_eid;
1463  unsigned int cachable = AST_DEVSTATE_CACHABLE;
1464  item = iks_find(iks_find(iks_find(pak->x, "event"), "items"), "item");
1465  if (!item) {
1466  ast_log(LOG_ERROR, "Could not parse incoming PubSub event\n");
1467  return IKS_FILTER_EAT;
1468  }
1469  item_id = iks_find_attrib(item, "id");
1470  item_content = iks_child(item);
1471  ast_str_to_eid(&pubsub_eid, iks_find_attrib(item_content, "eid"));
1472  if (!ast_eid_cmp(&ast_eid_default, &pubsub_eid)) {
1473  ast_debug(1, "Returning here, eid of incoming event matches ours!\n");
1474  return IKS_FILTER_EAT;
1475  }
1476  if (!strcasecmp(iks_name(item_content), "state")) {
1477  if ((cachable_str = iks_find_attrib(item_content, "cachable"))) {
1478  sscanf(cachable_str, "%30u", &cachable);
1479  }
1480  device_state = iks_find_cdata(item, "state");
1482  ast_devstate_val(device_state),
1484  &pubsub_eid);
1485  return IKS_FILTER_EAT;
1486  } else if (!strcasecmp(iks_name(item_content), "mailbox")) {
1487  mailbox = strsep(&item_id, "@");
1488  sscanf(iks_find_cdata(item_content, "OLDMSGS"), "%10d", &oldmsgs);
1489  sscanf(iks_find_cdata(item_content, "NEWMSGS"), "%10d", &newmsgs);
1490 
1491  ast_publish_mwi_state_full(mailbox, item_id, newmsgs, oldmsgs, NULL, &pubsub_eid);
1492 
1493  return IKS_FILTER_EAT;
1494  } else {
1495  ast_debug(1, "Don't know how to handle PubSub event of type %s\n",
1496  iks_name(item_content));
1497  return IKS_FILTER_EAT;
1498  }
1499 
1500  return IKS_FILTER_EAT;
1501 }
An Entity ID is essentially a MAC address, brief and unique.
Definition: utils.h:813
int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2)
Compare two EIDs.
Definition: utils.c:3094
enum ast_device_state ast_devstate_val(const char *val)
Convert device state from text to integer value.
Definition: devicestate.c:260
int ast_str_to_eid(struct ast_eid *eid, const char *s)
Convert a string into an EID.
Definition: utils.c:3077
#define ast_debug(level,...)
Log a DEBUG message.
int ast_publish_mwi_state_full(const char *mailbox, const char *context, int new_msgs, int old_msgs, const char *channel_id, struct ast_eid *eid)
Publish a MWI state update via stasis with all parameters.
Definition: mwi.c:393
int ast_publish_device_state_full(const char *device, enum ast_device_state state, enum ast_devstate_cache cachable, struct ast_eid *eid)
Publish a device state update with EID.
Definition: devicestate.c:709
struct ast_eid ast_eid_default
Global EID.
Definition: options.c:93
static iks* xmpp_pubsub_iq_create ( struct ast_xmpp_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 1045 of file res_xmpp.c.

References ao2_global_obj_ref, ast_xmpp_client_lock(), ast_xmpp_client_unlock(), ast_xmpp_increment_mid(), ast_xmpp_client::mid, ast_xmpp_client::name, ast_xmpp_client_config::pubsubnode, RAII_VAR, and xmpp_config_find().

Referenced by xmpp_pubsub_build_node_request(), xmpp_pubsub_build_publish_skeleton(), xmpp_pubsub_create_affiliations(), xmpp_pubsub_create_node(), xmpp_pubsub_delete_node(), xmpp_pubsub_subscribe(), and xmpp_pubsub_unsubscribe().

1046 {
1047  RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
1048  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
1049  iks *request;
1050 
1051  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name)) ||
1052  !(request = iks_new("iq"))) {
1053  return NULL;
1054  }
1055 
1056  if (!ast_strlen_zero(clientcfg->pubsubnode)) {
1057  iks_insert_attrib(request, "to", clientcfg->pubsubnode);
1058  }
1059 
1060  iks_insert_attrib(request, "from", client->jid->full);
1061  iks_insert_attrib(request, "type", type);
1062  ast_xmpp_client_lock(client);
1063  ast_xmpp_increment_mid(client->mid);
1064  iks_insert_attrib(request, "id", client->mid);
1065  ast_xmpp_client_unlock(client);
1066 
1067  return request;
1068 }
XMPP Client Configuration.
Definition: res_xmpp.c:450
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:657
void ast_xmpp_increment_mid(char *mid)
Helper function which increments the message identifier.
Definition: res_xmpp.c:1025
void ast_xmpp_client_lock(struct ast_xmpp_client *client)
Lock an XMPP client connection.
Definition: res_xmpp.c:899
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
const ast_string_field name
Definition: xmpp.h:123
char mid[6]
Definition: xmpp.h:125
void ast_xmpp_client_unlock(struct ast_xmpp_client *client)
Unlock an XMPP client connection.
Definition: res_xmpp.c:904
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
static void xmpp_pubsub_mwi_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message msg 
)
static

Callback function for MWI events.

Parameters
datavoid pointer to ast_client structure
sub,msg

Definition at line 1335 of file res_xmpp.c.

References ast_eid_cmp(), ast_eid_default, ast_mwi_state_type(), ast_mwi_state::eid, ast_mwi_state::new_msgs, ast_mwi_state::old_msgs, stasis_message_data(), stasis_message_type(), stasis_subscription_is_subscribed(), ast_mwi_state::uniqueid, and xmpp_pubsub_publish_mwi().

Referenced by xmpp_init_event_distribution().

1336 {
1337  struct ast_xmpp_client *client = data;
1338  char oldmsgs[10], newmsgs[10];
1339  struct ast_mwi_state *mwi_state;
1340 
1342  return;
1343  }
1344 
1345  mwi_state = stasis_message_data(msg);
1346 
1347  if (ast_eid_cmp(&ast_eid_default, &mwi_state->eid)) {
1348  /* If the event didn't originate from this server, don't send it back out. */
1349  return;
1350  }
1351 
1352  snprintf(oldmsgs, sizeof(oldmsgs), "%d", mwi_state->old_msgs);
1353  snprintf(newmsgs, sizeof(newmsgs), "%d", mwi_state->new_msgs);
1354  xmpp_pubsub_publish_mwi(client, mwi_state->uniqueid, oldmsgs, newmsgs);
1355 }
int stasis_subscription_is_subscribed(const struct stasis_subscription *sub)
Returns whether a subscription is currently subscribed.
Definition: stasis.c:1150
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2)
Compare two EIDs.
Definition: utils.c:3094
XMPP Client Connection.
Definition: xmpp.h:119
int new_msgs
Definition: mwi.h:459
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
static void xmpp_pubsub_publish_mwi(struct ast_xmpp_client *client, const char *mailbox, const char *oldmsgs, const char *newmsgs)
Publish MWI to a PubSub node.
Definition: res_xmpp.c:1269
struct stasis_message_type * ast_mwi_state_type(void)
Get the Stasis Message Bus API message type for MWI messages.
struct ast_eid eid
Definition: mwi.h:463
const ast_string_field uniqueid
Definition: mwi.h:458
struct ast_eid ast_eid_default
Global EID.
Definition: options.c:93
int old_msgs
Definition: mwi.h:460
The structure that contains MWI state.
Definition: mwi.h:455
static void xmpp_pubsub_publish_device_state ( struct ast_xmpp_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
cachable

Definition at line 1300 of file res_xmpp.c.

References ao2_global_obj_ref, ast_eid_default, ast_eid_to_str(), ast_xmpp_client_send(), RAII_VAR, xmpp_pubsub_build_publish_skeleton(), and xmpp_pubsub_create_node().

Referenced by xmpp_pubsub_devstate_cb().

1302 {
1303  RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
1304  iks *request, *state;
1305  char eid_str[20], cachable_str[2];
1306 
1307  if (!cfg || !cfg->global || !(request = xmpp_pubsub_build_publish_skeleton(client, device, "device_state", cachable))) {
1308  return;
1309  }
1310 
1311  if (ast_test_flag(&cfg->global->pubsub, XMPP_PUBSUB_AUTOCREATE)) {
1312  if (ast_test_flag(&cfg->global->pubsub, XMPP_XEP0248)) {
1313  xmpp_pubsub_create_node(client, "leaf", device, "device_state");
1314  } else {
1315  xmpp_pubsub_create_node(client, NULL, device, NULL);
1316  }
1317  }
1318 
1319  ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
1320  state = iks_insert(request, "state");
1321  iks_insert_attrib(state, "xmlns", "http://asterisk.org");
1322  iks_insert_attrib(state, "eid", eid_str);
1323  snprintf(cachable_str, sizeof(cachable_str), "%u", cachable);
1324  iks_insert_attrib(state, "cachable", cachable_str);
1325  iks_insert_cdata(state, device_state, strlen(device_state));
1326  ast_xmpp_client_send(client, iks_root(request));
1327  iks_delete(request);
1328 }
char * ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
Convert an EID to a string.
Definition: utils.c:2839
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
static iks * xmpp_pubsub_build_publish_skeleton(struct ast_xmpp_client *client, const char *node, const char *event_type, unsigned int cachable)
Build the skeleton of a publish.
Definition: res_xmpp.c:1077
static void xmpp_pubsub_create_node(struct ast_xmpp_client *client, const char *node_type, const char *name, const char *collection_name)
Create a pubsub node.
Definition: res_xmpp.c:1198
struct ast_eid ast_eid_default
Global EID.
Definition: options.c:93
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
int ast_xmpp_client_send(struct ast_xmpp_client *client, iks *stanza)
Send an XML stanza out using an established XMPP client connection.
Definition: res_xmpp.c:2534
static void xmpp_pubsub_publish_mwi ( struct ast_xmpp_client client,
const char *  mailbox,
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
mailboxThe mailbox identifier
oldmsgsOld messages
newmsgsNew Messages

Definition at line 1269 of file res_xmpp.c.

References AST_DEVSTATE_CACHABLE, ast_eid_default, ast_eid_to_str(), ast_xmpp_client_send(), and xmpp_pubsub_build_publish_skeleton().

Referenced by xmpp_pubsub_mwi_cb().

1271 {
1272  char eid_str[20];
1273  iks *mailbox_node, *request;
1274 
1275  request = xmpp_pubsub_build_publish_skeleton(client, mailbox, "message_waiting",
1277  if (!request) {
1278  return;
1279  }
1280 
1281  ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
1282  mailbox_node = iks_insert(request, "mailbox");
1283  iks_insert_attrib(mailbox_node, "xmlns", "http://asterisk.org");
1284  iks_insert_attrib(mailbox_node, "eid", eid_str);
1285  iks_insert_cdata(iks_insert(mailbox_node, "NEWMSGS"), newmsgs, strlen(newmsgs));
1286  iks_insert_cdata(iks_insert(mailbox_node, "OLDMSGS"), oldmsgs, strlen(oldmsgs));
1287 
1288  ast_xmpp_client_send(client, iks_root(request));
1289 
1290  iks_delete(request);
1291 }
char * ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
Convert an EID to a string.
Definition: utils.c:2839
static iks * xmpp_pubsub_build_publish_skeleton(struct ast_xmpp_client *client, const char *node, const char *event_type, unsigned int cachable)
Build the skeleton of a publish.
Definition: res_xmpp.c:1077
struct ast_eid ast_eid_default
Global EID.
Definition: options.c:93
int ast_xmpp_client_send(struct ast_xmpp_client *client, iks *stanza)
Send an XML stanza out using an established XMPP client connection.
Definition: res_xmpp.c:2534
static int xmpp_pubsub_receive_node_list ( void *  data,
ikspak *  pak 
)
static

Receive pubsub item lists.

Parameters
datapointer to ast_xmpp_client structure
pakresponse from pubsub diso::items query
Return values
IKS_FILTER_EAT

Definition at line 3998 of file res_xmpp.c.

References ast_xmpp_client::name.

Referenced by xmpp_pubsub_request_nodes().

3999 {
4000  struct ast_xmpp_client *client = data;
4001  iks *item = NULL;
4002 
4003  if (iks_has_children(pak->query)) {
4004  item = iks_first_tag(pak->query);
4005  ast_verbose("Connection %s: %s\nNode name: %s\n", client->name, client->jid->partial,
4006  iks_find_attrib(item, "node"));
4007  while ((item = iks_next_tag(item))) {
4008  ast_verbose("Node name: %s\n", iks_find_attrib(item, "node"));
4009  }
4010  }
4011 
4012  if (item) {
4013  iks_delete(item);
4014  }
4015 
4016 
4017  return IKS_FILTER_EAT;
4018 }
XMPP Client Connection.
Definition: xmpp.h:119
const ast_string_field name
Definition: xmpp.h:123
static void xmpp_pubsub_request_nodes ( struct ast_xmpp_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

Definition at line 4025 of file res_xmpp.c.

References ast_xmpp_client_send(), ast_xmpp_client::mid, ast_xmpp_client::name, xmpp_pubsub_build_node_request(), and xmpp_pubsub_receive_node_list().

Referenced by xmpp_cli_list_pubsub_nodes().

4026 {
4027  iks *request = xmpp_pubsub_build_node_request(client, collection);
4028 
4029  if (!request) {
4030  ast_log(LOG_ERROR, "Could not request pubsub nodes on client '%s' - IQ could not be created\n", client->name);
4031  return;
4032  }
4033 
4034  iks_filter_add_rule(client->filter, xmpp_pubsub_receive_node_list, client, IKS_RULE_TYPE,
4035  IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID, client->mid,
4036  IKS_RULE_DONE);
4037  ast_xmpp_client_send(client, request);
4038  iks_delete(request);
4039 
4040 }
static iks * xmpp_pubsub_build_node_request(struct ast_xmpp_client *client, const char *collection)
Build the a node request.
Definition: res_xmpp.c:3974
static int xmpp_pubsub_receive_node_list(void *data, ikspak *pak)
Receive pubsub item lists.
Definition: res_xmpp.c:3998
const ast_string_field name
Definition: xmpp.h:123
char mid[6]
Definition: xmpp.h:125
int ast_xmpp_client_send(struct ast_xmpp_client *client, iks *stanza)
Send an XML stanza out using an established XMPP client connection.
Definition: res_xmpp.c:2534
static void xmpp_pubsub_subscribe ( struct ast_xmpp_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

Definition at line 1410 of file res_xmpp.c.

References ao2_global_obj_ref, ast_xmpp_client_send(), ast_xmpp_client::name, RAII_VAR, and xmpp_pubsub_iq_create().

Referenced by xmpp_init_event_distribution().

1411 {
1412  RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
1413  iks *request = xmpp_pubsub_iq_create(client, "set");
1414  iks *pubsub, *subscribe;
1415 
1416  if (!cfg || !cfg->global || !request) {
1417  ast_log(LOG_ERROR, "Could not create IQ when creating pubsub subscription on client '%s'\n", client->name);
1418  return;
1419  }
1420 
1421  pubsub = iks_insert(request, "pubsub");
1422  iks_insert_attrib(pubsub, "xmlns", "http://jabber.org/protocol/pubsub");
1423  subscribe = iks_insert(pubsub, "subscribe");
1424  iks_insert_attrib(subscribe, "jid", client->jid->partial);
1425  iks_insert_attrib(subscribe, "node", node);
1426  if (ast_test_flag(&cfg->global->pubsub, XMPP_XEP0248)) {
1427  iks *options, *x, *sub_options, *sub_type, *sub_depth, *sub_expire;
1428  options = iks_insert(pubsub, "options");
1429  x = iks_insert(options, "x");
1430  iks_insert_attrib(x, "xmlns", "jabber:x:data");
1431  iks_insert_attrib(x, "type", "submit");
1432  sub_options = iks_insert(x, "field");
1433  iks_insert_attrib(sub_options, "var", "FORM_TYPE");
1434  iks_insert_attrib(sub_options, "type", "hidden");
1435  iks_insert_cdata(iks_insert(sub_options, "value"),
1436  "http://jabber.org/protocol/pubsub#subscribe_options", 51);
1437  sub_type = iks_insert(x, "field");
1438  iks_insert_attrib(sub_type, "var", "pubsub#subscription_type");
1439  iks_insert_cdata(iks_insert(sub_type, "value"), "items", 5);
1440  sub_depth = iks_insert(x, "field");
1441  iks_insert_attrib(sub_depth, "var", "pubsub#subscription_depth");
1442  iks_insert_cdata(iks_insert(sub_depth, "value"), "all", 3);
1443  sub_expire = iks_insert(x, "field");
1444  iks_insert_attrib(sub_expire, "var", "pubsub#expire");
1445  iks_insert_cdata(iks_insert(sub_expire, "value"), "presence", 8);
1446  }
1447  ast_xmpp_client_send(client, request);
1448  iks_delete(request);
1449 }
Definition: test_heap.c:38
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
const ast_string_field name
Definition: xmpp.h:123
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
static iks * xmpp_pubsub_iq_create(struct ast_xmpp_client *client, const char *type)
Create an IQ packet.
Definition: res_xmpp.c:1045
int ast_xmpp_client_send(struct ast_xmpp_client *client, iks *stanza)
Send an XML stanza out using an established XMPP client connection.
Definition: res_xmpp.c:2534
static void xmpp_pubsub_unsubscribe ( struct ast_xmpp_client client,
const char *  node 
)
static

Unsubscribe from a PubSub node.

Parameters
clientthe configured XMPP client we use to connect to a XMPP server
nodethe name of the node to which to unsubscribe from

Definition at line 1385 of file res_xmpp.c.

References ast_xmpp_client_send(), ast_xmpp_client::name, and xmpp_pubsub_iq_create().

Referenced by ast_xmpp_client_disconnect(), and xmpp_init_event_distribution().

1386 {
1387  iks *request = xmpp_pubsub_iq_create(client, "set");
1388  iks *pubsub, *unsubscribe;
1389 
1390  if (!request) {
1391  ast_log(LOG_ERROR, "Could not create IQ when creating pubsub unsubscription on client '%s'\n", client->name);
1392  return;
1393  }
1394 
1395  pubsub = iks_insert(request, "pubsub");
1396  iks_insert_attrib(pubsub, "xmlns", "http://jabber.org/protocol/pubsub");
1397  unsubscribe = iks_insert(pubsub, "unsubscribe");
1398  iks_insert_attrib(unsubscribe, "jid", client->jid->partial);
1399  iks_insert_attrib(unsubscribe, "node", node);
1400 
1401  ast_xmpp_client_send(client, request);
1402  iks_delete(request);
1403 }
Definition: test_heap.c:38
const ast_string_field name
Definition: xmpp.h:123
static iks * xmpp_pubsub_iq_create(struct ast_xmpp_client *client, const char *type)
Create an IQ packet.
Definition: res_xmpp.c:1045
int ast_xmpp_client_send(struct ast_xmpp_client *client, iks *stanza)
Send an XML stanza out using an established XMPP client connection.
Definition: res_xmpp.c:2534
static int xmpp_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 1879 of file res_xmpp.c.

References ao2_global_obj_ref, AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_xmpp_chatroom_send(), ast_xmpp_client_config::client, ast_xmpp_client_config::flags, RAII_VAR, xmpp_config_find(), and XMPP_MAX_RESJIDLEN.

Referenced by load_module().

1880 {
1881  RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
1882  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
1883  char *s, nick[XMPP_MAX_RESJIDLEN];
1884  AST_DECLARE_APP_ARGS(args,
1885  AST_APP_ARG(sender);
1886  AST_APP_ARG(groupchat);
1888  AST_APP_ARG(nick);
1889  );
1890 
1891  if (ast_strlen_zero(data)) {
1892  ast_log(LOG_ERROR, "%s requires arguments (sender,groupchatid,message[,nickname])\n", app_ajisendgroup);
1893  return -1;
1894  }
1895  s = ast_strdupa(data);
1896 
1897  AST_STANDARD_APP_ARGS(args, s);
1898  if ((args.argc < 3) || (args.argc > 4) || ast_strlen_zero(args.message) || !strchr(args.groupchat, '@')) {
1899  ast_log(LOG_ERROR, "%s requires arguments (sender,groupchatid,message[,nickname])\n", app_ajisendgroup);
1900  return -1;
1901  }
1902 
1903  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, args.sender))) {
1904  ast_log(LOG_ERROR, "Could not find sender connection: '%s'\n", args.sender);
1905  return -1;
1906  }
1907 
1908  if (ast_strlen_zero(args.nick) || args.argc == 3) {
1909  if (ast_test_flag(&clientcfg->flags, XMPP_COMPONENT)) {
1910  snprintf(nick, sizeof(nick), "asterisk");
1911  } else {
1912  snprintf(nick, sizeof(nick), "%s", clientcfg->client->jid->user);
1913  }
1914  } else {
1915  snprintf(nick, sizeof(nick), "%s", args.nick);
1916  }
1917 
1918  ast_xmpp_chatroom_send(clientcfg->client, nick, args.groupchat, args.message);
1919 
1920  return 0;
1921 }
int ast_xmpp_chatroom_send(struct ast_xmpp_client *client, const char *nickname, const char *address, const char *message)
Send a message to an XMPP multi-user chatroom.
Definition: res_xmpp.c:1015
XMPP Client Configuration.
Definition: res_xmpp.c:450
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:657
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
#define XMPP_MAX_RESJIDLEN
Maximum size of a resource JID.
Definition: xmpp.h:65
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_APP_ARG(name)
Define an application argument.

Variable Documentation

struct ast_custom_function jabberreceive_function
static
Initial value:
= {
.name = "JABBER_RECEIVE",
.read = acf_jabberreceive_read,
}

Definition at line 2079 of file res_xmpp.c.

struct ast_custom_function jabberstatus_function
static
Initial value:
= {
.name = "JABBER_STATUS",
.read = acf_jabberstatus_read,
}

Definition at line 1706 of file res_xmpp.c.

const struct ast_msg_tech msg_tech
static
Initial value:
= {
.name = "xmpp",
.msg_send = xmpp_send_cb,
}

Definition at line 2157 of file res_xmpp.c.

struct aco_file res_xmpp_conf
Initial value:
= {
.filename = "xmpp.conf",
.alias = "jabber.conf",
.types = ACO_TYPES(&global_option, &client_option),
}
#define ACO_TYPES(...)
A helper macro to ensure that aco_info types always have a sentinel.
static struct aco_type global_option
An aco_type structure to link the "general" category to the skel_global_config type.
Definition: app_skel.c:241

Definition at line 823 of file res_xmpp.c.

const struct xmpp_pak_handler xmpp_pak_handlers[]
static
Initial value:
= {
{ IKS_PAK_MESSAGE, xmpp_pak_message, },
{ IKS_PAK_PRESENCE, xmpp_pak_presence, },
{ IKS_PAK_S10N, xmpp_pak_s10n, },
}
static int xmpp_pak_presence(struct ast_xmpp_client *client, struct ast_xmpp_client_config *cfg, iks *node, ikspak *pak)
Internal function called when a presence message is received.
Definition: res_xmpp.c:3263
static int xmpp_pak_s10n(struct ast_xmpp_client *client, struct ast_xmpp_client_config *cfg, iks *node, ikspak *pak)
Internal function called when a subscription message is received.
Definition: res_xmpp.c:3392
static int xmpp_pak_message(struct ast_xmpp_client *client, struct ast_xmpp_client_config *cfg, iks *node, ikspak *pak)
Internal function called when a message is received.
Definition: res_xmpp.c:3117