Asterisk - The Open Source Telephony Project  GIT-master-1f78ee9
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 420 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 1630 of file res_xmpp.c.

Referenced by get_buddy_status().

◆ BUDDY_OFFLINE

#define BUDDY_OFFLINE   6

Definition at line 1629 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 417 of file res_xmpp.c.

◆ RESOURCE_BUCKETS

#define RESOURCE_BUCKETS   53

Number of buckets for resources (per buddy)

Definition at line 423 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 429 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 426 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 395 of file res_xmpp.c.

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

◆ anonymous enum

anonymous enum

Supported pubsub configuration flags.

Enumerator
XMPP_XEP0248 
XMPP_PUBSUB 
XMPP_PUBSUB_AUTOCREATE 

Definition at line 410 of file res_xmpp.c.

410  {
411  XMPP_XEP0248 = (1 << 0),
412  XMPP_PUBSUB = (1 << 1),
413  XMPP_PUBSUB_AUTOCREATE = (1 << 2),
414 };

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 4704 of file res_xmpp.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

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

1934 {
1936  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
1937  char *parse = NULL;
1938  int timeout, jidlen, resourcelen, found = 0;
1939  struct timeval start;
1940  long diff = 0;
1941  struct ast_xmpp_message *message;
1943  AST_APP_ARG(account);
1944  AST_APP_ARG(jid);
1945  AST_APP_ARG(timeout);
1946  );
1948  AST_APP_ARG(screenname);
1949  AST_APP_ARG(resource);
1950  );
1951 
1952  if (ast_strlen_zero(data)) {
1953  ast_log(LOG_WARNING, "%s requires arguments (account,jid[,timeout])\n", name);
1954  return -1;
1955  }
1956 
1957  parse = ast_strdupa(data);
1958  AST_STANDARD_APP_ARGS(args, parse);
1959 
1960  if (args.argc < 2 || args.argc > 3) {
1961  ast_log(LOG_WARNING, "%s requires arguments (account,jid[,timeout])\n", name);
1962  return -1;
1963  }
1964 
1965  parse = ast_strdupa(args.jid);
1966  AST_NONSTANDARD_APP_ARGS(jid, parse, '/');
1967  if (jid.argc < 1 || jid.argc > 2 || strlen(args.jid) > XMPP_MAX_JIDLEN) {
1968  ast_log(LOG_WARNING, "Invalid JID : %s\n", parse);
1969  return -1;
1970  }
1971 
1972  if (ast_strlen_zero(args.timeout)) {
1973  timeout = 20;
1974  } else {
1975  sscanf(args.timeout, "%d", &timeout);
1976  if (timeout <= 0) {
1977  ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
1978  return -1;
1979  }
1980  }
1981 
1982  jidlen = strlen(jid.screenname);
1983  resourcelen = ast_strlen_zero(jid.resource) ? 0 : strlen(jid.resource);
1984 
1985  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, args.account))) {
1986  ast_log(LOG_WARNING, "Could not find client %s, exiting\n", args.account);
1987  return -1;
1988  }
1989 
1990  ast_debug(3, "Waiting for an XMPP message from %s\n", args.jid);
1991 
1992  start = ast_tvnow();
1993 
1994  if (chan && ast_autoservice_start(chan) < 0) {
1995  ast_log(LOG_WARNING, "Cannot start autoservice for channel %s\n", ast_channel_name(chan));
1996  return -1;
1997  }
1998 
1999  /* search the messages list, grab the first message that matches with
2000  * the from JID we're expecting, and remove it from the messages list */
2001  while (diff < timeout) {
2002  struct timespec ts = { 0, };
2003  struct timeval wait;
2004  int res = 0;
2005 
2006  wait = ast_tvadd(start, ast_tv(timeout, 0));
2007  ts.tv_sec = wait.tv_sec;
2008  ts.tv_nsec = wait.tv_usec * 1000;
2009 
2010  /* wait up to timeout seconds for an incoming message */
2012  if (AST_LIST_EMPTY(&clientcfg->client->messages)) {
2014  }
2016  if (res == ETIMEDOUT) {
2017  ast_debug(3, "No message received from %s in %d seconds\n", args.jid, timeout);
2018  break;
2019  }
2020 
2021  AST_LIST_LOCK(&clientcfg->client->messages);
2022  AST_LIST_TRAVERSE_SAFE_BEGIN(&clientcfg->client->messages, message, list) {
2023  if (jid.argc == 1) {
2024  /* no resource provided, compare bare JIDs */
2025  if (strncasecmp(jid.screenname, message->from, jidlen)) {
2026  continue;
2027  }
2028  } else {
2029  /* resource appended, compare bare JIDs and resources */
2030  char *resource = strchr(message->from, '/');
2031  if (!resource || strlen(resource) == 0) {
2032  ast_log(LOG_WARNING, "Remote JID has no resource : %s\n", message->from);
2033  if (strncasecmp(jid.screenname, message->from, jidlen)) {
2034  continue;
2035  }
2036  } else {
2037  resource ++;
2038  if (strncasecmp(jid.screenname, message->from, jidlen) || strncmp(jid.resource, resource, resourcelen)) {
2039  continue;
2040  }
2041  }
2042  }
2043  /* check if the message is not too old */
2044  if (ast_tvdiff_sec(ast_tvnow(), message->arrived) >= clientcfg->message_timeout) {
2045  ast_debug(3, "Found old message from %s, deleting it\n", message->from);
2047  xmpp_message_destroy(message);
2048  continue;
2049  }
2050  found = 1;
2051  ast_copy_string(buf, message->message, buflen);
2053  xmpp_message_destroy(message);
2054  break;
2055  }
2057  AST_LIST_UNLOCK(&clientcfg->client->messages);
2058  if (found) {
2059  break;
2060  }
2061 
2062  /* check timeout */
2063  diff = ast_tvdiff_ms(ast_tvnow(), start);
2064  }
2065 
2066  if (chan && ast_autoservice_stop(chan) < 0) {
2067  ast_log(LOG_WARNING, "Cannot stop autoservice for channel %s\n", ast_channel_name(chan));
2068  }
2069 
2070  /* return if we timed out */
2071  if (!found) {
2072  ast_log(LOG_NOTICE, "Timed out : no message received from %s\n", args.jid);
2073  return -1;
2074  }
2075 
2076  return 0;
2077 }
#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:441
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:648
#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:529
#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:514
static ast_cond_t message_received_condition
Definition: res_xmpp.c:513
#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 1667 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().

1668 {
1670  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
1672  AST_APP_ARG(sender);
1673  AST_APP_ARG(jid);
1674  );
1676  AST_APP_ARG(screenname);
1677  AST_APP_ARG(resource);
1678  );
1679 
1680  if (ast_strlen_zero(data)) {
1681  ast_log(LOG_ERROR, "Usage: JABBER_STATUS(<sender>,<jid>[/<resource>])\n");
1682  return 0;
1683  }
1684  AST_STANDARD_APP_ARGS(args, data);
1685 
1686  if (args.argc != 2) {
1687  ast_log(LOG_ERROR, "JABBER_STATUS requires 2 arguments: sender and jid.\n");
1688  return -1;
1689  }
1690 
1691  AST_NONSTANDARD_APP_ARGS(jid, args.jid, '/');
1692  if (jid.argc < 1 || jid.argc > 2) {
1693  ast_log(LOG_WARNING, "Wrong JID %s, exiting\n", args.jid);
1694  return -1;
1695  }
1696 
1697  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, args.sender))) {
1698  ast_log(LOG_WARNING, "Could not find sender connection: '%s'\n", args.sender);
1699  return -1;
1700  }
1701 
1702  snprintf(buf, buflen, "%d", get_buddy_status(clientcfg, jid.screenname, jid.resource));
1703 
1704  return 0;
1705 }
XMPP Client Configuration.
Definition: res_xmpp.c:441
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:648
#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:1632
#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 4704 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 934 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.

935 {
936  int res = 0;
937  iks *invite, *body = NULL, *namespace = NULL;
938 
939  if (!(invite = iks_new("message")) || !(body = iks_new("body")) || !(namespace = iks_new("x"))) {
940  res = -1;
941  goto done;
942  }
943 
944  iks_insert_attrib(invite, "to", user);
945  ast_xmpp_client_lock(client);
946  iks_insert_attrib(invite, "id", client->mid);
947  ast_xmpp_increment_mid(client->mid);
948  ast_xmpp_client_unlock(client);
949  iks_insert_cdata(body, message, 0);
950  iks_insert_node(invite, body);
951  iks_insert_attrib(namespace, "xmlns", "jabber:x:conference");
952  iks_insert_attrib(namespace, "jid", room);
953  iks_insert_node(invite, namespace);
954 
955  res = ast_xmpp_client_send(client, invite);
956 
957 done:
958  iks_delete(namespace);
959  iks_delete(body);
960  iks_delete(invite);
961 
962  return res;
963 }
void ast_xmpp_increment_mid(char *mid)
Helper function which increments the message identifier.
Definition: res_xmpp.c:1016
void ast_xmpp_client_lock(struct ast_xmpp_client *client)
Lock an XMPP client connection.
Definition: res_xmpp.c:890
#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:895
int ast_xmpp_client_send(struct ast_xmpp_client *client, iks *stanza)
Send an XML stanza out using an established XMPP client connection.
Definition: res_xmpp.c:2534

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

References xmpp_client_set_group_presence().

Referenced by xmpp_join_exec().

1002 {
1003  return xmpp_client_set_group_presence(client, room, IKS_SHOW_AVAILABLE, nickname);
1004 }
static int xmpp_client_set_group_presence(struct ast_xmpp_client *client, const char *room, int level, const char *nick)
Definition: res_xmpp.c:965

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

