Asterisk - The Open Source Telephony Project  18.5.0
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"
Include dependency graph for res_xmpp.c:

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

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. More...
 
enum  { XMPP_XEP0248 = (1 << 0), XMPP_PUBSUB = (1 << 1), XMPP_PUBSUB_AUTOCREATE = (1 << 2) }
 Supported pubsub configuration flags. More...
 

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. More...
 
static void ast_xmpp_client_config_destructor (void *obj)
 Destructor function for configuration. More...
 
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. More...
 
static int xmpp_buddy_cmp (void *obj, void *arg, int flags)
 Comparator function for XMPP buddy. More...
 
static void xmpp_buddy_destructor (void *obj)
 Destructor callback function for XMPP buddy. More...
 
static int xmpp_buddy_hash (const void *obj, const int flags)
 Hashing function for XMPP buddy. More...
 
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)
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
static void xmpp_client_change_state (struct ast_xmpp_client *client, int state)
 Internal function which changes the XMPP client state. More...
 
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. More...
 
static void xmpp_client_destructor (void *obj)
 Destructor callback function for XMPP client. More...
 
static void * xmpp_client_find_or_create (const char *category)
 Look up existing client or create a new one. More...
 
static int xmpp_client_receive (struct ast_xmpp_client *client, unsigned int timeout)
 Internal function which receives data from the XMPP client connection. More...
 
static int xmpp_client_reconnect (struct ast_xmpp_client *client)
 Internal function used to reconnect an XMPP client to its server. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
static int xmpp_client_send_raw_message (struct ast_xmpp_client *client, const char *message)
 Internal function which sends a raw message. More...
 
static int xmpp_client_service_discovery_get_hook (void *data, ikspak *pak)
 Hook function called when client receives a service discovery get message. More...
 
static int xmpp_client_service_discovery_result_hook (void *data, ikspak *pak)
 Hook function called when client receives a service discovery result message. More...
 
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. More...
 
static int xmpp_client_subscribe_user (void *obj, void *arg, int flags)
 Callback function which subscribes to a user if needed. More...
 
static void * xmpp_client_thread (void *data)
 XMPP client connection thread. More...
 
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. More...
 
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. More...
 
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. More...
 
static int xmpp_component_register_get_hook (void *data, ikspak *pak)
 Hook function called when the component is queried about registration. More...
 
static int xmpp_component_register_set_hook (void *data, ikspak *pak)
 Hook function called when someone registers to the component. More...
 
static int xmpp_component_service_discovery_get_hook (void *data, ikspak *pak)
 Hook function called when component receives a service discovery get message. More...
 
static int xmpp_component_service_discovery_items_hook (void *data, ikspak *pak)
 Hook function called when we receive a service discovery items request. More...
 
static void * xmpp_config_alloc (void)
 Allocator for XMPP configuration. More...
 
static int xmpp_config_cmp (void *obj, void *arg, int flags)
 Comparator function for configuration. More...
 
static void xmpp_config_destructor (void *obj)
 Destructor for XMPP configuration. More...
 
static void * xmpp_config_find (struct ao2_container *tmp_container, const char *category)
 Find function for configuration. More...
 
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. More...
 
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. More...
 
static int xmpp_is_secure (struct ast_xmpp_client *client)
 Helper function which returns whether an XMPP client connection is secure or not. More...
 
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. More...
 
static void xmpp_message_destroy (struct ast_xmpp_message *message)
 Destroy function for XMPP messages. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
static void xmpp_resource_destructor (void *obj)
 Destructor callback function for XMPP resource. More...
 
static int xmpp_resource_hash (const void *obj, const int flags)
 Hashing function for XMPP resource. More...
 
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. More...
 
static int xmpp_resource_is_available (void *obj, void *arg, int flags)
 Callback function which returns when the resource is available. More...
 
static int xmpp_roster_hook (void *data, ikspak *pak)
 Hook function called when roster is received from server. More...
 
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. More...
 
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. More...
 
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.

Macro Definition Documentation

◆ BUDDY_BUCKETS

#define BUDDY_BUCKETS   53

Number of buckets for buddies (per client)

Definition at line 423 of file res_xmpp.c.

Referenced by ast_xmpp_client_config_alloc(), and xmpp_client_alloc().

◆ BUDDY_NOT_IN_ROSTER

#define BUDDY_NOT_IN_ROSTER   7

Definition at line 1633 of file res_xmpp.c.

Referenced by get_buddy_status().

◆ BUDDY_OFFLINE

#define BUDDY_OFFLINE   6

Definition at line 1632 of file res_xmpp.c.

Referenced by get_buddy_status().

◆ CLIENT_BUCKETS

#define CLIENT_BUCKETS   53

Number of buckets for client connections.

Definition at line 420 of file res_xmpp.c.

◆ RESOURCE_BUCKETS

#define RESOURCE_BUCKETS   53

Number of buckets for resources (per buddy)

Definition at line 426 of file res_xmpp.c.

Referenced by xmpp_client_create_buddy().

◆ STATUS_DISAPPEAR

#define STATUS_DISAPPEAR   6

Status for a disappearing buddy.

Definition at line 432 of file res_xmpp.c.

Referenced by xmpp_pak_presence().

◆ XMPP_TLS_NS

#define XMPP_TLS_NS   "urn:ietf:params:xml:ns:xmpp-tls"

Namespace for TLS support.

Definition at line 429 of file res_xmpp.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

Supported general configuration flags.

Enumerator
XMPP_AUTOPRUNE 
XMPP_AUTOREGISTER 
XMPP_AUTOACCEPT 
XMPP_DEBUG 
XMPP_USETLS 
XMPP_USESASL 
XMPP_FORCESSL 
XMPP_KEEPALIVE 
XMPP_COMPONENT 
XMPP_SEND_TO_DIALPLAN 
XMPP_DISTRIBUTE_EVENTS 

Definition at line 398 of file res_xmpp.c.

398  {
399  XMPP_AUTOPRUNE = (1 << 0),
400  XMPP_AUTOREGISTER = (1 << 1),
401  XMPP_AUTOACCEPT = (1 << 2),
402  XMPP_DEBUG = (1 << 3),
403  XMPP_USETLS = (1 << 4),
404  XMPP_USESASL = (1 << 5),
405  XMPP_FORCESSL = (1 << 6),
406  XMPP_KEEPALIVE = (1 << 7),
407  XMPP_COMPONENT = (1 << 8),
408  XMPP_SEND_TO_DIALPLAN = (1 << 9),
409  XMPP_DISTRIBUTE_EVENTS = (1 << 10),
410 };

◆ anonymous enum

anonymous enum

Supported pubsub configuration flags.

Enumerator
XMPP_XEP0248 
XMPP_PUBSUB 
XMPP_PUBSUB_AUTOCREATE 

Definition at line 413 of file res_xmpp.c.

413  {
414  XMPP_XEP0248 = (1 << 0),
415  XMPP_PUBSUB = (1 << 1),
416  XMPP_PUBSUB_AUTOCREATE = (1 << 2),
417 };

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 4707 of file res_xmpp.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 4707 of file res_xmpp.c.

◆ acf_jabberreceive_read()

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

Definition at line 1936 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, args, ast_xmpp_message::arrived, AST_APP_ARG, ast_autoservice_start(), ast_autoservice_stop(), ast_channel_name(), ast_cond_timedwait, ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log, ast_mutex_lock, ast_mutex_unlock, AST_NONSTANDARD_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero, ast_tv(), ast_tvadd(), ast_tvdiff_ms(), ast_tvdiff_sec(), ast_tvnow(), ast_xmpp_message::from, globals, LOG_NOTICE, LOG_WARNING, ast_xmpp_message::message, NULL, parse(), RAII_VAR, timeout, xmpp_config_find(), XMPP_MAX_JIDLEN, and xmpp_message_destroy().

1937 {
1939  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
1940  char *parse = NULL;
1941  int timeout, jidlen, resourcelen, found = 0;
1942  struct timeval start;
1943  long diff = 0;
1944  struct ast_xmpp_message *message;
1946  AST_APP_ARG(account);
1947  AST_APP_ARG(jid);
1948  AST_APP_ARG(timeout);
1949  );
1951  AST_APP_ARG(screenname);
1952  AST_APP_ARG(resource);
1953  );
1954 
1955  if (ast_strlen_zero(data)) {
1956  ast_log(LOG_WARNING, "%s requires arguments (account,jid[,timeout])\n", name);
1957  return -1;
1958  }
1959 
1960  parse = ast_strdupa(data);
1961  AST_STANDARD_APP_ARGS(args, parse);
1962 
1963  if (args.argc < 2 || args.argc > 3) {
1964  ast_log(LOG_WARNING, "%s requires arguments (account,jid[,timeout])\n", name);
1965  return -1;
1966  }
1967 
1968  parse = ast_strdupa(args.jid);
1969  AST_NONSTANDARD_APP_ARGS(jid, parse, '/');
1970  if (jid.argc < 1 || jid.argc > 2 || strlen(args.jid) > XMPP_MAX_JIDLEN) {
1971  ast_log(LOG_WARNING, "Invalid JID : %s\n", parse);
1972  return -1;
1973  }
1974 
1975  if (ast_strlen_zero(args.timeout)) {
1976  timeout = 20;
1977  } else {
1978  sscanf(args.timeout, "%d", &timeout);
1979  if (timeout <= 0) {
1980  ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
1981  return -1;
1982  }
1983  }
1984 
1985  jidlen = strlen(jid.screenname);
1986  resourcelen = ast_strlen_zero(jid.resource) ? 0 : strlen(jid.resource);
1987 
1988  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, args.account))) {
1989  ast_log(LOG_WARNING, "Could not find client %s, exiting\n", args.account);
1990  return -1;
1991  }
1992 
1993  ast_debug(3, "Waiting for an XMPP message from %s\n", args.jid);
1994 
1995  start = ast_tvnow();
1996 
1997  if (chan && ast_autoservice_start(chan) < 0) {
1998  ast_log(LOG_WARNING, "Cannot start autoservice for channel %s\n", ast_channel_name(chan));
1999  return -1;
2000  }
2001 
2002  /* search the messages list, grab the first message that matches with
2003  * the from JID we're expecting, and remove it from the messages list */
2004  while (diff < timeout) {
2005  struct timespec ts = { 0, };
2006  struct timeval wait;
2007  int res = 0;
2008 
2009  wait = ast_tvadd(start, ast_tv(timeout, 0));
2010  ts.tv_sec = wait.tv_sec;
2011  ts.tv_nsec = wait.tv_usec * 1000;
2012 
2013  /* wait up to timeout seconds for an incoming message */
2015  if (AST_LIST_EMPTY(&clientcfg->client->messages)) {
2017  }
2019  if (res == ETIMEDOUT) {
2020  ast_debug(3, "No message received from %s in %d seconds\n", args.jid, timeout);
2021  break;
2022  }
2023 
2024  AST_LIST_LOCK(&clientcfg->client->messages);
2025  AST_LIST_TRAVERSE_SAFE_BEGIN(&clientcfg->client->messages, message, list) {
2026  if (jid.argc == 1) {
2027  /* no resource provided, compare bare JIDs */
2028  if (strncasecmp(jid.screenname, message->from, jidlen)) {
2029  continue;
2030  }
2031  } else {
2032  /* resource appended, compare bare JIDs and resources */
2033  char *resource = strchr(message->from, '/');
2034  if (!resource || strlen(resource) == 0) {
2035  ast_log(LOG_WARNING, "Remote JID has no resource : %s\n", message->from);
2036  if (strncasecmp(jid.screenname, message->from, jidlen)) {
2037  continue;
2038  }
2039  } else {
2040  resource ++;
2041  if (strncasecmp(jid.screenname, message->from, jidlen) || strncmp(jid.resource, resource, resourcelen)) {
2042  continue;
2043  }
2044  }
2045  }
2046  /* check if the message is not too old */
2047  if (ast_tvdiff_sec(ast_tvnow(), message->arrived) >= clientcfg->message_timeout) {
2048  ast_debug(3, "Found old message from %s, deleting it\n", message->from);
2050  xmpp_message_destroy(message);
2051  continue;
2052  }
2053  found = 1;
2054  ast_copy_string(buf, message->message, buflen);
2056  xmpp_message_destroy(message);
2057  break;
2058  }
2060  AST_LIST_UNLOCK(&clientcfg->client->messages);
2061  if (found) {
2062  break;
2063  }
2064 
2065  /* check timeout */
2066  diff = ast_tvdiff_ms(ast_tvnow(), start);
2067  }
2068 
2069  if (chan && ast_autoservice_stop(chan) < 0) {
2070  ast_log(LOG_WARNING, "Cannot stop autoservice for channel %s\n", ast_channel_name(chan));
2071  }
2072 
2073  /* return if we timed out */
2074  if (!found) {
2075  ast_log(LOG_NOTICE, "Timed out : no message received from %s\n", args.jid);
2076  return -1;
2077  }
2078 
2079  return 0;
2080 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:200
XMPP Client Configuration.
Definition: res_xmpp.c:444
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
int64_t ast_tvdiff_sec(struct timeval end, struct timeval start)
Computes the difference (in seconds) between two struct timeval instances.
Definition: time.h:64
static int timeout
Definition: cdr_mysql.c:86
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define ast_mutex_lock(a)
Definition: lock.h:187
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
const char * args
#define NULL
Definition: resample.c:96
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
char * from
Definition: xmpp.h:102
#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:911
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static struct console_pvt globals
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:266
struct timeval arrived
Definition: xmpp.h:105
#define XMPP_MAX_JIDLEN
Definition: xmpp.h:62
char * message
Definition: xmpp.h:103
XMPP Message.
Definition: xmpp.h:101
static void xmpp_message_destroy(struct ast_xmpp_message *message)
Destroy function for XMPP messages.
Definition: res_xmpp.c:532
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283
#define LOG_NOTICE
Definition: logger.h:263
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
static const char name[]
Definition: cdr_mysql.c:74
static ast_mutex_t messagelock
Definition: res_xmpp.c:517
static ast_cond_t message_received_condition
Definition: res_xmpp.c:516
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:226
const char * ast_channel_name(const struct ast_channel *chan)
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:204
#define ast_mutex_unlock(a)
Definition: lock.h:188
#define AST_APP_ARG(name)
Define an application argument.

◆ acf_jabberstatus_read()

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

Definition at line 1670 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log, AST_NONSTANDARD_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strlen_zero, get_buddy_status(), globals, LOG_ERROR, LOG_WARNING, NULL, RAII_VAR, and xmpp_config_find().

1671 {
1673  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
1675  AST_APP_ARG(sender);
1676  AST_APP_ARG(jid);
1677  );
1679  AST_APP_ARG(screenname);
1680  AST_APP_ARG(resource);
1681  );
1682 
1683  if (ast_strlen_zero(data)) {
1684  ast_log(LOG_ERROR, "Usage: JABBER_STATUS(<sender>,<jid>[/<resource>])\n");
1685  return 0;
1686  }
1687  AST_STANDARD_APP_ARGS(args, data);
1688 
1689  if (args.argc != 2) {
1690  ast_log(LOG_ERROR, "JABBER_STATUS requires 2 arguments: sender and jid.\n");
1691  return -1;
1692  }
1693 
1694  AST_NONSTANDARD_APP_ARGS(jid, args.jid, '/');
1695  if (jid.argc < 1 || jid.argc > 2) {
1696  ast_log(LOG_WARNING, "Wrong JID %s, exiting\n", args.jid);
1697  return -1;
1698  }
1699 
1700  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, args.sender))) {
1701  ast_log(LOG_WARNING, "Could not find sender connection: '%s'\n", args.sender);
1702  return -1;
1703  }
1704 
1705  snprintf(buf, buflen, "%d", get_buddy_status(clientcfg, jid.screenname, jid.resource));
1706 
1707  return 0;
1708 }
XMPP Client Configuration.
Definition: res_xmpp.c:444
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
const char * args
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#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:911
static struct console_pvt globals
#define LOG_ERROR
Definition: logger.h:285
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
static int get_buddy_status(struct ast_xmpp_client_config *clientcfg, char *screenname, char *resource)
Definition: res_xmpp.c:1635
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ AO2_GLOBAL_OBJ_STATIC()

static AO2_GLOBAL_OBJ_STATIC ( globals  )
static

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 4707 of file res_xmpp.c.

◆ ast_xmpp_chatroom_invite()

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 937 of file res_xmpp.c.

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

938 {
939  int res = 0;
940  iks *invite, *body = NULL, *namespace = NULL;
941 
942  if (!(invite = iks_new("message")) || !(body = iks_new("body")) || !(namespace = iks_new("x"))) {
943  res = -1;
944  goto done;
945  }
946 
947  iks_insert_attrib(invite, "to", user);
948  ast_xmpp_client_lock(client);
949  iks_insert_attrib(invite, "id", client->mid);
950  ast_xmpp_increment_mid(client->mid);
951  ast_xmpp_client_unlock(client);
952  iks_insert_cdata(body, message, 0);
953  iks_insert_node(invite, body);
954  iks_insert_attrib(namespace, "xmlns", "jabber:x:conference");
955  iks_insert_attrib(namespace, "jid", room);
956  iks_insert_node(invite, namespace);
957 
958  res = ast_xmpp_client_send(client, invite);
959 
960 done:
961  iks_delete(namespace);
962  iks_delete(body);
963  iks_delete(invite);
964 
965  return res;
966 }
void ast_xmpp_increment_mid(char *mid)
Helper function which increments the message identifier.
Definition: res_xmpp.c:1019
void ast_xmpp_client_lock(struct ast_xmpp_client *client)
Lock an XMPP client connection.
Definition: res_xmpp.c:893
#define NULL
Definition: resample.c:96
int done
Definition: test_amihooks.c:48
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:898
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:2537

◆ ast_xmpp_chatroom_join()

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 1004 of file res_xmpp.c.

References xmpp_client_set_group_presence().

Referenced by xmpp_join_exec().

1005 {
1006  return xmpp_client_set_group_presence(client, room, IKS_SHOW_AVAILABLE, nickname);
1007 }
static int xmpp_client_set_group_presence(struct ast_xmpp_client *client, const char *room, int level, const char *nick)
Definition: res_xmpp.c:968

◆ ast_xmpp_chatroom_leave()

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 1014 of file res_xmpp.c.

References xmpp_client_set_group_presence().

Referenced by xmpp_leave_exec().

1015 {
1016  return xmpp_client_set_group_presence(client, room, IKS_SHOW_UNAVAILABLE, nickname);
1017 }
static int xmpp_client_set_group_presence(struct ast_xmpp_client *client, const char *room, int level, const char *nick)
Definition: res_xmpp.c:968

◆ ast_xmpp_chatroom_send()

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 1009 of file res_xmpp.c.

References xmpp_client_send_message().

Referenced by xmpp_sendgroup_exec().

1010 {
1011  return xmpp_client_send_message(client, 1, nickname, address, message);
1012 }
char * address
Definition: f2c.h:59
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:904

◆ ast_xmpp_client_config_alloc()

static void* ast_xmpp_client_config_alloc ( const char *  cat)
static

Allocator function for configuration.

Definition at line 671 of file res_xmpp.c.

References ao2_alloc, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ao2_ref, ast_string_field_init, ast_string_field_set, ast_xmpp_client_config_destructor(), ast_xmpp_client_config::buddies, BUDDY_BUCKETS, ast_xmpp_client_config::client, name, NULL, xmpp_buddy_cmp(), xmpp_buddy_hash(), and xmpp_client_find_or_create().

672 {
673  struct ast_xmpp_client_config *cfg;
674 
675  if (!(cfg = ao2_alloc(sizeof(*cfg), ast_xmpp_client_config_destructor))) {
676  return NULL;
677  }
678 
679  if (ast_string_field_init(cfg, 512)) {
680  ao2_ref(cfg, -1);
681  return NULL;
682  }
683 
684  if (!(cfg->client = xmpp_client_find_or_create(cat))) {
685  ao2_ref(cfg, -1);
686  return NULL;
687  }
688 
691  if (!cfg->buddies) {
692  ao2_ref(cfg, -1);
693  return NULL;
694  }
695 
696  ast_string_field_set(cfg, name, cat);
697 
698  return cfg;
699 }
XMPP Client Configuration.
Definition: res_xmpp.c:444
static int xmpp_buddy_cmp(void *obj, void *arg, int flags)
Comparator function for XMPP buddy.
Definition: res_xmpp.c:581
#define NULL
Definition: resample.c:96
#define BUDDY_BUCKETS
Number of buckets for buddies (per client)
Definition: res_xmpp.c:423
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static void ast_xmpp_client_config_destructor(void *obj)
Destructor function for configuration.
Definition: res_xmpp.c:523
struct ao2_container * buddies
Definition: res_xmpp.c:464
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
static int xmpp_buddy_hash(const void *obj, const int flags)
Hashing function for XMPP buddy.
Definition: res_xmpp.c:572
struct ast_xmpp_client * client
Definition: res_xmpp.c:463
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
static const char name[]
Definition: cdr_mysql.c:74
static void * xmpp_client_find_or_create(const char *category)
Look up existing client or create a new one.
Definition: res_xmpp.c:657
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ ast_xmpp_client_config_destructor()

static void ast_xmpp_client_config_destructor ( void *  obj)
static

Destructor function for configuration.

Definition at line 523 of file res_xmpp.c.

References ao2_cleanup, ast_string_field_free_memory, ast_xmpp_client_config::buddies, and ast_xmpp_client_config::client.

Referenced by ast_xmpp_client_config_alloc().

524 {
525  struct ast_xmpp_client_config *cfg = obj;
527  ao2_cleanup(cfg->client);
528  ao2_cleanup(cfg->buddies);
529 }
XMPP Client Configuration.
Definition: res_xmpp.c:444
struct ao2_container * buddies
Definition: res_xmpp.c:464
struct ast_xmpp_client * client
Definition: res_xmpp.c:463
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368

◆ ast_xmpp_client_disconnect()

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 3528 of file res_xmpp.c.

References AST_PTHREADT_NULL, ast_xmpp_client::device_state_sub, ast_xmpp_client::mwi_sub, NULL, ast_xmpp_client::parser, ast_xmpp_client::ssl_context, ast_xmpp_client::ssl_session, stasis_unsubscribe_and_join(), ast_xmpp_client::stream_flags, ast_xmpp_client::thread, xmpp_client_change_state(), xmpp_pubsub_unsubscribe(), XMPP_STATE_DISCONNECTED, and XMPP_STATE_DISCONNECTING.

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

3529 {
3530  if ((client->thread != AST_PTHREADT_NULL) && !pthread_equal(pthread_self(), client->thread)) {
3532  pthread_cancel(client->thread);
3533  pthread_join(client->thread, NULL);
3534  client->thread = AST_PTHREADT_NULL;
3535  }
3536 
3537  if (client->mwi_sub) {
3538  client->mwi_sub = stasis_unsubscribe_and_join(client->mwi_sub);
3539  xmpp_pubsub_unsubscribe(client, "message_waiting");
3540  }
3541 
3542  if (client->device_state_sub) {
3544  xmpp_pubsub_unsubscribe(client, "device_state");
3545  }
3546 
3547 #ifdef HAVE_OPENSSL
3548  if (client->stream_flags & SECURE) {
3549  SSL_shutdown(client->ssl_session);
3550  SSL_CTX_free(client->ssl_context);
3551  SSL_free(client->ssl_session);
3552  }
3553 
3554  client->stream_flags = 0;
3555 #endif
3556 
3557  if (client->parser) {
3558  iks_disconnect(client->parser);
3559  }
3560 
3562 
3563  return 0;
3564 }
iksparser * parser
Definition: xmpp.h:127
#define NULL
Definition: resample.c:96
struct stasis_subscription * device_state_sub
Definition: xmpp.h:146
unsigned int stream_flags
Definition: xmpp.h:134
struct stasis_subscription * mwi_sub
Definition: xmpp.h:144
#define AST_PTHREADT_NULL
Definition: lock.h:66
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
Definition: stasis.c:1136
pthread_t thread
Definition: xmpp.h:139
SSL_CTX * ssl_context
Definition: xmpp.h:131
static void xmpp_pubsub_unsubscribe(struct ast_xmpp_client *client, const char *node)
Unsubscribe from a PubSub node.
Definition: res_xmpp.c:1388
SSL * ssl_session
Definition: xmpp.h:132
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:590

◆ ast_xmpp_client_find()

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 875 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ao2_ref, globals, NULL, RAII_VAR, and xmpp_config_find().

Referenced by custom_connection_handler().

876 {
878  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
879 
880  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, name))) {
881  return NULL;
882  }
883 
884  ao2_ref(clientcfg->client, +1);
885  return clientcfg->client;
886 }
XMPP Client Configuration.
Definition: res_xmpp.c:444
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
#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:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct console_pvt globals
static const char name[]
Definition: cdr_mysql.c:74
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ ast_xmpp_client_lock()

void ast_xmpp_client_lock ( struct ast_xmpp_client client)

Lock an XMPP client connection.

Parameters
clientPointer to the client

Definition at line 893 of file res_xmpp.c.

References ao2_lock.

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().

894 {
895  ao2_lock(client);
896 }
#define ao2_lock(a)
Definition: astobj2.h:718

◆ ast_xmpp_client_send()

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 2537 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_group_presence(), 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_handle_error(), xmpp_pubsub_publish_device_state(), xmpp_pubsub_publish_mwi(), xmpp_pubsub_purge_nodes(), xmpp_pubsub_request_nodes(), xmpp_pubsub_subscribe(), and xmpp_pubsub_unsubscribe().

2538 {
2539  return xmpp_client_send_raw_message(client, iks_string(iks_stack(stanza), stanza));
2540 }
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:2492

◆ ast_xmpp_client_send_message()

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 932 of file res_xmpp.c.

References NULL, and xmpp_client_send_message().

Referenced by jingle_sendtext(), manager_jabber_send(), xmpp_send_cb(), and xmpp_send_exec().

933 {
934  return xmpp_client_send_message(client, 0, NULL, user, message);
935 }
#define NULL
Definition: resample.c:96
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:904

◆ ast_xmpp_client_unlock()

void ast_xmpp_client_unlock ( struct ast_xmpp_client client)

Unlock an XMPP client connection.

Parameters
clientPointer to the client

Definition at line 898 of file res_xmpp.c.

References ao2_unlock.

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().

899 {
900  ao2_unlock(client);
901 }
#define ao2_unlock(a)
Definition: astobj2.h:730

◆ ast_xmpp_client_unref()

void ast_xmpp_client_unref ( struct ast_xmpp_client client)

Release XMPP client connection reference.

Parameters
clientPointer to the client

Definition at line 888 of file res_xmpp.c.

References ao2_ref.

Referenced by jingle_endpoint_destructor(), and jingle_session_destructor().

889 {
890  ao2_ref(client, -1);
891 }
#define ao2_ref(o, delta)
Definition: astobj2.h:464

◆ ast_xmpp_increment_mid()

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 1019 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().

1020 {
1021  int i = 0;
1022 
1023  for (i = strlen(mid) - 1; i >= 0; i--) {
1024  if (mid[i] != 'z') {
1025  mid[i] = mid[i] + 1;
1026  i = 0;
1027  } else {
1028  mid[i] = 'a';
1029  }
1030  }
1031 }

◆ cached_devstate_cb()

static int cached_devstate_cb ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 1575 of file res_xmpp.c.

References ast_xmpp_client::device_state_sub, and xmpp_pubsub_devstate_cb().

Referenced by xmpp_init_event_distribution().

1576 {
1577  struct stasis_message *msg = obj;
1578  struct ast_xmpp_client *client = arg;
1579  xmpp_pubsub_devstate_cb(client, client->device_state_sub, msg);
1580  return 0;
1581 }
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:1364
XMPP Client Connection.
Definition: xmpp.h:119

◆ client_bitfield_handler()

static int client_bitfield_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Definition at line 4529 of file res_xmpp.c.

References ast_set2_flag, ast_true(), ast_xmpp_client_config::flags, ast_xmpp_client_config::mod_flags, ast_variable::name, ast_variable::value, XMPP_AUTOACCEPT, XMPP_AUTOPRUNE, XMPP_AUTOREGISTER, XMPP_COMPONENT, XMPP_DEBUG, XMPP_DISTRIBUTE_EVENTS, XMPP_FORCESSL, XMPP_KEEPALIVE, XMPP_SEND_TO_DIALPLAN, XMPP_USESASL, and XMPP_USETLS.

Referenced by load_module().

4530 {
4531  struct ast_xmpp_client_config *cfg = obj;
4532 
4533  if (!strcasecmp(var->name, "debug")) {
4534  ast_set2_flag(&cfg->flags, ast_true(var->value), XMPP_DEBUG);
4535  } else if (!strcasecmp(var->name, "type")) {
4536  ast_set2_flag(&cfg->flags, !strcasecmp(var->value, "component") ? 1 : 0, XMPP_COMPONENT);
4537  } else if (!strcasecmp(var->name, "distribute_events")) {
4539  } else if (!strcasecmp(var->name, "usetls")) {
4540  ast_set2_flag(&cfg->flags, ast_true(var->value), XMPP_USETLS);
4541  } else if (!strcasecmp(var->name, "usesasl")) {
4543  } else if (!strcasecmp(var->name, "forceoldssl")) {
4545  } else if (!strcasecmp(var->name, "keepalive")) {
4547  } else if (!strcasecmp(var->name, "autoprune")) {
4550  } else if (!strcasecmp(var->name, "autoregister")) {
4553  } else if (!strcasecmp(var->name, "auth_policy")) {
4554  ast_set2_flag(&cfg->flags, !strcasecmp(var->value, "accept") ? 1 : 0, XMPP_AUTOACCEPT);
4556  } else if (!strcasecmp(var->name, "sendtodialplan")) {
4558  } else {
4559  return -1;
4560  }
4561 
4562  return 0;
4563 }
XMPP Client Configuration.
Definition: res_xmpp.c:444
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
struct ast_flags flags
Definition: res_xmpp.c:460
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
struct ast_flags mod_flags
Definition: res_xmpp.c:461

◆ client_buddy_handler()

static int client_buddy_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Definition at line 4594 of file res_xmpp.c.

References ao2_find, ao2_ref, ast_xmpp_client_config::buddies, OBJ_KEY, ast_variable::value, and xmpp_client_create_buddy().

Referenced by load_module().

4595 {
4596  struct ast_xmpp_client_config *cfg = obj;
4597  struct ast_xmpp_buddy *buddy;
4598 
4599  if ((buddy = ao2_find(cfg->buddies, var->value, OBJ_KEY))) {
4600  ao2_ref(buddy, -1);
4601  return -1;
4602  }
4603 
4604  if (!(buddy = xmpp_client_create_buddy(cfg->buddies, var->value))) {
4605  return -1;
4606  }
4607 
4608  ao2_ref(buddy, -1);
4609 
4610  return 0;
4611 }
static struct ast_xmpp_buddy * xmpp_client_create_buddy(struct ao2_container *container, const char *id)
Internal function which creates a buddy on a client.
Definition: res_xmpp.c:2166
XMPP Client Configuration.
Definition: res_xmpp.c:444
#define OBJ_KEY
Definition: astobj2.h:1155
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ao2_container * buddies
Definition: res_xmpp.c:464
XMPP Buddy.
Definition: xmpp.h:112
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756

◆ client_status_handler()

static int client_status_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Definition at line 4565 of file res_xmpp.c.

References ast_xmpp_client_config::status, and ast_variable::value.

Referenced by load_module().

4566 {
4567  struct ast_xmpp_client_config *cfg = obj;
4568 
4569  if (!strcasecmp(var->value, "unavailable")) {
4570  cfg->status = IKS_SHOW_UNAVAILABLE;
4571  } else if (!strcasecmp(var->value, "available") || !strcasecmp(var->value, "online")) {
4572  cfg->status = IKS_SHOW_AVAILABLE;
4573  } else if (!strcasecmp(var->value, "chat") || !strcasecmp(var->value, "chatty")) {
4574  cfg->status = IKS_SHOW_CHAT;
4575  } else if (!strcasecmp(var->value, "away")) {
4576  cfg->status = IKS_SHOW_AWAY;
4577  } else if (!strcasecmp(var->value, "xa") || !strcasecmp(var->value, "xaway")) {
4578  cfg->status = IKS_SHOW_XA;
4579  } else if (!strcasecmp(var->value, "dnd")) {
4580  cfg->status = IKS_SHOW_DND;
4581  } else if (!strcasecmp(var->value, "invisible")) {
4582 #ifdef IKS_SHOW_INVISIBLE
4583  cfg->status = IKS_SHOW_INVISIBLE;
4584 #else
4585  cfg->status = IKS_SHOW_DND;
4586 #endif
4587  } else {
4588  return -1;
4589  }
4590 
4591  return 0;
4592 }
XMPP Client Configuration.
Definition: res_xmpp.c:444
enum ikshowtype status
Definition: res_xmpp.c:462

◆ CONFIG_INFO_STANDARD()

