Asterisk - The Open Source Telephony Project  GIT-master-09303e8
Data Structures | Macros | Enumerations | Functions | Variables
res_xmpp.c File Reference

XMPP client and component module. More...

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

Go to the source code of this file.

Data Structures

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

Macros

#define BUDDY_BUCKETS   53
 Number of buckets for buddies (per client) 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 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_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#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:851
#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
#define ast_strlen_zero(a)
Definition: muted.c:73
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_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:851
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.
#define ast_strlen_zero(a)
Definition: muted.c:73
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, stasis_unsubscribe_and_join(), 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
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:1135
pthread_t thread
Definition: xmpp.h:139
static void xmpp_pubsub_unsubscribe(struct ast_xmpp_client *client, const char *node)
Unsubscribe from a PubSub node.
Definition: res_xmpp.c:1388
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:851
#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:1822
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
#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
struct ast_xmpp_message::@323 list
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
struct ast_xmpp_client::@324 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:851
#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:444
#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:851
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
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
#define ast_strlen_zero(a)
Definition: muted.c:73
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:1822
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:2718
#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 RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:851
static struct console_pvt globals
#define ast_strlen_zero(a)
Definition: muted.c:73
#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

◆ 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:851
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:851
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:851
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:851
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:851
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:851
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
#define BUDDY_BUCKETS
Number of buckets for buddies (per client)
Definition: res_xmpp.c:423
#define ast_log
Definition: astobj2.c:42
struct ast_xmpp_client::@324 messages
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:257
#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_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:397
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_strlen_zero(a)
Definition: muted.c:73
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:73

◆ 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:960
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_pthread_create_background(a, b, c, d)
Definition: utils.h:507
#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:851
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
#define ast_strlen_zero(a)
Definition: muted.c:73
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
#define NULL
Definition: resample.c:96
struct ast_xmpp_message::@323 list
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
Definition: linkedlists.h:652
struct ast_xmpp_client::@324 messages
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:851
#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:444
#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_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#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:851
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
#define ast_strlen_zero(a)
Definition: muted.c:73
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_calloc, ast_log, buf, len(), LOG_ERROR, ast_xmpp_client::name, NULL, ast_xmpp_client::parser, 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
#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, ast_xmpp_client::parser, 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
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#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
#define ast_free(a)
Definition: astmm.h:182
iksid * jid
Definition: xmpp.h:126
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_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 RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:851
static struct console_pvt globals
#define XMPP_MAX_JIDLEN
Definition: xmpp.h:62
#define ast_strlen_zero(a)
Definition: muted.c:73
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::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

◆ 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:851
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
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:851
static struct console_pvt globals
#define LOG_ERROR
Definition: logger.h:285
#define ast_strlen_zero(a)
Definition: muted.c:73
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:444
#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:851
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</