References xmpp_client_set_group_presence().

Referenced by xmpp_leave_exec().

1012 {
1013  return xmpp_client_set_group_presence(client, room, IKS_SHOW_UNAVAILABLE, nickname);
1014 }
static int xmpp_client_set_group_presence(struct ast_xmpp_client *client, const char *room, int level, const char *nick)
Definition: res_xmpp.c:965

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

References xmpp_client_send_message().

Referenced by xmpp_sendgroup_exec().

1007 {
1008  return xmpp_client_send_message(client, 1, nickname, address, message);
1009 }
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:901

◆ ast_xmpp_client_config_alloc()

static void* ast_xmpp_client_config_alloc ( const char *  cat)
static

Allocator function for configuration.

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

669 {
670  struct ast_xmpp_client_config *cfg;
671 
672  if (!(cfg = ao2_alloc(sizeof(*cfg), ast_xmpp_client_config_destructor))) {
673  return NULL;
674  }
675 
676  if (ast_string_field_init(cfg, 512)) {
677  ao2_ref(cfg, -1);
678  return NULL;
679  }
680 
681  if (!(cfg->client = xmpp_client_find_or_create(cat))) {
682  ao2_ref(cfg, -1);
683  return NULL;
684  }
685 
688  if (!cfg->buddies) {
689  ao2_ref(cfg, -1);
690  return NULL;
691  }
692 
693  ast_string_field_set(cfg, name, cat);
694 
695  return cfg;
696 }
XMPP Client Configuration.
Definition: res_xmpp.c:441
static int xmpp_buddy_cmp(void *obj, void *arg, int flags)
Comparator function for XMPP buddy.
Definition: res_xmpp.c:578
#define NULL
Definition: resample.c:96
#define BUDDY_BUCKETS
Number of buckets for buddies (per client)
Definition: res_xmpp.c:420
#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:520
struct ao2_container * buddies
Definition: res_xmpp.c:461
#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:569
struct ast_xmpp_client * client
Definition: res_xmpp.c:460
#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:654
#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 520 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().

521 {
522  struct ast_xmpp_client_config *cfg = obj;
524  ao2_cleanup(cfg->client);
525  ao2_cleanup(cfg->buddies);
526 }
XMPP Client Configuration.
Definition: res_xmpp.c:441
struct ao2_container * buddies
Definition: res_xmpp.c:461
struct ast_xmpp_client * client
Definition: res_xmpp.c:460
#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 3525 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().

3526 {
3527  if ((client->thread != AST_PTHREADT_NULL) && !pthread_equal(pthread_self(), client->thread)) {
3529  pthread_cancel(client->thread);
3530  pthread_join(client->thread, NULL);
3531  client->thread = AST_PTHREADT_NULL;
3532  }
3533 
3534  if (client->mwi_sub) {
3535  client->mwi_sub = stasis_unsubscribe_and_join(client->mwi_sub);
3536  xmpp_pubsub_unsubscribe(client, "message_waiting");
3537  }
3538 
3539  if (client->device_state_sub) {
3541  xmpp_pubsub_unsubscribe(client, "device_state");
3542  }
3543 
3544 #ifdef HAVE_OPENSSL
3545  if (client->stream_flags & SECURE) {
3546  SSL_shutdown(client->ssl_session);
3547  SSL_CTX_free(client->ssl_context);
3548  SSL_free(client->ssl_session);
3549  }
3550 
3551  client->stream_flags = 0;
3552 #endif
3553 
3554  if (client->parser) {
3555  iks_disconnect(client->parser);
3556  }
3557 
3559 
3560  return 0;
3561 }
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:1132
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:1385
static void xmpp_client_change_state(struct ast_xmpp_client *client, int state)
Internal function which changes the XMPP client state.
Definition: res_xmpp.c:587

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

873 {
875  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
876 
877  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, name))) {
878  return NULL;
879  }
880 
881  ao2_ref(clientcfg->client, +1);
882  return clientcfg->client;
883 }
XMPP Client Configuration.
Definition: res_xmpp.c:441
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:648
#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 890 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().

891 {
892  ao2_lock(client);
893 }
#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 2534 of file res_xmpp.c.

References xmpp_client_send_raw_message().

Referenced by ast_xmpp_chatroom_invite(), jingle_send_error_response(), jingle_send_response(), jingle_send_session_action(), jingle_send_session_info(), jingle_send_session_terminate(), jingle_send_transport_info(), xmpp_client_authenticate_digest(), xmpp_client_authenticate_sasl(), xmpp_client_authenticating(), xmpp_client_send_disco_info_request(), xmpp_client_send_message(), xmpp_client_service_discovery_get_hook(), xmpp_client_set_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().

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

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

930 {
931  return xmpp_client_send_message(client, 0, NULL, user, message);
932 }
#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:901

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

896 {
897  ao2_unlock(client);
898 }
#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 885 of file res_xmpp.c.

References ao2_ref.

Referenced by jingle_endpoint_destructor(), and jingle_session_destructor().

886 {
887  ao2_ref(client, -1);
888 }
#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 1016 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().

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

◆ cached_devstate_cb()

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

Definition at line 1572 of file res_xmpp.c.

References ast_xmpp_client::device_state_sub, and xmpp_pubsub_devstate_cb().

Referenced by xmpp_init_event_distribution().

1573 {
1574  struct stasis_message *msg = obj;
1575  struct ast_xmpp_client *client = arg;
1576  xmpp_pubsub_devstate_cb(client, client->device_state_sub, msg);
1577  return 0;
1578 }
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:1361
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 4526 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().

4527 {
4528  struct ast_xmpp_client_config *cfg = obj;
4529 
4530  if (!strcasecmp(var->name, "debug")) {
4531  ast_set2_flag(&cfg->flags, ast_true(var->value), XMPP_DEBUG);
4532  } else if (!strcasecmp(var->name, "type")) {
4533  ast_set2_flag(&cfg->flags, !strcasecmp(var->value, "component") ? 1 : 0, XMPP_COMPONENT);
4534  } else if (!strcasecmp(var->name, "distribute_events")) {
4536  } else if (!strcasecmp(var->name, "usetls")) {
4537  ast_set2_flag(&cfg->flags, ast_true(var->value), XMPP_USETLS);
4538  } else if (!strcasecmp(var->name, "usesasl")) {
4540  } else if (!strcasecmp(var->name, "forceoldssl")) {
4542  } else if (!strcasecmp(var->name, "keepalive")) {
4544  } else if (!strcasecmp(var->name, "autoprune")) {
4547  } else if (!strcasecmp(var->name, "autoregister")) {
4550  } else if (!strcasecmp(var->name, "auth_policy")) {
4551  ast_set2_flag(&cfg->flags, !strcasecmp(var->value, "accept") ? 1 : 0, XMPP_AUTOACCEPT);
4553  } else if (!strcasecmp(var->name, "sendtodialplan")) {
4555  } else {
4556  return -1;
4557  }
4558 
4559  return 0;
4560 }
XMPP Client Configuration.
Definition: res_xmpp.c:441
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
struct ast_flags flags
Definition: res_xmpp.c:457
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:1821
struct ast_flags mod_flags
Definition: res_xmpp.c:458

◆ client_buddy_handler()

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

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

4592 {
4593  struct ast_xmpp_client_config *cfg = obj;
4594  struct ast_xmpp_buddy *buddy;
4595 
4596  if ((buddy = ao2_find(cfg->buddies, var->value, OBJ_KEY))) {
4597  ao2_ref(buddy, -1);
4598  return -1;
4599  }
4600 
4601  if (!(buddy = xmpp_client_create_buddy(cfg->buddies, var->value))) {
4602  return -1;
4603  }
4604 
4605  ao2_ref(buddy, -1);
4606 
4607  return 0;
4608 }
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:2163
XMPP Client Configuration.
Definition: res_xmpp.c:441
#define OBJ_KEY
Definition: astobj2.h:1155
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ao2_container * buddies
Definition: res_xmpp.c:461
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 4562 of file res_xmpp.c.

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

Referenced by load_module().

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

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

2093 {
2095  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
2096  int deleted = 0, isold = 0;
2097  struct ast_xmpp_message *message = NULL;
2098 
2099  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name))) {
2100  return 0;
2101  }
2102 
2103  AST_LIST_LOCK(&client->messages);
2104  AST_LIST_TRAVERSE_SAFE_BEGIN(&client->messages, message, list) {
2105  if (isold) {
2106  if (!from || !strncasecmp(from, message->from, strlen(from))) {
2108  xmpp_message_destroy(message);
2109  deleted++;
2110  }
2111  } else if (ast_tvdiff_sec(ast_tvnow(), message->arrived) >= clientcfg->message_timeout) {
2112  isold = 1;
2113  if (!from || !strncasecmp(from, message->from, strlen(from))) {
2115  xmpp_message_destroy(message);
2116  deleted++;
2117  }
2118  }
2119  }
2121  AST_LIST_UNLOCK(&client->messages);
2122 
2123  return deleted;
2124 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
XMPP Client Configuration.
Definition: res_xmpp.c:441
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:648
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
int64_t ast_tvdiff_sec(struct timeval end, struct timeval start)
Computes the difference (in seconds) between two struct timeval instances.
Definition: time.h:64
struct ast_xmpp_message::@321 list
struct ast_xmpp_client::@322 messages
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
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:529
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 3824 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().