CONFIG_INFO_STANDARD ( cfg_info  ,
globals  ,
xmpp_config_alloc  ,
files = ACO_FILES(&res_xmpp_conf),
post_apply_config = xmpp_config_post_apply 
)

◆ delete_old_messages()

static int delete_old_messages ( struct ast_xmpp_client client,
char *  from 
)
static

Definition at line 2095 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ast_xmpp_message::arrived, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_tvdiff_sec(), ast_tvnow(), ast_xmpp_message::from, globals, ast_xmpp_message::list, ast_xmpp_client::messages, ast_xmpp_client::name, NULL, RAII_VAR, xmpp_config_find(), and xmpp_message_destroy().

Referenced by xmpp_pak_message().

2096 {
2098  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
2099  int deleted = 0, isold = 0;
2100  struct ast_xmpp_message *message = NULL;
2101 
2102  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name))) {
2103  return 0;
2104  }
2105 
2106  AST_LIST_LOCK(&client->messages);
2107  AST_LIST_TRAVERSE_SAFE_BEGIN(&client->messages, message, list) {
2108  if (isold) {
2109  if (!from || !strncasecmp(from, message->from, strlen(from))) {
2111  xmpp_message_destroy(message);
2112  deleted++;
2113  }
2114  } else if (ast_tvdiff_sec(ast_tvnow(), message->arrived) >= clientcfg->message_timeout) {
2115  isold = 1;
2116  if (!from || !strncasecmp(from, message->from, strlen(from))) {
2118  xmpp_message_destroy(message);
2119  deleted++;
2120  }
2121  }
2122  }
2124  AST_LIST_UNLOCK(&client->messages);
2125 
2126  return deleted;
2127 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
XMPP Client Configuration.
Definition: res_xmpp.c:444
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
int64_t ast_tvdiff_sec(struct timeval end, struct timeval start)
Computes the difference (in seconds) between two struct timeval instances.
Definition: time.h:64
struct ast_xmpp_message::@329 list
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
struct ast_xmpp_client::@330 messages
char * from
Definition: xmpp.h:102
#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:911
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
static struct console_pvt globals
struct timeval arrived
Definition: xmpp.h:105
XMPP Message.
Definition: xmpp.h:101
static void xmpp_message_destroy(struct ast_xmpp_message *message)
Destroy function for XMPP messages.
Definition: res_xmpp.c:532
const ast_string_field name
Definition: xmpp.h:123
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528

◆ fetch_access_token()

static int fetch_access_token ( struct ast_xmpp_client_config cfg)
static

Definition at line 3827 of file res_xmpp.c.

References ast_asprintf, ast_debug, ast_free, ast_func_read(), ast_json_load_string(), ast_json_object_get(), ast_json_string_get(), ast_json_unref(), ast_log, ast_string_field_set, LOG_ERROR, ast_xmpp_client_config::name, NULL, ast_xmpp_client_config::oauth_clientid, ast_xmpp_client_config::oauth_secret, password, RAII_VAR, ast_xmpp_client_config::refresh_token, and url.

Referenced by xmpp_client_reconnect().

3828 {
3829  RAII_VAR(char *, cmd, NULL, ast_free);
3830  char cBuf[1024] = "";
3831  const char *url = "https://www.googleapis.com/oauth2/v3/token";
3832  struct ast_json_error error;
3833  RAII_VAR(struct ast_json *, jobj, NULL, ast_json_unref);
3834 
3835  if (ast_asprintf(&cmd,
3836  "CURL(%s,client_id=%s&client_secret=%s&refresh_token=%s&grant_type=refresh_token)",
3837  url, cfg->oauth_clientid, cfg->oauth_secret, cfg->refresh_token) < 0) {
3838  return -1;
3839  }
3840 
3841  ast_debug(2, "Performing OAuth 2.0 authentication for client '%s' using command: %s\n",
3842  cfg->name, cmd);
3843 
3844  if (ast_func_read(NULL, cmd, cBuf, sizeof(cBuf) - 1)) {
3845  ast_log(LOG_ERROR, "CURL is unavailable. This is required for OAuth 2.0 authentication of XMPP client '%s'. Please ensure it is loaded.\n",
3846  cfg->name);
3847  return -1;
3848  }
3849 
3850  ast_debug(2, "OAuth 2.0 authentication for client '%s' returned: %s\n", cfg->name, cBuf);
3851 
3852  jobj = ast_json_load_string(cBuf, &error);
3853  if (jobj) {
3854  const char *token = ast_json_string_get(ast_json_object_get(jobj, "access_token"));
3855  if (token) {
3856  ast_string_field_set(cfg, password, token);
3857  return 0;
3858  }
3859  }
3860 
3861  ast_log(LOG_ERROR, "An error occurred while performing OAuth 2.0 authentication for client '%s': %s\n", cfg->name, cBuf);
3862 
3863  return -1;
3864 }
int ast_func_read(struct ast_channel *chan, const char *function, char *workspace, size_t len)
executes a read operation on a function
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct ast_json * ast_json_load_string(const char *input, struct ast_json_error *error)
Parse null terminated string into a JSON object or array.
Definition: json.c:546
#define NULL
Definition: resample.c:96
static struct ast_str * password
Definition: cdr_mysql.c:77
JSON parsing error information.
Definition: json.h:829
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:269
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#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:911
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:273
const ast_string_field name
Definition: res_xmpp.c:456
#define LOG_ERROR
Definition: logger.h:285
#define ast_free(a)
Definition: astmm.h:182
const ast_string_field oauth_secret
Definition: res_xmpp.c:456
const ast_string_field oauth_clientid
Definition: res_xmpp.c:456
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:397
Abstract JSON element (object, array, string, int, ...).
int error(const char *format,...)
Definition: utils/frame.c:999
const ast_string_field refresh_token
Definition: res_xmpp.c:456
static char url[512]
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ get_buddy_status()

static int get_buddy_status ( struct ast_xmpp_client_config clientcfg,
char *  screenname,
char *  resource 
)
static

Definition at line 1635 of file res_xmpp.c.

References ao2_callback, ao2_cleanup, ao2_find, ast_strlen_zero, ast_xmpp_client::buddies, BUDDY_NOT_IN_ROSTER, BUDDY_OFFLINE, ast_xmpp_client_config::client, OBJ_KEY, ast_xmpp_buddy::resources, ast_xmpp_resource::status, status, xmpp_resource_cmp(), and xmpp_resource_immediate().

Referenced by acf_jabberstatus_read().

1636 {
1637  int status = BUDDY_OFFLINE;
1638  struct ast_xmpp_resource *res;
1639  struct ast_xmpp_buddy *buddy = ao2_find(clientcfg->client->buddies, screenname, OBJ_KEY);
1640 
1641  if (!buddy) {
1642  return BUDDY_NOT_IN_ROSTER;
1643  }
1644 
1645  res = ao2_callback(
1646  buddy->resources,
1647  0,
1649  resource);
1650 
1651  if (res) {
1652  status = res->status;
1653  }
1654 
1655  ao2_cleanup(res);
1656  ao2_cleanup(buddy);
1657 
1658  return status;
1659 }
#define BUDDY_NOT_IN_ROSTER
Definition: res_xmpp.c:1633
#define BUDDY_OFFLINE
Definition: res_xmpp.c:1632
#define OBJ_KEY
Definition: astobj2.h:1155
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
#define ast_strlen_zero(foo)
Definition: strings.h:52
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 on...
Definition: res_xmpp.c:1627
XMPP Resource.
Definition: xmpp.h:92
struct ast_xmpp_client * client
Definition: res_xmpp.c:463
XMPP Buddy.
Definition: xmpp.h:112
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
struct ao2_container * resources
Definition: xmpp.h:114
static int xmpp_resource_cmp(void *obj, void *arg, int flags)
Comparator function for XMPP resource.
Definition: res_xmpp.c:847
struct ao2_container * buddies
Definition: xmpp.h:137
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
jack_status_t status
Definition: app_jack.c:146

◆ global_bitfield_handler()

static int global_bitfield_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Definition at line 4506 of file res_xmpp.c.

References ast_set2_flag, ast_true(), ast_xmpp_global_config::general, global, ast_variable::name, ast_xmpp_global_config::pubsub, ast_variable::value, XMPP_AUTOACCEPT, XMPP_AUTOPRUNE, XMPP_AUTOREGISTER, XMPP_PUBSUB_AUTOCREATE, and XMPP_XEP0248.

Referenced by load_module().

4507 {
4508  struct ast_xmpp_global_config *global = obj;
4509 
4510  if (!strcasecmp(var->name, "debug")) {
4511  debug = ast_true(var->value);
4512  } else if (!strcasecmp(var->name, "autoprune")) {
4514  } else if (!strcasecmp(var->name, "autoregister")) {
4516  } else if (!strcasecmp(var->name, "auth_policy")) {
4517  ast_set2_flag(&global->general, !strcasecmp(var->value, "accept") ? 1 : 0, XMPP_AUTOACCEPT);
4518  } else if (!strcasecmp(var->name, "collection_nodes")) {
4519  ast_set2_flag(&global->pubsub, ast_true(var->value), XMPP_XEP0248);
4520  } else if (!strcasecmp(var->name, "pubsub_autocreate")) {
4522  } else {
4523  return -1;
4524  }
4525 
4526  return 0;
4527 }
static struct aco_type global
Definition: test_config.c:1445
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
static int debug
Global debug status.
Definition: res_xmpp.c:435
struct ast_flags pubsub
Definition: res_xmpp.c:440
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
struct ast_flags general
Definition: res_xmpp.c:439
XMPP Global Configuration.
Definition: res_xmpp.c:438

◆ load_module()

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 4623 of file res_xmpp.c.

References ACO_EXACT, aco_info_destroy(), aco_info_init(), aco_option_register, aco_option_register_custom, aco_process_config(), ACO_PROCESS_ERROR, ARRAY_LEN, ast_cli_register_multiple, ast_cond_init, ast_custom_function_register, ast_eid_default, ast_eid_is_empty(), ast_log, ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_msg_tech_register(), ast_mutex_init, ast_register_application_xml, client_bitfield_handler(), client_buddy_handler(), client_status_handler(), context, EVENT_FLAG_SYSTEM, FLDSET, global_bitfield_handler(), LOG_WARNING, manager_jabber_send(), NULL, OPT_STRINGFIELD_T, OPT_UINT_T, password, priority, STRFLDSET, xmpp_join_exec(), xmpp_leave_exec(), xmpp_send_exec(), and xmpp_sendgroup_exec().

Referenced by reload().

4624 {
4625  if (aco_info_init(&cfg_info)) {
4626  return AST_MODULE_LOAD_DECLINE;
4627  }
4628 
4630  aco_option_register_custom(&cfg_info, "autoprune", ACO_EXACT, global_options, "no", global_bitfield_handler, 0);
4631  aco_option_register_custom(&cfg_info, "autoregister", ACO_EXACT, global_options, "yes", global_bitfield_handler, 0);
4632  aco_option_register_custom(&cfg_info, "collection_nodes", ACO_EXACT, global_options, "no", global_bitfield_handler, 0);
4633  aco_option_register_custom(&cfg_info, "pubsub_autocreate", ACO_EXACT, global_options, "no", global_bitfield_handler, 0);
4634  aco_option_register_custom(&cfg_info, "auth_policy", ACO_EXACT, global_options, "accept", global_bitfield_handler, 0);
4635 
4638  aco_option_register(&cfg_info, "refresh_token", ACO_EXACT, client_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_xmpp_client_config, refresh_token));
4639  aco_option_register(&cfg_info, "oauth_clientid", ACO_EXACT, client_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_xmpp_client_config, oauth_clientid));
4640  aco_option_register(&cfg_info, "oauth_secret", ACO_EXACT, client_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_xmpp_client_config, oauth_secret));
4641  aco_option_register(&cfg_info, "serverhost", ACO_EXACT, client_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_xmpp_client_config, server));
4642  aco_option_register(&cfg_info, "statusmessage", ACO_EXACT, client_options, "Online and Available", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_xmpp_client_config, statusmsg));
4643  aco_option_register(&cfg_info, "pubsub_node", ACO_EXACT, client_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_xmpp_client_config, pubsubnode));
4645  aco_option_register(&cfg_info, "priority", ACO_EXACT, client_options, "1", OPT_UINT_T, 0, FLDSET(struct ast_xmpp_client_config, priority));
4646  aco_option_register(&cfg_info, "port", ACO_EXACT, client_options, "5222", OPT_UINT_T, 0, FLDSET(struct ast_xmpp_client_config, port));
4647  aco_option_register(&cfg_info, "timeout", ACO_EXACT, client_options, "5", OPT_UINT_T, 0, FLDSET(struct ast_xmpp_client_config, message_timeout));
4648 
4649  /* Global options that can be overridden per client must not specify a default */
4653 
4656  aco_option_register_custom(&cfg_info, "distribute_events", ACO_EXACT, client_options, "no", client_bitfield_handler, 0);
4659  aco_option_register_custom(&cfg_info, "forceoldssl", ACO_EXACT, client_options, "no", client_bitfield_handler, 0);
4660  aco_option_register_custom(&cfg_info, "keepalive", ACO_EXACT, client_options, "yes", client_bitfield_handler, 0);
4661  aco_option_register_custom(&cfg_info, "sendtodialplan", ACO_EXACT, client_options, "no", client_bitfield_handler, 0);
4662  aco_option_register_custom(&cfg_info, "status", ACO_EXACT, client_options, "available", client_status_handler, 0);
4664 
4665  if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {
4666  aco_info_destroy(&cfg_info);
4667  return AST_MODULE_LOAD_DECLINE;
4668  }
4669 
4671 
4676 
4681 
4684 
4686  ast_log(LOG_WARNING, "Entity ID is not set. The distributing device state or MWI will not work.\n");
4687  }
4688 
4689  return AST_MODULE_LOAD_SUCCESS;
4690 }
static int global_bitfield_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition: res_xmpp.c:4506
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static int client_buddy_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition: res_xmpp.c:4594
XMPP Client Configuration.
Definition: res_xmpp.c:444
static int manager_jabber_send(struct mansession *s, const struct message *m)
Definition: res_xmpp.c:3927
#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:1781
#define LOG_WARNING
Definition: logger.h:274
#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.
Definition: message.c:1569
#define ast_cond_init(cond, attr)
Definition: lock.h:199
#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 NULL
Definition: resample.c:96
static int priority
static struct ast_custom_function jabberstatus_function
Definition: res_xmpp.c:1710
static struct ast_str * password
Definition: cdr_mysql.c:77
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
#define ast_log
Definition: astobj2.c:42
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
static const char * app_ajisendgroup
Definition: res_xmpp.c:511
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
static const struct ast_msg_tech msg_tech
Definition: res_xmpp.c:2160
Type for default option handler for unsigned integers.
struct aco_type * client_options[]
Definition: res_xmpp.c:815
static struct ast_custom_function jabberreceive_function
Definition: res_xmpp.c:2082
Their was an error and no changes were applied.
static struct ast_cli_entry xmpp_cli[]
Definition: res_xmpp.c:4474
static int client_bitfield_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition: res_xmpp.c:4529
static const char * app_ajisend
Definition: res_xmpp.c:510
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
static int xmpp_send_exec(struct ast_channel *chan, const char *data)
Definition: res_xmpp.c:1842
static int xmpp_sendgroup_exec(struct ast_channel *chan, const char *data)
Application to send a message to a groupchat.
Definition: res_xmpp.c:1883
static int client_status_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition: res_xmpp.c:4565
#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
static ast_mutex_t messagelock
Definition: res_xmpp.c:517
structure to hold users read from users.conf
struct ast_eid ast_eid_default
Global EID.
Definition: options.c:93
static ast_cond_t message_received_condition
Definition: res_xmpp.c:516
struct aco_type * global_options[]
Definition: res_xmpp.c:802
static const char * app_ajijoin
Definition: res_xmpp.c:513
static int xmpp_join_exec(struct ast_channel *chan, const char *data)
Application to join a chat room.
Definition: res_xmpp.c:1722
Type for default option handler for stringfields.
static const char * app_ajileave
Definition: res_xmpp.c:514
int ast_eid_is_empty(const struct ast_eid *eid)
Check if EID is empty.
Definition: main/utils.c:2847
#define ast_mutex_init(pmutex)
Definition: lock.h:184
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:186
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1508
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626

◆ manager_jabber_send()

static int manager_jabber_send ( struct mansession s,
const struct message m 
)
static

Definition at line 3927 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ast_strlen_zero, ast_xmpp_client_send_message(), astman_append(), astman_get_header(), astman_send_ack(), astman_send_error(), globals, NULL, RAII_VAR, and xmpp_config_find().

Referenced by load_module().

3928 {
3930  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
3931  const char *id = astman_get_header(m, "ActionID");
3932  const char *jabber = astman_get_header(m, "Jabber");
3933  const char *screenname = astman_get_header(m, "ScreenName");
3934  const char *message = astman_get_header(m, "Message");
3935 
3936  if (ast_strlen_zero(jabber)) {
3937  astman_send_error(s, m, "No transport specified");
3938  return 0;
3939  }
3940  if (ast_strlen_zero(screenname)) {
3941  astman_send_error(s, m, "No ScreenName specified");
3942  return 0;
3943  }
3944  if (ast_strlen_zero(message)) {
3945  astman_send_error(s, m, "No Message specified");
3946  return 0;
3947  }
3948 
3949  astman_send_ack(s, m, "Attempting to send Jabber Message");
3950 
3951  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, jabber))) {
3952  astman_send_error(s, m, "Could not find Sender");
3953  return 0;
3954  }
3955 
3956  if (strchr(screenname, '@') && !ast_xmpp_client_send_message(clientcfg->client, screenname, message)) {
3957  astman_append(s, "Response: Success\r\n");
3958  } else {
3959  astman_append(s, "Response: Error\r\n");
3960  }
3961 
3962  if (!ast_strlen_zero(id)) {
3963  astman_append(s, "ActionID: %s\r\n", id);
3964  }
3965 
3966  astman_append(s, "\r\n");
3967 
3968  return 0;
3969 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3080
XMPP Client Configuration.
Definition: res_xmpp.c:444
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
#define NULL
Definition: resample.c:96
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
#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:911
static struct console_pvt globals
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
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.
Definition: res_xmpp.c:932

◆ openssl_error_string()

static char* openssl_error_string ( void  )
static

Definition at line 2569 of file res_xmpp.c.

References ast_calloc, buf, len(), and NULL.

Referenced by xmpp_client_requested_tls().

2570 {
2571  char *buf = NULL, *ret;
2572  size_t len;
2573  BIO *bio = BIO_new(BIO_s_mem());
2574 
2575  ERR_print_errors(bio);
2576  len = BIO_get_mem_data(bio, &buf);
2577  ret = ast_calloc(1, len + 1);
2578  if (ret) {
2579  memcpy(ret, buf, len);
2580  }
2581  BIO_free(bio);
2582  return ret;
2583 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define NULL
Definition: resample.c:96
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204

◆ reload()

static int reload ( void  )
static

Definition at line 4692 of file res_xmpp.c.

References aco_process_config(), ACO_PROCESS_ERROR, AST_MODFLAG_GLOBAL_SYMBOLS, AST_MODFLAG_LOAD_ORDER, AST_MODPRI_CHANNEL_DEPEND, AST_MODULE_INFO(), AST_MODULE_LOAD_DECLINE, AST_MODULE_SUPPORT_CORE, ASTERISK_GPL_KEY, load_module(), and unload_module().

4693 {
4694  if (aco_process_config(&cfg_info, 1) == ACO_PROCESS_ERROR) {
4695  return AST_MODULE_LOAD_DECLINE;
4696  }
4697 
4698  return 0;
4699 }
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.
Their was an error and no changes were applied.
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78

◆ sleep_with_backoff()

static void sleep_with_backoff ( unsigned int *  sleep_time)
static

Definition at line 3719 of file res_xmpp.c.

References MIN, and NULL.

Referenced by xmpp_client_thread().

3720 {
3721  /* We're OK with our thread dying here */
3722  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
3723 
3724  sleep(*sleep_time);
3725  *sleep_time = MIN(60, *sleep_time * 2);
3726 
3727  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
3728 }
#define NULL
Definition: resample.c:96
#define MIN(a, b)
Definition: utils.h:226

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 4485 of file res_xmpp.c.

References aco_info_destroy(), ao2_global_obj_release, ARRAY_LEN, ast_cli_unregister_multiple(), ast_cond_destroy, ast_custom_function_unregister(), ast_manager_unregister(), ast_msg_tech_unregister(), ast_mutex_destroy, ast_unregister_application(), and globals.

Referenced by reload().

4486 {
4494  ast_manager_unregister("JabberSend");
4497  aco_info_destroy(&cfg_info);
4499 
4502 
4503  return 0;
4504 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
static struct ast_custom_function jabberstatus_function
Definition: res_xmpp.c:1710
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
static const char * app_ajisendgroup
Definition: res_xmpp.c:511
static const char * app_ajistatus
Definition: res_xmpp.c:512
static const struct ast_msg_tech msg_tech
Definition: res_xmpp.c:2160
static struct console_pvt globals
static struct ast_custom_function jabberreceive_function
Definition: res_xmpp.c:2082
static struct ast_cli_entry xmpp_cli[]
Definition: res_xmpp.c:4474
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7258
static const char * app_ajisend
Definition: res_xmpp.c:510
int ast_msg_tech_unregister(const struct ast_msg_tech *tech)
Unregister a message technology.
Definition: message.c:1610
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
#define ao2_global_obj_release(holder)
Definition: astobj2.h:865
#define ast_cond_destroy(cond)
Definition: lock.h:200
static ast_mutex_t messagelock
Definition: res_xmpp.c:517
static ast_cond_t message_received_condition
Definition: res_xmpp.c:516
static const char * app_ajijoin
Definition: res_xmpp.c:513
static const char * app_ajileave
Definition: res_xmpp.c:514
#define ast_mutex_destroy(a)
Definition: lock.h:186

◆ xmpp_action_hook()

static int xmpp_action_hook ( void *  data,
int  type,
iks *  node 
)
static

Action hook for when things occur.

Definition at line 3458 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ARRAY_LEN, ast_log, ast_test_flag, xmpp_state_handler::component, ast_xmpp_client::filter, globals, handler(), LOG_ERROR, ast_xmpp_client::name, NULL, RAII_VAR, ast_xmpp_client::state, xmpp_pak_handler::type, XMPP_COMPONENT, xmpp_config_find(), XMPP_MAX_ATTRLEN, xmpp_pak_handlers, XMPP_STATE_DISCONNECTING, and xmpp_state_handlers.

Referenced by xmpp_client_config_post_apply().

3459 {
3461  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
3462  struct ast_xmpp_client *client = data;
3463  ikspak *pak;
3464  int i;
3465 
3466  if (!node) {
3467  ast_log(LOG_ERROR, "xmpp_action_hook was called without a packet\n");
3468  return IKS_HOOK;
3469  }
3470 
3471  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name))) {
3472  return IKS_HOOK;
3473  }
3474 
3475  /* If the client is disconnecting ignore everything */
3476  if (client->state == XMPP_STATE_DISCONNECTING) {
3477  return IKS_HOOK;
3478  }
3479 
3480  pak = iks_packet(node);
3481 
3482  /* work around iksemel's impossibility to recognize node names
3483  * containing a colon. Set the namespace of the corresponding
3484  * node accordingly. */
3485  if (iks_has_children(node) && strchr(iks_name(iks_child(node)), ':')) {
3486  char *node_ns = NULL;
3487  char attr[XMPP_MAX_ATTRLEN];
3488  char *node_name = iks_name(iks_child(node));
3489  char *aux = strchr(node_name, ':') + 1;
3490  snprintf(attr, strlen("xmlns:") + (strlen(node_name) - strlen(aux)), "xmlns:%s", node_name);
3491  node_ns = iks_find_attrib(iks_child(node), attr);
3492  if (node_ns) {
3493  pak->ns = node_ns;
3494  pak->query = iks_child(node);
3495  }
3496  }
3497 
3498  /* Process through any state handlers */
3499  for (i = 0; i < ARRAY_LEN(xmpp_state_handlers); i++) {
3500  if ((xmpp_state_handlers[i].state == client->state) && (xmpp_state_handlers[i].component == (ast_test_flag(&clientcfg->flags, XMPP_COMPONENT) ? 1 : 0))) {
3501  if (xmpp_state_handlers[i].handler(client, clientcfg, type, node)) {
3502  /* If the handler wants us to stop now, do so */
3503  return IKS_HOOK;
3504  }
3505  break;
3506  }
3507  }
3508 
3509  /* Process through any PAK handlers */
3510  for (i = 0; i < ARRAY_LEN(xmpp_pak_handlers); i++) {
3511  if (xmpp_pak_handlers[i].type == pak->type) {
3512  if (xmpp_pak_handlers[i].handler(client, clientcfg, node, pak)) {
3513  /* If the handler wants us to stop now, do so */
3514  return IKS_HOOK;
3515  }
3516  break;
3517  }
3518  }
3519 
3520  /* Send the packet through the filter in case any filters want to process it */
3521  iks_filter_packet(client->filter, pak);
3522 
3523  iks_delete(node);
3524 
3525  return IKS_OK;
3526 }
static const char type[]
Definition: chan_ooh323.c:109
Definition: test_heap.c:38
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
XMPP Client Configuration.
Definition: res_xmpp.c:444
#define ast_test_flag(p, flag)
Definition: utils.h:63
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
#define XMPP_MAX_ATTRLEN
Maximum size of an attribute.
Definition: xmpp.h:68
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
static const struct xmpp_state_handler xmpp_state_handlers[]
#define ast_log
Definition: astobj2.c:42
XMPP Client Connection.
Definition: xmpp.h:119
#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:911
static struct console_pvt globals
#define LOG_ERROR
Definition: logger.h:285
enum xmpp_state state
Definition: xmpp.h:136
iksfilter * filter
Definition: xmpp.h:128
const ast_string_field name
Definition: xmpp.h:123
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static void handler(const char *name, int response_code, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Definition: test_ari.c:59
static const struct xmpp_pak_handler xmpp_pak_handlers[]

◆ xmpp_buddy_cmp()

static int xmpp_buddy_cmp ( void *  obj,
void *  arg,
int  flags 
)
static

Comparator function for XMPP buddy.

Definition at line 581 of file res_xmpp.c.

References CMP_MATCH, CMP_STOP, ast_xmpp_buddy::id, and OBJ_KEY.

Referenced by ast_xmpp_client_config_alloc(), and xmpp_client_alloc().

582 {
583  struct ast_xmpp_buddy *buddy1 = obj, *buddy2 = arg;
584  const char *id = arg;
585 
586  return !strcmp(buddy1->id, flags & OBJ_KEY ? id : buddy2->id) ? CMP_MATCH | CMP_STOP : 0;
587 }
#define OBJ_KEY
Definition: astobj2.h:1155
char id[XMPP_MAX_JIDLEN]
Definition: xmpp.h:113
XMPP Buddy.
Definition: xmpp.h:112

◆ xmpp_buddy_destructor()

static void xmpp_buddy_destructor ( void *  obj)
static

Destructor callback function for XMPP buddy.

Definition at line 856 of file res_xmpp.c.

References ao2_ref, and ast_xmpp_buddy::resources.

Referenced by xmpp_client_create_buddy().

857 {
858  struct ast_xmpp_buddy *buddy = obj;
859 
860  if (buddy->resources) {
861  ao2_ref(buddy->resources, -1);
862  }
863 }
#define ao2_ref(o, delta)
Definition: astobj2.h:464
XMPP Buddy.
Definition: xmpp.h:112
struct ao2_container * resources
Definition: xmpp.h:114

◆ xmpp_buddy_hash()

static int xmpp_buddy_hash ( const void *  obj,
const int  flags 
)
static

Hashing function for XMPP buddy.

Definition at line 572 of file res_xmpp.c.

References ast_str_hash(), ast_xmpp_buddy::id, and OBJ_KEY.

Referenced by ast_xmpp_client_config_alloc(), and xmpp_client_alloc().

573 {
574  const struct ast_xmpp_buddy *buddy = obj;
575  const char *id = obj;
576 
577  return ast_str_hash(flags & OBJ_KEY ? id : buddy->id);
578 }
#define OBJ_KEY
Definition: astobj2.h:1155
char id[XMPP_MAX_JIDLEN]
Definition: xmpp.h:113
XMPP Buddy.
Definition: xmpp.h:112
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1206

◆ xmpp_cli_create_collection()

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 4222 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, globals, name, NULL, RAII_VAR, ast_cli_entry::usage, xmpp_config_find(), and xmpp_pubsub_create_collection().

4223 {
4225  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
4226  const char *name, *collection_name;
4227 
4228  switch (cmd) {
4229  case CLI_INIT:
4230  e->command = "xmpp create collection";
4231  e->usage =
4232  "Usage: xmpp create collection <connection> <collection>\n"
4233  " Creates a PubSub collection node using the account\n"
4234  " as configured in xmpp.conf.\n";
4235  return NULL;
4236  case CLI_GENERATE:
4237  return NULL;
4238  }
4239 
4240  if (a->argc != 5) {
4241  return CLI_SHOWUSAGE;
4242  }
4243  name = a->argv[3];
4244  collection_name = a->argv[4];
4245 
4246  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, name))) {
4247  ast_cli(a->fd, "Unable to find client '%s'!\n", name);
4248  return CLI_FAILURE;
4249  }
4250 
4251  ast_cli(a->fd, "Creating test PubSub node collection.\n");
4252 
4253  xmpp_pubsub_create_collection(clientcfg->client, collection_name);
4254 
4255  return CLI_SUCCESS;
4256 }
static void xmpp_pubsub_create_collection(struct ast_xmpp_client *client, const char *collection_name)
Create a PubSub collection node.
Definition: res_xmpp.c:1242
XMPP Client Configuration.
Definition: res_xmpp.c:444
const int argc
Definition: cli.h:160
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
Definition: cli.h:152
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#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:911
const int fd
Definition: cli.h:159
static struct console_pvt globals
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_FAILURE
Definition: cli.h:46
static const char name[]
Definition: cdr_mysql.c:74
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ xmpp_cli_create_leafnode()

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 4262 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, globals, name, NULL, RAII_VAR, ast_cli_entry::usage, xmpp_config_find(), and xmpp_pubsub_create_leaf().

4263 {
4265  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
4266  const char *name, *collection_name, *leaf_name;
4267 
4268  switch (cmd) {
4269  case CLI_INIT:
4270  e->command = "xmpp create leaf";
4271  e->usage =
4272  "Usage: xmpp create leaf <connection> <collection> <leaf>\n"
4273  " Creates a PubSub leaf node using the account\n"
4274  " as configured in xmpp.conf.\n";
4275  return NULL;
4276  case CLI_GENERATE:
4277  return NULL;
4278  }
4279 
4280  if (a->argc != 6) {
4281  return CLI_SHOWUSAGE;
4282  }
4283  name = a->argv[3];
4284  collection_name = a->argv[4];
4285  leaf_name = a->argv[5];
4286 
4287  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, name))) {
4288  ast_cli(a->fd, "Unable to find client '%s'!\n", name);
4289  return CLI_FAILURE;
4290  }
4291 
4292  ast_cli(a->fd, "Creating test PubSub node collection.\n");
4293 
4294  xmpp_pubsub_create_leaf(clientcfg->client, collection_name, leaf_name);
4295 
4296  return CLI_SUCCESS;
4297 }
XMPP Client Configuration.
Definition: res_xmpp.c:444
const int argc
Definition: cli.h:160
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
Definition: cli.h:152
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#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:911
const int fd
Definition: cli.h:159
static struct console_pvt globals
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_FAILURE
Definition: cli.h:46
static const char name[]
Definition: cdr_mysql.c:74
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
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:1255
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ xmpp_cli_delete_pubsub_node()

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 4184 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, globals, name, NULL, RAII_VAR, ast_cli_entry::usage, xmpp_config_find(), and xmpp_pubsub_delete_node().

4186 {
4188  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
4189  const char *name;
4190 
4191  switch (cmd) {
4192  case CLI_INIT:
4193  e->command = "xmpp delete node";
4194  e->usage =
4195  "Usage: xmpp delete node <connection> <node>\n"
4196  " Deletes a node on PubSub server\n"
4197  " as configured in xmpp.conf.\n";
4198  return NULL;
4199  case CLI_GENERATE:
4200  return NULL;
4201  }
4202 
4203  if (a->argc != 5) {
4204  return CLI_SHOWUSAGE;
4205  }
4206  name = a->argv[3];
4207 
4208  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, name))) {
4209  ast_cli(a->fd, "Unable to find client '%s'!\n", name);
4210  return CLI_FAILURE;
4211  }
4212 
4213  xmpp_pubsub_delete_node(clientcfg->client, a->argv[4]);
4214 
4215  return CLI_SUCCESS;
4216 }
XMPP Client Configuration.
Definition: res_xmpp.c:444
const int argc
Definition: cli.h:160
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
Definition: cli.h:152
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#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:911
const int fd
Definition: cli.h:159
static struct console_pvt globals
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_FAILURE
Definition: cli.h:46
static const char name[]
Definition: cdr_mysql.c:74
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static void xmpp_pubsub_delete_node(struct ast_xmpp_client *client, const char *node_name)
Delete a PubSub node.
Definition: res_xmpp.c:1219