3825 {
3826  RAII_VAR(char *, cmd, NULL, ast_free);
3827  char cBuf[1024] = "";
3828  const char *url = "https://www.googleapis.com/oauth2/v3/token";
3829  struct ast_json_error error;
3830  RAII_VAR(struct ast_json *, jobj, NULL, ast_json_unref);
3831 
3832  if (ast_asprintf(&cmd,
3833  "CURL(%s,client_id=%s&client_secret=%s&refresh_token=%s&grant_type=refresh_token)",
3834  url, cfg->oauth_clientid, cfg->oauth_secret, cfg->refresh_token) < 0) {
3835  return -1;
3836  }
3837 
3838  ast_debug(2, "Performing OAuth 2.0 authentication for client '%s' using command: %s\n",
3839  cfg->name, cmd);
3840 
3841  if (ast_func_read(NULL, cmd, cBuf, sizeof(cBuf) - 1)) {
3842  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",
3843  cfg->name);
3844  return -1;
3845  }
3846 
3847  ast_debug(2, "OAuth 2.0 authentication for client '%s' returned: %s\n", cfg->name, cBuf);
3848 
3849  jobj = ast_json_load_string(cBuf, &error);
3850  if (jobj) {
3851  const char *token = ast_json_string_get(ast_json_object_get(jobj, "access_token"));
3852  if (token) {
3853  ast_string_field_set(cfg, password, token);
3854  return 0;
3855  }
3856  }
3857 
3858  ast_log(LOG_ERROR, "An error occurred while performing OAuth 2.0 authentication for client '%s': %s\n", cfg->name, cBuf);
3859 
3860  return -1;
3861 }
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:453
#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:453
const ast_string_field oauth_clientid
Definition: res_xmpp.c:453
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:453
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 1632 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().

1633 {
1634  int status = BUDDY_OFFLINE;
1635  struct ast_xmpp_resource *res;
1636  struct ast_xmpp_buddy *buddy = ao2_find(clientcfg->client->buddies, screenname, OBJ_KEY);
1637 
1638  if (!buddy) {
1639  return BUDDY_NOT_IN_ROSTER;
1640  }
1641 
1642  res = ao2_callback(
1643  buddy->resources,
1644  0,
1646  resource);
1647 
1648  if (res) {
1649  status = res->status;
1650  }
1651 
1652  ao2_cleanup(res);
1653  ao2_cleanup(buddy);
1654 
1655  return status;
1656 }
#define BUDDY_NOT_IN_ROSTER
Definition: res_xmpp.c:1630
#define BUDDY_OFFLINE
Definition: res_xmpp.c:1629
#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:1624
XMPP Resource.
Definition: xmpp.h:92
struct ast_xmpp_client * client
Definition: res_xmpp.c:460
#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:844
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 4503 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().

4504 {
4505  struct ast_xmpp_global_config *global = obj;
4506 
4507  if (!strcasecmp(var->name, "debug")) {
4508  debug = ast_true(var->value);
4509  } else if (!strcasecmp(var->name, "autoprune")) {
4511  } else if (!strcasecmp(var->name, "autoregister")) {
4513  } else if (!strcasecmp(var->name, "auth_policy")) {
4514  ast_set2_flag(&global->general, !strcasecmp(var->value, "accept") ? 1 : 0, XMPP_AUTOACCEPT);
4515  } else if (!strcasecmp(var->name, "collection_nodes")) {
4516  ast_set2_flag(&global->pubsub, ast_true(var->value), XMPP_XEP0248);
4517  } else if (!strcasecmp(var->name, "pubsub_autocreate")) {
4519  } else {
4520  return -1;
4521  }
4522 
4523  return 0;
4524 }
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:432
struct ast_flags pubsub
Definition: res_xmpp.c:437
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:1821
struct ast_flags general
Definition: res_xmpp.c:436
XMPP Global Configuration.
Definition: res_xmpp.c:435

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

4621 {
4622  if (aco_info_init(&cfg_info)) {
4623  return AST_MODULE_LOAD_DECLINE;
4624  }
4625 
4627  aco_option_register_custom(&cfg_info, "autoprune", ACO_EXACT, global_options, "no", global_bitfield_handler, 0);
4628  aco_option_register_custom(&cfg_info, "autoregister", ACO_EXACT, global_options, "yes", global_bitfield_handler, 0);
4629  aco_option_register_custom(&cfg_info, "collection_nodes", ACO_EXACT, global_options, "no", global_bitfield_handler, 0);
4630  aco_option_register_custom(&cfg_info, "pubsub_autocreate", ACO_EXACT, global_options, "no", global_bitfield_handler, 0);
4631  aco_option_register_custom(&cfg_info, "auth_policy", ACO_EXACT, global_options, "accept", global_bitfield_handler, 0);
4632 
4635  aco_option_register(&cfg_info, "refresh_token", ACO_EXACT, client_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_xmpp_client_config, refresh_token));
4636  aco_option_register(&cfg_info, "oauth_clientid", ACO_EXACT, client_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_xmpp_client_config, oauth_clientid));
4637  aco_option_register(&cfg_info, "oauth_secret", ACO_EXACT, client_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_xmpp_client_config, oauth_secret));
4638  aco_option_register(&cfg_info, "serverhost", ACO_EXACT, client_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_xmpp_client_config, server));
4639  aco_option_register(&cfg_info, "statusmessage", ACO_EXACT, client_options, "Online and Available", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_xmpp_client_config, statusmsg));
4640  aco_option_register(&cfg_info, "pubsub_node", ACO_EXACT, client_options, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_xmpp_client_config, pubsubnode));
4642  aco_option_register(&cfg_info, "priority", ACO_EXACT, client_options, "1", OPT_UINT_T, 0, FLDSET(struct ast_xmpp_client_config, priority));
4643  aco_option_register(&cfg_info, "port", ACO_EXACT, client_options, "5222", OPT_UINT_T, 0, FLDSET(struct ast_xmpp_client_config, port));
4644  aco_option_register(&cfg_info, "timeout", ACO_EXACT, client_options, "5", OPT_UINT_T, 0, FLDSET(struct ast_xmpp_client_config, message_timeout));
4645 
4646  /* Global options that can be overridden per client must not specify a default */
4650 
4653  aco_option_register_custom(&cfg_info, "distribute_events", ACO_EXACT, client_options, "no", client_bitfield_handler, 0);
4656  aco_option_register_custom(&cfg_info, "forceoldssl", ACO_EXACT, client_options, "no", client_bitfield_handler, 0);
4657  aco_option_register_custom(&cfg_info, "keepalive", ACO_EXACT, client_options, "yes", client_bitfield_handler, 0);
4658  aco_option_register_custom(&cfg_info, "sendtodialplan", ACO_EXACT, client_options, "no", client_bitfield_handler, 0);
4659  aco_option_register_custom(&cfg_info, "status", ACO_EXACT, client_options, "available", client_status_handler, 0);
4661 
4662  if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {
4663  aco_info_destroy(&cfg_info);
4664  return AST_MODULE_LOAD_DECLINE;
4665  }
4666 
4668 
4673 
4678 
4681 
4683  ast_log(LOG_WARNING, "Entity ID is not set. The distributing device state or MWI will not work.\n");
4684  }
4685 
4686  return AST_MODULE_LOAD_SUCCESS;
4687 }
static int global_bitfield_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition: res_xmpp.c:4503
#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:4591
XMPP Client Configuration.
Definition: res_xmpp.c:441
static int manager_jabber_send(struct mansession *s, const struct message *m)
Definition: res_xmpp.c:3924
#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:1778
#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:1532
#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:1707
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:508
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:2157
Type for default option handler for unsigned integers.
struct aco_type * client_options[]
Definition: res_xmpp.c:812
static struct ast_custom_function jabberreceive_function
Definition: res_xmpp.c:2079
Their was an error and no changes were applied.
static struct ast_cli_entry xmpp_cli[]
Definition: res_xmpp.c:4471
static int client_bitfield_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition: res_xmpp.c:4526
static const char * app_ajisend
Definition: res_xmpp.c:507
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:1839
static int xmpp_sendgroup_exec(struct ast_channel *chan, const char *data)
Application to send a message to a groupchat.
Definition: res_xmpp.c:1880
static int client_status_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition: res_xmpp.c:4562
#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:514
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:513
struct aco_type * global_options[]
Definition: res_xmpp.c:799
static const char * app_ajijoin
Definition: res_xmpp.c:510
static int xmpp_join_exec(struct ast_channel *chan, const char *data)
Application to join a chat room.
Definition: res_xmpp.c:1719
Type for default option handler for stringfields.
static const char * app_ajileave
Definition: res_xmpp.c:511
int ast_eid_is_empty(const struct ast_eid *eid)
Check if EID is empty.
Definition: main/utils.c:2717
#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:1504
#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 3924 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().

3925 {
3927  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
3928  const char *id = astman_get_header(m, "ActionID");
3929  const char *jabber = astman_get_header(m, "Jabber");
3930  const char *screenname = astman_get_header(m, "ScreenName");
3931  const char *message = astman_get_header(m, "Message");
3932 
3933  if (ast_strlen_zero(jabber)) {
3934  astman_send_error(s, m, "No transport specified");
3935  return 0;
3936  }
3937  if (ast_strlen_zero(screenname)) {
3938  astman_send_error(s, m, "No ScreenName specified");
3939  return 0;
3940  }
3941  if (ast_strlen_zero(message)) {
3942  astman_send_error(s, m, "No Message specified");
3943  return 0;
3944  }
3945 
3946  astman_send_ack(s, m, "Attempting to send Jabber Message");
3947 
3948  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, jabber))) {
3949  astman_send_error(s, m, "Could not find Sender");
3950  return 0;
3951  }
3952 
3953  if (strchr(screenname, '@') && !ast_xmpp_client_send_message(clientcfg->client, screenname, message)) {
3954  astman_append(s, "Response: Success\r\n");
3955  } else {
3956  astman_append(s, "Response: Error\r\n");
3957  }
3958 
3959  if (!ast_strlen_zero(id)) {
3960  astman_append(s, "ActionID: %s\r\n", id);
3961  }
3962 
3963  astman_append(s, "\r\n");
3964 
3965  return 0;
3966 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3080
XMPP Client Configuration.
Definition: res_xmpp.c:441
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:648
#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:929