◆ xmpp_cli_list_pubsub_nodes()

static char* xmpp_cli_list_pubsub_nodes ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 4053 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, globals, name, NULL, RAII_VAR, ast_cli_entry::usage, xmpp_config_find(), and xmpp_pubsub_request_nodes().

4055 {
4057  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
4058  const char *name = NULL, *collection = NULL;
4059 
4060  switch (cmd) {
4061  case CLI_INIT:
4062  e->command = "xmpp list nodes";
4063  e->usage =
4064  "Usage: xmpp list nodes <connection> [collection]\n"
4065  " Lists the user's nodes on the respective connection\n"
4066  " ([connection] as configured in xmpp.conf.)\n";
4067  return NULL;
4068  case CLI_GENERATE:
4069  return NULL;
4070  }
4071 
4072  if (a->argc > 5 || a->argc < 4) {
4073  return CLI_SHOWUSAGE;
4074  } else if (a->argc == 4 || a->argc == 5) {
4075  name = a->argv[3];
4076  }
4077 
4078  if (a->argc == 5) {
4079  collection = a->argv[4];
4080  }
4081 
4082  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, name))) {
4083  ast_cli(a->fd, "Unable to find client '%s'!\n", name);
4084  return CLI_FAILURE;
4085  }
4086 
4087  ast_cli(a->fd, "Listing pubsub nodes.\n");
4088 
4089  xmpp_pubsub_request_nodes(clientcfg->client, collection);
4090 
4091  return CLI_SUCCESS;
4092 }
XMPP Client Configuration.
Definition: res_xmpp.c:444
const int argc
Definition: cli.h:160
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
static void xmpp_pubsub_request_nodes(struct ast_xmpp_client *client, const char *collection)
Request item list from pubsub.
Definition: res_xmpp.c:4029
Definition: cli.h:152
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#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:911
const int fd
Definition: cli.h:159
static struct console_pvt globals
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_FAILURE
Definition: cli.h:46
static const char name[]
Definition: cdr_mysql.c:74
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ xmpp_cli_purge_pubsub_nodes()

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 4139 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_test_flag, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, globals, name, NULL, RAII_VAR, ast_cli_entry::usage, xmpp_config_find(), xmpp_pubsub_delete_node(), xmpp_pubsub_purge_nodes(), and XMPP_XEP0248.

4141 {
4143  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
4144  const char *name;
4145 
4146  switch (cmd) {
4147  case CLI_INIT:
4148  e->command = "xmpp purge nodes";
4149  e->usage =
4150  "Usage: xmpp purge nodes <connection> <node>\n"
4151  " Purges nodes on PubSub server\n"
4152  " as configured in xmpp.conf.\n";
4153  return NULL;
4154  case CLI_GENERATE:
4155  return NULL;
4156  }
4157 
4158  if (a->argc != 5) {
4159  return CLI_SHOWUSAGE;
4160  }
4161  name = a->argv[3];
4162 
4163  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, name))) {
4164  ast_cli(a->fd, "Unable to find client '%s'!\n", name);
4165  return CLI_FAILURE;
4166  }
4167 
4168  if (ast_test_flag(&cfg->global->pubsub, XMPP_XEP0248)) {
4169  xmpp_pubsub_purge_nodes(clientcfg->client, a->argv[4]);
4170  } else {
4171  xmpp_pubsub_delete_node(clientcfg->client, a->argv[4]);
4172  }
4173 
4174  return CLI_SUCCESS;
4175 }
XMPP Client Configuration.
Definition: res_xmpp.c:444
#define ast_test_flag(p, flag)
Definition: utils.h:63
const int argc
Definition: cli.h:160
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
Definition: cli.h:152
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#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:911
const int fd
Definition: cli.h:159
static void xmpp_pubsub_purge_nodes(struct ast_xmpp_client *client, const char *collection_name)
Definition: res_xmpp.c:4121
static struct console_pvt globals
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_FAILURE
Definition: cli.h:46
static const char name[]
Definition: cdr_mysql.c:74
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static void xmpp_pubsub_delete_node(struct ast_xmpp_client *client, const char *node_name)
Delete a PubSub node.
Definition: res_xmpp.c:1219

◆ xmpp_client_alloc()

static struct ast_xmpp_client* xmpp_client_alloc ( const char *  name)
static

Allocator function for ast_xmpp_client.

Definition at line 604 of file res_xmpp.c.

References ao2_alloc, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ao2_ref, ast_copy_string(), ast_endpoint_create(), AST_LIST_HEAD_INIT, ast_log, AST_PTHREADT_NULL, ast_string_field_init, ast_string_field_set, ast_xmpp_client::buddies, BUDDY_BUCKETS, ast_xmpp_client::endpoint, LOG_ERROR, ast_xmpp_client::messages, ast_xmpp_client::mid, NULL, ast_xmpp_client::stack, ast_xmpp_client::thread, ast_xmpp_client::timeout, xmpp_buddy_cmp(), xmpp_buddy_hash(), xmpp_client_change_state(), xmpp_client_destructor(), and XMPP_STATE_DISCONNECTED.

Referenced by xmpp_client_find_or_create().

605 {
606  struct ast_xmpp_client *client;
607 
608  if (!(client = ao2_alloc(sizeof(*client), xmpp_client_destructor))) {
609  return NULL;
610  }
611 
612  AST_LIST_HEAD_INIT(&client->messages);
613  client->thread = AST_PTHREADT_NULL;
614 
615  client->endpoint = ast_endpoint_create("XMPP", name);
616  if (!client->endpoint) {
617  ao2_ref(client, -1);
618  return NULL;
619  }
620 
623  if (!client->buddies) {
624  ast_log(LOG_ERROR, "Could not initialize buddy container for '%s'\n", name);
625  ao2_ref(client, -1);
626  return NULL;
627  }
628 
629  if (ast_string_field_init(client, 512)) {
630  ast_log(LOG_ERROR, "Could not initialize stringfields for '%s'\n", name);
631  ao2_ref(client, -1);
632  return NULL;
633  }
634 
635  if (!(client->stack = iks_stack_new(8192, 8192))) {
636  ast_log(LOG_ERROR, "Could not create an Iksemel stack for '%s'\n", name);
637  ao2_ref(client, -1);
638  return NULL;
639  }
640 
641  ast_string_field_set(client, name, name);
642 
643  client->timeout = 50;
645  ast_copy_string(client->mid, "aaaaa", sizeof(client->mid));
646 
647  return client;
648 }
ikstack * stack
Definition: xmpp.h:129
struct ast_endpoint * ast_endpoint_create(const char *tech, const char *resource)
Create an endpoint struct.
static int xmpp_buddy_cmp(void *obj, void *arg, int flags)
Comparator function for XMPP buddy.
Definition: res_xmpp.c:581
#define NULL
Definition: resample.c:96
struct ast_xmpp_client::@330 messages
#define BUDDY_BUCKETS
Number of buckets for buddies (per client)
Definition: res_xmpp.c:423
#define ast_log
Definition: astobj2.c:42
XMPP Client Connection.
Definition: xmpp.h:119
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define LOG_ERROR
Definition: logger.h:285
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
static int xmpp_buddy_hash(const void *obj, const int flags)
Hashing function for XMPP buddy.
Definition: res_xmpp.c:572
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
static const char name[]
Definition: cdr_mysql.c:74
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
Definition: linkedlists.h:625
struct ast_endpoint * endpoint
Definition: xmpp.h:148
static void xmpp_client_destructor(void *obj)
Destructor callback function for XMPP client.
Definition: res_xmpp.c:545
struct ao2_container * buddies
Definition: xmpp.h:137
pthread_t thread
Definition: xmpp.h:139
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int timeout
Definition: xmpp.h:140
char mid[6]
Definition: xmpp.h:125
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:590
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ xmpp_client_authenticate()

static int xmpp_client_authenticate ( struct ast_xmpp_client client,
struct ast_xmpp_client_config cfg,
int  type,
iks *  node 
)
static

Internal function called when we need to authenticate.

Definition at line 2760 of file res_xmpp.c.

References ast_test_flag, ast_xmpp_client_config::flags, xmpp_client_authenticate_digest(), xmpp_client_authenticate_sasl(), and XMPP_USESASL.

2761 {
2763 }
static const char type[]
Definition: chan_ooh323.c:109
Definition: test_heap.c:38
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.
Definition: res_xmpp.c:2695
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_flags flags
Definition: res_xmpp.c:460
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.
Definition: res_xmpp.c:2657

◆ xmpp_client_authenticate_digest()

static int xmpp_client_authenticate_digest ( struct ast_xmpp_client client,
struct ast_xmpp_client_config cfg,
int  type,
iks *  node 
)
static

Internal function called when we need to authenticate using non-SASL.

Definition at line 2657 of file res_xmpp.c.

References ast_log, ast_sha1_hash(), ast_xmpp_client_lock(), ast_xmpp_client_send(), ast_xmpp_client_unlock(), ast_xmpp_increment_mid(), buf, ast_xmpp_client::filter, ast_xmpp_client::jid, LOG_ERROR, ast_xmpp_client::mid, ast_xmpp_client::name, NULL, ast_xmpp_client_config::password, xmpp_client_change_state(), xmpp_connect_hook(), and XMPP_STATE_AUTHENTICATING.

Referenced by xmpp_client_authenticate().

2658 {
2659  iks *iq = NULL, *query = NULL;
2660  char buf[41], sidpass[100];
2661 
2662  if (!(iq = iks_new("iq")) || !(query = iks_insert(iq, "query"))) {
2663  ast_log(LOG_ERROR, "Stanzas could not be allocated for authentication on client '%s'\n", client->name);
2664  iks_delete(iq);
2665  return -1;
2666  }
2667 
2668  iks_insert_attrib(iq, "type", "set");
2669  iks_insert_cdata(iks_insert(query, "username"), client->jid->user, 0);
2670  iks_insert_cdata(iks_insert(query, "resource"), client->jid->resource, 0);
2671 
2672  iks_insert_attrib(query, "xmlns", "jabber:iq:auth");
2673  snprintf(sidpass, sizeof(sidpass), "%s%s", iks_find_attrib(node, "id"), cfg->password);
2674  ast_sha1_hash(buf, sidpass);
2675  iks_insert_cdata(iks_insert(query, "digest"), buf, 0);
2676 
2677  ast_xmpp_client_lock(client);
2678  iks_filter_add_rule(client->filter, xmpp_connect_hook, client, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID, client->mid, IKS_RULE_DONE);
2679  iks_insert_attrib(iq, "id", client->mid);
2680  ast_xmpp_increment_mid(client->mid);
2681  ast_xmpp_client_unlock(client);
2682 
2683  iks_insert_attrib(iq, "to", client->jid->server);
2684 
2685  ast_xmpp_client_send(client, iq);
2686 
2687  iks_delete(iq);
2688 
2690 
2691  return 0;
2692 }
Definition: test_heap.c:38
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
void ast_xmpp_increment_mid(char *mid)
Helper function which increments the message identifier.
Definition: res_xmpp.c:1019
const ast_string_field password
Definition: res_xmpp.c:456
void ast_xmpp_client_lock(struct ast_xmpp_client *client)
Lock an XMPP client connection.
Definition: res_xmpp.c:893
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
void ast_sha1_hash(char *output, const char *input)
Produces SHA1 hash based on input string.
Definition: main/utils.c:264
#define LOG_ERROR
Definition: logger.h:285
iksfilter * filter
Definition: xmpp.h:128
iksid * jid
Definition: xmpp.h:126
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:898
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:590
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:2537
static int xmpp_connect_hook(void *data, ikspak *pak)
Hook function called when client finishes authenticating with the server.
Definition: res_xmpp.c:2436

◆ xmpp_client_authenticate_sasl()

static int xmpp_client_authenticate_sasl ( struct ast_xmpp_client client,
struct ast_xmpp_client_config cfg,
int  type,
iks *  node 
)
static

Internal function called when we need to authenticate using SASL.

Definition at line 2695 of file res_xmpp.c.

References ast_base64encode(), ast_log, ast_strdupa, ast_strlen_zero, ast_xmpp_client_send(), base64, ast_xmpp_client::jid, len(), LOG_ERROR, ast_xmpp_client::name, ast_xmpp_client::parser, ast_xmpp_client_config::password, ast_xmpp_client_config::refresh_token, strsep(), xmpp_client_change_state(), xmpp_is_secure(), and XMPP_STATE_AUTHENTICATING.

Referenced by xmpp_client_authenticate().

2696 {
2697  int features, len = strlen(client->jid->user) + strlen(cfg->password) + 3;
2698  iks *auth;
2699  char combined[len];
2700  char base64[(len + 2) * 4 / 3];
2701 
2702  if (strcmp(iks_name(node), "stream:features")) {
2703  /* Ignore anything beside stream features */
2704  return 0;
2705  }
2706 
2707  features = iks_stream_features(node);
2708 
2709  if ((features & IKS_STREAM_SASL_MD5) && !xmpp_is_secure(client)) {
2710  if (iks_start_sasl(client->parser, IKS_SASL_DIGEST_MD5, (char*)client->jid->user, (char*)cfg->password) != IKS_OK) {
2711  ast_log(LOG_ERROR, "Tried to authenticate client '%s' using SASL DIGEST-MD5 but could not\n", client->name);
2712  return -1;
2713  }
2714 
2716  return 0;
2717  }
2718 
2719  /* Our only other available option is plain so if they don't support it, bail out now */
2720  if (!(features & IKS_STREAM_SASL_PLAIN)) {
2721  ast_log(LOG_ERROR, "Tried to authenticate client '%s' using SASL PLAIN but server does not support it\n", client->name);
2722  return -1;
2723  }
2724 
2725  if (!(auth = iks_new("auth"))) {
2726  ast_log(LOG_ERROR, "Could not allocate memory for SASL PLAIN authentication for client '%s'\n", client->name);
2727  return -1;
2728  }
2729 
2730  iks_insert_attrib(auth, "xmlns", IKS_NS_XMPP_SASL);
2731  if (!ast_strlen_zero(cfg->refresh_token)) {
2732  iks_insert_attrib(auth, "mechanism", "X-OAUTH2");
2733  iks_insert_attrib(auth, "auth:service", "oauth2");
2734  iks_insert_attrib(auth, "xmlns:auth", "http://www.google.com/talk/protocol/auth");
2735  } else {
2736  iks_insert_attrib(auth, "mechanism", "PLAIN");
2737  }
2738 
2739  if (strchr(client->jid->user, '/')) {
2740  char *user = ast_strdupa(client->jid->user);
2741 
2742  snprintf(combined, sizeof(combined), "%c%s%c%s", 0, strsep(&user, "/"), 0, cfg->password);
2743  } else {
2744  snprintf(combined, sizeof(combined), "%c%s%c%s", 0, client->jid->user, 0, cfg->password);
2745  }
2746 
2747  ast_base64encode(base64, (const unsigned char *) combined, len - 1, (len + 2) * 4 / 3);
2748  iks_insert_cdata(auth, base64, 0);
2749 
2750  ast_xmpp_client_send(client, auth);
2751 
2752  iks_delete(auth);
2753 
2755 
2756  return 0;
2757 }
Definition: test_heap.c:38
iksparser * parser
Definition: xmpp.h:127
const ast_string_field password
Definition: res_xmpp.c:456
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static int xmpp_is_secure(struct ast_xmpp_client *client)
Helper function which returns whether an XMPP client connection is secure or not. ...
Definition: res_xmpp.c:866
#define LOG_ERROR
Definition: logger.h:285
int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64.
Definition: main/utils.c:404
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
iksid * jid
Definition: xmpp.h:126
structure to hold users read from users.conf
const ast_string_field name
Definition: xmpp.h:123
char * strsep(char **str, const char *delims)
const ast_string_field refresh_token
Definition: res_xmpp.c:456
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:590
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:2537
static char base64[64]
Definition: main/utils.c:78

◆ xmpp_client_authenticating()

static int xmpp_client_authenticating ( struct ast_xmpp_client client,
struct ast_xmpp_client_config cfg,
int  type,
iks *  node 
)
static

Internal function called when we are authenticating.

Definition at line 2766 of file res_xmpp.c.

References ast_log, ast_xmpp_client_lock(), ast_xmpp_client_send(), ast_xmpp_client_unlock(), ast_xmpp_increment_mid(), ast_xmpp_client::filter, ast_xmpp_client::jid, LOG_ERROR, ast_xmpp_client::mid, ast_xmpp_client::name, xmpp_connect_hook(), and xmpp_send_stream_header().

2767 {
2768  int features;
2769 
2770  if (!strcmp(iks_name(node), "success")) {
2771  /* Authentication was a success, yay! */
2772  xmpp_send_stream_header(client, cfg, client->jid->server);
2773 
2774  return 0;
2775  } else if (!strcmp(iks_name(node), "failure")) {
2776  /* Authentication was a bust, disconnect and reconnect later */
2777  return -1;
2778  } else if (strcmp(iks_name(node), "stream:features")) {
2779  /* Ignore any other responses */
2780  return 0;
2781  }
2782 
2783  features = iks_stream_features(node);
2784 
2785  if (features & IKS_STREAM_BIND) {
2786  iks *auth;
2787 
2788  if (!(auth = iks_make_resource_bind(client->jid))) {
2789  ast_log(LOG_ERROR, "Failed to allocate memory for stream bind on client '%s'\n", client->name);
2790  return -1;
2791  }
2792 
2793  ast_xmpp_client_lock(client);
2794  iks_insert_attrib(auth, "id", client->mid);
2795  ast_xmpp_increment_mid(client->mid);
2796  ast_xmpp_client_unlock(client);
2797  ast_xmpp_client_send(client, auth);
2798 
2799  iks_delete(auth);
2800 
2801  iks_filter_add_rule(client->filter, xmpp_connect_hook, client, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_DONE);
2802  }
2803 
2804  if (features & IKS_STREAM_SESSION) {
2805  iks *auth;
2806 
2807  if (!(auth = iks_make_session())) {
2808  ast_log(LOG_ERROR, "Failed to allocate memory for stream session on client '%s'\n", client->name);
2809  return -1;
2810  }
2811 
2812  iks_insert_attrib(auth, "id", "auth");
2813  ast_xmpp_client_lock(client);
2814  ast_xmpp_increment_mid(client->mid);
2815  ast_xmpp_client_unlock(client);
2816  ast_xmpp_client_send(client, auth);
2817 
2818  iks_delete(auth);
2819 
2820  iks_filter_add_rule(client->filter, xmpp_connect_hook, client, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID, "auth", IKS_RULE_DONE);
2821  }
2822 
2823  return 0;
2824 }
Definition: test_heap.c:38
void ast_xmpp_increment_mid(char *mid)
Helper function which increments the message identifier.
Definition: res_xmpp.c:1019
void ast_xmpp_client_lock(struct ast_xmpp_client *client)
Lock an XMPP client connection.
Definition: res_xmpp.c:893
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
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.
Definition: res_xmpp.c:2525
iksfilter * filter
Definition: xmpp.h:128
iksid * jid
Definition: xmpp.h:126
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:898
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:2537
static int xmpp_connect_hook(void *data, ikspak *pak)
Hook function called when client finishes authenticating with the server.
Definition: res_xmpp.c:2436

◆ xmpp_client_change_state()

static void xmpp_client_change_state ( struct ast_xmpp_client client,
int  state 
)
static

Internal function which changes the XMPP client state.

Definition at line 590 of file res_xmpp.c.

References AST_ENDPOINT_OFFLINE, AST_ENDPOINT_ONLINE, ast_endpoint_set_state(), ast_xmpp_client::endpoint, ast_xmpp_client::state, state, XMPP_STATE_CONNECTED, and XMPP_STATE_DISCONNECTED.

Referenced by ast_xmpp_client_disconnect(), xmpp_client_alloc(), xmpp_client_authenticate_digest(), xmpp_client_authenticate_sasl(), xmpp_client_reconnect(), xmpp_client_request_tls(), xmpp_client_requested_tls(), xmpp_component_authenticate(), xmpp_component_authenticating(), xmpp_connect_hook(), and xmpp_roster_hook().

591 {
592  if (state == client->state) {
593  return;
594  }
595  client->state = state;
596  if (client->state == XMPP_STATE_DISCONNECTED) {
598  } else if (client->state == XMPP_STATE_CONNECTED) {
600  }
601 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
void ast_endpoint_set_state(struct ast_endpoint *endpoint, enum ast_endpoint_state state)
Updates the state of the given endpoint.
enum xmpp_state state
Definition: xmpp.h:136
struct ast_endpoint * endpoint
Definition: xmpp.h:148

◆ xmpp_client_config_merge_buddies()

static int xmpp_client_config_merge_buddies ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 3811 of file res_xmpp.c.

References ao2_find, ao2_link, ao2_ref, ast_xmpp_buddy::id, and OBJ_KEY.

Referenced by xmpp_client_config_post_apply().

3812 {
3813  struct ast_xmpp_buddy *buddy1 = obj, *buddy2;
3814  struct ao2_container *buddies = arg;
3815 
3816  /* If the buddy does not already exist link it into the client buddies container */
3817  if (!(buddy2 = ao2_find(buddies, buddy1->id, OBJ_KEY))) {
3818  ao2_link(buddies, buddy1);
3819  } else {
3820  ao2_ref(buddy2, -1);
3821  }
3822 
3823  /* All buddies are unlinked from the configuration buddies container, always */
3824  return 1;
3825 }
#define OBJ_KEY
Definition: astobj2.h:1155
char id[XMPP_MAX_JIDLEN]
Definition: xmpp.h:113
#define ao2_ref(o, delta)
Definition: astobj2.h:464
XMPP Buddy.
Definition: xmpp.h:112
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
Generic container type.
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ xmpp_client_config_post_apply()

static int xmpp_client_config_post_apply ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 3866 of file res_xmpp.c.

References ao2_callback, ao2_cleanup, ao2_global_obj_ref, ast_copy_flags, ast_log, ast_pthread_create_background, ast_strlen_zero, ast_test_flag, ast_xmpp_client_disconnect(), ast_xmpp_client::buddies, ast_xmpp_client_config::buddies, ast_xmpp_client_config::client, ast_flags::flags, ast_xmpp_client_config::flags, globals, ast_xmpp_client::jid, LOG_ERROR, ast_xmpp_client_config::mod_flags, ast_xmpp_client_config::name, NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, ast_xmpp_client::parser, RAII_VAR, ast_xmpp_client::reconnect, ast_xmpp_client::stack, ast_xmpp_client::state, ast_xmpp_client_config::status, ast_xmpp_client_config::statusmsg, ast_xmpp_client::thread, ast_xmpp_client_config::user, xmpp_action_hook(), XMPP_AUTOACCEPT, XMPP_AUTOPRUNE, XMPP_AUTOREGISTER, xmpp_client_config_merge_buddies(), xmpp_client_set_presence(), xmpp_client_subscribe_user(), xmpp_client_thread(), XMPP_COMPONENT, xmpp_log_hook(), and XMPP_STATE_CONNECTED.

Referenced by xmpp_config_post_apply().

3867 {
3868  struct ast_xmpp_client_config *cfg = obj;
3870 
3871  /* Merge global options that have not been modified */
3872  ast_copy_flags(&cfg->flags, &gcfg->global->general, ~(cfg->mod_flags.flags) & (XMPP_AUTOPRUNE | XMPP_AUTOREGISTER | XMPP_AUTOACCEPT));
3873 
3874  /* Merge buddies as need be */
3876 
3877  if (cfg->client->reconnect) {
3878  /* Disconnect the existing session since our role is changing, or we are starting up */
3880 
3881  if (!(cfg->client->parser = iks_stream_new(ast_test_flag(&cfg->flags, XMPP_COMPONENT) ? "jabber:component:accept" : "jabber:client", cfg->client,
3882  xmpp_action_hook))) {
3883  ast_log(LOG_ERROR, "Iksemel stream could not be created for client '%s' - client not active\n", cfg->name);
3884  return -1;
3885  }
3886 
3887  iks_set_log_hook(cfg->client->parser, xmpp_log_hook);
3888 
3889  /* Create a JID based on the given user, if no resource is given use the default */
3890  if (!strchr(cfg->user, '/') && !ast_test_flag(&cfg->flags, XMPP_COMPONENT)) {
3891  char resource[strlen(cfg->user) + strlen("/asterisk-xmpp") + 1];
3892 
3893  snprintf(resource, sizeof(resource), "%s/asterisk-xmpp", cfg->user);
3894  cfg->client->jid = iks_id_new(cfg->client->stack, resource);
3895  } else {
3896  cfg->client->jid = iks_id_new(cfg->client->stack, cfg->user);
3897  }
3898 
3899  if (!cfg->client->jid || (ast_strlen_zero(cfg->client->jid->user) && !ast_test_flag(&cfg->flags, XMPP_COMPONENT))) {
3900  ast_log(LOG_ERROR, "Jabber identity '%s' could not be created for client '%s' - client not active\n", cfg->user, cfg->name);
3901  return -1;
3902  }
3903 
3905 
3906  cfg->client->reconnect = 0;
3907  } else if (cfg->client->state == XMPP_STATE_CONNECTED) {
3908  /* If this client is connected update their presence status since it may have changed */
3909  xmpp_client_set_presence(cfg->client, NULL, cfg->client->jid->full, cfg->status, cfg->statusmsg);
3910 
3911  /* Subscribe to the status of any newly added buddies */
3912  if (ast_test_flag(&cfg->flags, XMPP_AUTOREGISTER)) {
3914  }
3915  }
3916 
3917  return 0;
3918 }
ikstack * stack
Definition: xmpp.h:129
iksparser * parser
Definition: xmpp.h:127
XMPP Client Configuration.
Definition: res_xmpp.c:444
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
static void * xmpp_client_thread(void *data)
XMPP client connection thread.
Definition: res_xmpp.c:3731
unsigned int flags
Definition: utils.h:200
struct ast_flags flags
Definition: res_xmpp.c:460
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
unsigned int reconnect
Definition: xmpp.h:142
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
static int xmpp_client_config_merge_buddies(void *obj, void *arg, int flags)
Definition: res_xmpp.c:3811
#define NULL
Definition: resample.c:96
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.
Definition: res_xmpp.c:2308
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:567
#define ast_log
Definition: astobj2.c:42
#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:911
const ast_string_field user
Definition: res_xmpp.c:456
const ast_string_field statusmsg
Definition: res_xmpp.c:456
static struct console_pvt globals
struct ao2_container * buddies
Definition: res_xmpp.c:464
int ast_xmpp_client_disconnect(struct ast_xmpp_client *client)
Disconnect an XMPP client connection.
Definition: res_xmpp.c:3528
const ast_string_field name
Definition: res_xmpp.c:456
#define LOG_ERROR
Definition: logger.h:285
enum xmpp_state state
Definition: xmpp.h:136
struct ast_xmpp_client * client
Definition: res_xmpp.c:463
static void xmpp_log_hook(void *data, const char *xmpp, size_t size, int incoming)
Logging hook function.
Definition: res_xmpp.c:2474
static int xmpp_action_hook(void *data, int type, iks *node)
Action hook for when things occur.
Definition: res_xmpp.c:3458
iksid * jid
Definition: xmpp.h:126
static int xmpp_client_subscribe_user(void *obj, void *arg, int flags)
Callback function which subscribes to a user if needed.
Definition: res_xmpp.c:2229
struct ao2_container * buddies
Definition: xmpp.h:137
pthread_t thread
Definition: xmpp.h:139
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
enum ikshowtype status
Definition: res_xmpp.c:462
struct ast_flags mod_flags
Definition: res_xmpp.c:461

◆ xmpp_client_create_buddy()

static struct ast_xmpp_buddy* xmpp_client_create_buddy ( struct ao2_container container,
const char *  id 
)
static

Internal function which creates a buddy on a client.

Definition at line 2166 of file res_xmpp.c.

References ao2_alloc, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ao2_link, ao2_ref, ast_copy_string(), ast_xmpp_buddy::id, NULL, RESOURCE_BUCKETS, ast_xmpp_buddy::resources, ast_xmpp_buddy::subscribe, xmpp_buddy_destructor(), xmpp_resource_cmp(), and xmpp_resource_hash().

Referenced by client_buddy_handler(), xmpp_pak_s10n(), and xmpp_roster_hook().

2167 {
2168  struct ast_xmpp_buddy *buddy;
2169 
2170  if (!(buddy = ao2_alloc(sizeof(*buddy), xmpp_buddy_destructor))) {
2171  return NULL;
2172  }
2173 
2176  if (!buddy->resources) {
2177  ao2_ref(buddy, -1);
2178  return NULL;
2179  }
2180 
2181  ast_copy_string(buddy->id, id, sizeof(buddy->id));
2182 
2183  /* Assume we need to subscribe to get their presence until proven otherwise */
2184  buddy->subscribe = 1;
2185 
2186  ao2_link(container, buddy);
2187 
2188  return buddy;
2189 }
static int xmpp_resource_hash(const void *obj, const int flags)
Hashing function for XMPP resource.
Definition: res_xmpp.c:839
#define RESOURCE_BUCKETS
Number of buckets for resources (per buddy)
Definition: res_xmpp.c:426
char id[XMPP_MAX_JIDLEN]
Definition: xmpp.h:113
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
unsigned int subscribe
Definition: xmpp.h:115
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
XMPP Buddy.
Definition: xmpp.h:112
struct ao2_container * resources
Definition: xmpp.h:114
static int xmpp_resource_cmp(void *obj, void *arg, int flags)
Comparator function for XMPP resource.
Definition: res_xmpp.c:847
static void xmpp_buddy_destructor(void *obj)
Destructor callback function for XMPP buddy.
Definition: res_xmpp.c:856
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ xmpp_client_destructor()

static void xmpp_client_destructor ( void *  obj)
static

Destructor callback function for XMPP client.

Definition at line 545 of file res_xmpp.c.

References ao2_cleanup, ast_endpoint_shutdown(), AST_LIST_HEAD_DESTROY, AST_LIST_REMOVE_HEAD, ast_xmpp_client_disconnect(), ast_xmpp_client::buddies, ast_xmpp_client::endpoint, ast_xmpp_client::filter, ast_xmpp_message::list, ast_xmpp_message::message, ast_xmpp_client::messages, NULL, ast_xmpp_client::stack, and xmpp_message_destroy().

Referenced by xmpp_client_alloc().

546 {
547  struct ast_xmpp_client *client = obj;
548  struct ast_xmpp_message *message;
549 
551 
553  client->endpoint = NULL;
554 
555  if (client->filter) {
556  iks_filter_delete(client->filter);
557  }
558 
559  if (client->stack) {
560  iks_stack_delete(client->stack);
561  }
562 
563  ao2_cleanup(client->buddies);
564 
565  while ((message = AST_LIST_REMOVE_HEAD(&client->messages, list))) {
566  xmpp_message_destroy(message);
567  }
569 }
ikstack * stack
Definition: xmpp.h:129
struct ast_xmpp_message::@329 list
#define NULL
Definition: resample.c:96
struct ast_xmpp_client::@330 messages
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
Definition: linkedlists.h:652
XMPP Client Connection.
Definition: xmpp.h:119
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
int ast_xmpp_client_disconnect(struct ast_xmpp_client *client)
Disconnect an XMPP client connection.
Definition: res_xmpp.c:3528
char * message
Definition: xmpp.h:103
XMPP Message.
Definition: xmpp.h:101
static void xmpp_message_destroy(struct ast_xmpp_message *message)
Destroy function for XMPP messages.
Definition: res_xmpp.c:532
iksfilter * filter
Definition: xmpp.h:128
struct ast_endpoint * endpoint
Definition: xmpp.h:148
struct ao2_container * buddies
Definition: xmpp.h:137
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_endpoint_shutdown(struct ast_endpoint *endpoint)
Shutsdown an ast_endpoint.

◆ xmpp_client_find_or_create()

static void* xmpp_client_find_or_create ( const char *  category)
static

Look up existing client or create a new one.

Definition at line 657 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ao2_ref, globals, NULL, RAII_VAR, xmpp_client_alloc(), and xmpp_config_find().

Referenced by ast_xmpp_client_config_alloc().

658 {
660  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
661 
662  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, category))) {
663  return xmpp_client_alloc(category);
664  }
665 
666  ao2_ref(clientcfg->client, +1);
667  return clientcfg->client;
668 }
XMPP Client Configuration.
Definition: res_xmpp.c:444
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
static struct ast_xmpp_client * xmpp_client_alloc(const char *name)
Allocator function for ast_xmpp_client.
Definition: res_xmpp.c:604
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
#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:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct console_pvt globals
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ xmpp_client_receive()

static int xmpp_client_receive ( struct ast_xmpp_client client,
unsigned int  timeout 
)
static

Internal function which receives data from the XMPP client connection.

Definition at line 3651 of file res_xmpp.c.