◆ reload()

static int reload ( void  )
static

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

4690 {
4691  if (aco_process_config(&cfg_info, 1) == ACO_PROCESS_ERROR) {
4692  return AST_MODULE_LOAD_DECLINE;
4693  }
4694 
4695  return 0;
4696 }
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 3716 of file res_xmpp.c.

References MIN, and NULL.

Referenced by xmpp_client_thread().

3717 {
3718  /* We're OK with our thread dying here */
3719  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
3720 
3721  sleep(*sleep_time);
3722  *sleep_time = MIN(60, *sleep_time * 2);
3723 
3724  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
3725 }
#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 4482 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().

4483 {
4491  ast_manager_unregister("JabberSend");
4494  aco_info_destroy(&cfg_info);
4496 
4499 
4500  return 0;
4501 }
#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:1707
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
static const char * app_ajisendgroup
Definition: res_xmpp.c:508
static const char * app_ajistatus
Definition: res_xmpp.c:509
static const struct ast_msg_tech msg_tech
Definition: res_xmpp.c:2157
static struct console_pvt globals
static struct ast_custom_function jabberreceive_function
Definition: res_xmpp.c:2079
static struct ast_cli_entry xmpp_cli[]
Definition: res_xmpp.c:4471
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:507
int ast_msg_tech_unregister(const struct ast_msg_tech *tech)
Unregister a message technology.
Definition: message.c:1573
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:514
static ast_cond_t message_received_condition
Definition: res_xmpp.c:513
static const char * app_ajijoin
Definition: res_xmpp.c:510
static const char * app_ajileave
Definition: res_xmpp.c:511
#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 3455 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().

3456 {
3458  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
3459  struct ast_xmpp_client *client = data;
3460  ikspak *pak;
3461  int i;
3462 
3463  if (!node) {
3464  ast_log(LOG_ERROR, "xmpp_action_hook was called without a packet\n");
3465  return IKS_HOOK;
3466  }
3467 
3468  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name))) {
3469  return IKS_HOOK;
3470  }
3471 
3472  /* If the client is disconnecting ignore everything */
3473  if (client->state == XMPP_STATE_DISCONNECTING) {
3474  return IKS_HOOK;
3475  }
3476 
3477  pak = iks_packet(node);
3478 
3479  /* work around iksemel's impossibility to recognize node names
3480  * containing a colon. Set the namespace of the corresponding
3481  * node accordingly. */
3482  if (iks_has_children(node) && strchr(iks_name(iks_child(node)), ':')) {
3483  char *node_ns = NULL;
3484  char attr[XMPP_MAX_ATTRLEN];
3485  char *node_name = iks_name(iks_child(node));
3486  char *aux = strchr(node_name, ':') + 1;
3487  snprintf(attr, strlen("xmlns:") + (strlen(node_name) - strlen(aux)), "xmlns:%s", node_name);
3488  node_ns = iks_find_attrib(iks_child(node), attr);
3489  if (node_ns) {
3490  pak->ns = node_ns;
3491  pak->query = iks_child(node);
3492  }
3493  }
3494 
3495  /* Process through any state handlers */
3496  for (i = 0; i < ARRAY_LEN(xmpp_state_handlers); i++) {
3497  if ((xmpp_state_handlers[i].state == client->state) && (xmpp_state_handlers[i].component == (ast_test_flag(&clientcfg->flags, XMPP_COMPONENT) ? 1 : 0))) {
3498  if (xmpp_state_handlers[i].handler(client, clientcfg, type, node)) {
3499  /* If the handler wants us to stop now, do so */
3500  return IKS_HOOK;
3501  }
3502  break;
3503  }
3504  }
3505 
3506  /* Process through any PAK handlers */
3507  for (i = 0; i < ARRAY_LEN(xmpp_pak_handlers); i++) {
3508  if (xmpp_pak_handlers[i].type == pak->type) {
3509  if (xmpp_pak_handlers[i].handler(client, clientcfg, node, pak)) {
3510  /* If the handler wants us to stop now, do so */
3511  return IKS_HOOK;
3512  }
3513  break;
3514  }
3515  }
3516 
3517  /* Send the packet through the filter in case any filters want to process it */
3518  iks_filter_packet(client->filter, pak);
3519 
3520  iks_delete(node);
3521 
3522  return IKS_OK;
3523 }
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:441
#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:648
#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 578 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().

579 {
580  struct ast_xmpp_buddy *buddy1 = obj, *buddy2 = arg;
581  const char *id = arg;
582 
583  return !strcmp(buddy1->id, flags & OBJ_KEY ? id : buddy2->id) ? CMP_MATCH | CMP_STOP : 0;
584 }
#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 853 of file res_xmpp.c.

References ao2_ref, and ast_xmpp_buddy::resources.

Referenced by xmpp_client_create_buddy().

854 {
855  struct ast_xmpp_buddy *buddy = obj;
856 
857  if (buddy->resources) {
858  ao2_ref(buddy->resources, -1);
859  }
860 }
#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 569 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().

570 {
571  const struct ast_xmpp_buddy *buddy = obj;
572  const char *id = obj;
573 
574  return ast_str_hash(flags & OBJ_KEY ? id : buddy->id);
575 }
#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 4219 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().

4220 {
4222  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
4223  const char *name, *collection_name;
4224 
4225  switch (cmd) {
4226  case CLI_INIT:
4227  e->command = "xmpp create collection";
4228  e->usage =
4229  "Usage: xmpp create collection <connection> <collection>\n"
4230  " Creates a PubSub collection node using the account\n"
4231  " as configured in xmpp.conf.\n";
4232  return NULL;
4233  case CLI_GENERATE:
4234  return NULL;
4235  }
4236 
4237  if (a->argc != 5) {
4238  return CLI_SHOWUSAGE;
4239  }
4240  name = a->argv[3];
4241  collection_name = a->argv[4];
4242 
4243  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, name))) {
4244  ast_cli(a->fd, "Unable to find client '%s'!\n", name);
4245  return CLI_FAILURE;
4246  }
4247 
4248  ast_cli(a->fd, "Creating test PubSub node collection.\n");
4249 
4250  xmpp_pubsub_create_collection(clientcfg->client, collection_name);
4251 
4252  return CLI_SUCCESS;
4253 }
static void xmpp_pubsub_create_collection(struct ast_xmpp_client *client, const char *collection_name)
Create a PubSub collection node.
Definition: res_xmpp.c:1239
XMPP Client Configuration.
Definition: res_xmpp.c:441
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:648
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 4259 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().

4260 {
4262  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
4263  const char *name, *collection_name, *leaf_name;
4264 
4265  switch (cmd) {
4266  case CLI_INIT:
4267  e->command = "xmpp create leaf";
4268  e->usage =
4269  "Usage: xmpp create leaf <connection> <collection> <leaf>\n"
4270  " Creates a PubSub leaf node using the account\n"
4271  " as configured in xmpp.conf.\n";
4272  return NULL;
4273  case CLI_GENERATE:
4274  return NULL;
4275  }
4276 
4277  if (a->argc != 6) {
4278  return CLI_SHOWUSAGE;
4279  }
4280  name = a->argv[3];
4281  collection_name = a->argv[4];
4282  leaf_name = a->argv[5];
4283 
4284  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, name))) {
4285  ast_cli(a->fd, "Unable to find client '%s'!\n", name);
4286  return CLI_FAILURE;
4287  }
4288 
4289  ast_cli(a->fd, "Creating test PubSub node collection.\n");
4290 
4291  xmpp_pubsub_create_leaf(clientcfg->client, collection_name, leaf_name);
4292 
4293  return CLI_SUCCESS;
4294 }
XMPP Client Configuration.
Definition: res_xmpp.c:441
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:648
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:1252
#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 4181 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().

4183 {
4185  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
4186  const char *name;
4187 
4188  switch (cmd) {
4189  case CLI_INIT:
4190  e->command = "xmpp delete node";
4191  e->usage =
4192  "Usage: xmpp delete node <connection> <node>\n"
4193  " Deletes a node on PubSub server\n"
4194  " as configured in xmpp.conf.\n";
4195  return NULL;
4196  case CLI_GENERATE:
4197  return NULL;
4198  }
4199 
4200  if (a->argc != 5) {
4201  return CLI_SHOWUSAGE;
4202  }
4203  name = a->argv[3];
4204 
4205  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, name))) {
4206  ast_cli(a->fd, "Unable to find client '%s'!\n", name);
4207  return CLI_FAILURE;
4208  }
4209 
4210  xmpp_pubsub_delete_node(clientcfg->client, a->argv[4]);
4211 
4212  return CLI_SUCCESS;
4213 }
XMPP Client Configuration.
Definition: res_xmpp.c:441
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:648
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:1216

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

4052 {
4054  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
4055  const char *name = NULL, *collection = NULL;
4056 
4057  switch (cmd) {
4058  case CLI_INIT:
4059  e->command = "xmpp list nodes";
4060  e->usage =
4061  "Usage: xmpp list nodes <connection> [collection]\n"
4062  " Lists the user's nodes on the respective connection\n"
4063  " ([connection] as configured in xmpp.conf.)\n";
4064  return NULL;
4065  case CLI_GENERATE:
4066  return NULL;
4067  }
4068 
4069  if (a->argc > 5 || a->argc < 4) {
4070  return CLI_SHOWUSAGE;
4071  } else if (a->argc == 4 || a->argc == 5) {
4072  name = a->argv[3];
4073  }
4074 
4075  if (a->argc == 5) {
4076  collection = a->argv[4];
4077  }
4078 
4079  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, name))) {
4080  ast_cli(a->fd, "Unable to find client '%s'!\n", name);
4081  return CLI_FAILURE;
4082  }
4083 
4084  ast_cli(a->fd, "Listing pubsub nodes.\n");
4085 
4086  xmpp_pubsub_request_nodes(clientcfg->client, collection);
4087 
4088  return CLI_SUCCESS;
4089 }
XMPP Client Configuration.
Definition: res_xmpp.c:441
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:648
static void xmpp_pubsub_request_nodes(struct ast_xmpp_client *client, const char *collection)
Request item list from pubsub.
Definition: res_xmpp.c:4026
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 4136 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.

4138 {
4140  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
4141  const char *name;
4142 
4143  switch (cmd) {
4144  case CLI_INIT:
4145  e->command = "xmpp purge nodes";
4146  e->usage =
4147  "Usage: xmpp purge nodes <connection> <node>\n"
4148  " Purges nodes on PubSub server\n"
4149  " as configured in xmpp.conf.\n";
4150  return NULL;
4151  case CLI_GENERATE:
4152  return NULL;
4153  }
4154 
4155  if (a->argc != 5) {
4156  return CLI_SHOWUSAGE;
4157  }
4158  name = a->argv[3];
4159 
4160  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, name))) {
4161  ast_cli(a->fd, "Unable to find client '%s'!\n", name);
4162  return CLI_FAILURE;
4163  }
4164 
4165  if (ast_test_flag(&cfg->global->pubsub, XMPP_XEP0248)) {
4166  xmpp_pubsub_purge_nodes(clientcfg->client, a->argv[4]);
4167  } else {
4168  xmpp_pubsub_delete_node(clientcfg->client, a->argv[4]);
4169  }
4170 
4171  return CLI_SUCCESS;
4172 }
XMPP Client Configuration.
Definition: res_xmpp.c:441
#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:648
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:4118
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:1216

◆ xmpp_client_alloc()

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

Allocator function for ast_xmpp_client.

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

602 {
603  struct ast_xmpp_client *client;
604 
605  if (!(client = ao2_alloc(sizeof(*client), xmpp_client_destructor))) {
606  return NULL;
607  }
608 
609  AST_LIST_HEAD_INIT(&client->messages);
610  client->thread = AST_PTHREADT_NULL;
611 
612  client->endpoint = ast_endpoint_create("XMPP", name);
613  if (!client->endpoint) {
614  ao2_ref(client, -1);
615  return NULL;
616  }
617 
620  if (!client->buddies) {
621  ast_log(LOG_ERROR, "Could not initialize buddy container for '%s'\n", name);
622  ao2_ref(client, -1);
623  return NULL;
624  }
625 
626  if (ast_string_field_init(client, 512)) {
627  ast_log(LOG_ERROR, "Could not initialize stringfields for '%s'\n", name);
628  ao2_ref(client, -1);
629  return NULL;
630  }
631 
632  if (!(client->stack = iks_stack_new(8192, 8192))) {
633  ast_log(LOG_ERROR, "Could not create an Iksemel stack for '%s'\n", name);
634  ao2_ref(client, -1);
635  return NULL;
636  }
637 
638  ast_string_field_set(client, name, name);
639 
640  client->timeout = 50;
642  ast_copy_string(client->mid, "aaaaa", sizeof(client->mid));
643 
644  return client;
645 }
ikstack * stack
Definition: xmpp.h:129
struct ast_endpoint * ast_endpoint_create(const char *tech, const char *resource)
Create an endpoint struct.
struct ast_xmpp_client::@322 messages
static int xmpp_buddy_cmp(void *obj, void *arg, int flags)
Comparator function for XMPP buddy.
Definition: res_xmpp.c:578
#define NULL
Definition: resample.c:96
#define BUDDY_BUCKETS
Number of buckets for buddies (per client)
Definition: res_xmpp.c:420
#define ast_log
Definition: astobj2.c:42
XMPP Client Connection.
Definition: xmpp.h:119
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define LOG_ERROR
Definition: logger.h:285
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
static int xmpp_buddy_hash(const void *obj, const int flags)
Hashing function for XMPP buddy.
Definition: res_xmpp.c:569
#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:542
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:587
#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 2757 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.

2758 {
2760 }
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:2692
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_flags flags
Definition: res_xmpp.c:457
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:2654

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

2655 {
2656  iks *iq = NULL, *query = NULL;
2657  char buf[41], sidpass[100];
2658 
2659  if (!(iq = iks_new("iq")) || !(query = iks_insert(iq, "query"))) {
2660  ast_log(LOG_ERROR, "Stanzas could not be allocated for authentication on client '%s'\n", client->name);
2661  iks_delete(iq);
2662  return -1;
2663  }
2664 
2665  iks_insert_attrib(iq, "type", "set");
2666  iks_insert_cdata(iks_insert(query, "username"), client->jid->user, 0);
2667  iks_insert_cdata(iks_insert(query, "resource"), client->jid->resource, 0);
2668 
2669  iks_insert_attrib(query, "xmlns", "jabber:iq:auth");
2670  snprintf(sidpass, sizeof(sidpass), "%s%s", iks_find_attrib(node, "id"), cfg->password);
2671  ast_sha1_hash(buf, sidpass);
2672  iks_insert_cdata(iks_insert(query, "digest"), buf, 0);
2673 
2674  ast_xmpp_client_lock(client);
2675  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);
2676  iks_insert_attrib(iq, "id", client->mid);
2677  ast_xmpp_increment_mid(client->mid);
2678  ast_xmpp_client_unlock(client);
2679 
2680  iks_insert_attrib(iq, "to", client->jid->server);
2681 
2682  ast_xmpp_client_send(client, iq);
2683 
2684  iks_delete(iq);
2685 
2687 
2688  return 0;
2689 }
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:1016
const ast_string_field password
Definition: res_xmpp.c:453
void ast_xmpp_client_lock(struct ast_xmpp_client *client)
Lock an XMPP client connection.
Definition: res_xmpp.c:890
#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:895
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:587
int ast_xmpp_client_send(struct ast_xmpp_client *client, iks *stanza)
Send an XML stanza out using an established XMPP client connection.
Definition: res_xmpp.c:2534
static int xmpp_connect_hook(void *data, ikspak *pak)
Hook function called when client finishes authenticating with the server.
Definition: res_xmpp.c:2433

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

2693 {
2694  int features, len = strlen(client->jid->user) + strlen(cfg->password) + 3;
2695  iks *auth;
2696  char combined[len];
2697  char base64[(len + 2) * 4 / 3];
2698 
2699  if (strcmp(iks_name(node), "stream:features")) {
2700  /* Ignore anything beside stream features */
2701  return 0;
2702  }
2703 
2704  features = iks_stream_features(node);
2705 
2706  if ((features & IKS_STREAM_SASL_MD5) && !xmpp_is_secure(client)) {
2707  if (iks_start_sasl(client->parser, IKS_SASL_DIGEST_MD5, (char*)client->jid->user, (char*)cfg->password) != IKS_OK) {
2708  ast_log(LOG_ERROR, "Tried to authenticate client '%s' using SASL DIGEST-MD5 but could not\n", client->name);
2709  return -1;
2710  }
2711 
2713  return 0;
2714  }
2715 
2716  /* Our only other available option is plain so if they don't support it, bail out now */
2717  if (!(features & IKS_STREAM_SASL_PLAIN)) {
2718  ast_log(LOG_ERROR, "Tried to authenticate client '%s' using SASL PLAIN but server does not support it\n", client->name);
2719  return -1;
2720  }
2721 
2722  if (!(auth = iks_new("auth"))) {
2723  ast_log(LOG_ERROR, "Could not allocate memory for SASL PLAIN authentication for client '%s'\n", client->name);
2724  return -1;
2725  }
2726 
2727  iks_insert_attrib(auth, "xmlns", IKS_NS_XMPP_SASL);
2728  if (!ast_strlen_zero(cfg->refresh_token)) {
2729  iks_insert_attrib(auth, "mechanism", "X-OAUTH2");
2730  iks_insert_attrib(auth, "auth:service", "oauth2");
2731  iks_insert_attrib(auth, "xmlns:auth", "http://www.google.com/talk/protocol/auth");
2732  } else {
2733  iks_insert_attrib(auth, "mechanism", "PLAIN");
2734  }
2735 
2736  if (strchr(client->jid->user, '/')) {
2737  char *user = ast_strdupa(client->jid->user);
2738 
2739  snprintf(combined, sizeof(combined), "%c%s%c%s", 0, strsep(&user, "/"), 0, cfg->password);
2740  } else {
2741  snprintf(combined, sizeof(combined), "%c%s%c%s", 0, client->jid->user, 0, cfg->password);
2742  }
2743 
2744  ast_base64encode(base64, (const unsigned char *) combined, len - 1, (len + 2) * 4 / 3);
2745  iks_insert_cdata(auth, base64, 0);
2746 
2747  ast_xmpp_client_send(client, auth);
2748 
2749  iks_delete(auth);
2750 
2752 
2753  return 0;
2754 }
Definition: test_heap.c:38
iksparser * parser
Definition: xmpp.h:127
const ast_string_field password
Definition: res_xmpp.c:453
#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:863
#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:396
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:453
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:587
int ast_xmpp_client_send(struct ast_xmpp_client *client, iks *stanza)
Send an XML stanza out using an established XMPP client connection.
Definition: res_xmpp.c:2534
static 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 2763 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().