References ast_debug, ast_log, buf, c, IKS_NET_EXPIRED, ast_xmpp_client::jid, len(), LOG_WARNING, ast_xmpp_client::name, NET_IO_BUF_SIZE, newbuf(), ast_xmpp_client::parser, xmpp_io_recv(), xmpp_log_hook(), and xmpp_ping_request().

Referenced by xmpp_client_thread().

3652 {
3653  int len, ret, pos = 0, newbufpos = 0;
3654  char buf[NET_IO_BUF_SIZE - 1] = "";
3655  char newbuf[NET_IO_BUF_SIZE - 1] = "";
3656  unsigned char c;
3657 
3658  while (1) {
3659  len = xmpp_io_recv(client, buf, NET_IO_BUF_SIZE - 2, timeout);
3660  if (len < 0) return IKS_NET_RWERR;
3661  if (len == 0) return IKS_NET_EXPIRED;
3662  buf[len] = '\0';
3663 
3664  /* our iksemel parser won't work as expected if we feed
3665  it with XML packets that contain multiple whitespace
3666  characters between tags */
3667  while (pos < len) {
3668  c = buf[pos];
3669  /* if we stumble on the ending tag character,
3670  we skip any whitespace that follows it*/
3671  if (c == '>') {
3672  while (isspace(buf[pos+1])) {
3673  pos++;
3674  }
3675  }
3676  newbuf[newbufpos] = c;
3677  newbufpos++;
3678  pos++;
3679  }
3680  pos = 0;
3681  newbufpos = 0;
3682 
3683  /* Log the message here, because iksemel's logHook is
3684  unaccessible */
3685  xmpp_log_hook(client, buf, len, 1);
3686 
3687  if(buf[0] == ' ') {
3688  ast_debug(1, "JABBER: Detected Google Keep Alive. "
3689  "Sending out Ping request for client '%s'\n", client->name);
3690  /* If we just send out the ping here then we will have socket
3691  * read errors because the socket will timeout */
3692  xmpp_ping_request(client, client->jid->server, client->jid->full);
3693  }
3694 
3695  /* let iksemel deal with the string length,
3696  and reset our buffer */
3697  ret = iks_parse(client->parser, newbuf, 0, 0);
3698  memset(newbuf, 0, sizeof(newbuf));
3699 
3700  switch (ret) {
3701  case IKS_NOMEM:
3702  ast_log(LOG_WARNING, "Parsing failure: Out of memory.\n");
3703  break;
3704  case IKS_BADXML:
3705  ast_log(LOG_WARNING, "Parsing failure: Invalid XML.\n");
3706  break;
3707  case IKS_HOOK:
3708  ast_log(LOG_WARNING, "Parsing failure: Hook returned an error.\n");
3709  break;
3710  }
3711  if (ret != IKS_OK) {
3712  return ret;
3713  }
3714  ast_debug(3, "XML parsing successful\n");
3715  }
3716  return IKS_OK;
3717 }
iksparser * parser
Definition: xmpp.h:127
#define NET_IO_BUF_SIZE
Definition: xmpp.h:38
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
static int timeout
Definition: cdr_mysql.c:86
static struct test_val c
#define IKS_NET_EXPIRED
Definition: xmpp.h:41
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
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.
Definition: res_xmpp.c:3232
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static void xmpp_log_hook(void *data, const char *xmpp, size_t size, int incoming)
Logging hook function.
Definition: res_xmpp.c:2474
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.
Definition: res_xmpp.c:3617
iksid * jid
Definition: xmpp.h:126
const ast_string_field name
Definition: xmpp.h:123
static BUFHEAD * newbuf(HTAB *hashp, u_int32_t addr, BUFHEAD *prev_bp)
Definition: hash_buf.c:160

◆ xmpp_client_reconnect()

static int xmpp_client_reconnect ( struct ast_xmpp_client client)
static

Internal function used to reconnect an XMPP client to its server.

Definition at line 3567 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ast_debug, ast_log, ast_strlen_zero, ast_test_flag, ast_xmpp_client_disconnect(), fetch_access_token(), ast_xmpp_client::filter, globals, ast_xmpp_client::jid, LOG_ERROR, ast_xmpp_client::name, NULL, ast_xmpp_client::parser, RAII_VAR, S_OR, ast_xmpp_client::timeout, xmpp_client_change_state(), XMPP_COMPONENT, xmpp_config_find(), XMPP_STATE_AUTHENTICATE, XMPP_STATE_REQUEST_TLS, and XMPP_USETLS.

Referenced by xmpp_client_thread().

3568 {
3569  struct timeval tv = { .tv_sec = 5, .tv_usec = 0 };
3571  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
3572  int res = IKS_NET_NOCONN;
3573 
3574  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name))) {
3575  return -1;
3576  }
3577 
3579 
3580  client->timeout = 50;
3581  iks_parser_reset(client->parser);
3582 
3583  if (!client->filter && !(client->filter = iks_filter_new())) {
3584  ast_log(LOG_ERROR, "Could not create IKS filter for client connection '%s'\n", client->name);
3585  return -1;
3586  }
3587 
3588  if (!ast_strlen_zero(clientcfg->refresh_token)) {
3589  ast_debug(2, "Obtaining OAuth access token for client '%s'\n", client->name);
3590  if (fetch_access_token(clientcfg)) {
3591  return -1;
3592  }
3593  }
3594 
3595  /* If it's a component connect to user otherwise connect to server */
3596  res = iks_connect_via(client->parser, S_OR(clientcfg->server, client->jid->server), clientcfg->port,
3597  ast_test_flag(&clientcfg->flags, XMPP_COMPONENT) ? clientcfg->user : client->jid->server);
3598 
3599  /* Set socket timeout options */
3600  setsockopt(iks_fd(client->parser), SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));
3601 
3602  if (res == IKS_NET_NOCONN) {
3603  ast_log(LOG_ERROR, "No XMPP connection available when trying to connect client '%s'\n", client->name);
3604  return -1;
3605  } else if (res == IKS_NET_NODNS) {
3606  ast_log(LOG_ERROR, "No DNS available for XMPP connection when trying to connect client '%s'\n", client->name);
3607  return -1;
3608  }
3609 
3610  /* Depending on the configuration of the client we eiher jump to requesting TLS, or authenticating */
3612 
3613  return 0;
3614 }
iksparser * parser
Definition: xmpp.h:127
XMPP Client Configuration.
Definition: res_xmpp.c:444
#define ast_test_flag(p, flag)
Definition: utils.h:63
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#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:911
static struct console_pvt globals
int ast_xmpp_client_disconnect(struct ast_xmpp_client *client)
Disconnect an XMPP client connection.
Definition: res_xmpp.c:3528
#define LOG_ERROR
Definition: logger.h:285
iksfilter * filter
Definition: xmpp.h:128
iksid * jid
Definition: xmpp.h:126
const ast_string_field name
Definition: xmpp.h:123
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int timeout
Definition: xmpp.h:140
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
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:590
static int fetch_access_token(struct ast_xmpp_client_config *cfg)
Definition: res_xmpp.c:3827

◆ xmpp_client_request_tls()

static int xmpp_client_request_tls ( struct ast_xmpp_client client,
struct ast_xmpp_client_config cfg,
int  type,
iks *  node 
)
static

Internal function called when we need to request TLS support.

Definition at line 2543 of file res_xmpp.c.

References ast_log, LOG_ERROR, ast_xmpp_client::name, ast_xmpp_client::parser, ast_xmpp_client::stream_flags, xmpp_client_change_state(), xmpp_is_secure(), XMPP_STATE_AUTHENTICATE, and XMPP_STATE_REQUESTED_TLS.

2544 {
2545  /* If the client connection is already secure we can jump straight to authenticating */
2546  if (xmpp_is_secure(client)) {
2548  return 0;
2549  }
2550 
2551 #ifndef HAVE_OPENSSL
2552  ast_log(LOG_ERROR, "TLS connection for client '%s' cannot be established. OpenSSL is not available.\n", client->name);
2553  return -1;
2554 #else
2555  if (iks_send_raw(client->parser, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>") == IKS_NET_TLSFAIL) {
2556  ast_log(LOG_ERROR, "TLS connection for client '%s' cannot be started.\n", client->name);
2557  return -1;
2558  }
2559 
2560  client->stream_flags |= TRY_SECURE;
2561 
2563 
2564  return 0;
2565 #endif
2566 }
iksparser * parser
Definition: xmpp.h:127
unsigned int stream_flags
Definition: xmpp.h:134
#define ast_log
Definition: astobj2.c:42
static int xmpp_is_secure(struct ast_xmpp_client *client)
Helper function which returns whether an XMPP client connection is secure or not. ...
Definition: res_xmpp.c:866
#define LOG_ERROR
Definition: logger.h:285
const ast_string_field name
Definition: xmpp.h:123
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:590

◆ xmpp_client_requested_tls()

static int xmpp_client_requested_tls ( struct ast_xmpp_client client,
struct ast_xmpp_client_config cfg,
int  type,
iks *  node 
)
static

Internal function called when we receive a response to our TLS initiation request.

Definition at line 2587 of file res_xmpp.c.

References ast_debug, ast_free, ast_log, ast_xmpp_client::jid, LOG_ERROR, ast_xmpp_client::name, openssl_error_string(), ast_xmpp_client::parser, ast_xmpp_client::ssl_context, ast_xmpp_client::ssl_method, ast_xmpp_client::ssl_session, ast_xmpp_client::stream_flags, xmpp_client_change_state(), xmpp_send_stream_header(), and XMPP_STATE_AUTHENTICATE.

2588 {
2589 #ifdef HAVE_OPENSSL
2590  int sock;
2591  long ssl_opts;
2592  char *err;
2593 #endif
2594 
2595  if (!strcmp(iks_name(node), "success")) {
2596  /* TLS is up and working, we can move on to authenticating now */
2598  return 0;
2599  } else if (!strcmp(iks_name(node), "failure")) {
2600  /* TLS negotiation was a failure, close it on down! */
2601  return -1;
2602  } else if (strcmp(iks_name(node), "proceed")) {
2603  /* Ignore any other responses */
2604  return 0;
2605  }
2606 
2607 #ifndef HAVE_OPENSSL
2608  ast_log(LOG_ERROR, "Somehow we managed to try to start TLS negotiation on client '%s' without OpenSSL support, disconnecting\n", client->name);
2609  return -1;
2610 #else
2611  client->ssl_method = SSLv23_method();
2612  if (!(client->ssl_context = SSL_CTX_new((SSL_METHOD *) client->ssl_method))) {
2613  goto failure;
2614  }
2615 
2616  ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
2617  SSL_CTX_set_options(client->ssl_context, ssl_opts);
2618 
2619  if (!(client->ssl_session = SSL_new(client->ssl_context))) {
2620  goto failure;
2621  }
2622 
2623  sock = iks_fd(client->parser);
2624  if (!SSL_set_fd(client->ssl_session, sock)) {
2625  goto failure;
2626  }
2627 
2628  if (SSL_connect(client->ssl_session) <= 0) {
2629  goto failure;
2630  }
2631 
2632  client->stream_flags &= (~TRY_SECURE);
2633  client->stream_flags |= SECURE;
2634 
2635  if (xmpp_send_stream_header(client, cfg, client->jid->server) != IKS_OK) {
2636  ast_log(LOG_ERROR, "TLS connection for client '%s' could not be established, failed to send stream header after negotiation\n",
2637  client->name);
2638  return -1;
2639  }
2640 
2641  ast_debug(1, "TLS connection for client '%s' started with server\n", client->name);
2642 
2644 
2645  return 0;
2646 
2647 failure:
2648  err = openssl_error_string();
2649  ast_log(LOG_ERROR, "TLS connection for client '%s' cannot be established. "
2650  "OpenSSL initialization failed: %s\n", client->name, err);
2651  ast_free(err);
2652  return -1;
2653 #endif
2654 }
Definition: test_heap.c:38
iksparser * parser
Definition: xmpp.h:127
unsigned int stream_flags
Definition: xmpp.h:134
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
const SSL_METHOD * ssl_method
Definition: xmpp.h:133
#define LOG_ERROR
Definition: logger.h:285
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.
Definition: res_xmpp.c:2525
#define ast_free(a)
Definition: astmm.h:182
iksid * jid
Definition: xmpp.h:126
const ast_string_field name
Definition: xmpp.h:123
SSL_CTX * ssl_context
Definition: xmpp.h:131
SSL * ssl_session
Definition: xmpp.h:132
static char * openssl_error_string(void)
Definition: res_xmpp.c:2569
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:590

◆ xmpp_client_send_disco_info_request()

static int xmpp_client_send_disco_info_request ( struct ast_xmpp_client client,
const char *  to,
const char *  from 
)
static

Helper function which sends a discovery information request to a user.

Definition at line 3195 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.

Referenced by xmpp_pak_presence().

3196 {
3197  iks *iq, *query;
3198  int res;
3199 
3200  if (!(iq = iks_new("iq")) || !(query = iks_new("query"))) {
3201  iks_delete(iq);
3202  return -1;
3203  }
3204 
3205  iks_insert_attrib(iq, "type", "get");
3206  iks_insert_attrib(iq, "to", to);
3207  iks_insert_attrib(iq, "from", from);
3208  ast_xmpp_client_lock(client);
3209  iks_insert_attrib(iq, "id", client->mid);
3210  ast_xmpp_increment_mid(client->mid);
3211  ast_xmpp_client_unlock(client);
3212  iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info");
3213  iks_insert_node(iq, query);
3214 
3215  res = ast_xmpp_client_send(client, iq);
3216 
3217  iks_delete(query);
3218  iks_delete(iq);
3219 
3220  return res;
3221 }
void ast_xmpp_increment_mid(char *mid)
Helper function which increments the message identifier.
Definition: res_xmpp.c:1019
void ast_xmpp_client_lock(struct ast_xmpp_client *client)
Lock an XMPP client connection.
Definition: res_xmpp.c:893
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:898
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:2537

◆ xmpp_client_send_message()

static int xmpp_client_send_message ( struct ast_xmpp_client client,
int  group,
const char *  nick,
const char *  address,
const char *  message 
)
static

Internal function used to send a message to a user or chatroom.

Definition at line 904 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ast_strlen_zero, ast_test_flag, ast_xmpp_client_send(), globals, ast_xmpp_client::jid, ast_xmpp_client::name, NULL, RAII_VAR, XMPP_COMPONENT, xmpp_config_find(), and XMPP_MAX_JIDLEN.

Referenced by ast_xmpp_chatroom_send(), and ast_xmpp_client_send_message().

905 {
907  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
908  int res = 0;
909  char from[XMPP_MAX_JIDLEN];
910  iks *message_packet;
911 
912  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name)) ||
913  !(message_packet = iks_make_msg(group ? IKS_TYPE_GROUPCHAT : IKS_TYPE_CHAT, address, message))) {
914  return -1;
915  }
916 
917  if (!ast_strlen_zero(nick) && ast_test_flag(&clientcfg->flags, XMPP_COMPONENT)) {
918  snprintf(from, sizeof(from), "%s@%s/%s", nick, client->jid->full, nick);
919  } else {
920  snprintf(from, sizeof(from), "%s", client->jid->full);
921  }
922 
923  iks_insert_attrib(message_packet, "from", from);
924 
925  res = ast_xmpp_client_send(client, message_packet);
926 
927  iks_delete(message_packet);
928 
929  return res;
930 }
XMPP Client Configuration.
Definition: res_xmpp.c:444
#define ast_test_flag(p, flag)
Definition: utils.h:63
char * address
Definition: f2c.h:59
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#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:911
static struct console_pvt globals
#define XMPP_MAX_JIDLEN
Definition: xmpp.h:62
iksid * jid
Definition: xmpp.h:126
const ast_string_field name
Definition: xmpp.h:123
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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:2537

◆ xmpp_client_send_raw_message()

static int xmpp_client_send_raw_message ( struct ast_xmpp_client client,
const char *  message 
)
static

Internal function which sends a raw message.

Definition at line 2492 of file res_xmpp.c.

References len(), ast_xmpp_client::parser, ast_xmpp_client::ssl_session, ast_xmpp_client::state, xmpp_is_secure(), xmpp_log_hook(), and XMPP_STATE_DISCONNECTED.

Referenced by ast_xmpp_client_send(), xmpp_component_authenticate(), and xmpp_send_stream_header().

2493 {
2494  int ret;
2495 
2496  if (client->state == XMPP_STATE_DISCONNECTED) {
2497  /* iks_send_raw will crash without a connection */
2498  return IKS_NET_NOCONN;
2499  }
2500 
2501 #ifdef HAVE_OPENSSL
2502  if (xmpp_is_secure(client)) {
2503  int len = strlen(message);
2504 
2505  ret = SSL_write(client->ssl_session, message, len);
2506  if (ret) {
2507  /* Log the message here, because iksemel's logHook is
2508  unaccessible */
2509  xmpp_log_hook(client, message, len, 0);
2510  return IKS_OK;
2511  }
2512  }
2513 #endif
2514  /* If needed, data will be sent unencrypted, and logHook will
2515  be called inside iks_send_raw */
2516  ret = iks_send_raw(client->parser, message);
2517  if (ret != IKS_OK) {
2518  return ret;
2519  }
2520 
2521  return IKS_OK;
2522 }
iksparser * parser
Definition: xmpp.h:127
static int xmpp_is_secure(struct ast_xmpp_client *client)
Helper function which returns whether an XMPP client connection is secure or not. ...
Definition: res_xmpp.c:866
enum xmpp_state state
Definition: xmpp.h:136
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static void xmpp_log_hook(void *data, const char *xmpp, size_t size, int incoming)
Logging hook function.
Definition: res_xmpp.c:2474
SSL * ssl_session
Definition: xmpp.h:132

◆ xmpp_client_service_discovery_get_hook()

static int xmpp_client_service_discovery_get_hook ( void *  data,
ikspak *  pak 
)
static

Hook function called when client receives a service discovery get message.

Definition at line 2346 of file res_xmpp.c.

References ast_log, ast_xmpp_client_send(), end, ast_xmpp_client::jid, LOG_ERROR, ast_xmpp_client::name, and NULL.

Referenced by xmpp_connect_hook().

2347 {
2348  struct ast_xmpp_client *client = data;
2349  iks *iq, *disco = NULL, *ident = NULL, *google = NULL, *jingle = NULL, *ice = NULL, *rtp = NULL, *audio = NULL, *video = NULL, *query = NULL;
2350 
2351  if (!(iq = iks_new("iq")) || !(query = iks_new("query")) || !(ident = iks_new("identity")) || !(disco = iks_new("feature")) ||
2352  !(google = iks_new("feature")) || !(jingle = iks_new("feature")) || !(ice = iks_new("feature")) || !(rtp = iks_new("feature")) ||
2353  !(audio = iks_new("feature")) || !(video = iks_new("feature"))) {
2354  ast_log(LOG_ERROR, "Could not allocate memory for responding to service discovery request from '%s' on client '%s'\n",
2355  pak->from->full, client->name);
2356  goto end;
2357  }
2358 
2359  iks_insert_attrib(iq, "from", client->jid->full);
2360 
2361  if (pak->from) {
2362  iks_insert_attrib(iq, "to", pak->from->full);
2363  }
2364 
2365  iks_insert_attrib(iq, "type", "result");
2366  iks_insert_attrib(iq, "id", pak->id);
2367  iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info");
2368  iks_insert_attrib(ident, "category", "client");
2369  iks_insert_attrib(ident, "type", "pc");
2370  iks_insert_attrib(ident, "name", "asterisk");
2371  iks_insert_attrib(disco, "var", "http://jabber.org/protocol/disco#info");
2372 
2373  iks_insert_attrib(google, "var", "http://www.google.com/xmpp/protocol/voice/v1");
2374  iks_insert_attrib(jingle, "var", "urn:xmpp:jingle:1");
2375  iks_insert_attrib(ice, "var", "urn:xmpp:jingle:transports:ice-udp:1");
2376  iks_insert_attrib(rtp, "var", "urn:xmpp:jingle:apps:rtp:1");
2377  iks_insert_attrib(audio, "var", "urn:xmpp:jingle:apps:rtp:audio");
2378  iks_insert_attrib(video, "var", "urn:xmpp:jingle:apps:rtp:video");
2379  iks_insert_node(iq, query);
2380  iks_insert_node(query, ident);
2381  iks_insert_node(query, google);
2382  iks_insert_node(query, disco);
2383  iks_insert_node(query, jingle);
2384  iks_insert_node(query, ice);
2385  iks_insert_node(query, rtp);
2386  iks_insert_node(query, audio);
2387  iks_insert_node(query, video);
2388  ast_xmpp_client_send(client, iq);
2389 
2390 end:
2391  iks_delete(query);
2392  iks_delete(video);
2393  iks_delete(audio);
2394  iks_delete(rtp);
2395  iks_delete(ice);
2396  iks_delete(jingle);
2397  iks_delete(google);
2398  iks_delete(ident);
2399  iks_delete(disco);
2400  iks_delete(iq);
2401 
2402  return IKS_FILTER_EAT;
2403 }
#define NULL
Definition: resample.c:96
char * end
Definition: eagi_proxy.c:73
#define ast_log
Definition: astobj2.c:42
XMPP Client Connection.
Definition: xmpp.h:119
#define LOG_ERROR
Definition: logger.h:285
iksid * jid
Definition: xmpp.h:126
const ast_string_field name
Definition: xmpp.h:123
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:2537

◆ xmpp_client_service_discovery_result_hook()

static int xmpp_client_service_discovery_result_hook ( void *  data,
ikspak *  pak 
)
static

Hook function called when client receives a service discovery result message.

Definition at line 2406 of file res_xmpp.c.

References ao2_callback, ao2_find, ao2_lock, ao2_ref, ao2_unlock, ast_xmpp_client::buddies, ast_xmpp_resource::caps, ast_xmpp_capabilities::jingle, OBJ_KEY, ast_xmpp_resource::resource, ast_xmpp_buddy::resources, and xmpp_resource_cmp().

Referenced by xmpp_component_authenticating(), and xmpp_connect_hook().

2407 {
2408  struct ast_xmpp_client *client = data;
2409  struct ast_xmpp_buddy *buddy;
2410  struct ast_xmpp_resource *resource;
2411 
2412  if (!(buddy = ao2_find(client->buddies, pak->from->partial, OBJ_KEY))) {
2413  return IKS_FILTER_EAT;
2414  }
2415 
2416  if (!(resource = ao2_callback(buddy->resources, 0, xmpp_resource_cmp, pak->from->resource))) {
2417  ao2_ref(buddy, -1);
2418  return IKS_FILTER_EAT;
2419  }
2420 
2421  ao2_lock(resource);
2422 
2423  if (iks_find_with_attrib(pak->query, "feature", "var", "urn:xmpp:jingle:1")) {
2424  resource->caps.jingle = 1;
2425  }
2426 
2427  ao2_unlock(resource);
2428 
2429  ao2_ref(resource, -1);
2430  ao2_ref(buddy, -1);
2431 
2432  return IKS_FILTER_EAT;
2433 }
#define OBJ_KEY
Definition: astobj2.h:1155
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
char resource[XMPP_MAX_RESJIDLEN]
Definition: xmpp.h:93
#define ao2_unlock(a)
Definition: astobj2.h:730
XMPP Client Connection.
Definition: xmpp.h:119
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
XMPP Resource.
Definition: xmpp.h:92
unsigned int jingle
Definition: xmpp.h:87
XMPP Buddy.
Definition: xmpp.h:112
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
struct ao2_container * resources
Definition: xmpp.h:114
static int xmpp_resource_cmp(void *obj, void *arg, int flags)
Comparator function for XMPP resource.
Definition: res_xmpp.c:847
struct ao2_container * buddies
Definition: xmpp.h:137
struct ast_xmpp_capabilities caps
Definition: xmpp.h:97

◆ xmpp_client_set_group_presence()

static int xmpp_client_set_group_presence ( struct ast_xmpp_client client,
const char *  room,
int  level,
const char *  nick 
)
static

Definition at line 968 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ast_test_flag, ast_xmpp_client_send(), done, globals, ast_xmpp_client::jid, ast_xmpp_client::name, NULL, RAII_VAR, S_OR, XMPP_COMPONENT, xmpp_config_find(), and XMPP_MAX_JIDLEN.

Referenced by ast_xmpp_chatroom_join(), and ast_xmpp_chatroom_leave().

969 {
971  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
972  int res = 0;
973  iks *presence = NULL, *x = NULL;
974  char from[XMPP_MAX_JIDLEN], roomid[XMPP_MAX_JIDLEN];
975 
976  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name)) ||
977  !(presence = iks_make_pres(level, NULL)) || !(x = iks_new("x"))) {
978  res = -1;
979  goto done;
980  }
981 
982  if (ast_test_flag(&clientcfg->flags, XMPP_COMPONENT)) {
983  snprintf(from, sizeof(from), "%s@%s/%s", nick, client->jid->full, nick);
984  snprintf(roomid, sizeof(roomid), "%s/%s", room, nick);
985  } else {
986  snprintf(from, sizeof(from), "%s", client->jid->full);
987  snprintf(roomid, sizeof(roomid), "%s/%s", room, S_OR(nick, client->jid->user));
988  }
989 
990  iks_insert_attrib(presence, "to", roomid);
991  iks_insert_attrib(presence, "from", from);
992  iks_insert_attrib(x, "xmlns", "http://jabber.org/protocol/muc");
993  iks_insert_node(presence, x);
994 
995  res = ast_xmpp_client_send(client, presence);
996 
997 done:
998  iks_delete(x);
999  iks_delete(presence);
1000 
1001  return res;
1002 }
XMPP Client Configuration.
Definition: res_xmpp.c:444
#define ast_test_flag(p, flag)
Definition: utils.h:63
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
int done
Definition: test_amihooks.c:48
#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:911
static struct console_pvt globals
#define XMPP_MAX_JIDLEN
Definition: xmpp.h:62
iksid * jid
Definition: xmpp.h:126
const ast_string_field name
Definition: xmpp.h:123
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
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:2537

◆ xmpp_client_set_presence()

static void xmpp_client_set_presence ( struct ast_xmpp_client client,
const char *  to,
const char *  from,
int  level,
const char *  desc 
)
static

Internal function which changes the presence status of an XMPP client.

Definition at line 2308 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ast_log, ast_strlen_zero, ast_xmpp_client_send(), done, globals, LOG_ERROR, ast_xmpp_client::name, NULL, priority, RAII_VAR, and xmpp_config_find().

Referenced by xmpp_client_config_post_apply(), xmpp_connect_hook(), xmpp_pak_presence(), and xmpp_pak_s10n().

2309 {
2311  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
2312  iks *presence = NULL, *cnode = NULL, *priority = NULL;
2313  char priorityS[10];
2314 
2315  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name)) ||
2316  !(presence = iks_make_pres(level, desc)) || !(cnode = iks_new("c")) || !(priority = iks_new("priority"))) {
2317  ast_log(LOG_ERROR, "Unable to allocate stanzas for setting presence status for client '%s'\n", client->name);
2318  goto done;
2319  }
2320 
2321  if (!ast_strlen_zero(to)) {
2322  iks_insert_attrib(presence, "to", to);
2323  }
2324 
2325  if (!ast_strlen_zero(from)) {
2326  iks_insert_attrib(presence, "from", from);
2327  }
2328 
2329  snprintf(priorityS, sizeof(priorityS), "%d", clientcfg->priority);
2330  iks_insert_cdata(priority, priorityS, strlen(priorityS));
2331  iks_insert_node(presence, priority);
2332  iks_insert_attrib(cnode, "node", "http://www.asterisk.org/xmpp/client/caps");
2333  iks_insert_attrib(cnode, "ver", "asterisk-xmpp");
2334  iks_insert_attrib(cnode, "ext", "voice-v1 video-v1 camera-v1");
2335  iks_insert_attrib(cnode, "xmlns", "http://jabber.org/protocol/caps");
2336  iks_insert_node(presence, cnode);
2337  ast_xmpp_client_send(client, presence);
2338 
2339 done:
2340  iks_delete(cnode);
2341  iks_delete(presence);
2342  iks_delete(priority);
2343 }
XMPP Client Configuration.
Definition: res_xmpp.c:444
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
static const char desc[]
Definition: cdr_mysql.c:73
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
static int priority
#define ast_strlen_zero(foo)
Definition: strings.h:52
int done
Definition: test_amihooks.c:48
#define ast_log
Definition: astobj2.c:42
#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:911
static struct console_pvt globals
#define LOG_ERROR
Definition: logger.h:285
const ast_string_field name
Definition: xmpp.h:123
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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:2537

◆ xmpp_client_subscribe_user()

static int xmpp_client_subscribe_user ( void *  obj,
void *  arg,
int  flags 
)
static

Callback function which subscribes to a user if needed.

Definition at line 2229 of file res_xmpp.c.

References ast_log, ast_xmpp_client_send(), ast_xmpp_buddy::id, LOG_WARNING, ast_xmpp_client::name, and ast_xmpp_buddy::subscribe.

Referenced by xmpp_client_config_post_apply(), and xmpp_roster_hook().

2230 {
2231  struct ast_xmpp_buddy *buddy = obj;
2232  struct ast_xmpp_client *client = arg;
2233 
2234  if (!buddy->subscribe) {
2235  return 0;
2236  }
2237 
2238  if (ast_xmpp_client_send(client, iks_make_s10n(IKS_TYPE_SUBSCRIBE, buddy->id,
2239  "Greetings! I am the Asterisk Open Source PBX and I want to subscribe to your presence\n"))) {
2240  ast_log(LOG_WARNING, "Could not send subscription for '%s' on client '%s'\n",
2241  buddy->id, client->name);
2242  }
2243 
2244  buddy->subscribe = 0;
2245 
2246  return 0;
2247 }
#define LOG_WARNING
Definition: logger.h:274
char id[XMPP_MAX_JIDLEN]
Definition: xmpp.h:113
#define ast_log
Definition: astobj2.c:42
XMPP Client Connection.
Definition: xmpp.h:119
unsigned int subscribe
Definition: xmpp.h:115
XMPP Buddy.
Definition: xmpp.h:112
const ast_string_field name
Definition: xmpp.h:123
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:2537

◆ xmpp_client_thread()

static void* xmpp_client_thread ( void *  data)
static

XMPP client connection thread.

Definition at line 3731 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ast_debug, ast_log, ast_test_flag, ast_xmpp_client_disconnect(), globals, IKS_NET_EXPIRED, ast_xmpp_client::jid, LOG_ERROR, LOG_WARNING, ast_xmpp_client::name, NULL, RAII_VAR, sleep_with_backoff(), ast_xmpp_client::state, ast_xmpp_client::timeout, xmpp_client_receive(), xmpp_client_reconnect(), xmpp_config_find(), XMPP_KEEPALIVE, xmpp_ping_request(), XMPP_STATE_CONNECTED, and XMPP_STATE_DISCONNECTING.

Referenced by xmpp_client_config_post_apply().

3732 {
3733  struct ast_xmpp_client *client = data;
3734  int res = IKS_NET_RWERR;
3735  unsigned int sleep_time = 1;
3736 
3737  /* We only allow cancellation while sleeping */
3738  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
3739 
3740  do {
3741  if (client->state == XMPP_STATE_DISCONNECTING) {
3742  ast_debug(1, "[%s] Disconnecting\n", client->name);
3743  break;
3744  }
3745 
3746  if (res == IKS_NET_RWERR || client->timeout == 0) {
3747  ast_debug(3, "[%s] Connecting\n", client->name);
3748  if ((res = xmpp_client_reconnect(client)) != IKS_OK) {
3749  sleep_with_backoff(&sleep_time);
3750  res = IKS_NET_RWERR;
3751  }
3752  continue;
3753  }
3754 
3755  res = xmpp_client_receive(client, 1);
3756 
3757  /* Decrease timeout if no data received, and delete
3758  * old messages globally */
3759  if (res == IKS_NET_EXPIRED) {
3760  client->timeout--;
3761  }
3762 
3763  if (res == IKS_HOOK) {
3764  ast_debug(2, "[%s] Got hook event\n", client->name);
3765  } else if (res == IKS_NET_TLSFAIL) {
3766  ast_log(LOG_ERROR, "[%s] TLS failure\n", client->name);
3767  } else if (!client->timeout && client->state == XMPP_STATE_CONNECTED) {
3769  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
3770 
3771  if (cfg && cfg->clients) {
3772  clientcfg = xmpp_config_find(cfg->clients, client->name);
3773  }
3774 
3775  if (clientcfg && ast_test_flag(&clientcfg->flags, XMPP_KEEPALIVE)) {
3776  res = xmpp_ping_request(client, client->jid->server, client->jid->full);
3777  } else {
3778  res = IKS_OK;
3779  }
3780 
3781  if (res == IKS_OK) {
3782  client->timeout = 50;
3783  } else {
3784  ast_log(LOG_WARNING, "[%s] Network timeout\n", client->name);
3785  }
3786  } else if (res == IKS_NET_RWERR) {
3787  ast_log(LOG_WARNING, "[%s] Socket read error\n", client->name);
3789  sleep_with_backoff(&sleep_time);
3790  } else if (res == IKS_NET_NOSOCK) {
3791  ast_log(LOG_WARNING, "[%s] No socket\n", client->name);
3792  } else if (res == IKS_NET_NOCONN) {
3793  ast_log(LOG_WARNING, "[%s] No connection\n", client->name);
3794  } else if (res == IKS_NET_NODNS) {
3795  ast_log(LOG_WARNING, "[%s] No DNS\n", client->name);
3796  } else if (res == IKS_NET_NOTSUPP) {
3797  ast_log(LOG_WARNING, "[%s] Not supported\n", client->name);
3798  } else if (res == IKS_NET_DROPPED) {
3799  ast_log(LOG_WARNING, "[%s] Dropped?\n", client->name);
3800  } else if (res == IKS_NET_UNKNOWN) {
3801  ast_debug(5, "[%s] Unknown\n", client->name);
3802  } else if (res == IKS_OK) {
3803  sleep_time = 1;
3804  }
3805 
3806  } while (1);
3807 
3808  return NULL;
3809 }
static void sleep_with_backoff(unsigned int *sleep_time)
Definition: res_xmpp.c:3719
XMPP Client Configuration.
Definition: res_xmpp.c:444
static int xmpp_client_receive(struct ast_xmpp_client *client, unsigned int timeout)
Internal function which receives data from the XMPP client connection.
Definition: res_xmpp.c:3651
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:274
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
#define IKS_NET_EXPIRED
Definition: xmpp.h:41
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
XMPP Client Connection.
Definition: xmpp.h:119
#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:911
static int xmpp_client_reconnect(struct ast_xmpp_client *client)
Internal function used to reconnect an XMPP client to its server.
Definition: res_xmpp.c:3567
static struct console_pvt globals
int ast_xmpp_client_disconnect(struct ast_xmpp_client *client)
Disconnect an XMPP client connection.
Definition: res_xmpp.c:3528
#define LOG_ERROR
Definition: logger.h:285
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.
Definition: res_xmpp.c:3232
enum xmpp_state state
Definition: xmpp.h:136
iksid * jid
Definition: xmpp.h:126
const ast_string_field name
Definition: xmpp.h:123
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int timeout
Definition: xmpp.h:140

◆ xmpp_client_unsubscribe_user()

static int xmpp_client_unsubscribe_user ( struct ast_xmpp_client client,
const char *  user 
)
static

Helper function which unsubscribes a user and removes them from the roster.

Definition at line 2192 of file res_xmpp.c.

References ast_log, ast_xmpp_client_send(), done, item, ast_xmpp_client::jid, LOG_WARNING, ast_xmpp_client::name, and NULL.

Referenced by xmpp_roster_hook().

2193 {
2194  iks *iq, *query = NULL, *item = NULL;
2195 
2196  if (ast_xmpp_client_send(client, iks_make_s10n(IKS_TYPE_UNSUBSCRIBE, user,
2197  "Goodbye. Your status is no longer required.\n"))) {
2198  return -1;
2199  }
2200 
2201  if (!(iq = iks_new("iq")) || !(query = iks_new("query")) || !(item = iks_new("item"))) {
2202  ast_log(LOG_WARNING, "Could not allocate memory for roster removal of '%s' from client '%s'\n",
2203  user, client->name);
2204  goto done;
2205  }
2206 
2207  iks_insert_attrib(iq, "from", client->jid->full);
2208  iks_insert_attrib(iq, "type", "set");
2209  iks_insert_attrib(query, "xmlns", "jabber:iq:roster");
2210  iks_insert_node(iq, query);
2211  iks_insert_attrib(item, "jid", user);
2212  iks_insert_attrib(item, "subscription", "remove");
2213  iks_insert_node(query, item);
2214 
2215  if (ast_xmpp_client_send(client, iq)) {
2216  ast_log(LOG_WARNING, "Could not send roster removal request of '%s' from client '%s'\n",
2217  user, client->name);
2218  }
2219 
2220 done:
2221  iks_delete(item);
2222  iks_delete(query);
2223  iks_delete(iq);
2224 
2225  return 0;
2226 }
#define LOG_WARNING
Definition: logger.h:274
static struct aco_type item
Definition: test_config.c:1463
#define NULL
Definition: resample.c:96
int done
Definition: test_amihooks.c:48
#define ast_log
Definition: astobj2.c:42
iksid * jid
Definition: xmpp.h:126
structure to hold users read from users.conf
const ast_string_field name
Definition: xmpp.h:123
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:2537

◆ xmpp_component_authenticate()

static int xmpp_component_authenticate ( struct ast_xmpp_client client,
struct ast_xmpp_client_config cfg,
int  type,
iks *  node 
)
static

Internal function called when we should authenticate as a component.

Definition at line 2827 of file res_xmpp.c.

References ast_log, ast_sha1_hash(), LOG_ERROR, ast_xmpp_client::name, ast_xmpp_client_config::password, xmpp_client_change_state(), xmpp_client_send_raw_message(), and XMPP_STATE_AUTHENTICATING.

2828 {
2829  char secret[160], shasum[320], message[344];
2830  ikspak *pak = iks_packet(node);
2831 
2832  snprintf(secret, sizeof(secret), "%s%s", pak->id, cfg->password);
2833  ast_sha1_hash(shasum, secret);
2834  snprintf(message, sizeof(message), "<handshake>%s</handshake>", shasum);
2835 
2836  if (xmpp_client_send_raw_message(client, message) != IKS_OK) {
2837  ast_log(LOG_ERROR, "Unable to send handshake for component '%s'\n", client->name);
2838  return -1;
2839  }
2840 
2842 
2843  return 0;
2844 }
Definition: test_heap.c:38
const ast_string_field password
Definition: res_xmpp.c:456
#define ast_log
Definition: astobj2.c:42
void ast_sha1_hash(char *output, const char *input)
Produces SHA1 hash based on input string.
Definition: main/utils.c:264
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:2492
#define LOG_ERROR
Definition: logger.h:285
const ast_string_field name
Definition: xmpp.h:123
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:590

◆ xmpp_component_authenticating()

static int xmpp_component_authenticating ( struct ast_xmpp_client client,
struct ast_xmpp_client_config cfg,
int  type,
iks *  node 
)
static

Internal function called when we authenticated as a component.

Definition at line 3093 of file res_xmpp.c.

References ast_log, ast_xmpp_client::filter, LOG_ERROR, ast_xmpp_client::name, xmpp_client_change_state(), xmpp_client_service_discovery_result_hook(), xmpp_component_register_get_hook(), xmpp_component_register_set_hook(), xmpp_component_service_discovery_get_hook(), xmpp_component_service_discovery_items_hook(), and XMPP_STATE_CONNECTED.

3094 {
3095  if (!strcmp(iks_name(node), "stream:features")) {
3096  return 0;
3097  }
3098 
3099  if (strcmp(iks_name(node), "handshake")) {
3100  ast_log(LOG_ERROR, "Failed to authenticate component '%s'\n", client->name);
3101  return -1;
3102  }
3103 
3104  iks_filter_add_rule(client->filter, xmpp_component_service_discovery_items_hook, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#items", IKS_RULE_DONE);
3105 
3106  iks_filter_add_rule(client->filter, xmpp_component_service_discovery_get_hook, client, IKS_RULE_SUBTYPE, IKS_TYPE_GET, IKS_RULE_NS, "http://jabber.org/protocol/disco#info", IKS_RULE_DONE);
3107 
3108  /* This uses the client service discovery result hook on purpose, as the code is common between both */
3109  iks_filter_add_rule(client->filter, xmpp_client_service_discovery_result_hook, client, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_NS, "http://jabber.org/protocol/disco#info", IKS_RULE_DONE);
3110 
3111  iks_filter_add_rule(client->filter, xmpp_component_register_get_hook, client, IKS_RULE_SUBTYPE, IKS_TYPE_GET, IKS_RULE_NS, "jabber:iq:register", IKS_RULE_DONE);
3112  iks_filter_add_rule(client->filter, xmpp_component_register_set_hook, client, IKS_RULE_SUBTYPE, IKS_TYPE_SET, IKS_RULE_NS, "jabber:iq:register", IKS_RULE_DONE);
3113 
3115 
3116  return 0;
3117 }
Definition: test_heap.c:38
static int xmpp_client_service_discovery_result_hook(void *data, ikspak *pak)
Hook function called when client receives a service discovery result message.
Definition: res_xmpp.c:2406
static int xmpp_component_service_discovery_items_hook(void *data, ikspak *pak)
Hook function called when we receive a service discovery items request.
Definition: res_xmpp.c:3042
static int xmpp_component_register_get_hook(void *data, ikspak *pak)
Hook function called when the component is queried about registration.
Definition: res_xmpp.c:2934
#define ast_log
Definition: astobj2.c:42
static int xmpp_component_register_set_hook(void *data, ikspak *pak)
Hook function called when someone registers to the component.
Definition: res_xmpp.c:2995
#define LOG_ERROR
Definition: logger.h:285
iksfilter * filter
Definition: xmpp.h:128
const ast_string_field name
Definition: xmpp.h:123
static int xmpp_component_service_discovery_get_hook(void *data, ikspak *pak)
Hook function called when component receives a service discovery get message.
Definition: res_xmpp.c:2847
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:590

◆ xmpp_component_register_get_hook()

static int xmpp_component_register_get_hook ( void *  data,
ikspak *  pak 
)
static

Hook function called when the component is queried about registration.

Definition at line 2934 of file res_xmpp.c.

References ao2_cleanup, ao2_find, ao2_global_obj_ref, ao2_ref, ast_log, ast_xmpp_client_send(), ast_xmpp_client::buddies, done, error(), globals, LOG_ERROR, LOG_WARNING, ast_xmpp_client::name, NULL, OBJ_KEY, RAII_VAR, and xmpp_config_find().

Referenced by xmpp_component_authenticating().

2935 {
2937  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
2938  struct ast_xmpp_client *client = data;
2939  iks *iq = NULL, *query = NULL, *error = NULL, *notacceptable = NULL, *instructions = NULL;
2940  struct ast_xmpp_buddy *buddy;
2941  char *node;
2942 
2943  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name)) ||
2944  !(iq = iks_new("iq")) || !(query = iks_new("query")) || !(error = iks_new("error")) || !(notacceptable = iks_new("not-acceptable")) ||
2945  !(instructions = iks_new("instructions"))) {
2946  ast_log(LOG_ERROR, "Failed to allocate stanzas for register get response to '%s' on component '%s'\n",
2947  pak->from->partial, client->name);
2948  goto done;
2949  }
2950 
2951  iks_insert_attrib(iq, "from", clientcfg->user);
2952  iks_insert_attrib(iq, "to", pak->from->full);
2953  iks_insert_attrib(iq, "id", pak->id);
2954  iks_insert_attrib(iq, "type", "result");
2955  iks_insert_attrib(query, "xmlns", "jabber:iq:register");
2956  iks_insert_node(iq, query);
2957 
2958  if (!(buddy = ao2_find(client->buddies, pak->from->partial, OBJ_KEY))) {
2959  iks_insert_attrib(error, "code", "406");
2960  iks_insert_attrib(error, "type", "modify");
2961  iks_insert_attrib(notacceptable, "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas");
2962 
2963  iks_insert_node(iq, error);
2964  iks_insert_node(error, notacceptable);
2965 
2966  ast_log(LOG_ERROR, "Received register attempt from '%s' but buddy is not configured on component '%s'\n",
2967  pak->from->partial, client->name);
2968  } else if (!(node = iks_find_attrib(pak->query, "node"))) {
2969  iks_insert_cdata(instructions, "Welcome to Asterisk - the Open Source PBX.\n", 0);
2970  iks_insert_node(query, instructions);
2971  ao2_ref(buddy, -1);
2972  } else {
2973  ast_log(LOG_WARNING, "Received register get to component '%s' using unsupported node '%s' from '%s'\n",
2974  client->name, node, pak->from->partial);
2975  ao2_ref(buddy, -1);
2976  goto done;
2977  }
2978 
2979  if (ast_xmpp_client_send(client, iq)) {
2980  ast_log(LOG_WARNING, "Could not send response to '%s' for received register get on component '%s'\n",
2981  pak->from->partial, client->name);
2982  }
2983 
2984 done:
2985  iks_delete(instructions);
2986  iks_delete(notacceptable);
2987  iks_delete(error);
2988  iks_delete(query);
2989  iks_delete(iq);
2990 
2991  return IKS_FILTER_EAT;
2992 }
Definition: test_heap.c:38
XMPP Client Configuration.
Definition: res_xmpp.c:444
#define OBJ_KEY
Definition: astobj2.h:1155
#define LOG_WARNING
Definition: logger.h:274
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
int done
Definition: test_amihooks.c:48
#define ast_log
Definition: astobj2.c:42
XMPP Client Connection.
Definition: xmpp.h:119
#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:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct console_pvt globals
#define LOG_ERROR
Definition: logger.h:285
XMPP Buddy.
Definition: xmpp.h:112
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
const ast_string_field name
Definition: xmpp.h:123
struct ao2_container * buddies
Definition: xmpp.h:137
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int error(const char *format,...)
Definition: utils/frame.c:999
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:2537

◆ xmpp_component_register_set_hook()

static int xmpp_component_register_set_hook ( void *  data,
ikspak *  pak 
)
static

Hook function called when someone registers to the component.

Definition at line 2995 of file res_xmpp.c.

References ast_log, ast_xmpp_client_lock(), ast_xmpp_client_send(), ast_xmpp_client_unlock(), ast_xmpp_increment_mid(), done, ast_xmpp_client::jid, LOG_ERROR, LOG_WARNING, ast_xmpp_client::mid, ast_xmpp_client::name, and NULL.

Referenced by xmpp_component_authenticating().

2996 {
2997  struct ast_xmpp_client *client = data;
2998  iks *iq, *presence = NULL, *x = NULL;
2999 
3000  if (!(iq = iks_new("iq")) || !(presence = iks_new("presence")) || !(x = iks_new("x"))) {
3001  ast_log(LOG_ERROR, "Failed to allocate stanzas for register set response to '%s' on component '%s'\n",
3002  pak->from->partial, client->name);
3003  goto done;
3004  }
3005 
3006  iks_insert_attrib(iq, "from", client->jid->full);
3007  iks_insert_attrib(iq, "to", pak->from->full);
3008  iks_insert_attrib(iq, "id", pak->id);
3009  iks_insert_attrib(iq, "type", "result");
3010 
3011  if (ast_xmpp_client_send(client, iq)) {
3012  ast_log(LOG_WARNING, "Could not send response to '%s' for received register set on component '%s'\n",
3013  pak->from->partial, client->name);
3014  goto done;
3015  }
3016 
3017  iks_insert_attrib(presence, "from", client->jid->full);
3018  iks_insert_attrib(presence, "to", pak->from->partial);
3019  ast_xmpp_client_lock(client);
3020  iks_insert_attrib(presence, "id", client->mid);
3021  ast_xmpp_increment_mid(client->mid);
3022  ast_xmpp_client_unlock(client);
3023  iks_insert_attrib(presence, "type", "subscribe");
3024  iks_insert_attrib(x, "xmlns", "vcard-temp:x:update");
3025 
3026  iks_insert_node(presence, x);
3027 
3028  if (ast_xmpp_client_send(client, presence)) {
3029  ast_log(LOG_WARNING, "Could not send subscription to '%s' on component '%s'\n",
3030  pak->from->partial, client->name);
3031  }
3032 
3033 done:
3034  iks_delete(x);
3035  iks_delete(presence);
3036  iks_delete(iq);
3037 
3038  return IKS_FILTER_EAT;
3039 }
#define LOG_WARNING
Definition: logger.h:274
void ast_xmpp_increment_mid(char *mid)
Helper function which increments the message identifier.
Definition: res_xmpp.c:1019
void ast_xmpp_client_lock(struct ast_xmpp_client *client)
Lock an XMPP client connection.
Definition: res_xmpp.c:893
#define NULL
Definition: resample.c:96
int done
Definition: test_amihooks.c:48
#define ast_log
Definition: astobj2.c:42
XMPP Client Connection.
Definition: xmpp.h:119
#define LOG_ERROR
Definition: logger.h:285
iksid * jid
Definition: xmpp.h:126
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:898
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:2537

◆ xmpp_component_service_discovery_get_hook()

static int xmpp_component_service_discovery_get_hook ( void *  data,
ikspak *  pak 
)
static

Hook function called when component receives a service discovery get message.

Definition at line 2847 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ast_debug, ast_log, ast_xmpp_client_send(), commands, done, globals, item, LOG_ERROR, LOG_WARNING, ast_xmpp_client::name, NULL, RAII_VAR, version, and xmpp_config_find().

Referenced by xmpp_component_authenticating().

2848 {
2850  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
2851  struct ast_xmpp_client *client = data;
2852  iks *iq = NULL, *query = NULL, *identity = NULL, *disco = NULL, *reg = NULL, *commands = NULL, *gateway = NULL;
2853  iks *version = NULL, *vcard = NULL, *search = NULL, *item = NULL;
2854  char *node;
2855 
2856  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name)) ||
2857  !(iq = iks_new("iq")) || !(query = iks_new("query")) || !(identity = iks_new("identity")) || !(disco = iks_new("feature")) ||
2858  !(reg = iks_new("feature")) || !(commands = iks_new("feature")) || !(gateway = iks_new("feature")) || !(version = iks_new("feature")) ||
2859  !(vcard = iks_new("feature")) || !(search = iks_new("search")) || !(item = iks_new("item"))) {
2860  ast_log(LOG_ERROR, "Failed to allocate stanzas for service discovery get response to '%s' on component '%s'\n",
2861  pak->from->partial, client->name);
2862  goto done;
2863  }
2864 
2865  iks_insert_attrib(iq, "from", clientcfg->user);
2866  iks_insert_attrib(iq, "to", pak->from->full);
2867  iks_insert_attrib(iq, "id", pak->id);
2868  iks_insert_attrib(iq, "type", "result");
2869 
2870  if (!(node = iks_find_attrib(pak->query, "node"))) {
2871  iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info");
2872  iks_insert_attrib(identity, "category", "gateway");
2873  iks_insert_attrib(identity, "type", "pstn");
2874  iks_insert_attrib(identity, "name", "Asterisk The Open Source PBX");
2875  iks_insert_attrib(disco, "var", "http://jabber.org/protocol/disco");
2876  iks_insert_attrib(reg, "var", "jabber:iq:register");
2877  iks_insert_attrib(commands, "var", "http://jabber.org/protocol/commands");
2878  iks_insert_attrib(gateway, "var", "jabber:iq:gateway");
2879  iks_insert_attrib(version, "var", "jabber:iq:version");
2880  iks_insert_attrib(vcard, "var", "vcard-temp");
2881  iks_insert_attrib(search, "var", "jabber:iq:search");
2882 
2883  iks_insert_node(iq, query);
2884  iks_insert_node(query, identity);
2885  iks_insert_node(query, disco);
2886  iks_insert_node(query, reg);
2887  iks_insert_node(query, commands);
2888  iks_insert_node(query, gateway);
2889  iks_insert_node(query, version);
2890  iks_insert_node(query, vcard);
2891  iks_insert_node(query, search);
2892  } else if (!strcasecmp(node, "http://jabber.org/protocol/commands")) {
2893  iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items");
2894  iks_insert_attrib(query, "node", "http://jabber.org/protocol/commands");
2895  iks_insert_attrib(item, "node", "confirmaccount");
2896  iks_insert_attrib(item, "name", "Confirm account");
2897  iks_insert_attrib(item, "jid", clientcfg->user);
2898 
2899  iks_insert_node(iq, query);
2900  iks_insert_node(query, item);
2901  } else if (!strcasecmp(node, "confirmaccount")) {
2902  iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#info");
2903  iks_insert_attrib(commands, "var", "http://jabber.org/protocol/commands");
2904 
2905  iks_insert_node(iq, query);
2906  iks_insert_node(query, commands);
2907  } else {
2908  ast_debug(3, "Unsupported service discovery info request received with node '%s' on component '%s'\n",
2909  node, client->name);
2910  goto done;
2911  }
2912 
2913  if (ast_xmpp_client_send(client, iq)) {
2914  ast_log(LOG_WARNING, "Could not send response to service discovery request on component '%s'\n",
2915  client->name);
2916  }
2917 
2918 done:
2919  iks_delete(search);
2920  iks_delete(vcard);
2921  iks_delete(version);
2922  iks_delete(gateway);
2923  iks_delete(commands);
2924  iks_delete(reg);
2925  iks_delete(disco);
2926  iks_delete(identity);
2927  iks_delete(query);
2928  iks_delete(iq);
2929 
2930  return IKS_FILTER_EAT;
2931 }
Definition: test_heap.c:38
XMPP Client Configuration.
Definition: res_xmpp.c:444
#define LOG_WARNING
Definition: logger.h:274
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
static struct aco_type item
Definition: test_config.c:1463
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
int done
Definition: test_amihooks.c:48
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
XMPP Client Connection.
Definition: xmpp.h:119
#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:911
static struct agi_command commands[]
AGI commands list.
Definition: res_agi.c:3706
static struct console_pvt globals
#define LOG_ERROR
Definition: logger.h:285
static char version[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:391
const ast_string_field name
Definition: xmpp.h:123
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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:2537

◆ xmpp_component_service_discovery_items_hook()

static int xmpp_component_service_discovery_items_hook ( void *  data,
ikspak *  pak 
)
static

Hook function called when we receive a service discovery items request.

Definition at line 3042 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ast_log, ast_xmpp_client_send(), done, globals, item, LOG_ERROR, LOG_WARNING, ast_xmpp_client::name, NULL, RAII_VAR, and xmpp_config_find().

Referenced by xmpp_component_authenticating().

3043 {
3045  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
3046  struct ast_xmpp_client *client = data;
3047  iks *iq = NULL, *query = NULL, *item = NULL, *feature = NULL;
3048  char *node;
3049 
3050  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name)) ||
3051  !(iq = iks_new("iq")) || !(query = iks_new("query")) || !(item = iks_new("item")) || !(feature = iks_new("feature"))) {
3052  ast_log(LOG_ERROR, "Failed to allocate stanzas for service discovery items response to '%s' on component '%s'\n",
3053  pak->from->partial, client->name);
3054  goto done;
3055  }
3056 
3057  iks_insert_attrib(iq, "from", clientcfg->user);
3058  iks_insert_attrib(iq, "to", pak->from->full);
3059  iks_insert_attrib(iq, "id", pak->id);
3060  iks_insert_attrib(iq, "type", "result");
3061  iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items");
3062  iks_insert_node(iq, query);
3063 
3064  if (!(node = iks_find_attrib(pak->query, "node"))) {
3065  iks_insert_attrib(item, "node", "http://jabber.org/protocol/commands");
3066  iks_insert_attrib(item, "name", "Asterisk Commands");
3067  iks_insert_attrib(item, "jid", clientcfg->user);
3068 
3069  iks_insert_node(query, item);
3070  } else if (!strcasecmp(node, "http://jabber.org/protocol/commands")) {
3071  iks_insert_attrib(query, "node", "http://jabber.org/protocol/commands");
3072  } else {
3073  ast_log(LOG_WARNING, "Received service discovery items request to component '%s' using unsupported node '%s' from '%s'\n",
3074  client->name, node, pak->from->partial);
3075  goto done;
3076  }
3077 
3078  if (ast_xmpp_client_send(client, iq)) {
3079  ast_log(LOG_WARNING, "Could not send response to service discovery items request from '%s' on component '%s'\n",
3080  pak->from->partial, client->name);
3081  }
3082 
3083 done:
3084  iks_delete(feature);
3085  iks_delete(item);
3086  iks_delete(query);
3087  iks_delete(iq);
3088 
3089  return IKS_FILTER_EAT;
3090 }
Definition: test_heap.c:38
XMPP Client Configuration.
Definition: res_xmpp.c:444
#define LOG_WARNING
Definition: logger.h:274
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
static struct aco_type item
Definition: test_config.c:1463
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
int done
Definition: test_amihooks.c:48
#define ast_log
Definition: astobj2.c:42
XMPP Client Connection.
Definition: xmpp.h:119
#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:911
static struct console_pvt globals
#define LOG_ERROR
Definition: logger.h:285
const ast_string_field name
Definition: xmpp.h:123
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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:2537

◆ xmpp_config_alloc()

static void* xmpp_config_alloc ( void  )
static

Allocator for XMPP configuration.

Definition at line 718 of file res_xmpp.c.

References ao2_alloc, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_list, ao2_ref, xmpp_config::clients, error(), xmpp_config::global, NULL, xmpp_config_cmp(), and xmpp_config_destructor().

719 {
720  struct xmpp_config *cfg;
721 
722  if (!(cfg = ao2_alloc(sizeof(*cfg), xmpp_config_destructor))) {
723  return NULL;
724  }
725 
726  if (!(cfg->global = ao2_alloc(sizeof(*cfg->global), NULL))) {
727  goto error;
728  }
729 
732  if (!cfg->clients) {
733  goto error;
734  }
735 
736  return cfg;
737 error:
738  ao2_ref(cfg, -1);
739  return NULL;
740 }
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1335
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static void xmpp_config_destructor(void *obj)
Destructor for XMPP configuration.
Definition: res_xmpp.c:702
static int xmpp_config_cmp(void *obj, void *arg, int flags)
Comparator function for configuration.
Definition: res_xmpp.c:710
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
int error(const char *format,...)
Definition: utils/frame.c:999
struct ast_xmpp_global_config * global
Definition: res_xmpp.c:468
struct ao2_container * clients
Definition: res_xmpp.c:469

◆ xmpp_config_cmp()

static int xmpp_config_cmp ( void *  obj,
void *  arg,
int  flags 
)
static

Comparator function for configuration.

Definition at line 710 of file res_xmpp.c.

References CMP_MATCH, CMP_STOP, match(), ast_xmpp_client_config::name, and OBJ_KEY.

Referenced by xmpp_config_alloc().

711 {
712  struct ast_xmpp_client_config *one = obj, *two = arg;
713  const char *match = (flags & OBJ_KEY) ? arg : two->name;
714  return strcasecmp(one->name, match) ? 0 : (CMP_MATCH | CMP_STOP);
715 }
XMPP Client Configuration.
Definition: res_xmpp.c:444
#define OBJ_KEY
Definition: astobj2.h:1155
struct ast_flags flags
Definition: res_xmpp.c:460
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2315
const ast_string_field name
Definition: res_xmpp.c:456

◆ xmpp_config_destructor()

static void xmpp_config_destructor ( void *  obj)
static

Destructor for XMPP configuration.

Definition at line 702 of file res_xmpp.c.

References ao2_cleanup, xmpp_config::clients, and xmpp_config::global.

Referenced by xmpp_config_alloc().

703 {
704  struct xmpp_config *cfg = obj;
705  ao2_cleanup(cfg->global);
706  ao2_cleanup(cfg->clients);
707 }
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_xmpp_global_config * global
Definition: res_xmpp.c:468
struct ao2_container * clients
Definition: res_xmpp.c:469

◆ xmpp_config_find()

static void* xmpp_config_find ( struct ao2_container tmp_container,
const char *  category 
)
static

◆ xmpp_config_post_apply()

static void xmpp_config_post_apply ( void  )
static

Definition at line 787 of file res_xmpp.c.

References ao2_callback, ao2_cleanup, ao2_global_obj_ref, globals, NULL, OBJ_MULTIPLE, OBJ_NODATA, RAII_VAR, and xmpp_client_config_post_apply().

788 {
790 
792 }
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
#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:911
static struct console_pvt globals
static int xmpp_client_config_post_apply(void *obj, void *arg, int flags)
Definition: res_xmpp.c:3866
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ xmpp_config_prelink()

static int xmpp_config_prelink ( void *  newitem)
static

Definition at line 742 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ast_log, ast_strlen_zero, ast_test_flag, ast_xmpp_client_config::client, ast_xmpp_client_config::flags, globals, LOG_ERROR, ast_xmpp_client_config::name, NULL, ast_xmpp_client_config::oauth_clientid, ast_xmpp_client_config::oauth_secret, ast_xmpp_client_config::password, ast_xmpp_client_config::port, ast_xmpp_client_config::priority, RAII_VAR, ast_xmpp_client::reconnect, ast_xmpp_client_config::refresh_token, ast_xmpp_client_config::server, ast_xmpp_client_config::user, XMPP_COMPONENT, and xmpp_config_find().

743 {
744  struct ast_xmpp_client_config *clientcfg = newitem;
746  RAII_VAR(struct ast_xmpp_client_config *, oldclientcfg, NULL, ao2_cleanup);
747 
748  if (ast_strlen_zero(clientcfg->user)) {
749  ast_log(LOG_ERROR, "No user specified on client '%s'\n", clientcfg->name);
750  return -1;
751  } else if (ast_strlen_zero(clientcfg->password) && ast_strlen_zero(clientcfg->refresh_token)) {
752  ast_log(LOG_ERROR, "No password or refresh_token specified on client '%s'\n", clientcfg->name);
753  return -1;
754  } else if (ast_strlen_zero(clientcfg->server)) {
755  ast_log(LOG_ERROR, "No server specified on client '%s'\n", clientcfg->name);
756  return -1;
757  } else if (!ast_strlen_zero(clientcfg->refresh_token) &&
758  (ast_strlen_zero(clientcfg->oauth_clientid) || ast_strlen_zero(clientcfg->oauth_secret))) {
759  ast_log(LOG_ERROR, "No oauth_clientid or oauth_secret specified, so client '%s' can't be used\n", clientcfg->name);
760  return -1;
761  }
762 
763  /* If this is a new connection force a reconnect */
764  if (!cfg || !cfg->clients || !(oldclientcfg = xmpp_config_find(cfg->clients, clientcfg->name))) {
765  clientcfg->client->reconnect = 1;
766  return 0;
767  }
768 
769  /* If any configuration options are changing that would require reconnecting set the bit so we will do so if possible */
770  if (strcmp(clientcfg->user, oldclientcfg->user) ||
771  strcmp(clientcfg->password, oldclientcfg->password) ||
772  strcmp(clientcfg->refresh_token, oldclientcfg->refresh_token) ||
773  strcmp(clientcfg->oauth_clientid, oldclientcfg->oauth_clientid) ||
774  strcmp(clientcfg->oauth_secret, oldclientcfg->oauth_secret) ||
775  strcmp(clientcfg->server, oldclientcfg->server) ||
776  (clientcfg->port != oldclientcfg->port) ||
777  (ast_test_flag(&clientcfg->flags, XMPP_COMPONENT) != ast_test_flag(&oldclientcfg->flags, XMPP_COMPONENT)) ||
778  (clientcfg->priority != oldclientcfg->priority)) {
779  clientcfg->client->reconnect = 1;
780  } else {
781  clientcfg->client->reconnect = 0;
782  }
783 
784  return 0;
785 }
XMPP Client Configuration.
Definition: res_xmpp.c:444
#define ast_test_flag(p, flag)
Definition: utils.h:63
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
const ast_string_field password
Definition: res_xmpp.c:456
struct ast_flags flags
Definition: res_xmpp.c:460
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
unsigned int reconnect
Definition: xmpp.h:142
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#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:911
const ast_string_field user
Definition: res_xmpp.c:456
static struct console_pvt globals
const ast_string_field name
Definition: res_xmpp.c:456
#define LOG_ERROR
Definition: logger.h:285
struct ast_xmpp_client * client
Definition: res_xmpp.c:463
const ast_string_field oauth_secret
Definition: res_xmpp.c:456
const ast_string_field oauth_clientid
Definition: res_xmpp.c:456
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const ast_string_field refresh_token
Definition: res_xmpp.c:456
const ast_string_field server
Definition: res_xmpp.c:456

◆ xmpp_connect_hook()

static int xmpp_connect_hook ( void *  data,
ikspak *  pak 
)
static

Hook function called when client finishes authenticating with the server.

Definition at line 2436 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ast_log, ast_test_flag, ast_xmpp_client_send(), ast_xmpp_client::filter, globals, if(), ast_xmpp_client::jid, LOG_ERROR, ast_xmpp_client::name, NULL, RAII_VAR, ast_xmpp_client::stack, xmpp_client_change_state(), xmpp_client_service_discovery_get_hook(), xmpp_client_service_discovery_result_hook(), xmpp_client_set_presence(), xmpp_config_find(), XMPP_DISTRIBUTE_EVENTS, xmpp_init_event_distribution(), xmpp_roster_hook(), and XMPP_STATE_ROSTER.

Referenced by xmpp_client_authenticate_digest(), and xmpp_client_authenticating().