2764 {
2765  int features;
2766 
2767  if (!strcmp(iks_name(node), "success")) {
2768  /* Authentication was a success, yay! */
2769  xmpp_send_stream_header(client, cfg, client->jid->server);
2770 
2771  return 0;
2772  } else if (!strcmp(iks_name(node), "failure")) {
2773  /* Authentication was a bust, disconnect and reconnect later */
2774  return -1;
2775  } else if (strcmp(iks_name(node), "stream:features")) {
2776  /* Ignore any other responses */
2777  return 0;
2778  }
2779 
2780  features = iks_stream_features(node);
2781 
2782  if (features & IKS_STREAM_BIND) {
2783  iks *auth;
2784 
2785  if (!(auth = iks_make_resource_bind(client->jid))) {
2786  ast_log(LOG_ERROR, "Failed to allocate memory for stream bind on client '%s'\n", client->name);
2787  return -1;
2788  }
2789 
2790  ast_xmpp_client_lock(client);
2791  iks_insert_attrib(auth, "id", client->mid);
2792  ast_xmpp_increment_mid(client->mid);
2793  ast_xmpp_client_unlock(client);
2794  ast_xmpp_client_send(client, auth);
2795 
2796  iks_delete(auth);
2797 
2798  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);
2799  }
2800 
2801  if (features & IKS_STREAM_SESSION) {
2802  iks *auth;
2803 
2804  if (!(auth = iks_make_session())) {
2805  ast_log(LOG_ERROR, "Failed to allocate memory for stream session on client '%s'\n", client->name);
2806  return -1;
2807  }
2808 
2809  iks_insert_attrib(auth, "id", "auth");
2810  ast_xmpp_client_lock(client);
2811  ast_xmpp_increment_mid(client->mid);
2812  ast_xmpp_client_unlock(client);
2813  ast_xmpp_client_send(client, auth);
2814 
2815  iks_delete(auth);
2816 
2817  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);
2818  }
2819 
2820  return 0;
2821 }
Definition: test_heap.c:38
void ast_xmpp_increment_mid(char *mid)
Helper function which increments the message identifier.
Definition: res_xmpp.c:1016
void ast_xmpp_client_lock(struct ast_xmpp_client *client)
Lock an XMPP client connection.
Definition: res_xmpp.c:890
#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:2522
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:895
int ast_xmpp_client_send(struct ast_xmpp_client *client, iks *stanza)
Send an XML stanza out using an established XMPP client connection.
Definition: res_xmpp.c:2534
static int xmpp_connect_hook(void *data, ikspak *pak)
Hook function called when client finishes authenticating with the server.
Definition: res_xmpp.c:2433

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

588 {
589  if (state == client->state) {
590  return;
591  }
592  client->state = state;
593  if (client->state == XMPP_STATE_DISCONNECTED) {
595  } else if (client->state == XMPP_STATE_CONNECTED) {
597  }
598 }
enum sip_cc_notify_state state
Definition: chan_sip.c:956
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 3808 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().

3809 {
3810  struct ast_xmpp_buddy *buddy1 = obj, *buddy2;
3811  struct ao2_container *buddies = arg;
3812 
3813  /* If the buddy does not already exist link it into the client buddies container */
3814  if (!(buddy2 = ao2_find(buddies, buddy1->id, OBJ_KEY))) {
3815  ao2_link(buddies, buddy1);
3816  } else {
3817  ao2_ref(buddy2, -1);
3818  }
3819 
3820  /* All buddies are unlinked from the configuration buddies container, always */
3821  return 1;
3822 }
#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 3863 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().

3864 {
3865  struct ast_xmpp_client_config *cfg = obj;
3867 
3868  /* Merge global options that have not been modified */
3869  ast_copy_flags(&cfg->flags, &gcfg->global->general, ~(cfg->mod_flags.flags) & (XMPP_AUTOPRUNE | XMPP_AUTOREGISTER | XMPP_AUTOACCEPT));
3870 
3871  /* Merge buddies as need be */
3873 
3874  if (cfg->client->reconnect) {
3875  /* Disconnect the existing session since our role is changing, or we are starting up */
3877 
3878  if (!(cfg->client->parser = iks_stream_new(ast_test_flag(&cfg->flags, XMPP_COMPONENT) ? "jabber:component:accept" : "jabber:client", cfg->client,
3879  xmpp_action_hook))) {
3880  ast_log(LOG_ERROR, "Iksemel stream could not be created for client '%s' - client not active\n", cfg->name);
3881  return -1;
3882  }
3883 
3884  iks_set_log_hook(cfg->client->parser, xmpp_log_hook);
3885 
3886  /* Create a JID based on the given user, if no resource is given use the default */
3887  if (!strchr(cfg->user, '/') && !ast_test_flag(&cfg->flags, XMPP_COMPONENT)) {
3888  char resource[strlen(cfg->user) + strlen("/asterisk-xmpp") + 1];
3889 
3890  snprintf(resource, sizeof(resource), "%s/asterisk-xmpp", cfg->user);
3891  cfg->client->jid = iks_id_new(cfg->client->stack, resource);
3892  } else {
3893  cfg->client->jid = iks_id_new(cfg->client->stack, cfg->user);
3894  }
3895 
3896  if (!cfg->client->jid || (ast_strlen_zero(cfg->client->jid->user) && !ast_test_flag(&cfg->flags, XMPP_COMPONENT))) {
3897  ast_log(LOG_ERROR, "Jabber identity '%s' could not be created for client '%s' - client not active\n", cfg->user, cfg->name);
3898  return -1;
3899  }
3900 
3902 
3903  cfg->client->reconnect = 0;
3904  } else if (cfg->client->state == XMPP_STATE_CONNECTED) {
3905  /* If this client is connected update their presence status since it may have changed */
3906  xmpp_client_set_presence(cfg->client, NULL, cfg->client->jid->full, cfg->status, cfg->statusmsg);
3907 
3908  /* Subscribe to the status of any newly added buddies */
3909  if (ast_test_flag(&cfg->flags, XMPP_AUTOREGISTER)) {
3911  }
3912  }
3913 
3914  return 0;
3915 }
ikstack * stack
Definition: xmpp.h:129
iksparser * parser
Definition: xmpp.h:127
XMPP Client Configuration.
Definition: res_xmpp.c:441
#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:3728
unsigned int flags
Definition: utils.h:200
struct ast_flags flags
Definition: res_xmpp.c:457
#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:3808
#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:2305
#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:453
const ast_string_field statusmsg
Definition: res_xmpp.c:453
static struct console_pvt globals
struct ao2_container * buddies
Definition: res_xmpp.c:461
int ast_xmpp_client_disconnect(struct ast_xmpp_client *client)
Disconnect an XMPP client connection.
Definition: res_xmpp.c:3525
const ast_string_field name
Definition: res_xmpp.c:453
#define LOG_ERROR
Definition: logger.h:285
enum xmpp_state state
Definition: xmpp.h:136
struct ast_xmpp_client * client
Definition: res_xmpp.c:460
#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:2471
static int xmpp_action_hook(void *data, int type, iks *node)
Action hook for when things occur.
Definition: res_xmpp.c:3455
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:2226
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:459
struct ast_flags mod_flags
Definition: res_xmpp.c:458

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

2164 {
2165  struct ast_xmpp_buddy *buddy;
2166 
2167  if (!(buddy = ao2_alloc(sizeof(*buddy), xmpp_buddy_destructor))) {
2168  return NULL;
2169  }
2170 
2173  if (!buddy->resources) {
2174  ao2_ref(buddy, -1);
2175  return NULL;
2176  }
2177 
2178  ast_copy_string(buddy->id, id, sizeof(buddy->id));
2179 
2180  /* Assume we need to subscribe to get their presence until proven otherwise */
2181  buddy->subscribe = 1;
2182 
2183  ao2_link(container, buddy);
2184 
2185  return buddy;
2186 }
static int xmpp_resource_hash(const void *obj, const int flags)
Hashing function for XMPP resource.
Definition: res_xmpp.c:836
#define RESOURCE_BUCKETS
Number of buckets for resources (per buddy)
Definition: res_xmpp.c:423
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:844
static void xmpp_buddy_destructor(void *obj)
Destructor callback function for XMPP buddy.
Definition: res_xmpp.c:853
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 542 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().

543 {
544  struct ast_xmpp_client *client = obj;
545  struct ast_xmpp_message *message;
546 
548 
550  client->endpoint = NULL;
551 
552  if (client->filter) {
553  iks_filter_delete(client->filter);
554  }
555 
556  if (client->stack) {
557  iks_stack_delete(client->stack);
558  }
559 
560  ao2_cleanup(client->buddies);
561 
562  while ((message = AST_LIST_REMOVE_HEAD(&client->messages, list))) {
563  xmpp_message_destroy(message);
564  }
566 }
ikstack * stack
Definition: xmpp.h:129
struct ast_xmpp_message::@321 list
struct ast_xmpp_client::@322 messages
#define NULL
Definition: resample.c:96
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
Definition: linkedlists.h:652
XMPP Client Connection.
Definition: xmpp.h:119
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
int ast_xmpp_client_disconnect(struct ast_xmpp_client *client)
Disconnect an XMPP client connection.
Definition: res_xmpp.c:3525
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:529
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 654 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().

655 {
657  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
658 
659  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, category))) {
660  return xmpp_client_alloc(category);
661  }
662 
663  ao2_ref(clientcfg->client, +1);
664  return clientcfg->client;
665 }
XMPP Client Configuration.
Definition: res_xmpp.c:441
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:648
static struct ast_xmpp_client * xmpp_client_alloc(const char *name)
Allocator function for ast_xmpp_client.
Definition: res_xmpp.c:601
#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 3648 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().

3649 {
3650  int len, ret, pos = 0, newbufpos = 0;
3651  char buf[NET_IO_BUF_SIZE - 1] = "";
3652  char newbuf[NET_IO_BUF_SIZE - 1] = "";
3653  unsigned char c;
3654 
3655  while (1) {
3656  len = xmpp_io_recv(client, buf, NET_IO_BUF_SIZE - 2, timeout);
3657  if (len < 0) return IKS_NET_RWERR;
3658  if (len == 0) return IKS_NET_EXPIRED;
3659  buf[len] = '\0';
3660 
3661  /* our iksemel parser won't work as expected if we feed
3662  it with XML packets that contain multiple whitespace
3663  characters between tags */
3664  while (pos < len) {
3665  c = buf[pos];
3666  /* if we stumble on the ending tag character,
3667  we skip any whitespace that follows it*/
3668  if (c == '>') {
3669  while (isspace(buf[pos+1])) {
3670  pos++;
3671  }
3672  }
3673  newbuf[newbufpos] = c;
3674  newbufpos++;
3675  pos++;
3676  }
3677  pos = 0;
3678  newbufpos = 0;
3679 
3680  /* Log the message here, because iksemel's logHook is
3681  unaccessible */
3682  xmpp_log_hook(client, buf, len, 1);
3683 
3684  if(buf[0] == ' ') {
3685  ast_debug(1, "JABBER: Detected Google Keep Alive. "
3686  "Sending out Ping request for client '%s'\n", client->name);
3687  /* If we just send out the ping here then we will have socket
3688  * read errors because the socket will timeout */
3689  xmpp_ping_request(client, client->jid->server, client->jid->full);
3690  }
3691 
3692  /* let iksemel deal with the string length,
3693  and reset our buffer */
3694  ret = iks_parse(client->parser, newbuf, 0, 0);
3695  memset(newbuf, 0, sizeof(newbuf));
3696 
3697  switch (ret) {
3698  case IKS_NOMEM:
3699  ast_log(LOG_WARNING, "Parsing failure: Out of memory.\n");
3700  break;
3701  case IKS_BADXML:
3702  ast_log(LOG_WARNING, "Parsing failure: Invalid XML.\n");
3703  break;
3704  case IKS_HOOK:
3705  ast_log(LOG_WARNING, "Parsing failure: Hook returned an error.\n");
3706  break;
3707  }
3708  if (ret != IKS_OK) {
3709  return ret;
3710  }
3711  ast_debug(3, "XML parsing successful\n");
3712  }
3713  return IKS_OK;
3714 }
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:3229
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:2471
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:3614
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 3564 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().

3565 {
3566  struct timeval tv = { .tv_sec = 5, .tv_usec = 0 };
3568  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
3569  int res = IKS_NET_NOCONN;
3570 
3571  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name))) {
3572  return -1;
3573  }
3574 
3576 
3577  client->timeout = 50;
3578  iks_parser_reset(client->parser);
3579 
3580  if (!client->filter && !(client->filter = iks_filter_new())) {
3581  ast_log(LOG_ERROR, "Could not create IKS filter for client connection '%s'\n", client->name);
3582  return -1;
3583  }
3584 
3585  if (!ast_strlen_zero(clientcfg->refresh_token)) {
3586  ast_debug(2, "Obtaining OAuth access token for client '%s'\n", client->name);
3587  if (fetch_access_token(clientcfg)) {
3588  return -1;
3589  }
3590  }
3591 
3592  /* If it's a component connect to user otherwise connect to server */
3593  res = iks_connect_via(client->parser, S_OR(clientcfg->server, client->jid->server), clientcfg->port,
3594  ast_test_flag(&clientcfg->flags, XMPP_COMPONENT) ? clientcfg->user : client->jid->server);
3595 
3596  /* Set socket timeout options */
3597  setsockopt(iks_fd(client->parser), SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));
3598 
3599  if (res == IKS_NET_NOCONN) {
3600  ast_log(LOG_ERROR, "No XMPP connection available when trying to connect client '%s'\n", client->name);
3601  return -1;
3602  } else if (res == IKS_NET_NODNS) {
3603  ast_log(LOG_ERROR, "No DNS available for XMPP connection when trying to connect client '%s'\n", client->name);
3604  return -1;
3605  }
3606 
3607  /* Depending on the configuration of the client we eiher jump to requesting TLS, or authenticating */
3609 
3610  return 0;
3611 }
iksparser * parser
Definition: xmpp.h:127
XMPP Client Configuration.
Definition: res_xmpp.c:441
#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:648
#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:3525
#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:587
static int fetch_access_token(struct ast_xmpp_client_config *cfg)
Definition: res_xmpp.c:3824

◆ 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 2540 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.

2541 {
2542  /* If the client connection is already secure we can jump straight to authenticating */
2543  if (xmpp_is_secure(client)) {
2545  return 0;
2546  }
2547 
2548 #ifndef HAVE_OPENSSL
2549  ast_log(LOG_ERROR, "TLS connection for client '%s' cannot be established. OpenSSL is not available.\n", client->name);
2550  return -1;
2551 #else
2552  if (iks_send_raw(client->parser, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>") == IKS_NET_TLSFAIL) {
2553  ast_log(LOG_ERROR, "TLS connection for client '%s' cannot be started.\n", client->name);
2554  return -1;
2555  }
2556 
2557  client->stream_flags |= TRY_SECURE;
2558 
2560 
2561  return 0;
2562 #endif
2563 }
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:863
#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:587

◆ 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 2584 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.

2585 {
2586 #ifdef HAVE_OPENSSL
2587  int sock;
2588  long ssl_opts;
2589  char *err;
2590 #endif
2591 
2592  if (!strcmp(iks_name(node), "success")) {
2593  /* TLS is up and working, we can move on to authenticating now */
2595  return 0;
2596  } else if (!strcmp(iks_name(node), "failure")) {
2597  /* TLS negotiation was a failure, close it on down! */
2598  return -1;
2599  } else if (strcmp(iks_name(node), "proceed")) {
2600  /* Ignore any other responses */
2601  return 0;
2602  }
2603 
2604 #ifndef HAVE_OPENSSL
2605  ast_log(LOG_ERROR, "Somehow we managed to try to start TLS negotiation on client '%s' without OpenSSL support, disconnecting\n", client->name);
2606  return -1;
2607 #else
2608  client->ssl_method = SSLv23_method();
2609  if (!(client->ssl_context = SSL_CTX_new((SSL_METHOD *) client->ssl_method))) {
2610  goto failure;
2611  }
2612 
2613  ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
2614  SSL_CTX_set_options(client->ssl_context, ssl_opts);
2615 
2616  if (!(client->ssl_session = SSL_new(client->ssl_context))) {
2617  goto failure;
2618  }
2619 
2620  sock = iks_fd(client->parser);
2621  if (!SSL_set_fd(client->ssl_session, sock)) {
2622  goto failure;
2623  }
2624 
2625  if (SSL_connect(client->ssl_session) <= 0) {
2626  goto failure;
2627  }
2628 
2629  client->stream_flags &= (~TRY_SECURE);
2630  client->stream_flags |= SECURE;
2631 
2632  if (xmpp_send_stream_header(client, cfg, client->jid->server) != IKS_OK) {
2633  ast_log(LOG_ERROR, "TLS connection for client '%s' could not be established, failed to send stream header after negotiation\n",
2634  client->name);
2635  return -1;
2636  }
2637 
2638  ast_debug(1, "TLS connection for client '%s' started with server\n", client->name);
2639 
2641 
2642  return 0;
2643 
2644 failure:
2645  err = openssl_error_string();
2646  ast_log(LOG_ERROR, "TLS connection for client '%s' cannot be established. "
2647  "OpenSSL initialization failed: %s\n", client->name, err);
2648  ast_free(err);
2649  return -1;
2650 #endif
2651 }
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:2522
#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:587

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

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

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

902 {
904  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
905  int res = 0;
906  char from[XMPP_MAX_JIDLEN];
907  iks *message_packet;
908 
909  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name)) ||
910  !(message_packet = iks_make_msg(group ? IKS_TYPE_GROUPCHAT : IKS_TYPE_CHAT, address, message))) {
911  return -1;
912  }
913 
914  if (!ast_strlen_zero(nick) && ast_test_flag(&clientcfg->flags, XMPP_COMPONENT)) {
915  snprintf(from, sizeof(from), "%s@%s/%s", nick, client->jid->full, nick);
916  } else {
917  snprintf(from, sizeof(from), "%s", client->jid->full);
918  }
919 
920  iks_insert_attrib(message_packet, "from", from);
921 
922  res = ast_xmpp_client_send(client, message_packet);
923 
924  iks_delete(message_packet);
925 
926  return res;
927 }
XMPP Client Configuration.
Definition: res_xmpp.c:441
#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:648
#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:2534

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