2437 {
2439  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
2440  struct ast_xmpp_client *client = data;
2441  iks *roster;
2442 
2443  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name))) {
2444  return -1;
2445  }
2446 
2447  client->jid = (iks_find_cdata(pak->query, "jid")) ? iks_id_new(client->stack, iks_find_cdata(pak->query, "jid")) : client->jid;
2448 
2449  if (ast_test_flag(&clientcfg->flags, XMPP_DISTRIBUTE_EVENTS)) {
2451  }
2452 
2453  if (!(roster = iks_make_iq(IKS_TYPE_GET, IKS_NS_ROSTER))) {
2454  ast_log(LOG_ERROR, "Unable to allocate memory for roster request for client '%s'\n", client->name);
2455  return -1;
2456  }
2457 
2458  iks_filter_add_rule(client->filter, xmpp_client_service_discovery_get_hook, client, IKS_RULE_SUBTYPE, IKS_TYPE_GET, IKS_RULE_NS, "http://jabber.org/protocol/disco#info", IKS_RULE_DONE);
2459  iks_filter_add_rule(client->filter, xmpp_client_service_discovery_result_hook, client, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_NS, "http://jabber.org/protocol/disco#info", IKS_RULE_DONE);
2460 
2461  iks_insert_attrib(roster, "id", "roster");
2462  ast_xmpp_client_send(client, roster);
2463 
2464  iks_filter_remove_hook(client->filter, xmpp_connect_hook);
2465  iks_filter_add_rule(client->filter, xmpp_roster_hook, client, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID, "roster", IKS_RULE_DONE);
2466 
2467  xmpp_client_set_presence(client, NULL, client->jid->full, clientcfg->status, clientcfg->statusmsg);
2469 
2470  return IKS_FILTER_EAT;
2471 }
static int xmpp_client_service_discovery_get_hook(void *data, ikspak *pak)
Hook function called when client receives a service discovery get message.
Definition: res_xmpp.c:2346
ikstack * stack
Definition: xmpp.h:129
XMPP Client Configuration.
Definition: res_xmpp.c:444
#define ast_test_flag(p, flag)
Definition: utils.h:63
static int xmpp_client_service_discovery_result_hook(void *data, ikspak *pak)
Hook function called when client receives a service discovery result message.
Definition: res_xmpp.c:2406
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
if(!yyg->yy_init)
Definition: ast_expr2f.c:868
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
static int xmpp_roster_hook(void *data, ikspak *pak)
Hook function called when roster is received from server.
Definition: res_xmpp.c:2250
#define NULL
Definition: resample.c:96
static void xmpp_init_event_distribution(struct ast_xmpp_client *client)
Initialize collections for event distribution.
Definition: res_xmpp.c:1588
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.
Definition: res_xmpp.c:2308
#define ast_log
Definition: astobj2.c:42
XMPP Client Connection.
Definition: xmpp.h:119
#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:911
static struct console_pvt globals
#define LOG_ERROR
Definition: logger.h:285
iksfilter * filter
Definition: xmpp.h:128
iksid * jid
Definition: xmpp.h:126
const ast_string_field name
Definition: xmpp.h:123
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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:590
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:2537
static int xmpp_connect_hook(void *data, ikspak *pak)
Hook function called when client finishes authenticating with the server.
Definition: res_xmpp.c:2436

◆ xmpp_do_set_debug()

static char* xmpp_do_set_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 4304 of file res_xmpp.c.

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

4305 {
4306  switch (cmd) {
4307  case CLI_INIT:
4308  e->command = "xmpp set debug {on|off}";
4309  e->usage =
4310  "Usage: xmpp set debug {on|off}\n"
4311  " Enables/disables dumping of XMPP/Jabber packets for debugging purposes.\n";
4312  return NULL;
4313  case CLI_GENERATE:
4314  return NULL;
4315  }
4316 
4317  if (a->argc != e->args) {
4318  return CLI_SHOWUSAGE;
4319  }
4320 
4321  if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
4322  debug = 1;
4323  ast_cli(a->fd, "XMPP Debugging Enabled.\n");
4324  return CLI_SUCCESS;
4325  } else if (!strncasecmp(a->argv[e->args - 1], "off", 3)) {
4326  debug = 0;
4327  ast_cli(a->fd, "XMPP Debugging Disabled.\n");
4328  return CLI_SUCCESS;
4329  }
4330  return CLI_SHOWUSAGE; /* defaults to invalid */
4331 }
const int argc
Definition: cli.h:160
static int debug
Global debug status.
Definition: res_xmpp.c:435
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
int args
This gets set in ast_cli_register()
Definition: cli.h:185
const int fd
Definition: cli.h:159
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ xmpp_init_event_distribution()

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
Returns
void

Definition at line 1588 of file res_xmpp.c.

References ao2_callback, ao2_cleanup, 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(), cached_devstate_cb(), ast_xmpp_client::device_state_sub, ast_xmpp_client::filter, globals, ast_xmpp_client::mwi_sub, ast_xmpp_client::name, NULL, OBJ_NODATA, RAII_VAR, stasis_cache_dump(), stasis_subscribe, stasis_subscribe_pool, 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_error(), xmpp_pubsub_handle_event(), xmpp_pubsub_mwi_cb(), xmpp_pubsub_subscribe(), and xmpp_pubsub_unsubscribe().

Referenced by xmpp_connect_hook().

1589 {
1591  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
1592  RAII_VAR(struct ao2_container *, cached, NULL, ao2_cleanup);
1593 
1594  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name))) {
1595  return;
1596  }
1597 
1598  xmpp_pubsub_unsubscribe(client, "device_state");
1599  xmpp_pubsub_unsubscribe(client, "message_waiting");
1600 
1601  if (!(client->mwi_sub = stasis_subscribe_pool(ast_mwi_topic_all(), xmpp_pubsub_mwi_cb, client))) {
1602  return;
1603  }
1606 
1608  client->mwi_sub = stasis_unsubscribe(client->mwi_sub);
1609  return;
1610  }
1613 
1615  ao2_callback(cached, OBJ_NODATA, cached_devstate_cb, client);
1616 
1617  xmpp_pubsub_subscribe(client, "device_state");
1618  xmpp_pubsub_subscribe(client, "message_waiting");
1619  iks_filter_add_rule(client->filter, xmpp_pubsub_handle_event, client, IKS_RULE_TYPE,
1620  IKS_PAK_MESSAGE, IKS_RULE_FROM, clientcfg->pubsubnode, IKS_RULE_DONE);
1621  iks_filter_add_rule(client->filter, xmpp_pubsub_handle_error, client, IKS_RULE_TYPE,
1622  IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_ERROR, IKS_RULE_DONE);
1623 
1624 }
XMPP Client Configuration.
Definition: res_xmpp.c:444
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
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:1336
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
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:1079
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
struct stasis_topic * ast_mwi_topic_all(void)
Get the Stasis Message Bus API topic for MWI messages.
Definition: mwi.c:85
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
#define NULL
Definition: resample.c:96
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:1364
static void xmpp_pubsub_subscribe(struct ast_xmpp_client *client, const char *node)
Subscribe to a PubSub node.
Definition: res_xmpp.c:1414
static int cached_devstate_cb(void *obj, void *arg, int flags)
Definition: res_xmpp.c:1575
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:1461
struct stasis_subscription * mwi_sub
Definition: xmpp.h:144
#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:911
static struct console_pvt globals
#define stasis_subscribe(topic, callback, data)
Definition: stasis.h:652
struct stasis_cache * ast_device_state_cache(void)
Backend cache for ast_device_state_topic_cached()
Definition: devicestate.c:673
iksfilter * filter
Definition: xmpp.h:128
#define stasis_subscribe_pool(topic, callback, data)
Definition: stasis.h:682
struct stasis_subscription * stasis_unsubscribe(struct stasis_subscription *subscription)
Cancel a subscription.
Definition: stasis.c:973
struct stasis_topic * ast_device_state_topic_all(void)
Get the Stasis topic for device state messages.
Definition: devicestate.c:668
struct stasis_message_type * ast_mwi_state_type(void)
Get the Stasis Message Bus API message type for MWI messages.
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:1388
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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:1025
Generic container type.
static int xmpp_pubsub_handle_error(void *data, ikspak *pak)
Definition: res_xmpp.c:1507

◆ xmpp_io_recv()

static int xmpp_io_recv ( struct ast_xmpp_client client,
char *  buffer,
size_t  buf_len,
int  timeout 
)
static

Internal function which polls on an XMPP client and receives data.

Definition at line 3617 of file res_xmpp.c.

References ast_poll, len(), ast_xmpp_client::parser, ast_xmpp_client::ssl_session, and xmpp_is_secure().

Referenced by xmpp_client_receive().

3618 {
3619  struct pollfd pfd = { .events = POLLIN };
3620  int len, res;
3621 
3622 #ifdef HAVE_OPENSSL
3623  if (xmpp_is_secure(client)) {
3624  pfd.fd = SSL_get_fd(client->ssl_session);
3625  if (pfd.fd < 0) {
3626  return -1;
3627  }
3628  } else
3629 #endif /* HAVE_OPENSSL */
3630  pfd.fd = iks_fd(client->parser);
3631 
3632  res = ast_poll(&pfd, 1, timeout > 0 ? timeout * 1000 : -1);
3633  if (res > 0) {
3634 #ifdef HAVE_OPENSSL
3635  if (xmpp_is_secure(client)) {
3636  len = SSL_read(client->ssl_session, buffer, buf_len);
3637  } else
3638 #endif /* HAVE_OPENSSL */
3639  len = recv(pfd.fd, buffer, buf_len, 0);
3640 
3641  if (len > 0) {
3642  return len;
3643  } else if (len <= 0) {
3644  return -1;
3645  }
3646  }
3647  return res;
3648 }
iksparser * parser
Definition: xmpp.h:127
static int timeout
Definition: cdr_mysql.c:86
#define ast_poll(a, b, c)
Definition: poll-compat.h:88
static int xmpp_is_secure(struct ast_xmpp_client *client)
Helper function which returns whether an XMPP client connection is secure or not. ...
Definition: res_xmpp.c:866
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
SSL * ssl_session
Definition: xmpp.h:132

◆ xmpp_is_secure()

static int xmpp_is_secure ( struct ast_xmpp_client client)
static

Helper function which returns whether an XMPP client connection is secure or not.

Definition at line 866 of file res_xmpp.c.

References ast_xmpp_client::stream_flags.

Referenced by xmpp_client_authenticate_sasl(), xmpp_client_request_tls(), xmpp_client_send_raw_message(), and xmpp_io_recv().

867 {
868 #ifdef HAVE_OPENSSL
869  return client->stream_flags & SECURE;
870 #else
871  return 0;
872 #endif
873 }
unsigned int stream_flags
Definition: xmpp.h:134

◆ xmpp_join_exec()

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 1722 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero, ast_test_flag, ast_xmpp_chatroom_join(), globals, LOG_ERROR, NULL, RAII_VAR, XMPP_COMPONENT, xmpp_config_find(), and XMPP_MAX_RESJIDLEN.

Referenced by load_module().

1723 {
1725  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
1726  char *s, nick[XMPP_MAX_RESJIDLEN];
1728  AST_APP_ARG(sender);
1729  AST_APP_ARG(jid);
1730  AST_APP_ARG(nick);
1731  );
1732 
1733  if (ast_strlen_zero(data)) {
1734  ast_log(LOG_ERROR, "%s requires arguments (sender,jid[,nickname])\n", app_ajijoin);
1735  return -1;
1736  }
1737  s = ast_strdupa(data);
1738 
1740  if (args.argc < 2 || args.argc > 3) {
1741  ast_log(LOG_ERROR, "%s requires arguments (sender,jid[,nickname])\n", app_ajijoin);
1742  return -1;
1743  }
1744 
1745  if (strchr(args.jid, '/')) {
1746  ast_log(LOG_ERROR, "Invalid room name : resource must not be appended\n");
1747  return -1;
1748  }
1749 
1750  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, args.sender))) {
1751  ast_log(LOG_ERROR, "Could not find sender connection: '%s'\n", args.sender);
1752  return -1;
1753  }
1754 
1755  if (ast_strlen_zero(args.nick)) {
1756  if (ast_test_flag(&clientcfg->flags, XMPP_COMPONENT)) {
1757  snprintf(nick, sizeof(nick), "asterisk");
1758  } else {
1759  snprintf(nick, sizeof(nick), "%s", clientcfg->client->jid->user);
1760  }
1761  } else {
1762  snprintf(nick, sizeof(nick), "%s", args.nick);
1763  }
1764 
1765  if (!ast_strlen_zero(args.jid) && strchr(args.jid, '@')) {
1766  ast_xmpp_chatroom_join(clientcfg->client, args.jid, nick);
1767  } else {
1768  ast_log(LOG_ERROR, "Problem with specified jid of '%s'\n", args.jid);
1769  }
1770 
1771  return 0;
1772 }
XMPP Client Configuration.
Definition: res_xmpp.c:444
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; 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:651
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:1004
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
const char * args
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define XMPP_MAX_RESJIDLEN
Maximum size of a resource JID.
Definition: xmpp.h:65
#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:911
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static struct console_pvt globals
#define LOG_ERROR
Definition: logger.h:285
static const char * app_ajijoin
Definition: res_xmpp.c:513
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ xmpp_leave_exec()

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 1781 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero, ast_test_flag, ast_xmpp_chatroom_leave(), globals, LOG_ERROR, NULL, RAII_VAR, XMPP_COMPONENT, xmpp_config_find(), and XMPP_MAX_RESJIDLEN.

Referenced by load_module().

1782 {
1784  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
1785  char *s, nick[XMPP_MAX_RESJIDLEN];
1787  AST_APP_ARG(sender);
1788  AST_APP_ARG(jid);
1789  AST_APP_ARG(nick);
1790  );
1791 
1792  if (ast_strlen_zero(data)) {
1793  ast_log(LOG_ERROR, "%s requires arguments (sender,jid[,nickname])\n", app_ajileave);
1794  return -1;
1795  }
1796  s = ast_strdupa(data);
1797 
1799  if (args.argc < 2 || args.argc > 3) {
1800  ast_log(LOG_ERROR, "%s requires arguments (sender,jid[,nickname])\n", app_ajileave);
1801  return -1;
1802  }
1803 
1804  if (strchr(args.jid, '/')) {
1805  ast_log(LOG_ERROR, "Invalid room name, resource must not be appended\n");
1806  return -1;
1807  }
1808 
1809  if (ast_strlen_zero(args.jid) || !strchr(args.jid, '@')) {
1810  ast_log(LOG_ERROR, "No jabber ID specified\n");
1811  return -1;
1812  }
1813 
1814  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, args.sender))) {
1815  ast_log(LOG_ERROR, "Could not find sender connection: '%s'\n", args.sender);
1816  return -1;
1817  }
1818 
1819  if (ast_strlen_zero(args.nick)) {
1820  if (ast_test_flag(&clientcfg->flags, XMPP_COMPONENT)) {
1821  snprintf(nick, sizeof(nick), "asterisk");
1822  } else {
1823  snprintf(nick, sizeof(nick), "%s", clientcfg->client->jid->user);
1824  }
1825  } else {
1826  snprintf(nick, sizeof(nick), "%s", args.nick);
1827  }
1828 
1829  ast_xmpp_chatroom_leave(clientcfg->client, args.jid, nick);
1830 
1831  return 0;
1832 }
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:1014
XMPP Client Configuration.
Definition: res_xmpp.c:444
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; 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:651
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
const char * args
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define XMPP_MAX_RESJIDLEN
Maximum size of a resource JID.
Definition: xmpp.h:65
#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:911
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static struct console_pvt globals
#define LOG_ERROR
Definition: logger.h:285
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static const char * app_ajileave
Definition: res_xmpp.c:514
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ xmpp_log_hook()

static void xmpp_log_hook ( void *  data,
const char *  xmpp,
size_t  size,
int  incoming 
)
static

Logging hook function.

Definition at line 2474 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ast_test_flag, ast_verbose(), globals, ast_xmpp_client::name, NULL, RAII_VAR, xmpp_config_find(), and XMPP_DEBUG.

Referenced by xmpp_client_config_post_apply(), xmpp_client_receive(), and xmpp_client_send_raw_message().

2475 {
2477  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
2478  struct ast_xmpp_client *client = data;
2479 
2480  if (!debug && (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name)) || !ast_test_flag(&clientcfg->flags, XMPP_DEBUG))) {
2481  return;
2482  }
2483 
2484  if (!incoming) {
2485  ast_verbose("\n<--- XMPP sent to '%s' --->\n%s\n<------------->\n", client->name, xmpp);
2486  } else {
2487  ast_verbose("\n<--- XMPP received from '%s' --->\n%s\n<------------->\n", client->name, xmpp);
2488  }
2489 }
XMPP Client Configuration.
Definition: res_xmpp.c:444
#define ast_test_flag(p, flag)
Definition: utils.h:63
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
static int debug
Global debug status.
Definition: res_xmpp.c:435
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define NULL
Definition: resample.c:96
XMPP Client Connection.
Definition: xmpp.h:119
#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:911
static struct console_pvt globals
const ast_string_field name
Definition: xmpp.h:123
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ xmpp_message_destroy()

static void xmpp_message_destroy ( struct ast_xmpp_message message)
static

Destroy function for XMPP messages.

Definition at line 532 of file res_xmpp.c.

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

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

533 {
534  if (message->from) {
535  ast_free(message->from);
536  }
537  if (message->message) {
538  ast_free(message->message);
539  }
540 
541  ast_free(message);
542 }
char * from
Definition: xmpp.h:102
char * message
Definition: xmpp.h:103
#define ast_free(a)
Definition: astmm.h:182

◆ xmpp_pak_message()

static int xmpp_pak_message ( struct ast_xmpp_client client,
struct ast_xmpp_client_config cfg,
iks *  node,
ikspak *  pak 
)
static

Internal function called when a message is received.

Definition at line 3120 of file res_xmpp.c.

References ao2_cleanup, ao2_find, ast_xmpp_message::arrived, ast_calloc, ast_cond_broadcast, ast_copy_string(), ast_debug, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_msg_alloc(), ast_msg_destroy(), ast_msg_queue(), ast_msg_set_body(), ast_msg_set_context(), ast_msg_set_endpoint(), ast_msg_set_from(), ast_msg_set_tech(), ast_msg_set_to(), ast_msg_set_var(), ast_mutex_lock, ast_mutex_unlock, ast_strdup, ast_strlen_zero, ast_test_flag, ast_tvnow(), ast_xmpp_client_lock(), ast_xmpp_client_unlock(), ast_xmpp_client::buddies, ast_xmpp_client_config::context, delete_old_messages(), ast_xmpp_client_config::flags, ast_xmpp_message::from, ast_xmpp_message::id, ast_xmpp_buddy::id, ast_xmpp_message::message, ast_xmpp_client::messages, ast_xmpp_client::name, NULL, OBJ_KEY, OBJ_NOLOCK, S_OR, ast_xmpp_client_config::user, and XMPP_SEND_TO_DIALPLAN.

3121 {
3122  struct ast_xmpp_message *message;
3123  char *body;
3124  int deleted = 0;
3125 
3126  ast_debug(3, "XMPP client '%s' received a message\n", client->name);
3127 
3128  if (!(body = iks_find_cdata(pak->x, "body"))) {
3129  /* Message contains no body, ignore it. */
3130  return 0;
3131  }
3132 
3133  if (!(message = ast_calloc(1, sizeof(*message)))) {
3134  return -1;
3135  }
3136 
3137  message->arrived = ast_tvnow();
3138 
3139  message->message = ast_strdup(body);
3140 
3141  ast_copy_string(message->id, S_OR(pak->id, ""), sizeof(message->id));
3142  message->from = !ast_strlen_zero(pak->from->full) ? ast_strdup(pak->from->full) : NULL;
3143 
3145  struct ast_msg *msg;
3146  struct ast_xmpp_buddy *buddy;
3147 
3148  if ((msg = ast_msg_alloc())) {
3149  int res;
3150 
3151  ast_xmpp_client_lock(client);
3152 
3153  buddy = ao2_find(client->buddies, pak->from->partial, OBJ_KEY | OBJ_NOLOCK);
3154 
3155  res = ast_msg_set_to(msg, "xmpp:%s", cfg->user);
3156  res |= ast_msg_set_from(msg, "xmpp:%s", message->from);
3157  res |= ast_msg_set_body(msg, "%s", message->message);
3158  res |= ast_msg_set_context(msg, "%s", cfg->context);
3159  res |= ast_msg_set_tech(msg, "%s", "XMPP");
3160  res |= ast_msg_set_endpoint(msg, "%s", client->name);
3161 
3162  if (buddy) {
3163  res |= ast_msg_set_var(msg, "XMPP_BUDDY", buddy->id);
3164  }
3165 
3166  ao2_cleanup(buddy);
3167 
3168  ast_xmpp_client_unlock(client);
3169 
3170  if (res) {
3171  ast_msg_destroy(msg);
3172  } else {
3173  ast_msg_queue(msg);
3174  }
3175  }
3176  }
3177 
3178  /* remove old messages received from this JID
3179  * and insert received message */
3180  deleted = delete_old_messages(client, pak->from->partial);
3181  ast_debug(3, "Deleted %d messages for client %s from JID %s\n", deleted, client->name, pak->from->partial);
3182  AST_LIST_LOCK(&client->messages);
3183  AST_LIST_INSERT_HEAD(&client->messages, message, list);
3184  AST_LIST_UNLOCK(&client->messages);
3185 
3186  /* wake up threads waiting for messages */
3190 
3191  return 0;
3192 }
int ast_msg_set_tech(struct ast_msg *msg, const char *fmt,...)
Set the technology associated with this message.
Definition: message.c:509
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
int ast_msg_set_context(struct ast_msg *msg, const char *fmt,...)
Set the dialplan context for this message.
Definition: message.c:487
int ast_msg_set_body(struct ast_msg *msg, const char *fmt,...)
Set the &#39;body&#39; text of a message (in UTF-8)
Definition: message.c:476
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define OBJ_KEY
Definition: astobj2.h:1155
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
struct ast_msg * ast_msg_alloc(void)
Allocate a message.
Definition: message.c:418
char id[XMPP_MAX_JIDLEN]
Definition: xmpp.h:113
struct ast_flags flags
Definition: res_xmpp.c:460
Assume that the ao2_container is already locked.
Definition: astobj2.h:1067
void ast_xmpp_client_lock(struct ast_xmpp_client *client)
Lock an XMPP client connection.
Definition: res_xmpp.c:893
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
int ast_msg_set_to(struct ast_msg *msg, const char *fmt,...)
Set the &#39;to&#39; URI of a message.
Definition: message.c:454
struct ast_xmpp_client::@330 messages
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
char * from
Definition: xmpp.h:102
const ast_string_field user
Definition: res_xmpp.c:456
static int delete_old_messages(struct ast_xmpp_client *client, char *from)
Definition: res_xmpp.c:2095
#define ast_cond_broadcast(cond)
Definition: lock.h:202
int ast_msg_set_var(struct ast_msg *msg, const char *name, const char *value)
Set a variable on the message going to the dialplan.
Definition: message.c:615
struct timeval arrived
Definition: xmpp.h:105
int ast_msg_queue(struct ast_msg *msg)
Queue a message for routing through the dialplan.
Definition: message.c:958
char * message
Definition: xmpp.h:103
XMPP Message.
Definition: xmpp.h:101
const ast_string_field context
Definition: res_xmpp.c:456
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:710
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
XMPP Buddy.
Definition: xmpp.h:112
static ast_mutex_t messagelock
Definition: res_xmpp.c:517
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
const ast_string_field name
Definition: xmpp.h:123
int ast_msg_set_from(struct ast_msg *msg, const char *fmt,...)
Set the &#39;from&#39; URI of a message.
Definition: message.c:465
struct ao2_container * buddies
Definition: xmpp.h:137
static ast_cond_t message_received_condition
Definition: res_xmpp.c:516
int ast_msg_set_endpoint(struct ast_msg *msg, const char *fmt,...)
Set the technology&#39;s endpoint associated with this message.
Definition: message.c:520
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
char id[25]
Definition: xmpp.h:104
void ast_xmpp_client_unlock(struct ast_xmpp_client *client)
Unlock an XMPP client connection.
Definition: res_xmpp.c:898
A message.
Definition: message.c:233
struct ast_msg * ast_msg_destroy(struct ast_msg *msg)
Destroy an ast_msg.
Definition: message.c:448
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ xmpp_pak_presence()

static int xmpp_pak_presence ( struct ast_xmpp_client client,
struct ast_xmpp_client_config cfg,
iks *  node,
ikspak *  pak 
)
static

Internal function called when a presence message is received.

Definition at line 3266 of file res_xmpp.c.

References ao2_alloc, ao2_callback, ao2_find, ao2_link_flags, ao2_lock, ao2_ref, ao2_unlink_flags, ao2_unlock, ast_copy_string(), AST_DEVICE_NOT_INUSE, AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_free, ast_log, ast_strdup, ast_strlen_zero, ast_test_flag, ast_xmpp_client::buddies, ast_xmpp_resource::caps, ast_xmpp_resource::description, EVENT_FLAG_USER, ast_xmpp_client_config::flags, ast_xmpp_capabilities::google, ast_xmpp_buddy::id, ast_xmpp_client::jid, LOG_ERROR, LOG_WARNING, manager_event, ast_xmpp_client::name, ast_xmpp_capabilities::node, NULL, OBJ_KEY, OBJ_NOLOCK, ast_xmpp_resource::priority, ast_xmpp_resource::resource, ast_xmpp_buddy::resources, S_OR, ast_xmpp_resource::status, status, ast_xmpp_client_config::status, STATUS_DISAPPEAR, ast_xmpp_client_config::statusmsg, type, ast_xmpp_capabilities::version, xmpp_client_send_disco_info_request(), xmpp_client_set_presence(), XMPP_COMPONENT, xmpp_resource_cmp(), xmpp_resource_destructor(), and xmpp_resource_is_available().

3267 {
3268  struct ast_xmpp_buddy *buddy;
3269  struct ast_xmpp_resource *resource;
3270  char *type = iks_find_attrib(pak->x, "type");
3271  int status = pak->show ? pak->show : STATUS_DISAPPEAR;
3273 
3274  /* If this is a component presence probe request answer immediately with our presence status */
3275  if (ast_test_flag(&cfg->flags, XMPP_COMPONENT) && !ast_strlen_zero(type) && !strcasecmp(type, "probe")) {
3276  xmpp_client_set_presence(client, pak->from->full, iks_find_attrib(pak->x, "to"), cfg->status, cfg->statusmsg);
3277  }
3278 
3279  /* If no resource is available this is a general buddy presence update, which we will ignore */
3280  if (!pak->from->resource) {
3281  return 0;
3282  }
3283 
3284  if (!(buddy = ao2_find(client->buddies, pak->from->partial, OBJ_KEY))) {
3285  /* Only output the message if it is not about us */
3286  if (strcmp(client->jid->partial, pak->from->partial)) {
3287  ast_log(LOG_WARNING, "Received presence information about '%s' despite not having them in roster on client '%s'\n",
3288  pak->from->partial, client->name);
3289  }
3290  return 0;
3291  }
3292 
3293  ao2_lock(buddy->resources);
3294 
3295  if (!(resource = ao2_callback(buddy->resources, OBJ_NOLOCK, xmpp_resource_cmp, pak->from->resource))) {
3296  /* Only create the new resource if it is not going away - in reality this should not happen */
3297  if (status != STATUS_DISAPPEAR) {
3298  if (!(resource = ao2_alloc(sizeof(*resource), xmpp_resource_destructor))) {
3299  ast_log(LOG_ERROR, "Could not allocate resource object for resource '%s' of buddy '%s' on client '%s'\n",
3300  pak->from->resource, buddy->id, client->name);
3301  ao2_unlock(buddy->resources);
3302  ao2_ref(buddy, -1);
3303  return 0;
3304  }
3305 
3306  ast_copy_string(resource->resource, pak->from->resource, sizeof(resource->resource));
3307  }
3308  } else {
3309  /* We unlink the resource in case the priority changes or in case they are going away */
3310  ao2_unlink_flags(buddy->resources, resource, OBJ_NOLOCK);
3311  }
3312 
3313  /* Only update the resource and add it back in if it is not going away */
3314  if (resource && (status != STATUS_DISAPPEAR)) {
3315  char *node, *ver;
3316 
3317  /* Try to get the XMPP spec node, and fall back to Google if not found */
3318  if (!(node = iks_find_attrib(iks_find(pak->x, "c"), "node"))) {
3319  node = iks_find_attrib(iks_find(pak->x, "caps:c"), "node");
3320  }
3321 
3322  if (!(ver = iks_find_attrib(iks_find(pak->x, "c"), "ver"))) {
3323  ver = iks_find_attrib(iks_find(pak->x, "caps:c"), "ver");
3324  }
3325 
3326  if (resource->description) {
3327  ast_free(resource->description);
3328  }
3329 
3330  if ((node && strcmp(resource->caps.node, node)) || (ver && strcmp(resource->caps.version, ver))) {
3331  /* For interoperability reasons, proceed even if the resource fails to provide node or version */
3332  if (node) {
3333  ast_copy_string(resource->caps.node, node, sizeof(resource->caps.node));
3334  }
3335  if (ver) {
3336  ast_copy_string(resource->caps.version, ver, sizeof(resource->caps.version));
3337  }
3338 
3339  /* Google Talk places the capabilities information directly in presence, so see if it is there */
3340  if (iks_find_with_attrib(pak->x, "c", "node", "http://www.google.com/xmpp/client/caps") ||
3341  iks_find_with_attrib(pak->x, "caps:c", "node", "http://www.google.com/xmpp/client/caps") ||
3342  iks_find_with_attrib(pak->x, "c", "node", "http://www.android.com/gtalk/client/caps") ||
3343  iks_find_with_attrib(pak->x, "caps:c", "node", "http://www.android.com/gtalk/client/caps") ||
3344  iks_find_with_attrib(pak->x, "c", "node", "http://mail.google.com/xmpp/client/caps") ||
3345  iks_find_with_attrib(pak->x, "caps:c", "node", "http://mail.google.com/xmpp/client/caps")) {
3346  resource->caps.google = 1;
3347  }
3348 
3349  /* To discover if the buddy supports Jingle we need to query, so do so */
3350  if (xmpp_client_send_disco_info_request(client, pak->from->full, client->jid->full)) {
3351  ast_log(LOG_WARNING, "Could not send discovery information request to resource '%s' of buddy '%s' on client '%s', capabilities may be incomplete\n", resource->resource, buddy->id, client->name);
3352  }
3353  }
3354 
3355  resource->status = status;
3356  resource->description = ast_strdup(iks_find_cdata(pak->x, "status"));
3357  resource->priority = atoi((iks_find_cdata(pak->x, "priority")) ? iks_find_cdata(pak->x, "priority") : "0");
3358 
3359  ao2_link_flags(buddy->resources, resource, OBJ_NOLOCK);
3360 
3361  manager_event(EVENT_FLAG_USER, "JabberStatus",
3362  "Account: %s\r\nJID: %s\r\nResource: %s\r\nStatus: %d\r\nPriority: %d"
3363  "\r\nDescription: %s\r\n",
3364  client->name, pak->from->partial, resource->resource, resource->status,
3365  resource->priority, S_OR(resource->description, ""));
3366 
3367  ao2_ref(resource, -1);
3368  } else {
3369  /* This will get hit by presence coming in for an unknown resource, and also when a resource goes away */
3370  if (resource) {
3371  ao2_ref(resource, -1);
3372  }
3373 
3374  manager_event(EVENT_FLAG_USER, "JabberStatus",
3375  "Account: %s\r\nJID: %s\r\nStatus: %u\r\n",
3376  client->name, pak->from->partial, pak->show ? pak->show : IKS_SHOW_UNAVAILABLE);
3377  }
3378 
3379  /* Determine if at least one resource is available for device state purposes */
3380  if ((resource = ao2_callback(buddy->resources, OBJ_NOLOCK, xmpp_resource_is_available, NULL))) {
3381  state = AST_DEVICE_NOT_INUSE;
3382  ao2_ref(resource, -1);
3383  }
3384 
3385  ao2_unlock(buddy->resources);
3386 
3387  ao2_ref(buddy, -1);
3388 
3389  ast_devstate_changed(state, AST_DEVSTATE_CACHABLE, "XMPP/%s/%s", client->name, pak->from->partial);
3390 
3391  return 0;
3392 }
static const char type[]
Definition: chan_ooh323.c:109
Definition: test_heap.c:38
ast_device_state
Device States.
Definition: devicestate.h:52
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define OBJ_KEY
Definition: astobj2.h:1155
#define LOG_WARNING
Definition: logger.h:274
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
char id[XMPP_MAX_JIDLEN]
Definition: xmpp.h:113
struct ast_flags flags
Definition: res_xmpp.c:460
Assume that the ao2_container is already locked.
Definition: astobj2.h:1067
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.
Definition: res_xmpp.c:3195
static void xmpp_resource_destructor(void *obj)
Destructor callback function for XMPP resource.
Definition: res_xmpp.c:829
char resource[XMPP_MAX_RESJIDLEN]
Definition: xmpp.h:93
#define ao2_link_flags(container, obj, flags)
Definition: astobj2.h:1572
#define ao2_unlock(a)
Definition: astobj2.h:730
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
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.
Definition: res_xmpp.c:2308
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
char node[200]
Definition: xmpp.h:85
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
Definition: devicestate.c:510
#define STATUS_DISAPPEAR
Status for a disappearing buddy.
Definition: res_xmpp.c:432
unsigned int google
Definition: xmpp.h:88
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
const ast_string_field statusmsg
Definition: res_xmpp.c:456
XMPP Resource.
Definition: xmpp.h:92
#define LOG_ERROR
Definition: logger.h:285
#define EVENT_FLAG_USER
Definition: manager.h:77
char version[50]
Definition: xmpp.h:86
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
#define ast_free(a)
Definition: astmm.h:182
XMPP Buddy.
Definition: xmpp.h:112
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
struct ao2_container * resources
Definition: xmpp.h:114
iksid * jid
Definition: xmpp.h:126
const ast_string_field name
Definition: xmpp.h:123
static int xmpp_resource_cmp(void *obj, void *arg, int flags)
Comparator function for XMPP resource.
Definition: res_xmpp.c:847
struct ao2_container * buddies
Definition: xmpp.h:137
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
enum ikshowtype status
Definition: res_xmpp.c:462
#define ao2_unlink_flags(container, obj, flags)
Definition: astobj2.h:1622
int priority
Definition: xmpp.h:96
struct ast_xmpp_capabilities caps
Definition: xmpp.h:97
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:248
char * description
Definition: xmpp.h:95
static int xmpp_resource_is_available(void *obj, void *arg, int flags)
Callback function which returns when the resource is available.
Definition: res_xmpp.c:3224
jack_status_t status
Definition: app_jack.c:146

◆ xmpp_pak_s10n()

static int xmpp_pak_s10n ( struct ast_xmpp_client client,
struct ast_xmpp_client_config cfg,
iks *  node,
ikspak *  pak 
)
static

Internal function called when a subscription message is received.

Definition at line 3395 of file res_xmpp.c.

References ao2_find, ao2_lock, ao2_ref, ao2_unlock, ast_log, ast_test_flag, ast_xmpp_client_send(), ast_xmpp_client::buddies, ast_xmpp_client_config::flags, ast_xmpp_client::jid, LOG_ERROR, LOG_WARNING, ast_xmpp_client::name, NULL, OBJ_KEY, OBJ_NOLOCK, status, ast_xmpp_client_config::status, ast_xmpp_client_config::statusmsg, XMPP_AUTOREGISTER, xmpp_client_create_buddy(), xmpp_client_set_presence(), and XMPP_COMPONENT.

3396 {
3397  struct ast_xmpp_buddy *buddy;
3398 
3399  switch (pak->subtype) {
3400  case IKS_TYPE_SUBSCRIBE:
3401  if (ast_test_flag(&cfg->flags, XMPP_AUTOREGISTER)) {
3402  iks *presence, *status = NULL;
3403 
3404  if ((presence = iks_new("presence")) && (status = iks_new("status"))) {
3405  iks_insert_attrib(presence, "type", "subscribed");
3406  iks_insert_attrib(presence, "to", pak->from->full);
3407  iks_insert_attrib(presence, "from", client->jid->full);
3408 
3409  if (pak->id) {
3410  iks_insert_attrib(presence, "id", pak->id);
3411  }
3412 
3413  iks_insert_cdata(status, "Asterisk has approved your subscription", 0);
3414  iks_insert_node(presence, status);
3415 
3416  if (ast_xmpp_client_send(client, presence)) {
3417  ast_log(LOG_ERROR, "Could not send subscription acceptance to '%s' from client '%s'\n",
3418  pak->from->partial, client->name);
3419  }
3420  } else {
3421  ast_log(LOG_ERROR, "Could not allocate presence stanzas for accepting subscription from '%s' to client '%s'\n",
3422  pak->from->partial, client->name);
3423  }
3424 
3425  iks_delete(status);
3426  iks_delete(presence);
3427  }
3428 
3429  if (ast_test_flag(&cfg->flags, XMPP_COMPONENT)) {
3430  xmpp_client_set_presence(client, pak->from->full, iks_find_attrib(pak->x, "to"), cfg->status, cfg->statusmsg);
3431  }
3432  /* This purposely flows through so we have the subscriber amongst our buddies */
3433  case IKS_TYPE_SUBSCRIBED:
3434  ao2_lock(client->buddies);
3435 
3436  if (!(buddy = ao2_find(client->buddies, pak->from->partial, OBJ_KEY | OBJ_NOLOCK))) {
3437  buddy = xmpp_client_create_buddy(client->buddies, pak->from->partial);
3438  }
3439 
3440  if (!buddy) {
3441  ast_log(LOG_WARNING, "Could not find or create buddy '%s' on client '%s'\n",
3442  pak->from->partial, client->name);
3443  } else {
3444  ao2_ref(buddy, -1);
3445  }
3446 
3447  ao2_unlock(client->buddies);
3448 
3449  break;
3450  default:
3451  break;
3452  }
3453 
3454  return 0;
3455 }
static struct ast_xmpp_buddy * xmpp_client_create_buddy(struct ao2_container *container, const char *id)
Internal function which creates a buddy on a client.
Definition: res_xmpp.c:2166
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define OBJ_KEY
Definition: astobj2.h:1155
#define LOG_WARNING
Definition: logger.h:274
struct ast_flags flags
Definition: res_xmpp.c:460
Assume that the ao2_container is already locked.
Definition: astobj2.h:1067
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
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.
Definition: res_xmpp.c:2308
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
const ast_string_field statusmsg
Definition: res_xmpp.c:456
#define LOG_ERROR
Definition: logger.h:285
XMPP Buddy.
Definition: xmpp.h:112
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
iksid * jid
Definition: xmpp.h:126
const ast_string_field name
Definition: xmpp.h:123
struct ao2_container * buddies
Definition: xmpp.h:137
enum ikshowtype status
Definition: res_xmpp.c:462
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:2537
jack_status_t status
Definition: app_jack.c:146

◆ xmpp_ping_request()

static int xmpp_ping_request ( struct ast_xmpp_client client,
const char *  to,
const char *  from 
)
static

Helper function which sends a ping request to a server.

Definition at line 3232 of file res_xmpp.c.

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

Referenced by xmpp_client_receive(), and xmpp_client_thread().

3233 {
3234  iks *iq, *ping;
3235  int res;
3236 
3237  ast_debug(2, "JABBER: Sending Keep-Alive Ping for client '%s'\n", client->name);
3238 
3239  if (!(iq = iks_new("iq")) || !(ping = iks_new("ping"))) {
3240  iks_delete(iq);
3241  return -1;
3242  }
3243 
3244  iks_insert_attrib(iq, "type", "get");
3245  iks_insert_attrib(iq, "to", to);
3246  iks_insert_attrib(iq, "from", from);
3247 
3248  ast_xmpp_client_lock(client);
3249  iks_insert_attrib(iq, "id", client->mid);
3250  ast_xmpp_increment_mid(client->mid);
3251  ast_xmpp_client_unlock(client);
3252 
3253  iks_insert_attrib(ping, "xmlns", "urn:xmpp:ping");
3254  iks_insert_node(iq, ping);
3255 
3256  res = ast_xmpp_client_send(client, iq);
3257 
3258  iks_delete(ping);
3259  iks_delete(iq);
3260 
3261 
3262  return res;
3263 }
void ast_xmpp_increment_mid(char *mid)
Helper function which increments the message identifier.
Definition: res_xmpp.c:1019
void ast_xmpp_client_lock(struct ast_xmpp_client *client)
Lock an XMPP client connection.
Definition: res_xmpp.c:893
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
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:898
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:2537

◆ xmpp_pubsub_build_node_config()

static iks* xmpp_pubsub_build_node_config ( iks *  pubsub,
const char *  node_type,
const char *  collection_name 
)
static

Definition at line 1108 of file res_xmpp.c.

Referenced by xmpp_pubsub_create_node().

1109 {
1110  iks *configure, *x, *field_owner, *field_node_type, *field_node_config,
1111  *field_deliver_payload, *field_persist_items, *field_access_model,
1112  *field_pubsub_collection;
1113  configure = iks_insert(pubsub, "configure");
1114  x = iks_insert(configure, "x");
1115  iks_insert_attrib(x, "xmlns", "jabber:x:data");
1116  iks_insert_attrib(x, "type", "submit");
1117  field_owner = iks_insert(x, "field");
1118  iks_insert_attrib(field_owner, "var", "FORM_TYPE");
1119  iks_insert_attrib(field_owner, "type", "hidden");
1120  iks_insert_cdata(iks_insert(field_owner, "value"),
1121  "http://jabber.org/protocol/pubsub#owner", 39);
1122  if (node_type) {
1123  field_node_type = iks_insert(x, "field");
1124  iks_insert_attrib(field_node_type, "var", "pubsub#node_type");
1125  iks_insert_cdata(iks_insert(field_node_type, "value"), node_type, strlen(node_type));
1126  }
1127  field_node_config = iks_insert(x, "field");
1128  iks_insert_attrib(field_node_config, "var", "FORM_TYPE");
1129  iks_insert_attrib(field_node_config, "type", "hidden");
1130  iks_insert_cdata(iks_insert(field_node_config, "value"),
1131  "http://jabber.org/protocol/pubsub#node_config", 45);
1132  field_deliver_payload = iks_insert(x, "field");
1133  iks_insert_attrib(field_deliver_payload, "var", "pubsub#deliver_payloads");
1134  iks_insert_cdata(iks_insert(field_deliver_payload, "value"), "1", 1);
1135  field_persist_items = iks_insert(x, "field");
1136  iks_insert_attrib(field_persist_items, "var", "pubsub#persist_items");
1137  iks_insert_cdata(iks_insert(field_persist_items, "value"), "1", 1);
1138  field_access_model = iks_insert(x, "field");
1139  iks_insert_attrib(field_access_model, "var", "pubsub#access_model");
1140  iks_insert_cdata(iks_insert(field_access_model, "value"), "whitelist", 9);
1141  if (node_type && !strcasecmp(node_type, "leaf")) {
1142  field_pubsub_collection = iks_insert(x, "field");
1143  iks_insert_attrib(field_pubsub_collection, "var", "pubsub#collection");
1144  iks_insert_cdata(iks_insert(field_pubsub_collection, "value"), collection_name,
1145  strlen(collection_name));
1146  }
1147  return configure;
1148 }
node_type
Definition: ast_expr2.c:333

◆ xmpp_pubsub_build_node_request()

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 3977 of file res_xmpp.c.

References NULL, request(), and xmpp_pubsub_iq_create().

Referenced by xmpp_pubsub_purge_nodes(), and xmpp_pubsub_request_nodes().

3978 {
3979  iks *request = xmpp_pubsub_iq_create(client, "get"), *query;
3980 
3981  if (!request) {
3982  return NULL;
3983  }
3984 
3985  query = iks_insert(request, "query");
3986  iks_insert_attrib(query, "xmlns", "http://jabber.org/protocol/disco#items");
3987 
3988  if (collection) {
3989  iks_insert_attrib(query, "node", collection);
3990  }
3991 
3992  return request;
3993 }
#define NULL
Definition: resample.c:96
static int request(void *obj)
Definition: chan_pjsip.c:2559
static iks * xmpp_pubsub_iq_create(struct ast_xmpp_client *client, const char *type)
Create an IQ packet.
Definition: res_xmpp.c:1039

◆ xmpp_pubsub_build_publish_skeleton()

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
Returns
iks *

Definition at line 1071 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, AST_DEVSTATE_NOT_CACHABLE, ast_test_flag, globals, item, NULL, options, publish, ast_xmpp_global_config::pubsub, RAII_VAR, request(), xmpp_pubsub_iq_create(), and XMPP_XEP0248.

Referenced by xmpp_pubsub_publish_device_state(), and xmpp_pubsub_publish_mwi().

1073 {
1075  iks *request, *pubsub, *publish, *item;
1076 
1077  if (!cfg || !cfg->global || !(request = xmpp_pubsub_iq_create(client, "set"))) {
1078  return NULL;
1079  }
1080 
1081  pubsub = iks_insert(request, "pubsub");
1082  iks_insert_attrib(pubsub, "xmlns", "http://jabber.org/protocol/pubsub");
1083  publish = iks_insert(pubsub, "publish");
1084  iks_insert_attrib(publish, "node", ast_test_flag(&cfg->global->pubsub, XMPP_XEP0248) ? node : event_type);
1085  item = iks_insert(publish, "item");
1086  iks_insert_attrib(item, "id", node);
1087 
1088  if (cachable == AST_DEVSTATE_NOT_CACHABLE) {
1089  iks *options, *x, *field_form_type, *field_persist;
1090 
1091  options = iks_insert(pubsub, "publish-options");
1092  x = iks_insert(options, "x");
1093  iks_insert_attrib(x, "xmlns", "jabber:x:data");
1094  iks_insert_attrib(x, "type", "submit");
1095  field_form_type = iks_insert(x, "field");
1096  iks_insert_attrib(field_form_type, "var", "FORM_TYPE");
1097  iks_insert_attrib(field_form_type, "type", "hidden");
1098  iks_insert_cdata(iks_insert(field_form_type, "value"), "http://jabber.org/protocol/pubsub#publish-options", 0);
1099  field_persist = iks_insert(x, "field");
1100  iks_insert_attrib(field_persist, "var", "pubsub#persist_items");
1101  iks_insert_cdata(iks_insert(field_persist, "value"), "0", 1);
1102  }
1103 
1104  return item;
1105 
1106 }
Definition: test_heap.c:38
#define ast_test_flag(p, flag)
Definition: utils.h:63
static struct aco_type item
Definition: test_config.c:1463
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
unsigned char publish
Definition: res_corosync.c:241
#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:911
static struct console_pvt globals
static int request(void *obj)
Definition: chan_pjsip.c:2559
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static struct test_options options
static iks * xmpp_pubsub_iq_create(struct ast_xmpp_client *client, const char *type)
Create an IQ packet.
Definition: res_xmpp.c:1039

◆ xmpp_pubsub_create_affiliations()

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
Returns
void

Definition at line 1156 of file res_xmpp.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_log, ast_xmpp_client_send(), ast_xmpp_client::buddies, ast_xmpp_buddy::id, LOG_ERROR, ast_xmpp_client::name, ast_xmpp_global_config::pubsub, and xmpp_pubsub_iq_create().

Referenced by xmpp_pubsub_create_node().

1157 {
1158  iks *modify_affiliates = xmpp_pubsub_iq_create(client, "set");
1159  iks *pubsub, *affiliations, *affiliate;
1160  struct ao2_iterator i;
1161  struct ast_xmpp_buddy *buddy;
1162 
1163  if (!modify_affiliates) {
1164  ast_log(LOG_ERROR, "Could not create IQ for creating affiliations on client '%s'\n", client->name);
1165  return;
1166  }
1167 
1168  pubsub = iks_insert(modify_affiliates, "pubsub");
1169  iks_insert_attrib(pubsub, "xmlns", "http://jabber.org/protocol/pubsub#owner");
1170  affiliations = iks_insert(pubsub, "affiliations");
1171  iks_insert_attrib(affiliations, "node", node);
1172 
1173  i = ao2_iterator_init(client->buddies, 0);
1174  while ((buddy = ao2_iterator_next(&i))) {
1175  affiliate = iks_insert(affiliations, "affiliation");
1176  iks_insert_attrib(affiliate, "jid", buddy->id);
1177  iks_insert_attrib(affiliate, "affiliation", "owner");
1178  ao2_ref(buddy, -1);
1179  }
1181 
1182  ast_xmpp_client_send(client, modify_affiliates);
1183  iks_delete(modify_affiliates);
1184 }
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 ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define LOG_ERROR
Definition: logger.h:285
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
XMPP Buddy.
Definition: xmpp.h:112
const ast_string_field name
Definition: xmpp.h:123
struct ao2_container * buddies
Definition: xmpp.h:137
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
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:1039
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:2537

◆ xmpp_pubsub_create_collection()

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
Returns
void.

Definition at line 1242 of file res_xmpp.c.

References NULL, and xmpp_pubsub_create_node().

Referenced by xmpp_cli_create_collection(), and xmpp_pubsub_handle_error().

1243 {
1244  xmpp_pubsub_create_node(client, "collection", collection_name, NULL);
1245 }
#define NULL
Definition: resample.c:96
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:1194

◆ xmpp_pubsub_create_leaf()

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
Returns
void.

Definition at line 1255 of file res_xmpp.c.

References xmpp_pubsub_create_node().

Referenced by xmpp_cli_create_leafnode(), and xmpp_pubsub_handle_error().

1257 {
1258  xmpp_pubsub_create_node(client, "leaf", leaf_name, collection_name);
1259 }
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:1194

◆ xmpp_pubsub_create_node()

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
Returns
void

Definition at line 1194 of file res_xmpp.c.

References ast_xmpp_client_send(), ast_xmpp_global_config::pubsub, xmpp_pubsub_build_node_config(), xmpp_pubsub_create_affiliations(), and xmpp_pubsub_iq_create().

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

1196 {
1197  iks *node, *pubsub, *create;
1198 
1199  if (!(node = xmpp_pubsub_iq_create(client, "set"))) {
1200  return;
1201  }
1202 
1203  pubsub = iks_insert(node, "pubsub");
1204  iks_insert_attrib(pubsub, "xmlns", "http://jabber.org/protocol/pubsub");
1205  create = iks_insert(pubsub, "create");
1206  iks_insert_attrib(create, "node", name);
1207  xmpp_pubsub_build_node_config(pubsub, node_type, collection_name);
1208  ast_xmpp_client_send(client, node);
1210  iks_delete(node);
1211 }
Definition: test_heap.c:38
static iks * xmpp_pubsub_build_node_config(iks *pubsub, const char *node_type, const char *collection_name)
Definition: res_xmpp.c:1108
node_type
Definition: ast_expr2.c:333
static void xmpp_pubsub_create_affiliations(struct ast_xmpp_client *client, const char *node)
Add Owner affiliations for pubsub node.
Definition: res_xmpp.c:1156
static const char name[]
Definition: cdr_mysql.c:74
static iks * xmpp_pubsub_iq_create(struct ast_xmpp_client *client, const char *type)
Create an IQ packet.
Definition: res_xmpp.c:1039
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:2537

◆ xmpp_pubsub_delete_node()

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 return void

Definition at line 1219 of file res_xmpp.c.

References ast_xmpp_client_send(), ast_xmpp_global_config::pubsub, request(), and xmpp_pubsub_iq_create().

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

1220 {
1221  iks *request, *pubsub, *delete;
1222 
1223  if (!(request = xmpp_pubsub_iq_create(client, "set"))) {
1224  return;
1225  }
1226 
1227  pubsub = iks_insert(request, "pubsub");
1228  iks_insert_attrib(pubsub, "xmlns", "http://jabber.org/protocol/pubsub#owner");
1229  delete = iks_insert(pubsub, "delete");
1230  iks_insert_attrib(delete, "node", node_name);
1231  ast_xmpp_client_send(client, request);
1232 
1233  iks_delete(request);
1234 }
static int request(void *obj)
Definition: chan_pjsip.c:2559
static iks * xmpp_pubsub_iq_create(struct ast_xmpp_client *client, const char *type)
Create an IQ packet.
Definition: res_xmpp.c:1039
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:2537

◆ xmpp_pubsub_delete_node_list()

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
Returns
IKS_FILTER_EAT

Definition at line 4100 of file res_xmpp.c.

References ast_log, item, ast_xmpp_client::jid, LOG_WARNING, NULL, and xmpp_pubsub_delete_node().

Referenced by xmpp_pubsub_purge_nodes().

4101 {
4102  struct ast_xmpp_client *client = data;
4103  iks *item = NULL;
4104 
4105  if (iks_has_children(pak->query)) {
4106  item = iks_first_tag(pak->query);
4107  ast_log(LOG_WARNING, "Connection: %s Node name: %s\n", client->jid->partial,
4108  iks_find_attrib(item, "node"));
4109  while ((item = iks_next_tag(item))) {
4110  xmpp_pubsub_delete_node(client, iks_find_attrib(item, "node"));
4111  }
4112  }
4113 
4114  if (item) {
4115  iks_delete(item);
4116  }
4117 
4118  return IKS_FILTER_EAT;
4119 }
#define LOG_WARNING
Definition: logger.h:274
static struct aco_type item
Definition: test_config.c:1463
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
XMPP Client Connection.
Definition: xmpp.h:119
iksid * jid
Definition: xmpp.h:126
static void xmpp_pubsub_delete_node(struct ast_xmpp_client *client, const char *node_name)
Delete a PubSub node.
Definition: res_xmpp.c:1219

◆ xmpp_pubsub_devstate_cb()

static void xmpp_pubsub_devstate_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message msg 
)
static

Callback function for device state events.

Parameters
ast_event
datavoid pointer to ast_client structure
Returns
void

Definition at line 1364 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 cached_devstate_cb(), and xmpp_init_event_distribution().

1365 {
1366  struct ast_xmpp_client *client = data;
1367  struct ast_device_state_message *dev_state;
1368 
1370  return;
1371  }
1372 
1373  dev_state = stasis_message_data(msg);
1374  if (!dev_state->eid || ast_eid_cmp(&ast_eid_default, dev_state->eid)) {
1375  /* If the event is aggregate or didn't originate from this server, don't send it out. */
1376  return;
1377  }
1378 
1379  xmpp_pubsub_publish_device_state(client, dev_state->device, ast_devstate_str(dev_state->state), dev_state->cachable);
1380 }
enum ast_device_state state
Definition: devicestate.h:250
int stasis_subscription_is_subscribed(const struct stasis_subscription *sub)
Returns whether a subscription is currently subscribed.
Definition: stasis.c:1152
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:252
int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2)
Compare two EIDs.
Definition: main/utils.c:2842
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:248
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:240

◆ xmpp_pubsub_handle_error()

static int xmpp_pubsub_handle_error ( void *  data,
ikspak *  pak 
)
static

Definition at line 1507 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ast_debug, ast_log, ast_test_flag, ast_xmpp_client_send(), error(), globals, LOG_ERROR, NULL, RAII_VAR, request(), xmpp_pubsub_create_collection(), xmpp_pubsub_create_leaf(), xmpp_pubsub_create_node(), xmpp_pubsub_iq_create(), and XMPP_XEP0248.

Referenced by xmpp_init_event_distribution().

1508 {
1510  char *node_name, *error;
1511  int error_num;
1512  iks *orig_request, *orig_pubsub = iks_find(pak->x, "pubsub");
1513  struct ast_xmpp_client *client = data;
1514 
1515  if (!cfg || !cfg->global) {
1516  ast_log(LOG_ERROR, "No global configuration available\n");
1517  return IKS_FILTER_EAT;
1518  }
1519 
1520  if (!orig_pubsub) {
1521  ast_debug(1, "Error isn't a PubSub error, why are we here?\n");
1522  return IKS_FILTER_EAT;
1523  }
1524 
1525  orig_request = iks_child(orig_pubsub);
1526  error = iks_find_attrib(iks_find(pak->x, "error"), "code");
1527  node_name = iks_find_attrib(orig_request, "node");
1528 
1529  if (!sscanf(error, "%30d", &error_num)) {
1530  return IKS_FILTER_EAT;
1531  }
1532 
1533  if (error_num > 399 && error_num < 500 && error_num != 404) {
1535  "Error performing operation on PubSub node %s, %s.\n", node_name, error);
1536  return IKS_FILTER_EAT;
1537  } else if (error_num > 499 && error_num < 600) {
1538  ast_log(LOG_ERROR, "PubSub Server error, %s\n", error);
1539  return IKS_FILTER_EAT;
1540  }
1541 
1542  if (!strcasecmp(iks_name(orig_request), "publish")) {
1543  iks *request;
1544 
1545  if (ast_test_flag(&cfg->global->pubsub, XMPP_XEP0248)) {
1546  if (iks_find(iks_find(orig_request, "item"), "state")) {
1547  xmpp_pubsub_create_leaf(client, "device_state", node_name);
1548  } else if (iks_find(iks_find(orig_request, "item"), "mailbox")) {
1549  xmpp_pubsub_create_leaf(client, "message_waiting", node_name);
1550  }
1551  } else {
1552  xmpp_pubsub_create_node(client, NULL, node_name, NULL);
1553  }
1554 
1555  if ((request = xmpp_pubsub_iq_create(client, "set"))) {
1556  iks_insert_node(request, orig_pubsub);
1557  ast_xmpp_client_send(client, request);
1558  iks_delete(request);
1559  } else {
1560  ast_log(LOG_ERROR, "PubSub publish could not create IQ\n");
1561  }
1562 
1563  return IKS_FILTER_EAT;
1564  } else if (!strcasecmp(iks_name(orig_request), "subscribe")) {
1565  if (ast_test_flag(&cfg->global->pubsub, XMPP_XEP0248)) {
1566  xmpp_pubsub_create_collection(client, node_name);
1567  } else {
1568  xmpp_pubsub_create_node(client, NULL, node_name, NULL);
1569  }
1570  }
1571 
1572  return IKS_FILTER_EAT;
1573 }
static void xmpp_pubsub_create_collection(struct ast_xmpp_client *client, const char *collection_name)
Create a PubSub collection node.
Definition: res_xmpp.c:1242
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
XMPP Client Connection.
Definition: xmpp.h:119
#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:911
static struct console_pvt globals
#define LOG_ERROR
Definition: logger.h:285
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:1194
static int request(void *obj)
Definition: chan_pjsip.c:2559
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:1255
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int error(const char *format,...)
Definition: utils/frame.c:999
static iks * xmpp_pubsub_iq_create(struct ast_xmpp_client *client, const char *type)
Create an IQ packet.
Definition: res_xmpp.c:1039
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:2537

◆ xmpp_pubsub_handle_event()

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
Returns
IKS_FILTER_EAT

Definition at line 1461 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_log, ast_publish_device_state_full(), ast_publish_mwi_state_full(), ast_str_to_eid(), item, LOG_ERROR, mailbox, NULL, and strsep().

Referenced by xmpp_init_event_distribution().

1462 {
1463  char *item_id, *device_state, *mailbox, *cachable_str;
1464  int oldmsgs, newmsgs;
1465  iks *item, *item_content;
1466  struct ast_eid pubsub_eid;
1467  unsigned int cachable = AST_DEVSTATE_CACHABLE;
1468  item = iks_find(iks_find(iks_find(pak->x, "event"), "items"), "item");
1469  if (!item) {
1470  ast_log(LOG_ERROR, "Could not parse incoming PubSub event\n");
1471  return IKS_FILTER_EAT;
1472  }
1473  item_id = iks_find_attrib(item, "id");
1474  item_content = iks_child(item);
1475  ast_str_to_eid(&pubsub_eid, iks_find_attrib(item_content, "eid"));
1476  if (!ast_eid_cmp(&ast_eid_default, &pubsub_eid)) {
1477  ast_debug(1, "Returning here, eid of incoming event matches ours!\n");
1478  return IKS_FILTER_EAT;
1479  }
1480  if (!strcasecmp(iks_name(item_content), "state")) {
1481  if ((cachable_str = iks_find_attrib(item_content, "cachable"))) {
1482  sscanf(cachable_str, "%30u", &cachable);
1483  }
1484  device_state = iks_find_cdata(item, "state");
1486  ast_devstate_val(device_state),
1488  &pubsub_eid);
1489  return IKS_FILTER_EAT;
1490  } else if (!strcasecmp(iks_name(item_content), "mailbox")) {
1491  mailbox = strsep(&item_id, "@");
1492  sscanf(iks_find_cdata(item_content, "OLDMSGS"), "%10d", &oldmsgs);
1493  sscanf(iks_find_cdata(item_content, "NEWMSGS"), "%10d", &newmsgs);
1494 
1495  ast_publish_mwi_state_full(mailbox, item_id, newmsgs, oldmsgs, NULL, &pubsub_eid);
1496 
1497  return IKS_FILTER_EAT;
1498  } else {
1499  ast_debug(1, "Don't know how to handle PubSub event of type %s\n",
1500  iks_name(item_content));
1501  return IKS_FILTER_EAT;
1502  }
1503 
1504  return IKS_FILTER_EAT;
1505 }
static struct aco_type item
Definition: test_config.c:1463
#define NULL
Definition: resample.c:96
An Entity ID is essentially a MAC address, brief and unique.
Definition: utils.h:786
int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2)
Compare two EIDs.
Definition: main/utils.c:2842
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Definition: chan_mgcp.c:204
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
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: main/utils.c:2825
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:388
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
#define LOG_ERROR
Definition: logger.h:285
struct ast_eid ast_eid_default
Global EID.
Definition: options.c:93
char * strsep(char **str, const char *delims)

◆ xmpp_pubsub_iq_create()

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 1039 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ast_strlen_zero, ast_xmpp_client_lock(), ast_xmpp_client_unlock(), ast_xmpp_increment_mid(), globals, ast_xmpp_client::jid, ast_xmpp_client::mid, ast_xmpp_client::name, NULL, RAII_VAR, request(), 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_handle_error(), xmpp_pubsub_subscribe(), and xmpp_pubsub_unsubscribe().

1040 {
1042  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
1043  iks *request;
1044 
1045  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name)) ||
1046  !(request = iks_new("iq"))) {
1047  return NULL;
1048  }
1049 
1050  if (!ast_strlen_zero(clientcfg->pubsubnode)) {
1051  iks_insert_attrib(request, "to", clientcfg->pubsubnode);
1052  }
1053 
1054  iks_insert_attrib(request, "from", client->jid->full);
1055  iks_insert_attrib(request, "type", type);
1056  ast_xmpp_client_lock(client);
1057  ast_xmpp_increment_mid(client->mid);
1058  iks_insert_attrib(request, "id", client->mid);
1059  ast_xmpp_client_unlock(client);
1060 
1061  return request;
1062 }
static const char type[]
Definition: chan_ooh323.c:109
XMPP Client Configuration.
Definition: res_xmpp.c:444
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
void ast_xmpp_increment_mid(char *mid)
Helper function which increments the message identifier.
Definition: res_xmpp.c:1019
void ast_xmpp_client_lock(struct ast_xmpp_client *client)
Lock an XMPP client connection.
Definition: res_xmpp.c:893
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#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:911
static struct console_pvt globals
static int request(void *obj)
Definition: chan_pjsip.c:2559
iksid * jid
Definition: xmpp.h:126
const ast_string_field name
Definition: xmpp.h:123
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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:898

◆ xmpp_pubsub_mwi_cb()

static void xmpp_pubsub_mwi_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message msg 
)
static

Callback function for MWI events.

Parameters
ast_event
datavoid pointer to ast_client structure
Returns
void

Definition at line 1336 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().

1337 {
1338  struct ast_xmpp_client *client = data;
1339  char oldmsgs[10], newmsgs[10];
1340  struct ast_mwi_state *mwi_state;
1341 
1343  return;
1344  }
1345 
1346  mwi_state = stasis_message_data(msg);
1347 
1348  if (ast_eid_cmp(&ast_eid_default, &mwi_state->eid)) {
1349  /* If the event didn't originate from this server, don't send it back out. */
1350  return;
1351  }
1352 
1353  snprintf(oldmsgs, sizeof(oldmsgs), "%d", mwi_state->old_msgs);
1354  snprintf(newmsgs, sizeof(newmsgs), "%d", mwi_state->new_msgs);
1355  xmpp_pubsub_publish_mwi(client, mwi_state->uniqueid, oldmsgs, newmsgs);
1356 }
int stasis_subscription_is_subscribed(const struct stasis_subscription *sub)
Returns whether a subscription is currently subscribed.
Definition: stasis.c:1152
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: main/utils.c:2842
XMPP Client Connection.
Definition: xmpp.h:119
int old_msgs
Definition: mwi.h:462
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 ast_eid_default
Global EID.
Definition: options.c:93
int new_msgs
Definition: mwi.h:461
const ast_string_field uniqueid
Definition: mwi.h:460
The structure that contains MWI state.
Definition: mwi.h:457
struct ast_eid eid
Definition: mwi.h:465

◆ xmpp_pubsub_publish_device_state()

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
Returns
void

Definition at line 1300 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ast_eid_default, ast_eid_to_str(), ast_test_flag, ast_xmpp_client_send(), globals, NULL, RAII_VAR, request(), state, XMPP_PUBSUB_AUTOCREATE, xmpp_pubsub_build_publish_skeleton(), xmpp_pubsub_create_node(), and XMPP_XEP0248.

Referenced by xmpp_pubsub_devstate_cb().

1302 {
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 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
char * ast_eid_to_str(char *s, int maxlen, struct ast_eid *eid)
Convert an EID to a string.
Definition: main/utils.c:2587
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
#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:911
static struct console_pvt globals
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:1071
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:1194
static int request(void *obj)
Definition: chan_pjsip.c:2559
struct ast_eid ast_eid_default
Global EID.
Definition: options.c:93
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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:2537

◆ xmpp_pubsub_publish_mwi()

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
Returns
void

Definition at line 1269 of file res_xmpp.c.

References AST_DEVSTATE_CACHABLE, ast_eid_default, ast_eid_to_str(), ast_xmpp_client_send(), request(), 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: main/utils.c:2587
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Definition: chan_mgcp.c:204
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:1071
static int request(void *obj)
Definition: chan_pjsip.c:2559
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:2537

◆ xmpp_pubsub_purge_nodes()

static void xmpp_pubsub_purge_nodes ( struct ast_xmpp_client client,
const char *  collection_name 
)
static

Definition at line 4121 of file res_xmpp.c.

References ast_xmpp_client_send(), ast_xmpp_client::filter, ast_xmpp_client::mid, request(), xmpp_pubsub_build_node_request(), and xmpp_pubsub_delete_node_list().

Referenced by xmpp_cli_purge_pubsub_nodes().

4122 {
4123  iks *request = xmpp_pubsub_build_node_request(client, collection_name);
4124  ast_xmpp_client_send(client, request);
4125  iks_filter_add_rule(client->filter, xmpp_pubsub_delete_node_list, client, IKS_RULE_TYPE,
4126  IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID, client->mid,
4127  IKS_RULE_DONE);
4128  ast_xmpp_client_send(client, request);
4129  iks_delete(request);
4130 }
static int xmpp_pubsub_delete_node_list(void *data, ikspak *pak)
Delete pubsub item lists.
Definition: res_xmpp.c:4100
static iks * xmpp_pubsub_build_node_request(struct ast_xmpp_client *client, const char *collection)
Build the a node request.
Definition: res_xmpp.c:3977
iksfilter * filter
Definition: xmpp.h:128
static int request(void *obj)
Definition: chan_pjsip.c:2559
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:2537

◆ xmpp_pubsub_receive_node_list()

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
Returns
IKS_FILTER_EAT

Definition at line 4001 of file res_xmpp.c.

References ast_verbose(), item, ast_xmpp_client::jid, ast_xmpp_client::name, and NULL.

Referenced by xmpp_pubsub_request_nodes().

4002 {
4003  struct ast_xmpp_client *client = data;
4004  iks *item = NULL;
4005 
4006  if (iks_has_children(pak->query)) {
4007  item = iks_first_tag(pak->query);
4008  ast_verbose("Connection %s: %s\nNode name: %s\n", client->name, client->jid->partial,
4009  iks_find_attrib(item, "node"));
4010  while ((item = iks_next_tag(item))) {
4011  ast_verbose("Node name: %s\n", iks_find_attrib(item, "node"));
4012  }
4013  }
4014 
4015  if (item) {
4016  iks_delete(item);
4017  }
4018 
4019 
4020  return IKS_FILTER_EAT;
4021 }
static struct aco_type item
Definition: test_config.c:1463
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define NULL
Definition: resample.c:96
XMPP Client Connection.
Definition: xmpp.h:119
iksid * jid
Definition: xmpp.h:126
const ast_string_field name
Definition: xmpp.h:123

◆ xmpp_pubsub_request_nodes()

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
Returns
void

Definition at line 4029 of file res_xmpp.c.

References ast_log, ast_xmpp_client_send(), ast_xmpp_client::filter, LOG_ERROR, ast_xmpp_client::mid, ast_xmpp_client::name, request(), xmpp_pubsub_build_node_request(), and xmpp_pubsub_receive_node_list().

Referenced by xmpp_cli_list_pubsub_nodes().

4030 {
4031  iks *request = xmpp_pubsub_build_node_request(client, collection);
4032 
4033  if (!request) {
4034  ast_log(LOG_ERROR, "Could not request pubsub nodes on client '%s' - IQ could not be created\n", client->name);
4035  return;
4036  }
4037 
4038  iks_filter_add_rule(client->filter, xmpp_pubsub_receive_node_list, client, IKS_RULE_TYPE,
4039  IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID, client->mid,
4040  IKS_RULE_DONE);
4041  ast_xmpp_client_send(client, request);
4042  iks_delete(request);
4043 
4044 }
#define ast_log
Definition: astobj2.c:42
static iks * xmpp_pubsub_build_node_request(struct ast_xmpp_client *client, const char *collection)
Build the a node request.
Definition: res_xmpp.c:3977
#define LOG_ERROR
Definition: logger.h:285
static int xmpp_pubsub_receive_node_list(void *data, ikspak *pak)
Receive pubsub item lists.
Definition: res_xmpp.c:4001
iksfilter * filter
Definition: xmpp.h:128
static int request(void *obj)
Definition: chan_pjsip.c:2559
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:2537

◆ xmpp_pubsub_subscribe()

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
Returns
void

Definition at line 1414 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ast_log, ast_test_flag, ast_xmpp_client_send(), globals, ast_xmpp_client::jid, LOG_ERROR, ast_xmpp_client::name, options, ast_xmpp_global_config::pubsub, RAII_VAR, request(), subscribe, xmpp_pubsub_iq_create(), and XMPP_XEP0248.

Referenced by xmpp_init_event_distribution().

1415 {
1417  iks *request = xmpp_pubsub_iq_create(client, "set");
1418  iks *pubsub, *subscribe;
1419 
1420  if (!cfg || !cfg->global || !request) {
1421  ast_log(LOG_ERROR, "Could not create IQ when creating pubsub subscription on client '%s'\n", client->name);
1422  return;
1423  }
1424 
1425  pubsub = iks_insert(request, "pubsub");
1426  iks_insert_attrib(pubsub, "xmlns", "http://jabber.org/protocol/pubsub");
1427  subscribe = iks_insert(pubsub, "subscribe");
1428  iks_insert_attrib(subscribe, "jid", client->jid->partial);
1429  iks_insert_attrib(subscribe, "node", node);
1430  if (ast_test_flag(&cfg->global->pubsub, XMPP_XEP0248)) {
1431  iks *options, *x, *sub_options, *sub_type, *sub_depth, *sub_expire;
1432  options = iks_insert(pubsub, "options");
1433  x = iks_insert(options, "x");
1434  iks_insert_attrib(x, "xmlns", "jabber:x:data");
1435  iks_insert_attrib(x, "type", "submit");
1436  sub_options = iks_insert(x, "field");
1437  iks_insert_attrib(sub_options, "var", "FORM_TYPE");
1438  iks_insert_attrib(sub_options, "type", "hidden");
1439  iks_insert_cdata(iks_insert(sub_options, "value"),
1440  "http://jabber.org/protocol/pubsub#subscribe_options", 51);
1441  sub_type = iks_insert(x, "field");
1442  iks_insert_attrib(sub_type, "var", "pubsub#subscription_type");
1443  iks_insert_cdata(iks_insert(sub_type, "value"), "items", 5);
1444  sub_depth = iks_insert(x, "field");
1445  iks_insert_attrib(sub_depth, "var", "pubsub#subscription_depth");
1446  iks_insert_cdata(iks_insert(sub_depth, "value"), "all", 3);
1447  sub_expire = iks_insert(x, "field");
1448  iks_insert_attrib(sub_expire, "var", "pubsub#expire");
1449  iks_insert_cdata(iks_insert(sub_expire, "value"), "presence", 8);
1450  }
1451  ast_xmpp_client_send(client, request);
1452  iks_delete(request);
1453 }
Definition: test_heap.c:38
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define ast_log
Definition: astobj2.c:42
#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:911
static struct console_pvt globals
#define LOG_ERROR
Definition: logger.h:285
static int request(void *obj)
Definition: chan_pjsip.c:2559
iksid * jid
Definition: xmpp.h:126
const ast_string_field name
Definition: xmpp.h:123
unsigned char subscribe
Definition: res_corosync.c:243
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static struct test_options options
static iks * xmpp_pubsub_iq_create(struct ast_xmpp_client *client, const char *type)
Create an IQ packet.
Definition: res_xmpp.c:1039
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:2537

◆ xmpp_pubsub_unsubscribe()

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
Returns
void

Definition at line 1388 of file res_xmpp.c.

References ast_log, ast_xmpp_client_send(), ast_xmpp_client::jid, LOG_ERROR, ast_xmpp_client::name, ast_xmpp_global_config::pubsub, request(), unsubscribe(), and xmpp_pubsub_iq_create().

Referenced by ast_xmpp_client_disconnect(), and xmpp_init_event_distribution().

1389 {
1390  iks *request = xmpp_pubsub_iq_create(client, "set");
1391  iks *pubsub, *unsubscribe;
1392 
1393  if (!request) {
1394  ast_log(LOG_ERROR, "Could not create IQ when creating pubsub unsubscription on client '%s'\n", client->name);
1395  return;
1396  }
1397 
1398  pubsub = iks_insert(request, "pubsub");
1399  iks_insert_attrib(pubsub, "xmlns", "http://jabber.org/protocol/pubsub");
1400  unsubscribe = iks_insert(pubsub, "unsubscribe");
1401  iks_insert_attrib(unsubscribe, "jid", client->jid->partial);
1402  iks_insert_attrib(unsubscribe, "node", node);
1403 
1404  ast_xmpp_client_send(client, request);
1405  iks_delete(request);
1406 }
Definition: test_heap.c:38
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
static int unsubscribe(void *obj, void *arg, int flags)
static int request(void *obj)
Definition: chan_pjsip.c:2559
iksid * jid
Definition: xmpp.h:126
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:1039
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:2537

◆ xmpp_resource_cmp()

static int xmpp_resource_cmp ( void *  obj,
void *  arg,
int  flags 
)
static

Comparator function for XMPP resource.

Definition at line 847 of file res_xmpp.c.

References CMP_MATCH, CMP_STOP, and ast_xmpp_resource::resource.

Referenced by get_buddy_status(), xmpp_client_create_buddy(), xmpp_client_service_discovery_result_hook(), and xmpp_pak_presence().

848 {
849  struct ast_xmpp_resource *resource1 = obj;
850  const char *resource = arg;
851 
852  return !strcmp(resource1->resource, resource) ? CMP_MATCH | CMP_STOP : 0;
853 }
char resource[XMPP_MAX_RESJIDLEN]
Definition: xmpp.h:93
XMPP Resource.
Definition: xmpp.h:92

◆ xmpp_resource_destructor()

static void xmpp_resource_destructor ( void *  obj)
static

Destructor callback function for XMPP resource.

Definition at line 829 of file res_xmpp.c.

References ast_free, ast_xmpp_resource::description, and ast_xmpp_resource::resource.

Referenced by xmpp_pak_presence().

830 {
831  struct ast_xmpp_resource *resource = obj;
832 
833  if (resource->description) {
834  ast_free(resource->description);
835  }
836 }
char resource[XMPP_MAX_RESJIDLEN]
Definition: xmpp.h:93
XMPP Resource.
Definition: xmpp.h:92
#define ast_free(a)
Definition: astmm.h:182
char * description
Definition: xmpp.h:95

◆ xmpp_resource_hash()

static int xmpp_resource_hash ( const void *  obj,
const int  flags 
)
static

Hashing function for XMPP resource.

Definition at line 839 of file res_xmpp.c.

References OBJ_KEY, ast_xmpp_resource::priority, and ast_xmpp_resource::resource.

Referenced by xmpp_client_create_buddy().

840 {
841  const struct ast_xmpp_resource *resource = obj;
842 
843  return flags & OBJ_KEY ? -1 : resource->priority;
844 }
#define OBJ_KEY
Definition: astobj2.h:1155
char resource[XMPP_MAX_RESJIDLEN]
Definition: xmpp.h:93
XMPP Resource.
Definition: xmpp.h:92
int priority
Definition: xmpp.h:96

◆ xmpp_resource_immediate()

static int xmpp_resource_immediate ( void *  obj,
void *  arg,
int  flags 
)
static

Internal astobj2 callback function which returns the first resource, which is the highest priority one.

Definition at line 1627 of file res_xmpp.c.

References CMP_MATCH, and CMP_STOP.

Referenced by get_buddy_status().

1628 {
1629  return CMP_MATCH | CMP_STOP;
1630 }

◆ xmpp_resource_is_available()

static int xmpp_resource_is_available ( void *  obj,
void *  arg,
int  flags 
)
static

Callback function which returns when the resource is available.

Definition at line 3224 of file res_xmpp.c.

References CMP_MATCH, CMP_STOP, ast_xmpp_resource::resource, and ast_xmpp_resource::status.

Referenced by xmpp_pak_presence().

3225 {
3226  struct ast_xmpp_resource *resource = obj;
3227 
3228  return (resource->status == IKS_SHOW_AVAILABLE) ? CMP_MATCH | CMP_STOP : 0;
3229 }
char resource[XMPP_MAX_RESJIDLEN]
Definition: xmpp.h:93
XMPP Resource.
Definition: xmpp.h:92

◆ xmpp_roster_hook()

static int xmpp_roster_hook ( void *  data,
ikspak *  pak 
)
static

Hook function called when roster is received from server.

Definition at line 2250 of file res_xmpp.c.

References ao2_callback, ao2_cleanup, ao2_find, ao2_global_obj_ref, ao2_ref, ast_log, ast_test_flag, ast_xmpp_client::buddies, globals, item, LOG_ERROR, ast_xmpp_client::name, NULL, OBJ_KEY, OBJ_MULTIPLE, OBJ_NODATA, RAII_VAR, ast_xmpp_buddy::subscribe, XMPP_AUTOPRUNE, XMPP_AUTOREGISTER, xmpp_client_change_state(), xmpp_client_create_buddy(), xmpp_client_subscribe_user(), xmpp_client_unsubscribe_user(), xmpp_config_find(), and XMPP_STATE_CONNECTED.

Referenced by xmpp_connect_hook().

2251 {
2253  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
2254  struct ast_xmpp_client *client = data;
2255  iks *item;
2256 
2257  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name))) {
2258  return IKS_FILTER_EAT;
2259  }
2260 
2261  for (item = iks_child(pak->query); item; item = iks_next(item)) {
2262  struct ast_xmpp_buddy *buddy;
2263 
2264  if (iks_strcmp(iks_name(item), "item")) {
2265  continue;
2266  }
2267 
2268  if (!(buddy = ao2_find(client->buddies, iks_find_attrib(item, "jid"), OBJ_KEY))) {
2269  if (ast_test_flag(&clientcfg->flags, XMPP_AUTOPRUNE)) {
2270  /* The buddy has not been specified in the configuration file, we no longer
2271  * want them on our buddy list or to receive their presence. */
2272  if (xmpp_client_unsubscribe_user(client, iks_find_attrib(item, "jid"))) {
2273  ast_log(LOG_ERROR, "Could not unsubscribe user '%s' on client '%s'\n",
2274  iks_find_attrib(item, "jid"), client->name);
2275  }
2276  continue;
2277  }
2278 
2279  if (!(buddy = xmpp_client_create_buddy(client->buddies, iks_find_attrib(item, "jid")))) {
2280  ast_log(LOG_ERROR, "Could not allocate buddy '%s' on client '%s'\n", iks_find_attrib(item, "jid"),
2281  client->name);
2282  continue;
2283  }
2284  }
2285 
2286  /* Determine if we need to subscribe to their presence or not */
2287  if (!iks_strcmp(iks_find_attrib(item, "subscription"), "none") ||
2288  !iks_strcmp(iks_find_attrib(item, "subscription"), "from")) {
2289  buddy->subscribe = 1;
2290  } else {
2291  buddy->subscribe = 0;
2292  }
2293 
2294  ao2_ref(buddy, -1);
2295  }
2296 
2297  /* If autoregister is enabled we need to go through every buddy that we need to subscribe to and do so */
2298  if (ast_test_flag(&clientcfg->flags, XMPP_AUTOREGISTER)) {
2300  }
2301 
2303 
2304  return IKS_FILTER_EAT;
2305 }
static struct ast_xmpp_buddy * xmpp_client_create_buddy(struct ao2_container *container, const char *id)
Internal function which creates a buddy on a client.
Definition: res_xmpp.c:2166
XMPP Client Configuration.
Definition: res_xmpp.c:444
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.
Definition: res_xmpp.c:2192
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define OBJ_KEY
Definition: astobj2.h:1155
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
static struct aco_type item
Definition: test_config.c:1463
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
XMPP Client Connection.
Definition: xmpp.h:119
#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:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct console_pvt globals
unsigned int subscribe
Definition: xmpp.h:115
#define LOG_ERROR
Definition: logger.h:285
XMPP Buddy.
Definition: xmpp.h:112
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
static int xmpp_client_subscribe_user(void *obj, void *arg, int flags)
Callback function which subscribes to a user if needed.
Definition: res_xmpp.c:2229
const ast_string_field name
Definition: xmpp.h:123
struct ao2_container * buddies
Definition: xmpp.h:137
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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:590

◆ xmpp_send_cb()

static int xmpp_send_cb ( const struct ast_msg msg,
const char *  to,
const char *  from 
)
static

Definition at line 2129 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ast_debug, ast_log, ast_msg_get_body(), ast_strdupa, ast_strlen_zero, ast_xmpp_client_send_message(), globals, LOG_ERROR, LOG_WARNING, NULL, RAII_VAR, strsep(), and xmpp_config_find().

2130 {
2132  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
2133  char *sender, *dest;
2134  int res;
2135 
2136  sender = ast_strdupa(from);
2137  strsep(&sender, ":");
2138  dest = ast_strdupa(to);
2139  strsep(&dest, ":");
2140 
2141  if (ast_strlen_zero(sender)) {
2142  ast_log(LOG_ERROR, "MESSAGE(from) of '%s' invalid for XMPP\n", from);
2143  return -1;
2144  }
2145 
2146  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, sender))) {
2147  ast_log(LOG_WARNING, "Could not finder account to send from as '%s'\n", sender);
2148  return -1;
2149  }
2150 
2151  ast_debug(1, "Sending message to '%s' from '%s'\n", dest, clientcfg->name);
2152 
2153  if ((res = ast_xmpp_client_send_message(clientcfg->client, dest, ast_msg_get_body(msg))) != IKS_OK) {
2154  ast_log(LOG_WARNING, "Failed to send XMPP message (%d).\n", res);
2155  }
2156 
2157  return res == IKS_OK ? 0 : -1;
2158 }
XMPP Client Configuration.
Definition: res_xmpp.c:444
#define LOG_WARNING
Definition: logger.h:274
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
const char * ast_msg_get_body(const struct ast_msg *msg)
Get the body of a message.
Definition: message.c:531
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#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:911
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static struct console_pvt globals
#define LOG_ERROR
Definition: logger.h:285
char * strsep(char **str, const char *delims)
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
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.
Definition: res_xmpp.c:932

◆ xmpp_send_exec()

static int xmpp_send_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 1842 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero, ast_xmpp_client_send_message(), globals, LOG_WARNING, NULL, RAII_VAR, and xmpp_config_find().

Referenced by load_module().

1843 {
1845  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
1846  char *s;
1848  AST_APP_ARG(sender);
1849  AST_APP_ARG(recipient);
1851  );
1852 
1853  if (ast_strlen_zero(data)) {
1854  ast_log(LOG_WARNING, "%s requires arguments (account,jid,message)\n", app_ajisend);
1855  return -1;
1856  }
1857  s = ast_strdupa(data);
1858 
1860 
1861  if ((args.argc < 3) || ast_strlen_zero(args.message) || !strchr(args.recipient, '@')) {
1862  ast_log(LOG_WARNING, "%s requires arguments (account,jid,message)\n", app_ajisend);
1863  return -1;
1864  }
1865 
1866  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, args.sender))) {
1867  ast_log(LOG_WARNING, "Could not find sender connection: '%s'\n", args.sender);
1868  return -1;
1869  }
1870 
1871  ast_xmpp_client_send_message(clientcfg->client, args.recipient, args.message);
1872 
1873  return 0;
1874 }
XMPP Client Configuration.
Definition: res_xmpp.c:444
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:651
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
const char * args
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#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:911
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static struct console_pvt globals
static const char * app_ajisend
Definition: res_xmpp.c:510
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
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.
Definition: res_xmpp.c:932
#define AST_APP_ARG(name)
Define an application argument.

◆ xmpp_send_stream_header()

static int xmpp_send_stream_header ( struct ast_xmpp_client client,
const struct ast_xmpp_client_config cfg,
const char *  to 
)
static

Helper function which sends an XMPP stream header to the server.

Definition at line 2525 of file res_xmpp.c.

References ast_test_flag, ast_xmpp_client_config::flags, xmpp_client_send_raw_message(), and XMPP_COMPONENT.

Referenced by xmpp_client_authenticating(), and xmpp_client_requested_tls().

2526 {
2527  char *namespace = ast_test_flag(&cfg->flags, XMPP_COMPONENT) ? "jabber:component:accept" : "jabber:client";
2528  char msg[91 + strlen(namespace) + 6 + strlen(to) + 16 + 1];
2529 
2530  snprintf(msg, sizeof(msg), "<?xml version='1.0'?>"
2531  "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='"
2532  "%s' to='%s' version='1.0'>", namespace, to);
2533 
2534  return xmpp_client_send_raw_message(client, msg);
2535 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_flags flags
Definition: res_xmpp.c:460
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:2492

◆ xmpp_sendgroup_exec()

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 1883 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero, ast_test_flag, ast_xmpp_chatroom_send(), globals, LOG_ERROR, NULL, RAII_VAR, XMPP_COMPONENT, xmpp_config_find(), and XMPP_MAX_RESJIDLEN.

Referenced by load_module().

1884 {
1886  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
1887  char *s, nick[XMPP_MAX_RESJIDLEN];
1889  AST_APP_ARG(sender);
1890  AST_APP_ARG(groupchat);
1892  AST_APP_ARG(nick);
1893  );
1894 
1895  if (ast_strlen_zero(data)) {
1896  ast_log(LOG_ERROR, "%s requires arguments (sender,groupchatid,message[,nickname])\n", app_ajisendgroup);
1897  return -1;
1898  }
1899  s = ast_strdupa(data);
1900 
1902  if ((args.argc < 3) || (args.argc > 4) || ast_strlen_zero(args.message) || !strchr(args.groupchat, '@')) {
1903  ast_log(LOG_ERROR, "%s requires arguments (sender,groupchatid,message[,nickname])\n", app_ajisendgroup);
1904  return -1;
1905  }
1906 
1907  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, args.sender))) {
1908  ast_log(LOG_ERROR, "Could not find sender connection: '%s'\n", args.sender);
1909  return -1;
1910  }
1911 
1912  if (ast_strlen_zero(args.nick) || args.argc == 3) {
1913  if (ast_test_flag(&clientcfg->flags, XMPP_COMPONENT)) {
1914  snprintf(nick, sizeof(nick), "asterisk");
1915  } else {
1916  snprintf(nick, sizeof(nick), "%s", clientcfg->client->jid->user);
1917  }
1918  } else {
1919  snprintf(nick, sizeof(nick), "%s", args.nick);
1920  }
1921 
1922  ast_xmpp_chatroom_send(clientcfg->client, nick, args.groupchat, args.message);
1923 
1924  return 0;
1925 }
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:1009
XMPP Client Configuration.
Definition: res_xmpp.c:444
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; 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:651
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
const char * args
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
static const char * app_ajisendgroup
Definition: res_xmpp.c:511
#define XMPP_MAX_RESJIDLEN
Maximum size of a resource JID.
Definition: xmpp.h:65
#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:911
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static struct console_pvt globals
#define LOG_ERROR
Definition: logger.h:285
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ xmpp_show_buddies()

static char* xmpp_show_buddies ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 4414 of file res_xmpp.c.

References ao2_cleanup, ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_cli(), ast_xmpp_client::buddies, ast_xmpp_resource::caps, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_xmpp_client_config::client, ast_cli_entry::command, ast_cli_args::fd, globals, ast_xmpp_capabilities::google, ast_xmpp_buddy::id, ast_xmpp_capabilities::jingle, ast_xmpp_client_config::name, ast_xmpp_capabilities::node, NULL, RAII_VAR, ast_xmpp_resource::resource, ast_xmpp_buddy::resources, ast_cli_entry::usage, and ast_xmpp_capabilities::version.

4415 {
4417  struct ao2_iterator i;
4418  struct ast_xmpp_client_config *clientcfg;
4419 
4420  switch (cmd) {
4421  case CLI_INIT:
4422  e->command = "xmpp show buddies";
4423  e->usage =
4424  "Usage: xmpp show buddies\n"
4425  " Shows buddy lists of our clients\n";
4426  return NULL;
4427  case CLI_GENERATE:
4428  return NULL;
4429  }
4430 
4431  if (!cfg || !cfg->clients) {
4432  return NULL;
4433  }
4434 
4435  ast_cli(a->fd, "XMPP buddy lists\n");
4436 
4437  i = ao2_iterator_init(cfg->clients, 0);
4438  while ((clientcfg = ao2_iterator_next(&i))) {
4439  struct ao2_iterator bud;
4440  struct ast_xmpp_buddy *buddy;
4441 
4442  ast_cli(a->fd, "Client: %s\n", clientcfg->name);
4443 
4444  bud = ao2_iterator_init(clientcfg->client->buddies, 0);
4445  while ((buddy = ao2_iterator_next(&bud))) {
4446  struct ao2_iterator res;
4447  struct ast_xmpp_resource *resource;
4448 
4449  ast_cli(a->fd, "\tBuddy:\t%s\n", buddy->id);
4450 
4451  res = ao2_iterator_init(buddy->resources, 0);
4452  while ((resource = ao2_iterator_next(&res))) {
4453  ast_cli(a->fd, "\t\tResource: %s\n", resource->resource);
4454  ast_cli(a->fd, "\t\t\tnode: %s\n", resource->caps.node);
4455  ast_cli(a->fd, "\t\t\tversion: %s\n", resource->caps.version);
4456  ast_cli(a->fd, "\t\t\tGoogle Talk capable: %s\n", resource->caps.google ? "yes" : "no");
4457  ast_cli(a->fd, "\t\t\tJingle capable: %s\n", resource->caps.jingle ? "yes" : "no");
4458 
4459  ao2_ref(resource, -1);
4460  }
4461  ao2_iterator_destroy(&res);
4462 
4463  ao2_ref(buddy, -1);
4464  }
4465  ao2_iterator_destroy(&bud);
4466 
4467  ao2_ref(clientcfg, -1);
4468  }
4470 
4471  return CLI_SUCCESS;
4472 }
XMPP Client Configuration.
Definition: res_xmpp.c:444
char id[XMPP_MAX_JIDLEN]
Definition: xmpp.h:113
Definition: cli.h:152
char resource[XMPP_MAX_RESJIDLEN]
Definition: xmpp.h:93
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
char node[200]
Definition: xmpp.h:85
#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:911
const int fd
Definition: cli.h:159
unsigned int google
Definition: xmpp.h:88
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static struct console_pvt globals
const ast_string_field name
Definition: res_xmpp.c:456
XMPP Resource.
Definition: xmpp.h:92
struct ast_xmpp_client * client
Definition: res_xmpp.c:463
unsigned int jingle
Definition: xmpp.h:87
char version[50]
Definition: xmpp.h:86
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
char * command
Definition: cli.h:186
XMPP Buddy.
Definition: xmpp.h:112
struct ao2_container * resources
Definition: xmpp.h:114
const char * usage
Definition: cli.h:177
struct ao2_container * buddies
Definition: xmpp.h:137
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_xmpp_capabilities caps
Definition: xmpp.h:97
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ xmpp_show_clients()

static char* xmpp_show_clients ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 4338 of file res_xmpp.c.

References ao2_cleanup, ao2_container_count(), ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_xmpp_client_config::client, ast_cli_entry::command, ast_cli_args::fd, globals, ast_xmpp_client_config::name, NULL, RAII_VAR, ast_xmpp_client::state, state, ast_cli_entry::usage, ast_xmpp_client_config::user, XMPP_STATE_AUTHENTICATE, XMPP_STATE_AUTHENTICATING, XMPP_STATE_CONNECTED, XMPP_STATE_CONNECTING, XMPP_STATE_DISCONNECTED, XMPP_STATE_DISCONNECTING, XMPP_STATE_REQUEST_TLS, XMPP_STATE_REQUESTED_TLS, and XMPP_STATE_ROSTER.

4339 {
4341  struct ao2_iterator i;
4342  struct ast_xmpp_client_config *clientcfg;
4343 
4344  switch (cmd) {
4345  case CLI_INIT:
4346  e->command = "xmpp show connections";
4347  e->usage =
4348  "Usage: xmpp show connections\n"
4349  " Shows state of client and component connections\n";
4350  return NULL;
4351  case CLI_GENERATE:
4352  return NULL;
4353  }
4354 
4355  if (!cfg || !cfg->clients) {
4356  return NULL;
4357  }
4358 
4359  ast_cli(a->fd, "Jabber Users and their status:\n");
4360 
4361  i = ao2_iterator_init(cfg->clients, 0);
4362  while ((clientcfg = ao2_iterator_next(&i))) {
4363  char *state;
4364 
4365  switch (clientcfg->client->state) {
4367  state = "Disconnecting";
4368  break;
4370  state = "Disconnected";
4371  break;
4372  case XMPP_STATE_CONNECTING:
4373  state = "Connecting";
4374  break;
4376  state = "Waiting to request TLS";
4377  break;
4379  state = "Requested TLS";
4380  break;
4382  state = "Waiting to authenticate";
4383  break;
4385  state = "Authenticating";
4386  break;
4387  case XMPP_STATE_ROSTER:
4388  state = "Retrieving roster";
4389  break;
4390  case XMPP_STATE_CONNECTED:
4391  state = "Connected";
4392  break;
4393  default:
4394  state = "Unknown";
4395  }
4396 
4397  ast_cli(a->fd, " [%s] %s - %s\n", clientcfg->name, clientcfg->user, state);
4398 
4399  ao2_ref(clientcfg, -1);
4400  }
4402 
4403  ast_cli(a->fd, "----\n");
4404  ast_cli(a->fd, " Number of clients: %d\n", ao2_container_count(cfg->clients));
4405 
4406  return CLI_SUCCESS;
4407 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
XMPP Client Configuration.
Definition: res_xmpp.c:444
Definition: cli.h:152
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#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:911
const int fd
Definition: cli.h:159
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const ast_string_field user
Definition: res_xmpp.c:456
static struct console_pvt globals
const ast_string_field name
Definition: res_xmpp.c:456
enum xmpp_state state
Definition: xmpp.h:136
struct ast_xmpp_client * client
Definition: res_xmpp.c:463
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

Variable Documentation

◆ __mod_info

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

Definition at line 4707 of file res_xmpp.c.

◆ app_ajijoin

const char* app_ajijoin = "JabberJoin"
static

Definition at line 513 of file res_xmpp.c.

◆ app_ajileave

const char* app_ajileave = "JabberLeave"
static

Definition at line 514 of file res_xmpp.c.

◆ app_ajisend

const char* app_ajisend = "JabberSend"
static

Definition at line 510 of file res_xmpp.c.

◆ app_ajisendgroup

const char* app_ajisendgroup = "JabberSendGroup"
static

Definition at line 511 of file res_xmpp.c.

◆ app_ajistatus

const char* app_ajistatus = "JabberStatus"
static

Definition at line 512 of file res_xmpp.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 4707 of file res_xmpp.c.

◆ client_option

struct aco_type client_option
static

Definition at line 804 of file res_xmpp.c.

◆ client_options

struct aco_type* client_options[] = ACO_TYPES(&client_option)

Definition at line 815 of file res_xmpp.c.

◆ debug

int debug
static

◆ global_option

struct aco_type global_option
static

Definition at line 794 of file res_xmpp.c.

◆ global_options

struct aco_type* global_options[] = ACO_TYPES(&global_option)

Definition at line 802 of file res_xmpp.c.

◆ jabberreceive_function

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

Definition at line 2082 of file res_xmpp.c.

◆ jabberstatus_function

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

Definition at line 1710 of file res_xmpp.c.

◆ message_received_condition

ast_cond_t message_received_condition
static

Definition at line 516 of file res_xmpp.c.

◆ messagelock

ast_mutex_t messagelock
static

Definition at line 517 of file res_xmpp.c.

◆ msg_tech

const struct ast_msg_tech msg_tech
static
Initial value:
= {
.name = "xmpp",
.msg_send = xmpp_send_cb,
}
static int xmpp_send_cb(const struct ast_msg *msg, const char *to, const char *from)
Definition: res_xmpp.c:2129

Definition at line 2160 of file res_xmpp.c.

◆ res_xmpp_conf

struct aco_file res_xmpp_conf
Initial value:
= {
.filename = "xmpp.conf",
.alias = "jabber.conf",
}
#define ACO_TYPES(...)
A helper macro to ensure that aco_info types always have a sentinel.
static struct aco_type client_option
Definition: res_xmpp.c:804
static struct aco_type global_option
Definition: res_xmpp.c:794

Definition at line 817 of file res_xmpp.c.

◆ xmpp_cli

struct ast_cli_entry xmpp_cli[]
static

Definition at line 4474 of file res_xmpp.c.

◆ xmpp_pak_handlers

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:3266
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:3395
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:3120

Referenced by xmpp_action_hook().

◆ xmpp_state_handlers

const struct xmpp_state_handler xmpp_state_handlers[]
static

Referenced by xmpp_action_hook().