2490 {
2491  int ret;
2492 
2493  if (client->state == XMPP_STATE_DISCONNECTED) {
2494  /* iks_send_raw will crash without a connection */
2495  return IKS_NET_NOCONN;
2496  }
2497 
2498 #ifdef HAVE_OPENSSL
2499  if (xmpp_is_secure(client)) {
2500  int len = strlen(message);
2501 
2502  ret = SSL_write(client->ssl_session, message, len);
2503  if (ret) {
2504  /* Log the message here, because iksemel's logHook is
2505  unaccessible */
2506  xmpp_log_hook(client, message, len, 0);
2507  return IKS_OK;
2508  }
2509  }
2510 #endif
2511  /* If needed, data will be sent unencrypted, and logHook will
2512  be called inside iks_send_raw */
2513  ret = iks_send_raw(client->parser, message);
2514  if (ret != IKS_OK) {
2515  return ret;
2516  }
2517 
2518  return IKS_OK;
2519 }
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:863
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:2471

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

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

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

2404 {
2405  struct ast_xmpp_client *client = data;
2406  struct ast_xmpp_buddy *buddy;
2407  struct ast_xmpp_resource *resource;
2408 
2409  if (!(buddy = ao2_find(client->buddies, pak->from->partial, OBJ_KEY))) {
2410  return IKS_FILTER_EAT;
2411  }
2412 
2413  if (!(resource = ao2_callback(buddy->resources, 0, xmpp_resource_cmp, pak->from->resource))) {
2414  ao2_ref(buddy, -1);
2415  return IKS_FILTER_EAT;
2416  }
2417 
2418  ao2_lock(resource);
2419 
2420  if (iks_find_with_attrib(pak->query, "feature", "var", "urn:xmpp:jingle:1")) {
2421  resource->caps.jingle = 1;
2422  }
2423 
2424  ao2_unlock(resource);
2425 
2426  ao2_ref(resource, -1);
2427  ao2_ref(buddy, -1);
2428 
2429  return IKS_FILTER_EAT;
2430 }
#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:844
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 965 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().

966 {
968  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
969  int res = 0;
970  iks *presence = NULL, *x = NULL;
971  char from[XMPP_MAX_JIDLEN], roomid[XMPP_MAX_JIDLEN];
972 
973  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name)) ||
974  !(presence = iks_make_pres(level, NULL)) || !(x = iks_new("x"))) {
975  res = -1;
976  goto done;
977  }
978 
979  if (ast_test_flag(&clientcfg->flags, XMPP_COMPONENT)) {
980  snprintf(from, sizeof(from), "%s@%s/%s", nick, client->jid->full, nick);
981  snprintf(roomid, sizeof(roomid), "%s/%s", room, nick);
982  } else {
983  snprintf(from, sizeof(from), "%s", client->jid->full);
984  snprintf(roomid, sizeof(roomid), "%s/%s", room, S_OR(nick, client->jid->user));
985  }
986 
987  iks_insert_attrib(presence, "to", roomid);
988  iks_insert_attrib(presence, "from", from);
989  iks_insert_attrib(x, "xmlns", "http://jabber.org/protocol/muc");
990  iks_insert_node(presence, x);
991 
992  res = ast_xmpp_client_send(client, presence);
993 
994 done:
995  iks_delete(x);
996  iks_delete(presence);
997 
998  return res;
999 }
XMPP Client Configuration.
Definition: res_xmpp.c:441
#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:648
#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:2534

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

2306 {
2308  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
2309  iks *presence = NULL, *cnode = NULL, *priority = NULL;
2310  char priorityS[10];
2311 
2312  if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name)) ||
2313  !(presence = iks_make_pres(level, desc)) || !(cnode = iks_new("c")) || !(priority = iks_new("priority"))) {
2314  ast_log(LOG_ERROR, "Unable to allocate stanzas for setting presence status for client '%s'\n", client->name);
2315  goto done;
2316  }
2317 
2318  if (!ast_strlen_zero(to)) {
2319  iks_insert_attrib(presence, "to", to);
2320  }
2321 
2322  if (!ast_strlen_zero(from)) {
2323  iks_insert_attrib(presence, "from", from);
2324  }
2325 
2326  snprintf(priorityS, sizeof(priorityS), "%d", clientcfg->priority);
2327  iks_insert_cdata(priority, priorityS, strlen(priorityS));
2328  iks_insert_node(presence, priority);
2329  iks_insert_attrib(cnode, "node", "http://www.asterisk.org/xmpp/client/caps");
2330  iks_insert_attrib(cnode, "ver", "asterisk-xmpp");
2331  iks_insert_attrib(cnode, "ext", "voice-v1 video-v1 camera-v1");
2332  iks_insert_attrib(cnode, "xmlns", "http://jabber.org/protocol/caps");
2333  iks_insert_node(presence, cnode);
2334  ast_xmpp_client_send(client, presence);
2335 
2336 done:
2337  iks_delete(cnode);
2338  iks_delete(presence);
2339  iks_delete(priority);
2340 }
XMPP Client Configuration.
Definition: res_xmpp.c:441
static void * xmpp_config_find(struct ao2_container *tmp_container, const char *category)
Find function for configuration.
Definition: res_xmpp.c:648
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:2534

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

2227 {
2228  struct ast_xmpp_buddy *buddy = obj;
2229  struct ast_xmpp_client *client = arg;
2230 
2231  if (!buddy->subscribe) {
2232  return 0;
2233  }
2234 
2235  if (ast_xmpp_client_send(client, iks_make_s10n(IKS_TYPE_SUBSCRIBE, buddy->id,
2236  "Greetings! I am the Asterisk Open Source PBX and I want to subscribe to your presence\n"))) {
2237  ast_log(LOG_WARNING, "Could not send subscription for '%s' on client '%s'\n",
2238  buddy->id, client->name);
2239  }
2240 
2241  buddy->subscribe = 0;
2242 
2243  return 0;
2244 }
#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:2534

◆ xmpp_client_thread()

static void* xmpp_client_thread ( void *  data)
static

XMPP client connection thread.

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

3729 {
3730  struct ast_xmpp_client *client = data;
3731  int res = IKS_NET_RWERR;
3732  unsigned int sleep_time = 1;
3733 
3734  /* We only allow cancellation while sleeping */
3735  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
3736 
3737  do {
3738  if (client->state == XMPP_STATE_DISCONNECTING) {
3739  ast_debug(1, "[%s] Disconnecting\n", client->name);
3740  break;
3741  }
3742 
3743  if (res == IKS_NET_RWERR || client->timeout == 0) {
3744  ast_debug(3, "[%s] Connecting\n", client->name);
3745  if ((res = xmpp_client_reconnect(client)) != IKS_OK) {
3746  sleep_with_backoff(&sleep_time);
3747  res = IKS_NET_RWERR;
3748  }
3749  continue;
3750  }
3751 
3752  res = xmpp_client_receive(client, 1);
3753 
3754  /* Decrease timeout if no data received, and delete
3755  * old messages globally */
3756  if (res == IKS_NET_EXPIRED) {
3757  client->timeout--;
3758  }
3759 
3760  if (res == IKS_HOOK) {
3761  ast_debug(2, "[%s] Got hook event\n", client->name);
3762  } else if (res == IKS_NET_TLSFAIL) {
3763  ast_log(LOG_ERROR, "[%s] TLS failure\n", client->name);
3764  } else if (!client->timeout && client->state == XMPP_STATE_CONNECTED) {
3766  RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
3767 
3768  if (cfg && cfg->clients) {
3769  clientcfg = xmpp_config_find(cfg->clients, client->name);
3770  }
3771 
3772  if (clientcfg && ast_test_flag(&clientcfg->flags, XMPP_KEEPALIVE)) {
3773  res = xmpp_ping_request(client, client->jid->server, client->jid->full);
3774  } else {
3775  res = IKS_OK;
3776  }
3777 
3778  if (res == IKS_OK) {
3779  client->timeout = 50;
3780  } else {
3781  ast_log(LOG_WARNING, "[%s] Network timeout\n", client->name);
3782  }
3783  } else if (res == IKS_NET_RWERR) {
3784  ast_log(LOG_WARNING, "[%s] Socket read error\n", client->name);
3786  sleep_with_backoff(&sleep_time);
3787  } else if (res == IKS_NET_NOSOCK) {
3788  ast_log(LOG_WARNING, "[%s] No socket\n", client->name);
3789  } else if (res == IKS_NET_NOCONN) {
3790  ast_log(LOG_WARNING, "[%s] No connection\n", client->name);
3791  } else if (res == IKS_NET_NODNS) {
3792  ast_log(LOG_WARNING, "[%s] No DNS\n", client->name);
3793  } else if (res == IKS_NET_NOTSUPP) {
3794  ast_log(LOG_WARNING, "[%s] Not supported\n", client->name);
3795  } else if (res == IKS_NET_DROPPED) {
3796  ast_log(LOG_WARNING, "[%s] Dropped?\n", client->name);
3797  } else if (res == IKS_NET_UNKNOWN) {
3798  ast_debug(5, "[%s] Unknown\n", client->name);
3799  } else if (res == IKS_OK) {
3800  sleep_time = 1;
3801  }
3802 
3803  } while (1);
3804 
3805  return NULL;
3806 }
static void sleep_with_backoff(unsigned int *sleep_time)
Definition: res_xmpp.c:3716
XMPP Client Configuration.
Definition: res_xmpp.c:441
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:3648
#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:648
#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:3564
static struct console_pvt globals
int ast_xmpp_client_disconnect(struct ast_xmpp_client *client)
Disconnect an XMPP client connection.
Definition: