Asterisk - The Open Source Telephony Project GIT-master-a358458
Data Structures | Macros | Functions | Variables
main/message.c File Reference

Out-of-call text message support. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include "asterisk/module.h"
#include "asterisk/datastore.h"
#include "asterisk/pbx.h"
#include "asterisk/manager.h"
#include "asterisk/strings.h"
#include "asterisk/astobj2.h"
#include "asterisk/vector.h"
#include "asterisk/app.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/message.h"
Include dependency graph for main/message.c:

Go to the source code of this file.

Data Structures

struct  ast_msg
 A message. More...
 
struct  ast_msg_data
 Structure used to transport a message through the frame core. More...
 
struct  ast_msg_var_iterator
 
struct  msg_data
 
struct  outhead
 

Macros

#define ATTRIBUTE_UNSET   -1
 

Functions

static void __init_msg_q_chan (void)
 
static int action_messagesend (struct mansession *s, const struct message *m)
 
struct ast_msgast_msg_alloc (void)
 Allocate a message. More...
 
struct ast_msg_dataast_msg_data_alloc (enum ast_msg_data_source_type source, struct ast_msg_data_attribute attributes[], size_t count)
 Allocates an ast_msg_data structure. More...
 
struct ast_msg_dataast_msg_data_alloc2 (enum ast_msg_data_source_type source_type, const char *to, const char *from, const char *content_type, const char *body)
 Allocates an ast_msg_data structure. More...
 
struct ast_msg_dataast_msg_data_dup (struct ast_msg_data *msg)
 Clone an ast_msg_data structure. More...
 
const char * ast_msg_data_get_attribute (struct ast_msg_data *msg, enum ast_msg_data_attribute_type attribute_type)
 Get attribute from ast_msg_data. More...
 
size_t ast_msg_data_get_length (struct ast_msg_data *msg)
 Get length of the structure. More...
 
enum ast_msg_data_source_type ast_msg_data_get_source_type (struct ast_msg_data *msg)
 Get "source type" from ast_msg_data. More...
 
int ast_msg_data_queue_frame (struct ast_channel *channel, struct ast_msg_data *msg)
 Queue an AST_FRAME_TEXT_DATA frame containing an ast_msg_data structure. More...
 
struct ast_msgast_msg_destroy (struct ast_msg *msg)
 Destroy an ast_msg. More...
 
const char * ast_msg_get_body (const struct ast_msg *msg)
 Get the body of a message. More...
 
const char * ast_msg_get_endpoint (const struct ast_msg *msg)
 Retrieve the endpoint associated with this message. More...
 
const char * ast_msg_get_from (const struct ast_msg *msg)
 Retrieve the source of this message. More...
 
const char * ast_msg_get_tech (const struct ast_msg *msg)
 Retrieve the technology associated with this message. More...
 
const char * ast_msg_get_to (const struct ast_msg *msg)
 Retrieve the destination of this message. More...
 
const char * ast_msg_get_var (struct ast_msg *msg, const char *name)
 Get the specified variable on the message. More...
 
int ast_msg_handler_register (const struct ast_msg_handler *handler)
 Register a ast_msg_handler. More...
 
int ast_msg_handler_unregister (const struct ast_msg_handler *handler)
 Unregister a ast_msg_handler. More...
 
int ast_msg_has_destination (const struct ast_msg *msg)
 Determine if a particular message has a destination via some handler. More...
 
int ast_msg_init (void)
 
int ast_msg_queue (struct ast_msg *msg)
 Queue a message for routing through the dialplan. More...
 
struct ast_msgast_msg_ref (struct ast_msg *msg)
 Bump a msg's ref count. More...
 
int ast_msg_send (struct ast_msg *msg, const char *to, const char *from)
 Send a msg directly to an endpoint. More...
 
int ast_msg_set_body (struct ast_msg *msg, const char *fmt,...)
 Set the 'body' text of a message (in UTF-8) More...
 
int ast_msg_set_context (struct ast_msg *msg, const char *fmt,...)
 Set the dialplan context for this message. More...
 
int ast_msg_set_endpoint (struct ast_msg *msg, const char *fmt,...)
 Set the technology's endpoint associated with this message. More...
 
int ast_msg_set_exten (struct ast_msg *msg, const char *fmt,...)
 Set the dialplan extension for this message. More...
 
int ast_msg_set_from (struct ast_msg *msg, const char *fmt,...)
 Set the 'from' URI of a message. More...
 
int ast_msg_set_tech (struct ast_msg *msg, const char *fmt,...)
 Set the technology associated with this message. More...
 
int ast_msg_set_to (struct ast_msg *msg, const char *fmt,...)
 Set the 'to' URI of a message. More...
 
int ast_msg_set_var (struct ast_msg *msg, const char *name, const char *value)
 Set a variable on the message going to the dialplan. More...
 
int ast_msg_set_var_outbound (struct ast_msg *msg, const char *name, const char *value)
 Set a variable on the message being sent to a message tech directly. More...
 
void ast_msg_shutdown (void)
 
int ast_msg_tech_register (const struct ast_msg_tech *tech)
 Register a message technology. More...
 
int ast_msg_tech_unregister (const struct ast_msg_tech *tech)
 Unregister a message technology. More...
 
void ast_msg_var_iterator_destroy (struct ast_msg_var_iterator *iter)
 Destroy a message variable iterator. More...
 
static int ast_msg_var_iterator_get_next (const struct ast_msg *msg, struct ast_msg_var_iterator *iter, const char **name, const char **value, unsigned int send)
 
struct ast_msg_var_iteratorast_msg_var_iterator_init (const struct ast_msg *msg)
 Create a new message variable iterator. More...
 
int ast_msg_var_iterator_next (const struct ast_msg *msg, struct ast_msg_var_iterator *iter, const char **name, const char **value)
 Get the next variable name and value that is set for sending outbound. More...
 
int ast_msg_var_iterator_next_received (const struct ast_msg *msg, struct ast_msg_var_iterator *iter, const char **name, const char **value)
 Get the next variable name and value that was set on a received message. More...
 
void ast_msg_var_unref_current (struct ast_msg_var_iterator *iter)
 Unref a message var from inside an iterator loop. More...
 
static void chan_cleanup (struct ast_channel *chan)
 
static int chan_msg_indicate (struct ast_channel *chan, int condition, const void *data, size_t datalen)
 
static struct ast_framechan_msg_read (struct ast_channel *chan)
 
static int chan_msg_send_digit_begin (struct ast_channel *chan, char digit)
 
static int chan_msg_send_digit_end (struct ast_channel *chan, char digit, unsigned int duration)
 
static int chan_msg_write (struct ast_channel *chan, struct ast_frame *fr)
 
static struct ast_channelcreate_msg_q_chan (void)
 
static void destroy_msg_q_chan (void *data)
 
static int dialplan_handle_msg_cb (struct ast_msg *msg)
 
static int dialplan_has_destination_cb (const struct ast_msg *msg)
 
static void message_shutdown (void)
 
static struct msg_datamsg_data_alloc (void)
 
static int msg_data_cmp_fn (void *obj, void *arg, int flags)
 
static void msg_data_destructor (void *obj)
 
static struct msg_datamsg_data_find (struct ao2_container *vars, const char *name)
 
static int msg_data_func_read (struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
 
static int msg_data_func_write (struct ast_channel *chan, const char *function, char *data, const char *value)
 
static struct ast_datastoremsg_datastore_find_or_create (struct ast_channel *chan)
 
static void msg_destructor (void *obj)
 
static void msg_ds_destroy (void *data)
 
static const struct ast_msg_techmsg_find_by_tech_name (const char *tech_name)
 
static int msg_func_read (struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
 
static int msg_func_write (struct ast_channel *chan, const char *function, char *data, const char *value)
 
static int msg_handler_cmp (const struct ast_msg_handler *vec_elem, const struct ast_msg_handler *srch)
 Comparison callback for ast_msg_handler vector removal. More...
 
static const struct ast_msg_handlermsg_handler_find_by_tech_name (const char *tech_name)
 
static int msg_q_cb (void *data)
 
static void msg_route (struct ast_channel *chan, struct ast_msg *msg)
 
static int msg_send_exec (struct ast_channel *chan, const char *data)
 
static int msg_set_var_full (struct ast_msg *msg, const char *name, const char *value, unsigned int outbound)
 
static int msg_tech_cmp (const struct ast_msg_tech *vec_elem, const struct ast_msg_tech *srch)
 Comparison callback for ast_msg_tech vector removal. More...
 

Variables

static const char app_msg_send [] = "MessageSend"
 
static struct ast_msg_handler dialplan_msg_handler
 
static struct ast_channel_tech msg_chan_tech_hack
 
static struct ast_custom_function msg_data_function
 
static const struct ast_datastore_info msg_datastore
 
static struct ast_custom_function msg_function
 
struct {
   size_t   current
 
   const struct ast_msg_handler **   elems
 
   size_t   max
 
msg_handlers
 Vector of received message handlers. More...
 
static ast_rwlock_t msg_handlers_lock
 Lock for msg_handlers vector. More...
 
static struct ast_threadstorage msg_q_chan = { .once = PTHREAD_ONCE_INIT , .key_init = __init_msg_q_chan , .custom_init = NULL , }
 
static struct ast_taskprocessormsg_q_tp
 
struct {
   size_t   current
 
   const struct ast_msg_tech **   elems
 
   size_t   max
 
msg_techs
 Vector of message technologies. More...
 
static ast_rwlock_t msg_techs_lock
 Lock for msg_techs vector. More...
 

Detailed Description

Out-of-call text message support.

Author
Russell Bryant russe.nosp@m.ll@d.nosp@m.igium.nosp@m..com

Definition in file main/message.c.

Macro Definition Documentation

◆ ATTRIBUTE_UNSET

#define ATTRIBUTE_UNSET   -1

Definition at line 1444 of file main/message.c.

Function Documentation

◆ __init_msg_q_chan()

static void __init_msg_q_chan ( void  )
static

Definition at line 863 of file main/message.c.

867{

◆ action_messagesend()

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

Definition at line 1321 of file main/message.c.

1322{
1323 const char *destination = astman_get_header(m, "Destination");
1324 const char *to = astman_get_header(m, "To");
1325 const char *from = astman_get_header(m, "From");
1326 const char *body = astman_get_header(m, "Body");
1327 const char *base64body = astman_get_header(m, "Base64Body");
1328 const char *to_override = NULL;
1329 char base64decoded[1301] = { 0, };
1330 char *tech_name = NULL;
1331 struct ast_variable *vars = NULL;
1332 struct ast_variable *data = NULL;
1333 const struct ast_msg_tech *msg_tech;
1334 struct ast_msg *msg;
1335 int res = -1;
1336
1337 if (!ast_strlen_zero(destination)) {
1338 if (!ast_strlen_zero(to)) {
1339 to_override = to;
1340 }
1341 to = destination;
1342 } else {
1343 if (ast_strlen_zero(to)) {
1344 astman_send_error(s, m, "No 'To' address specified.");
1345 return 0;
1346 }
1347 }
1348
1349 if (!ast_strlen_zero(base64body)) {
1350 ast_base64decode((unsigned char *) base64decoded, base64body, sizeof(base64decoded) - 1);
1351 body = base64decoded;
1352 }
1353
1354 tech_name = ast_strdupa(to);
1355 tech_name = strsep(&tech_name, ":");
1356
1358 msg_tech = msg_find_by_tech_name(tech_name);
1359 if (!msg_tech) {
1361 astman_send_error(s, m, "Message technology not found.");
1362 return 0;
1363 }
1364
1365 if (!(msg = ast_msg_alloc())) {
1367 astman_send_error(s, m, "Internal failure\n");
1368 return 0;
1369 }
1370
1372 for (vars = data; vars; vars = vars->next) {
1373 ast_msg_set_var_outbound(msg, vars->name, vars->value);
1374 }
1375
1376 ast_msg_set_body(msg, "%s", body);
1377
1378 if (to_override) {
1379 ast_string_field_set(msg, to, to_override);
1380 }
1381
1382 res = msg_tech->msg_send(msg, S_OR(to, ""), S_OR(from, ""));
1383
1385
1387 ao2_ref(msg, -1);
1388
1389 if (res) {
1390 astman_send_error(s, m, "Message failed to send.");
1391 } else {
1392 astman_send_ack(s, m, "Message successfully sent");
1393 }
1394 return 0;
1395}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3381
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3413
struct ast_variable * astman_get_variables_order(const struct message *m, enum variable_orders order)
Get a linked list of the Variable: headers with order specified.
Definition: manager.c:3133
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:3042
char * strsep(char **str, const char *delims)
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
#define ast_rwlock_rdlock(a)
Definition: lock.h:235
#define ast_rwlock_unlock(a)
Definition: lock.h:234
static ast_rwlock_t msg_techs_lock
Lock for msg_techs vector.
Definition: main/message.c:269
struct ast_msg * ast_msg_alloc(void)
Allocate a message.
Definition: main/message.c:432
int ast_msg_set_body(struct ast_msg *msg, const char *fmt,...)
Set the 'body' text of a message (in UTF-8)
Definition: main/message.c:490
static const struct ast_msg_tech * msg_find_by_tech_name(const char *tech_name)
int ast_msg_set_var_outbound(struct ast_msg *msg, const char *name, const char *value)
Set a variable on the message being sent to a message tech directly.
Definition: main/message.c:624
@ ORDER_NATURAL
Definition: manager.h:288
static const struct ast_msg_tech msg_tech
#define NULL
Definition: resample.c:96
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
A message technology.
Definition: message.h:52
int(*const msg_send)(const struct ast_msg *msg, const char *to, const char *from)
Send a message.
Definition: message.h:75
A message.
Definition: main/message.c:247
struct ao2_container * vars
Definition: main/message.c:265
const ast_string_field from
Definition: main/message.c:263
const ast_string_field to
Definition: main/message.c:263
const ast_string_field body
Definition: main/message.c:263
Structure for variables, used for configurations and for channel variables.
int ast_base64decode(unsigned char *dst, const char *src, int max)
Decode data from base64.
Definition: utils.c:296

References ao2_ref, ast_base64decode(), ast_msg_alloc(), ast_msg_set_body(), ast_msg_set_var_outbound(), ast_rwlock_rdlock, ast_rwlock_unlock, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_variables_destroy(), astman_get_header(), astman_get_variables_order(), astman_send_ack(), astman_send_error(), ast_msg::body, ast_msg::from, msg_find_by_tech_name(), ast_msg_tech::msg_send, msg_tech, msg_techs_lock, NULL, ORDER_NATURAL, S_OR, strsep(), ast_msg::to, and ast_msg::vars.

Referenced by ast_msg_init().

◆ ast_msg_alloc()

struct ast_msg * ast_msg_alloc ( void  )

Allocate a message.

Allocate a message for the purposes of passing it into the Asterisk core to be routed through the dialplan. If ast_msg_queue() is not called, this message must be destroyed using ast_msg_destroy(). Otherwise, the message core code will take care of it.

Returns
A message object. This function will return NULL if an allocation error occurs.

Definition at line 432 of file main/message.c.

433{
434 struct ast_msg *msg;
435
436 if (!(msg = ao2_alloc(sizeof(*msg), msg_destructor))) {
437 return NULL;
438 }
439
440 if (ast_string_field_init(msg, 128)) {
441 ao2_ref(msg, -1);
442 return NULL;
443 }
444
447 if (!msg->vars) {
448 ao2_ref(msg, -1);
449 return NULL;
450 }
451 ast_string_field_set(msg, context, "default");
452
453 return msg;
454}
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition: astobj2.h:1327
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static void msg_destructor(void *obj)
Definition: main/message.c:424
static int msg_data_cmp_fn(void *obj, void *arg, int flags)
Definition: main/message.c:412
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359

References ao2_alloc, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_list, ao2_ref, ast_string_field_init, ast_string_field_set, voicemailpwcheck::context, msg_data_cmp_fn(), msg_destructor(), NULL, and ast_msg::vars.

Referenced by action_messagesend(), AST_TEST_DEFINE(), module_on_rx_request(), msg_datastore_find_or_create(), send_message(), and xmpp_pak_message().

◆ ast_msg_destroy()

struct ast_msg * ast_msg_destroy ( struct ast_msg msg)

Destroy an ast_msg.

This should only be called on a message if it was not passed on to ast_msg_queue().

Return values
NULLalways.

Definition at line 462 of file main/message.c.

463{
464 ao2_ref(msg, -1);
465 return NULL;
466}

References ao2_ref, and NULL.

Referenced by ast_msg_safe_destroy(), module_on_rx_request(), msg_data_destroy(), send_message(), and xmpp_pak_message().

◆ ast_msg_get_body()

const char * ast_msg_get_body ( const struct ast_msg msg)

Get the body of a message.

Note
The return value is valid only as long as the ast_message is valid. Hold a reference to the message if you plan on storing the return value.
Returns
The body of the messsage, encoded in UTF-8.

Definition at line 545 of file main/message.c.

546{
547 return msg->body;
548}

References ast_msg::body.

Referenced by AST_TEST_DEFINE(), msg_send(), msg_to_json(), and xmpp_send_cb().

◆ ast_msg_get_endpoint()

const char * ast_msg_get_endpoint ( const struct ast_msg msg)

Retrieve the endpoint associated with this message.

Since
12.5.0
Parameters
msgThe message to get the endpoint from
Returns
The endpoint associated with the message
Return values
NULLor empty string if the message has no associated endpoint

Definition at line 565 of file main/message.c.

566{
567 return msg->endpoint;
568}
const ast_string_field endpoint
Definition: main/message.c:263

References ast_msg::endpoint.

Referenced by AST_TEST_DEFINE(), and msg_to_endpoint().

◆ ast_msg_get_from()

const char * ast_msg_get_from ( const struct ast_msg msg)

Retrieve the source of this message.

Since
12.5.0
Parameters
msgThe message to get the soure from
Returns
The source of the message
Return values
NULLor empty string if the message has no source

Definition at line 550 of file main/message.c.

551{
552 return msg->from;
553}

References ast_msg::from.

Referenced by AST_TEST_DEFINE(), msg_send(), and msg_to_json().

◆ ast_msg_get_tech()

const char * ast_msg_get_tech ( const struct ast_msg msg)

Retrieve the technology associated with this message.

Since
12.5.0
Parameters
msgThe message to get the technology from
Returns
The technology of the message
Return values
NULLor empty string if the message has no associated technology

Definition at line 560 of file main/message.c.

561{
562 return msg->tech;
563}
const ast_string_field tech
Definition: main/message.c:263

References ast_msg::tech.

Referenced by AST_TEST_DEFINE(), and msg_to_endpoint().

◆ ast_msg_get_to()

const char * ast_msg_get_to ( const struct ast_msg msg)

Retrieve the destination of this message.

Since
12.5.0
Parameters
msgThe message to get the destination from
Returns
The destination of the message
Return values
NULLor empty string if the message has no destination

Definition at line 555 of file main/message.c.

556{
557 return msg->to;
558}

References ast_msg::to.

Referenced by AST_TEST_DEFINE(), msg_send(), msg_to_json(), and test_msg_has_destination_cb().

◆ ast_msg_get_var()

const char * ast_msg_get_var ( struct ast_msg msg,
const char *  name 
)

Get the specified variable on the message.

Note
The return value is valid only as long as the ast_message is valid. Hold a reference to the message if you plan on storing the return value. Do re-set the same message var name while holding a pointer to the result of this function.
Returns
The value associated with variable "name". NULL if variable not found.

Definition at line 634 of file main/message.c.

635{
636 struct msg_data *data;
637 const char *val = NULL;
638
639 if (!(data = msg_data_find(msg->vars, name))) {
640 return NULL;
641 }
642
643 /* Yep, this definitely looks like val would be a dangling pointer
644 * after the ref count is decremented. As long as the message structure
645 * is used in a thread safe manner, this will not be the case though.
646 * The ast_msg holds a reference to this object in the msg->vars container. */
647 val = data->value;
648 ao2_ref(data, -1);
649
650 return val;
651}
static const char name[]
Definition: format_mp3.c:68
static struct msg_data * msg_data_find(struct ao2_container *vars, const char *name)
Definition: main/message.c:586
struct ast_msg * msg
const ast_string_field value
Definition: main/message.c:238
Definition: ast_expr2.c:325

References ao2_ref, msg_data::msg, msg_data_find(), name, NULL, msg_data::value, and ast_msg::vars.

Referenced by AST_TEST_DEFINE(), msg_data_func_read(), and update_content_type().

◆ ast_msg_handler_register()

int ast_msg_handler_register ( const struct ast_msg_handler handler)

Register a ast_msg_handler.

Since
12.5.0
Parameters
handlerThe handler to register
Return values
0Success
non-zeroError

Definition at line 1657 of file main/message.c.

1658{
1659 const struct ast_msg_handler *match;
1660
1662
1664 if (match) {
1665 ast_log(LOG_ERROR, "Message handler already registered for '%s'\n",
1666 handler->name);
1668 return -1;
1669 }
1670
1672 ast_log(LOG_ERROR, "Failed to register message handler for '%s'\n",
1673 handler->name);
1675 return -1;
1676 }
1677 ast_verb(5, "Message handler '%s' registered.\n", handler->name);
1678
1680
1681 return 0;
1682
1683}
#define ast_log
Definition: astobj2.c:42
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2362
#define LOG_ERROR
#define ast_verb(level,...)
#define ast_rwlock_wrlock(a)
Definition: lock.h:236
static const struct ast_msg_handler * msg_handler_find_by_tech_name(const char *tech_name)
static ast_rwlock_t msg_handlers_lock
Lock for msg_handlers vector.
Definition: main/message.c:275
struct @374 msg_handlers
Vector of received message handlers.
An external processor of received messages.
Definition: message.h:98
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
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256

References ast_log, ast_rwlock_unlock, ast_rwlock_wrlock, AST_VECTOR_APPEND, ast_verb, handler(), LOG_ERROR, match(), msg_handler_find_by_tech_name(), msg_handlers, and msg_handlers_lock.

Referenced by ast_msg_init(), AST_TEST_DEFINE(), and messaging_init().

◆ ast_msg_handler_unregister()

int ast_msg_handler_unregister ( const struct ast_msg_handler handler)

Unregister a ast_msg_handler.

Since
12.5.0
Parameters
handlerThe handler to unregister
Return values
0Success
non-zeroError

Definition at line 1699 of file main/message.c.

1700{
1701 int match;
1702
1707
1708 if (match) {
1709 ast_log(LOG_ERROR, "No '%s' message handler found.\n", handler->name);
1710 return -1;
1711 }
1712
1713 ast_verb(5, "Message handler '%s' unregistered.\n", handler->name);
1714 return 0;
1715}
static int msg_handler_cmp(const struct ast_msg_handler *vec_elem, const struct ast_msg_handler *srch)
Comparison callback for ast_msg_handler vector removal.
#define AST_VECTOR_ELEM_CLEANUP_NOOP(elem)
Vector element cleanup that does nothing.
Definition: vector.h:571
#define AST_VECTOR_REMOVE_CMP_UNORDERED(vec, value, cmp, cleanup)
Remove an element from a vector that matches the given comparison.
Definition: vector.h:488

References ast_log, ast_rwlock_unlock, ast_rwlock_wrlock, AST_VECTOR_ELEM_CLEANUP_NOOP, AST_VECTOR_REMOVE_CMP_UNORDERED, ast_verb, handler(), LOG_ERROR, match(), msg_handler_cmp(), msg_handlers, and msg_handlers_lock.

Referenced by AST_TEST_DEFINE(), message_shutdown(), and messaging_cleanup().

◆ ast_msg_has_destination()

int ast_msg_has_destination ( const struct ast_msg msg)

Determine if a particular message has a destination via some handler.

Since
12.5.0
Parameters
msgThe message to check
Return values
0if the message has no handler that can find a destination
1if the message has a handler that can find a destination

Definition at line 951 of file main/message.c.

952{
953 int i;
954 int result = 0;
955
957 for (i = 0; i < AST_VECTOR_SIZE(&msg_handlers); i++) {
959
960 ast_debug(5, "Seeing if %s can handle message\n", handler->name);
961 if (handler->has_destination(msg)) {
962 ast_debug(5, "%s can handle message\n", handler->name);
963 result = 1;
964 break;
965 }
966 }
968
969 return result;
970}
static PGresult * result
Definition: cel_pgsql.c:84
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680

References ast_debug, ast_rwlock_rdlock, ast_rwlock_unlock, AST_VECTOR_GET, AST_VECTOR_SIZE, handler(), msg_handlers, msg_handlers_lock, and result.

Referenced by AST_TEST_DEFINE(), and module_on_rx_request().

◆ ast_msg_init()

int ast_msg_init ( void  )

Provided by message.c

Definition at line 1758 of file main/message.c.

1759{
1760 int res;
1761
1763 if (!msg_q_tp) {
1764 return -1;
1765 }
1766
1768 if (AST_VECTOR_INIT(&msg_techs, 8)) {
1769 return -1;
1770 }
1771
1773 if (AST_VECTOR_INIT(&msg_handlers, 4)) {
1774 return -1;
1775 }
1776
1778
1783
1785
1786 return res;
1787}
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
#define ast_rwlock_init(rwlock)
wrapper for rwlock with tracking enabled
Definition: lock.h:224
static const char app_msg_send[]
Definition: main/message.c:282
static struct ast_msg_handler dialplan_msg_handler
Definition: main/message.c:906
struct @373 msg_techs
Vector of message technologies.
static struct ast_custom_function msg_function
Definition: main/message.c:296
static struct ast_taskprocessor * msg_q_tp
Definition: main/message.c:280
static void message_shutdown(void)
int ast_msg_handler_register(const struct ast_msg_handler *handler)
Register a ast_msg_handler.
static int msg_send_exec(struct ast_channel *chan, const char *data)
static int action_messagesend(struct mansession *s, const struct message *m)
static struct ast_custom_function msg_data_function
Definition: main/message.c:307
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:202
#define EVENT_FLAG_MESSAGE
Definition: manager.h:95
int ast_register_application2(const char *app, int(*execute)(struct ast_channel *, const char *), const char *synopsis, const char *description, void *mod)
Register an application.
Definition: pbx_app.c:103
int __ast_custom_function_register(struct ast_custom_function *acf, struct ast_module *mod)
Register a custom function.
struct ast_taskprocessor * ast_taskprocessor_get(const char *name, enum ast_tps_options create)
Get a reference to a taskprocessor with the specified name and create the taskprocessor if necessary.
@ TPS_REF_DEFAULT
return a reference to a taskprocessor, create one if it does not exist
Definition: taskprocessor.h:76
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113

References __ast_custom_function_register(), action_messagesend(), app_msg_send, ast_manager_register_xml_core, ast_msg_handler_register(), ast_register_application2(), ast_register_cleanup(), ast_rwlock_init, ast_taskprocessor_get(), AST_VECTOR_INIT, dialplan_msg_handler, EVENT_FLAG_MESSAGE, message_shutdown(), msg_data_function, msg_function, msg_handlers, msg_handlers_lock, msg_q_tp, msg_send_exec(), msg_techs, msg_techs_lock, NULL, and TPS_REF_DEFAULT.

Referenced by asterisk_daemon().

◆ ast_msg_queue()

int ast_msg_queue ( struct ast_msg msg)

Queue a message for routing through the dialplan.

Regardless of the return value of this function, this funciton will take care of ensuring that the message object is properly destroyed when needed.

Return values
0message successfully queued
non-zerofailure, message not sent to dialplan

Definition at line 972 of file main/message.c.

973{
974 int res;
976 if (res == -1) {
977 ao2_ref(msg, -1);
978 }
979
980 return res;
981}
static int msg_q_cb(void *data)
Definition: main/message.c:921
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap) attribute_warn_unused_result
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.

References ao2_ref, ast_taskprocessor_push(), msg_q_cb(), and msg_q_tp.

Referenced by AST_TEST_DEFINE(), module_on_rx_request(), and xmpp_pak_message().

◆ ast_msg_ref()

struct ast_msg * ast_msg_ref ( struct ast_msg msg)

Bump a msg's ref count.

Definition at line 456 of file main/message.c.

457{
458 ao2_ref(msg, 1);
459 return msg;
460}

References ao2_ref.

Referenced by msg_data_create().

◆ ast_msg_send()

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

Send a msg directly to an endpoint.

Regardless of the return value of this function, this funciton will take care of ensuring that the message object is properly destroyed when needed.

Return values
0message successfully queued to be sent out
non-zerofailure, message not get sent out.

Definition at line 1397 of file main/message.c.

1398{
1399 char *tech_name = NULL;
1400 const struct ast_msg_tech *msg_tech;
1401 int res = -1;
1402
1403 if (ast_strlen_zero(to)) {
1404 ao2_ref(msg, -1);
1405 return -1;
1406 }
1407
1408 tech_name = ast_strdupa(to);
1409 tech_name = strsep(&tech_name, ":");
1410
1412 msg_tech = msg_find_by_tech_name(tech_name);
1413
1414 if (!msg_tech) {
1415 ast_log(LOG_ERROR, "Unknown message tech: %s\n", tech_name);
1417 return -1;
1418 }
1419
1420 res = msg_tech->msg_send(msg, S_OR(to, ""), S_OR(from, ""));
1421
1423
1424 ao2_ref(msg, -1);
1425
1426 return res;
1427}

References ao2_ref, ast_log, ast_rwlock_rdlock, ast_rwlock_unlock, ast_strdupa, ast_strlen_zero(), LOG_ERROR, msg_find_by_tech_name(), ast_msg_tech::msg_send, msg_tech, msg_techs_lock, NULL, S_OR, and strsep().

Referenced by AST_TEST_DEFINE(), and send_message().

◆ ast_msg_set_body()

int ast_msg_set_body ( struct ast_msg msg,
const char *  fmt,
  ... 
)

Set the 'body' text of a message (in UTF-8)

Return values
0success
-1failure

Definition at line 490 of file main/message.c.

491{
492 va_list ap;
493
494 va_start(ap, fmt);
495 ast_string_field_build_va(msg, body, fmt, ap);
496 va_end(ap);
497
498 return 0;
499}
#define ast_string_field_build_va(x, field, fmt, args)
Set a field to a complex (built) value.
Definition: stringfields.h:591

References ast_string_field_build_va, and ast_msg::body.

Referenced by action_messagesend(), AST_TEST_DEFINE(), msg_func_write(), rx_data_to_ast_msg(), send_message(), and xmpp_pak_message().

◆ ast_msg_set_context()

int ast_msg_set_context ( struct ast_msg msg,
const char *  fmt,
  ... 
)

Set the dialplan context for this message.

Return values
0success
-1failure

Definition at line 501 of file main/message.c.

502{
503 va_list ap;
504
505 va_start(ap, fmt);
506 ast_string_field_build_va(msg, context, fmt, ap);
507 va_end(ap);
508
509 return 0;
510}

References ast_string_field_build_va, and voicemailpwcheck::context.

Referenced by AST_TEST_DEFINE(), rx_data_to_ast_msg(), and xmpp_pak_message().

◆ ast_msg_set_endpoint()

int ast_msg_set_endpoint ( struct ast_msg msg,
const char *  fmt,
  ... 
)

Set the technology's endpoint associated with this message.

Since
12.5.0
Return values
0success
-1failure

Definition at line 534 of file main/message.c.

535{
536 va_list ap;
537
538 va_start(ap, fmt);
539 ast_string_field_build_va(msg, endpoint, fmt, ap);
540 va_end(ap);
541
542 return 0;
543}

References ast_string_field_build_va, and ast_msg::endpoint.

Referenced by AST_TEST_DEFINE(), rx_data_to_ast_msg(), and xmpp_pak_message().

◆ ast_msg_set_exten()

int ast_msg_set_exten ( struct ast_msg msg,
const char *  fmt,
  ... 
)

Set the dialplan extension for this message.

Return values
0success
-1failure

Definition at line 512 of file main/message.c.

513{
514 va_list ap;
515
516 va_start(ap, fmt);
517 ast_string_field_build_va(msg, exten, fmt, ap);
518 va_end(ap);
519
520 return 0;
521}

References ast_string_field_build_va, and ast_msg::exten.

Referenced by AST_TEST_DEFINE(), and rx_data_to_ast_msg().

◆ ast_msg_set_from()

int ast_msg_set_from ( struct ast_msg msg,
const char *  fmt,
  ... 
)

Set the 'from' URI of a message.

Return values
0success
-1failure

Definition at line 479 of file main/message.c.

480{
481 va_list ap;
482
483 va_start(ap, fmt);
484 ast_string_field_build_va(msg, from, fmt, ap);
485 va_end(ap);
486
487 return 0;
488}

References ast_string_field_build_va, and ast_msg::from.

Referenced by AST_TEST_DEFINE(), msg_func_write(), rx_data_to_ast_msg(), send_message(), and xmpp_pak_message().

◆ ast_msg_set_tech()

int ast_msg_set_tech ( struct ast_msg msg,
const char *  fmt,
  ... 
)

Set the technology associated with this message.

Since
12.5.0
Return values
0success
-1failure

Definition at line 523 of file main/message.c.

524{
525 va_list ap;
526
527 va_start(ap, fmt);
528 ast_string_field_build_va(msg, tech, fmt, ap);
529 va_end(ap);
530
531 return 0;
532}

References ast_string_field_build_va, and ast_msg::tech.

Referenced by AST_TEST_DEFINE(), rx_data_to_ast_msg(), and xmpp_pak_message().

◆ ast_msg_set_to()

int ast_msg_set_to ( struct ast_msg msg,
const char *  fmt,
  ... 
)

Set the 'to' URI of a message.

Return values
0success
-1failure

Definition at line 468 of file main/message.c.

469{
470 va_list ap;
471
472 va_start(ap, fmt);
473 ast_string_field_build_va(msg, to, fmt, ap);
474 va_end(ap);
475
476 return 0;
477}

References ast_string_field_build_va, and ast_msg::to.

Referenced by AST_TEST_DEFINE(), msg_func_write(), rx_data_to_ast_msg(), send_message(), and xmpp_pak_message().

◆ ast_msg_set_var()

int ast_msg_set_var ( struct ast_msg msg,
const char *  name,
const char *  value 
)

Set a variable on the message going to the dialplan.

Note
Setting a variable that already exists overwrites the existing variable value
Parameters
msg
nameName of variable to set
valueValue of variable to set
Return values
0success
-1failure

Definition at line 629 of file main/message.c.

630{
631 return msg_set_var_full(msg, name, value, 0);
632}
static int msg_set_var_full(struct ast_msg *msg, const char *name, const char *value, unsigned int outbound)
Definition: main/message.c:594
int value
Definition: syslog.c:37

References msg_data::msg, msg_set_var_full(), name, and value.

Referenced by AST_TEST_DEFINE(), headers_to_vars(), rx_data_to_ast_msg(), and xmpp_pak_message().

◆ ast_msg_set_var_outbound()

int ast_msg_set_var_outbound ( struct ast_msg msg,
const char *  name,
const char *  value 
)

Set a variable on the message being sent to a message tech directly.

Note
Setting a variable that already exists overwrites the existing variable value
Parameters
msg
nameName of variable to set
valueValue of variable to set
Return values
0success
-1failure

Definition at line 624 of file main/message.c.

625{
626 return msg_set_var_full(msg, name, value, 1);
627}

References msg_data::msg, msg_set_var_full(), name, and value.

Referenced by action_messagesend(), AST_TEST_DEFINE(), msg_data_func_write(), and send_message().

◆ ast_msg_shutdown()

void ast_msg_shutdown ( void  )

Provided by message.c

Definition at line 1717 of file main/message.c.

1718{
1719 if (msg_q_tp) {
1721 }
1722}
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.

References ast_taskprocessor_unreference(), and msg_q_tp.

Referenced by can_safely_quit().

◆ ast_msg_tech_register()

int ast_msg_tech_register ( const struct ast_msg_tech tech)

Register a message technology.

Return values
0success
non-zerofailure

Definition at line 1597 of file main/message.c.

1598{
1599 const struct ast_msg_tech *match;
1600
1602
1604 if (match) {
1605 ast_log(LOG_ERROR, "Message technology already registered for '%s'\n",
1606 tech->name);
1608 return -1;
1609 }
1610
1611 if (AST_VECTOR_APPEND(&msg_techs, tech)) {
1612 ast_log(LOG_ERROR, "Failed to register message technology for '%s'\n",
1613 tech->name);
1615 return -1;
1616 }
1617 ast_verb(5, "Message technology '%s' registered.\n", tech->name);
1618
1620
1621 return 0;
1622}
const char *const name
Name of this message technology.
Definition: message.h:61

References ast_log, ast_rwlock_unlock, ast_rwlock_wrlock, AST_VECTOR_APPEND, ast_verb, LOG_ERROR, match(), msg_find_by_tech_name(), msg_techs, msg_techs_lock, and ast_msg_tech::name.

Referenced by AST_TEST_DEFINE(), and load_module().

◆ ast_msg_tech_unregister()

int ast_msg_tech_unregister ( const struct ast_msg_tech tech)

Unregister a message technology.

Return values
0success
non-zerofailure

Definition at line 1638 of file main/message.c.

1639{
1640 int match;
1641
1646
1647 if (match) {
1648 ast_log(LOG_ERROR, "No '%s' message technology found.\n", tech->name);
1649 return -1;
1650 }
1651
1652 ast_verb(5, "Message technology '%s' unregistered.\n", tech->name);
1653
1654 return 0;
1655}
static int msg_tech_cmp(const struct ast_msg_tech *vec_elem, const struct ast_msg_tech *srch)
Comparison callback for ast_msg_tech vector removal.

References ast_log, ast_rwlock_unlock, ast_rwlock_wrlock, AST_VECTOR_ELEM_CLEANUP_NOOP, AST_VECTOR_REMOVE_CMP_UNORDERED, ast_verb, LOG_ERROR, match(), msg_tech_cmp(), msg_techs, msg_techs_lock, and ast_msg_tech::name.

Referenced by AST_TEST_DEFINE(), load_module(), and unload_module().

◆ ast_msg_var_iterator_destroy()

void ast_msg_var_iterator_destroy ( struct ast_msg_var_iterator iter)

Destroy a message variable iterator.

Parameters
iterIterator to be destroyed

Definition at line 720 of file main/message.c.

721{
722 if (iter) {
725 ast_free(iter);
726 }
727}
#define ast_free(a)
Definition: astmm.h:180
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
void ast_msg_var_unref_current(struct ast_msg_var_iterator *iter)
Unref a message var from inside an iterator loop.
Definition: main/message.c:714
struct ao2_iterator iter
Definition: main/message.c:654

References ao2_iterator_destroy(), ast_free, ast_msg_var_unref_current(), and ast_msg_var_iterator::iter.

Referenced by AST_TEST_DEFINE(), msg_to_json(), and vars_to_headers().

◆ ast_msg_var_iterator_get_next()

static int ast_msg_var_iterator_get_next ( const struct ast_msg msg,
struct ast_msg_var_iterator iter,
const char **  name,
const char **  value,
unsigned int  send 
)
static

Definition at line 672 of file main/message.c.

675{
676 struct msg_data *data;
677
678 if (!iter) {
679 return 0;
680 }
681
682 /* Skip any that we're told to */
683 while ((data = ao2_iterator_next(&iter->iter)) && (data->send != send)) {
684 ao2_ref(data, -1);
685 }
686
687 if (!data) {
688 return 0;
689 }
690
691 if (data->send == send) {
692 *name = data->name;
693 *value = data->value;
694 }
695
696 /* Leave the refcount to be cleaned up by the caller with
697 * ast_msg_var_unref_current after they finish with the pointers to the data */
698 iter->current_used = data;
699
700 return 1;
701}
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct msg_data * current_used
Definition: main/message.c:655
unsigned int send
Definition: main/message.c:239
const ast_string_field name
Definition: main/message.c:238

References ao2_iterator_next, ao2_ref, ast_msg_var_iterator::current_used, ast_msg_var_iterator::iter, name, msg_data::name, msg_data::send, msg_data::value, and value.

Referenced by ast_msg_var_iterator_next(), and ast_msg_var_iterator_next_received().

◆ ast_msg_var_iterator_init()

struct ast_msg_var_iterator * ast_msg_var_iterator_init ( const struct ast_msg msg)

Create a new message variable iterator.

Parameters
msgA message whose variables are to be iterated over
Returns
An opaque pointer to the new iterator

Definition at line 658 of file main/message.c.

659{
661
662 iter = ast_calloc(1, sizeof(*iter));
663 if (!iter) {
664 return NULL;
665 }
666
667 iter->iter = ao2_iterator_init(msg->vars, 0);
668
669 return iter;
670}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

References ao2_iterator_init(), ast_calloc, ast_msg_var_iterator::iter, NULL, and ast_msg::vars.

Referenced by AST_TEST_DEFINE(), msg_to_json(), and vars_to_headers().

◆ ast_msg_var_iterator_next()

int ast_msg_var_iterator_next ( const struct ast_msg msg,
struct ast_msg_var_iterator iter,
const char **  name,
const char **  value 
)

Get the next variable name and value that is set for sending outbound.

Parameters
msgThe message with the variables
iterAn iterator created with ast_msg_var_iterator_init
nameA pointer to the name result pointer
valueA pointer to the value result pointer
Return values
0No more entries
1Valid entry

Definition at line 703 of file main/message.c.

704{
705 return ast_msg_var_iterator_get_next(msg, iter, name, value, 1);
706}
static int ast_msg_var_iterator_get_next(const struct ast_msg *msg, struct ast_msg_var_iterator *iter, const char **name, const char **value, unsigned int send)
Definition: main/message.c:672

References ast_msg_var_iterator_get_next(), msg_data::msg, name, and value.

Referenced by AST_TEST_DEFINE(), and vars_to_headers().

◆ ast_msg_var_iterator_next_received()

int ast_msg_var_iterator_next_received ( const struct ast_msg msg,
struct ast_msg_var_iterator iter,
const char **  name,
const char **  value 
)

Get the next variable name and value that was set on a received message.

Parameters
msgThe message with the variables
iterAn iterator created with ast_msg_var_iterator_init
nameA pointer to the name result pointer
valueA pointer to the value result pointer
Return values
0No more entries
1Valid entry

Definition at line 708 of file main/message.c.

710{
711 return ast_msg_var_iterator_get_next(msg, iter, name, value, 0);
712}

References ast_msg_var_iterator_get_next(), msg_data::msg, name, and value.

Referenced by msg_to_json().

◆ ast_msg_var_unref_current()

void ast_msg_var_unref_current ( struct ast_msg_var_iterator iter)

Unref a message var from inside an iterator loop.

Definition at line 714 of file main/message.c.

715{
717 iter->current_used = NULL;
718}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934

References ao2_cleanup, ast_msg_var_iterator::current_used, and NULL.

Referenced by ast_msg_var_iterator_destroy(), AST_TEST_DEFINE(), msg_to_json(), and vars_to_headers().

◆ chan_cleanup()

static void chan_cleanup ( struct ast_channel chan)
static

Definition at line 788 of file main/message.c.

789{
790 struct ast_datastore *msg_ds, *ds;
791 struct varshead *headp;
792 struct ast_var_t *vardata;
793 struct ast_frame *cur;
794
795 ast_channel_lock(chan);
796
797 /*
798 * Remove the msg datastore. Free its data but keep around the datastore
799 * object and just reuse it.
800 */
801 if ((msg_ds = ast_channel_datastore_find(chan, &msg_datastore, NULL)) && msg_ds->data) {
802 ast_channel_datastore_remove(chan, msg_ds);
803 ao2_ref(msg_ds->data, -1);
804 msg_ds->data = NULL;
805 }
806
807 /*
808 * Destroy all other datastores.
809 */
810 while ((ds = AST_LIST_REMOVE_HEAD(ast_channel_datastores(chan), entry))) {
812 }
813
814 /*
815 * Destroy all channel variables.
816 */
817 headp = ast_channel_varshead(chan);
818 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) {
819 ast_var_delete(vardata);
820 }
821
822 /*
823 * Remove frames from read queue
824 */
825 while ((cur = AST_LIST_REMOVE_HEAD(ast_channel_readq(chan), frame_list))) {
826 ast_frfree(cur);
827 }
828
829 /*
830 * Restore msg datastore.
831 */
832 if (msg_ds) {
833 ast_channel_datastore_add(chan, msg_ds);
834 }
835
836 /*
837 * Clear softhangup flags.
838 */
840
841 /*
842 * Flush the alert pipe in case we miscounted somewhere when
843 * messing with frames on the read queue, we had to flush the
844 * read queue above, or we had an "Exceptionally long queue
845 * length" event.
846 */
848
849 ast_channel_unlock(chan);
850}
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2385
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2394
void ast_channel_clear_softhangup(struct ast_channel *chan, int flag)
Clear a set of softhangup flags from a channel.
Definition: channel.c:2432
struct varshead * ast_channel_varshead(struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2922
ast_alert_status_t ast_channel_internal_alert_flush(struct ast_channel *chan)
struct ast_readq_list * ast_channel_readq(struct ast_channel *chan)
@ AST_SOFTHANGUP_ALL
All softhangup flags.
Definition: channel.h:1161
struct ast_datastore_list * ast_channel_datastores(struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2923
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2399
void ast_var_delete(struct ast_var_t *var)
Definition: extconf.c:2471
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
#define ast_frfree(fr)
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
static const struct ast_datastore_info msg_datastore
Definition: main/message.c:286
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66
Data structure associated with a single frame of data.
Definition: search.h:40

References ao2_ref, ast_channel_clear_softhangup(), ast_channel_datastore_add(), ast_channel_datastore_find(), ast_channel_datastore_remove(), ast_channel_datastores(), ast_channel_internal_alert_flush(), ast_channel_lock, ast_channel_readq(), ast_channel_unlock, ast_channel_varshead(), ast_datastore_free(), ast_frfree, AST_LIST_REMOVE_HEAD, AST_SOFTHANGUP_ALL, ast_var_delete(), ast_datastore::data, msg_datastore, and NULL.

Referenced by dialplan_handle_msg_cb().

◆ chan_msg_indicate()

static int chan_msg_indicate ( struct ast_channel chan,
int  condition,
const void *  data,
size_t  datalen 
)
static

Definition at line 372 of file main/message.c.

374{
375 return 0;
376}

◆ chan_msg_read()

static struct ast_frame * chan_msg_read ( struct ast_channel chan)
static

Definition at line 346 of file main/message.c.

347{
348 return &ast_null_frame;
349}
struct ast_frame ast_null_frame
Definition: main/frame.c:79

References ast_null_frame.

◆ chan_msg_send_digit_begin()

static int chan_msg_send_digit_begin ( struct ast_channel chan,
char  digit 
)
static

Definition at line 386 of file main/message.c.

387{
388 return 0;
389}

◆ chan_msg_send_digit_end()

static int chan_msg_send_digit_end ( struct ast_channel chan,
char  digit,
unsigned int  duration 
)
static

Definition at line 399 of file main/message.c.

401{
402 return 0;
403}

◆ chan_msg_write()

static int chan_msg_write ( struct ast_channel chan,
struct ast_frame fr 
)
static

Definition at line 357 of file main/message.c.

358{
359 return 0;
360}

◆ create_msg_q_chan()

static struct ast_channel * create_msg_q_chan ( void  )
static

Definition at line 729 of file main/message.c.

730{
731 struct ast_channel *chan;
732 struct ast_datastore *ds;
733
735 NULL, NULL, NULL,
736 NULL, NULL, NULL, NULL, 0,
737 "%s", "Message/ast_msg_queue");
738
739 if (!chan) {
740 return NULL;
741 }
742
745 }
746
748 ast_channel_unlock(chan);
749 ast_channel_unlink(chan);
750
751 if (!(ds = ast_datastore_alloc(&msg_datastore, NULL))) {
752 ast_hangup(chan);
753 return NULL;
754 }
755
756 ast_channel_lock(chan);
758 ast_channel_unlock(chan);
759
760 return chan;
761}
@ AST_CHAN_TP_INTERNAL
Channels with this particular technology are an implementation detail of Asterisk and should generall...
Definition: channel.h:971
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2541
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1258
void ast_channel_unlink(struct ast_channel *chan)
Remove a channel from the global channels container.
Definition: channel.c:10529
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
@ AST_STATE_UP
Definition: channelstate.h:42
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:85
static struct ast_channel_tech msg_chan_tech_hack
Definition: main/message.c:328
#define ast_opt_hide_messaging_ami_events
Definition: options.h:137
Main Channel structure associated with a channel.

References AST_CHAN_TP_INTERNAL, ast_channel_alloc, ast_channel_datastore_add(), ast_channel_lock, ast_channel_tech_set(), ast_channel_unlink(), ast_channel_unlock, ast_datastore_alloc, ast_hangup(), ast_opt_hide_messaging_ami_events, AST_STATE_UP, msg_chan_tech_hack, msg_datastore, NULL, and ast_channel_tech::properties.

Referenced by dialplan_handle_msg_cb().

◆ destroy_msg_q_chan()

static void destroy_msg_q_chan ( void *  data)
static

Definition at line 852 of file main/message.c.

853{
854 struct ast_channel **chan = data;
855
856 if (!*chan) {
857 return;
858 }
859
860 ast_channel_release(*chan);
861}
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
Definition: channel.c:1584
const char * data

References ast_channel_release(), and ast_channel::data.

◆ dialplan_handle_msg_cb()

static int dialplan_handle_msg_cb ( struct ast_msg msg)
static

Definition at line 866 of file main/message.c.

867{
868 struct ast_channel **chan_p, *chan;
869 struct ast_datastore *ds;
870
871 if (!(chan_p = ast_threadstorage_get(&msg_q_chan, sizeof(struct ast_channel *)))) {
872 return -1;
873 }
874 if (!*chan_p) {
875 if (!(*chan_p = create_msg_q_chan())) {
876 return -1;
877 }
878 }
879 chan = *chan_p;
880
881 ast_channel_lock(chan);
882 if (!(ds = ast_channel_datastore_find(chan, &msg_datastore, NULL))) {
883 ast_channel_unlock(chan);
884 return -1;
885 }
886 ao2_ref(msg, +1);
887 ds->data = msg;
888 ast_channel_unlock(chan);
889
890 msg_route(chan, msg);
891 chan_cleanup(chan);
892
893 return 0;
894}
static void chan_cleanup(struct ast_channel *chan)
Definition: main/message.c:788
static struct ast_channel * create_msg_q_chan(void)
Definition: main/message.c:729
static struct ast_threadstorage msg_q_chan
Definition: main/message.c:863
static void msg_route(struct ast_channel *chan, struct ast_msg *msg)
Definition: main/message.c:770
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.

References ao2_ref, ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_threadstorage_get(), chan_cleanup(), create_msg_q_chan(), ast_datastore::data, msg_datastore, msg_q_chan, msg_route(), and NULL.

◆ dialplan_has_destination_cb()

static int dialplan_has_destination_cb ( const struct ast_msg msg)
static

Definition at line 897 of file main/message.c.

898{
899 if (ast_strlen_zero(msg->context)) {
900 return 0;
901 }
902
903 return ast_exists_extension(NULL, msg->context, S_OR(msg->exten, "s"), 1, NULL);
904}
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4175
const ast_string_field context
Definition: main/message.c:263
const ast_string_field exten
Definition: main/message.c:263

References ast_exists_extension(), ast_strlen_zero(), ast_msg::context, ast_msg::exten, NULL, and S_OR.

◆ message_shutdown()

static void message_shutdown ( void  )
static

Definition at line 1732 of file main/message.c.

1733{
1735
1739 ast_manager_unregister("MessageSend");
1740
1743
1746}
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:8041
#define ast_rwlock_destroy(rwlock)
Definition: lock.h:233
int ast_msg_handler_unregister(const struct ast_msg_handler *handler)
Unregister a ast_msg_handler.
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174

References app_msg_send, ast_custom_function_unregister(), ast_manager_unregister(), ast_msg_handler_unregister(), ast_rwlock_destroy, ast_unregister_application(), AST_VECTOR_FREE, dialplan_msg_handler, msg_data_function, msg_function, msg_handlers, msg_handlers_lock, msg_techs, and msg_techs_lock.

Referenced by ast_msg_init().

◆ msg_data_alloc()

static struct msg_data * msg_data_alloc ( void  )
static

Definition at line 570 of file main/message.c.

571{
572 struct msg_data *data;
573
574 if (!(data = ao2_alloc(sizeof(*data), msg_data_destructor))) {
575 return NULL;
576 }
577
578 if (ast_string_field_init(data, 32)) {
579 ao2_ref(data, -1);
580 return NULL;
581 }
582
583 return data;
584}
static void msg_data_destructor(void *obj)
Definition: main/message.c:418

References ao2_alloc, ao2_ref, ast_string_field_init, msg_data_destructor(), and NULL.

Referenced by msg_set_var_full().

◆ msg_data_cmp_fn()

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

Definition at line 412 of file main/message.c.

413{
414 const struct msg_data *one = obj, *two = arg;
415 return !strcasecmp(one->name, two->name) ? CMP_MATCH | CMP_STOP : 0;
416}
@ CMP_MATCH
Definition: astobj2.h:1027
@ CMP_STOP
Definition: astobj2.h:1028

References CMP_MATCH, CMP_STOP, and msg_data::name.

Referenced by ast_msg_alloc().

◆ msg_data_destructor()

static void msg_data_destructor ( void *  obj)
static

Definition at line 418 of file main/message.c.

419{
420 struct msg_data *data = obj;
422}
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374

References ast_string_field_free_memory.

Referenced by msg_data_alloc().

◆ msg_data_find()

static struct msg_data * msg_data_find ( struct ao2_container vars,
const char *  name 
)
static

Definition at line 586 of file main/message.c.

587{
588 struct msg_data tmp = {
589 .name = name,
590 };
591 return ao2_find(vars, &tmp, OBJ_POINTER);
592}
#define OBJ_POINTER
Definition: astobj2.h:1150
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
static int tmp()
Definition: bt_open.c:389

References ao2_find, name, OBJ_POINTER, and tmp().

Referenced by ast_msg_get_var(), and msg_set_var_full().

◆ msg_data_func_read()

static int msg_data_func_read ( struct ast_channel chan,
const char *  function,
char *  data,
char *  buf,
size_t  len 
)
static

Definition at line 1117 of file main/message.c.

1119{
1120 struct ast_datastore *ds;
1121 struct ast_msg *msg;
1122 const char *val;
1123
1124 if (!chan) {
1125 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
1126 return -1;
1127 }
1128
1129 ast_channel_lock(chan);
1130
1131 if (!(ds = ast_channel_datastore_find(chan, &msg_datastore, NULL))) {
1132 ast_channel_unlock(chan);
1133 ast_log(LOG_ERROR, "No MESSAGE data found on the channel to read.\n");
1134 return -1;
1135 }
1136
1137 msg = ds->data;
1138 ao2_ref(msg, +1);
1139 ast_channel_unlock(chan);
1140
1141 ao2_lock(msg);
1142
1143 if ((val = ast_msg_get_var(msg, data))) {
1145 }
1146
1147 ao2_unlock(msg);
1148 ao2_ref(msg, -1);
1149
1150 return 0;
1151}
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define LOG_WARNING
const char * ast_msg_get_var(struct ast_msg *msg, const char *name)
Get the specified variable on the message.
Definition: main/message.c:634
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425

References ao2_lock, ao2_ref, ao2_unlock, ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_log, ast_msg_get_var(), buf, ast_datastore::data, len(), LOG_ERROR, LOG_WARNING, msg_datastore, and NULL.

◆ msg_data_func_write()

static int msg_data_func_write ( struct ast_channel chan,
const char *  function,
char *  data,
const char *  value 
)
static

Definition at line 1153 of file main/message.c.

1155{
1156 struct ast_datastore *ds;
1157 struct ast_msg *msg;
1158
1159 if (!chan) {
1160 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
1161 return -1;
1162 }
1163
1164 ast_channel_lock(chan);
1165
1166 if (!(ds = msg_datastore_find_or_create(chan))) {
1167 ast_channel_unlock(chan);
1168 return -1;
1169 }
1170
1171 msg = ds->data;
1172 ao2_ref(msg, +1);
1173 ast_channel_unlock(chan);
1174
1175 ao2_lock(msg);
1176
1177 ast_msg_set_var_outbound(msg, data, value);
1178
1179 ao2_unlock(msg);
1180 ao2_ref(msg, -1);
1181
1182 return 0;
1183}
static struct ast_datastore * msg_datastore_find_or_create(struct ast_channel *chan)
Definition: main/message.c:994

References ao2_lock, ao2_ref, ao2_unlock, ast_channel_lock, ast_channel_unlock, ast_log, ast_msg_set_var_outbound(), ast_datastore::data, LOG_WARNING, msg_datastore_find_or_create(), and value.

◆ msg_datastore_find_or_create()

static struct ast_datastore * msg_datastore_find_or_create ( struct ast_channel chan)
static

Definition at line 994 of file main/message.c.

995{
996 struct ast_datastore *ds;
997
998 if ((ds = ast_channel_datastore_find(chan, &msg_datastore, NULL))) {
999 return ds;
1000 }
1001
1002 if (!(ds = ast_datastore_alloc(&msg_datastore, NULL))) {
1003 return NULL;
1004 }
1005
1006 if (!(ds->data = ast_msg_alloc())) {
1008 return NULL;
1009 }
1010
1011 ast_channel_datastore_add(chan, ds);
1012
1013 return ds;
1014}

References ast_channel_datastore_add(), ast_channel_datastore_find(), ast_datastore_alloc, ast_datastore_free(), ast_msg_alloc(), ast_datastore::data, msg_datastore, and NULL.

Referenced by msg_data_func_write(), and msg_func_write().

◆ msg_destructor()

static void msg_destructor ( void *  obj)
static

Definition at line 424 of file main/message.c.

425{
426 struct ast_msg *msg = obj;
427
429 ao2_cleanup(msg->vars);
430}

References ao2_cleanup, ast_string_field_free_memory, and ast_msg::vars.

Referenced by ast_msg_alloc().

◆ msg_ds_destroy()

static void msg_ds_destroy ( void *  data)
static

Definition at line 405 of file main/message.c.

406{
407 struct ast_msg *msg = data;
408
409 ao2_ref(msg, -1);
410}

References ao2_ref.

◆ msg_find_by_tech_name()

static const struct ast_msg_tech * msg_find_by_tech_name ( const char *  tech_name)
static

Definition at line 1196 of file main/message.c.

1197{
1198 const struct ast_msg_tech *current;
1199 int i;
1200
1201 for (i = 0; i < AST_VECTOR_SIZE(&msg_techs); i++) {
1203 if (!strcmp(current->name, tech_name)) {
1204 return current;
1205 }
1206 }
1207
1208 return NULL;
1209}
size_t current
Definition: main/message.c:272

References AST_VECTOR_GET, AST_VECTOR_SIZE, current, msg_techs, and NULL.

Referenced by action_messagesend(), ast_msg_send(), ast_msg_tech_register(), and msg_send_exec().

◆ msg_func_read()

static int msg_func_read ( struct ast_channel chan,
const char *  function,
char *  data,
char *  buf,
size_t  len 
)
static

Definition at line 1016 of file main/message.c.

1018{
1019 struct ast_datastore *ds;
1020 struct ast_msg *msg;
1021
1022 if (!chan) {
1023 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
1024 return -1;
1025 }
1026
1027 ast_channel_lock(chan);
1028
1029 if (!(ds = ast_channel_datastore_find(chan, &msg_datastore, NULL))) {
1030 ast_channel_unlock(chan);
1031 ast_log(LOG_ERROR, "No MESSAGE data found on the channel to read.\n");
1032 return -1;
1033 }
1034
1035 msg = ds->data;
1036 ao2_ref(msg, +1);
1037 ast_channel_unlock(chan);
1038
1039 ao2_lock(msg);
1040
1041 if (!strcasecmp(data, "to")) {
1042 ast_copy_string(buf, msg->to, len);
1043 } else if (!strcasecmp(data, "from")) {
1044 ast_copy_string(buf, msg->from, len);
1045 } else if (!strcasecmp(data, "body")) {
1046 ast_copy_string(buf, msg->body, len);
1047 } else {
1048 ast_log(LOG_WARNING, "Invalid argument to MESSAGE(): '%s'\n", data);
1049 }
1050
1051 ao2_unlock(msg);
1052 ao2_ref(msg, -1);
1053
1054 return 0;
1055}

References ao2_lock, ao2_ref, ao2_unlock, ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_log, ast_msg::body, buf, ast_datastore::data, ast_msg::from, len(), LOG_ERROR, LOG_WARNING, msg_datastore, NULL, and ast_msg::to.

◆ msg_func_write()

static int msg_func_write ( struct ast_channel chan,
const char *  function,
char *  data,
const char *  value 
)
static

Definition at line 1057 of file main/message.c.

1059{
1060 struct ast_datastore *ds;
1061 struct ast_msg *msg;
1062
1063 if (!chan) {
1064 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
1065 return -1;
1066 }
1067
1068 ast_channel_lock(chan);
1069
1070 if (!(ds = msg_datastore_find_or_create(chan))) {
1071 ast_channel_unlock(chan);
1072 return -1;
1073 }
1074
1075 msg = ds->data;
1076 ao2_ref(msg, +1);
1077 ast_channel_unlock(chan);
1078
1079 ao2_lock(msg);
1080
1081 if (!strcasecmp(data, "to")) {
1082 ast_msg_set_to(msg, "%s", value);
1083 } else if (!strcasecmp(data, "from")) {
1084 ast_msg_set_from(msg, "%s", value);
1085 } else if (!strcasecmp(data, "body")) {
1086 ast_msg_set_body(msg, "%s", value);
1087 } else if (!strcasecmp(data, "custom_data")) {
1088 int outbound = -1;
1089 if (!strcasecmp(value, "mark_all_outbound")) {
1090 outbound = 1;
1091 } else if (!strcasecmp(value, "clear_all_outbound")) {
1092 outbound = 0;
1093 } else {
1094 ast_log(LOG_WARNING, "'%s' is not a valid value for custom_data\n", value);
1095 }
1096
1097 if (outbound != -1) {
1098 struct msg_data *hdr_data;
1099 struct ao2_iterator iter = ao2_iterator_init(msg->vars, 0);
1100
1101 while ((hdr_data = ao2_iterator_next(&iter))) {
1102 hdr_data->send = outbound;
1103 ao2_ref(hdr_data, -1);
1104 }
1105 ao2_iterator_destroy(&iter);
1106 }
1107 } else {
1108 ast_log(LOG_WARNING, "'%s' is not a valid write argument.\n", data);
1109 }
1110
1111 ao2_unlock(msg);
1112 ao2_ref(msg, -1);
1113
1114 return 0;
1115}
int ast_msg_set_from(struct ast_msg *msg, const char *fmt,...)
Set the 'from' URI of a message.
Definition: main/message.c:479
int ast_msg_set_to(struct ast_msg *msg, const char *fmt,...)
Set the 'to' URI of a message.
Definition: main/message.c:468
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_channel_lock, ast_channel_unlock, ast_log, ast_msg_set_body(), ast_msg_set_from(), ast_msg_set_to(), ast_datastore::data, LOG_WARNING, msg_datastore_find_or_create(), msg_data::send, value, and ast_msg::vars.

◆ msg_handler_cmp()

static int msg_handler_cmp ( const struct ast_msg_handler vec_elem,
const struct ast_msg_handler srch 
)
static

Comparison callback for ast_msg_handler vector removal.

Parameters
vec_elemThe element in the vector being compared
srchThe element being looked up
Return values
non-zeroThe items are equal
0The items are not equal

Definition at line 1694 of file main/message.c.

1695{
1696 return !strcmp(vec_elem->name, srch->name);
1697}
const char * name
Name of the message handler.
Definition: message.h:102

References ast_msg_handler::name.

Referenced by ast_msg_handler_unregister().

◆ msg_handler_find_by_tech_name()

static const struct ast_msg_handler * msg_handler_find_by_tech_name ( const char *  tech_name)
static

Definition at line 1222 of file main/message.c.

1223{
1224 const struct ast_msg_handler *current;
1225 int i;
1226
1227 for (i = 0; i < AST_VECTOR_SIZE(&msg_handlers); i++) {
1229 if (!strcmp(current->name, tech_name)) {
1230 return current;
1231 }
1232 }
1233
1234 return NULL;
1235}

References AST_VECTOR_GET, AST_VECTOR_SIZE, current, msg_handlers, and NULL.

Referenced by ast_msg_handler_register().

◆ msg_q_cb()

static int msg_q_cb ( void *  data)
static

Definition at line 921 of file main/message.c.

922{
923 struct ast_msg *msg = data;
924 int res = 1;
925 int i;
926
928 for (i = 0; i < AST_VECTOR_SIZE(&msg_handlers); i++) {
930
931 if (!handler->has_destination(msg)) {
932 ast_debug(5, "Handler %s doesn't want message, moving on\n", handler->name);
933 continue;
934 }
935
936 ast_debug(5, "Dispatching message to %s handler\n", handler->name);
937 res &= handler->handle_msg(msg);
938 }
940
941 if (res != 0) {
942 ast_log(LOG_WARNING, "No handler processed message from %s to %s\n",
943 S_OR(msg->from, "<unknown>"), S_OR(msg->to, "<unknown>"));
944 }
945
946 ao2_ref(msg, -1);
947
948 return res;
949}

References ao2_ref, ast_debug, ast_log, ast_rwlock_rdlock, ast_rwlock_unlock, AST_VECTOR_GET, AST_VECTOR_SIZE, ast_msg::from, handler(), LOG_WARNING, msg_handlers, msg_handlers_lock, S_OR, and ast_msg::to.

Referenced by ast_msg_queue().

◆ msg_route()

static void msg_route ( struct ast_channel chan,
struct ast_msg msg 
)
static

Definition at line 770 of file main/message.c.

771{
772 struct ast_pbx_args pbx_args;
773
774 ast_explicit_goto(chan, msg->context, S_OR(msg->exten, "s"), 1);
775
776 memset(&pbx_args, 0, sizeof(pbx_args));
777 pbx_args.no_hangup_chan = 1,
778 ast_pbx_run_args(chan, &pbx_args);
779}
enum ast_pbx_result ast_pbx_run_args(struct ast_channel *c, struct ast_pbx_args *args)
Execute the PBX in the current thread.
Definition: pbx.c:4735
int ast_explicit_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:6945
Options for ast_pbx_run()
Definition: pbx.h:407

References ast_explicit_goto(), ast_pbx_run_args(), ast_msg::context, ast_msg::exten, ast_pbx_args::no_hangup_chan, and S_OR.

Referenced by dialplan_handle_msg_cb().

◆ msg_send_exec()

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

Definition at line 1241 of file main/message.c.

1242{
1243 struct ast_datastore *ds;
1244 struct ast_msg *msg;
1245 char *tech_name;
1246 const struct ast_msg_tech *msg_tech;
1247 char *parse;
1248 int res = -1;
1250 AST_APP_ARG(destination);
1251 AST_APP_ARG(from);
1252 AST_APP_ARG(to);
1253 );
1254
1255 if (ast_strlen_zero(data)) {
1256 ast_log(LOG_WARNING, "An argument is required to MessageSend()\n");
1257 pbx_builtin_setvar_helper(chan, "MESSAGE_SEND_STATUS", "INVALID_URI");
1258 return 0;
1259 }
1260
1261 parse = ast_strdupa(data);
1263
1264 if (ast_strlen_zero(args.destination)) {
1265 ast_log(LOG_WARNING, "A 'to' URI is required for MessageSend()\n");
1266 pbx_builtin_setvar_helper(chan, "MESSAGE_SEND_STATUS", "INVALID_URI");
1267 return 0;
1268 }
1269
1270 ast_channel_lock(chan);
1271
1272 if (!(ds = ast_channel_datastore_find(chan, &msg_datastore, NULL))) {
1273 ast_channel_unlock(chan);
1274 ast_log(LOG_WARNING, "No message data found on channel to send.\n");
1275 pbx_builtin_setvar_helper(chan, "MESSAGE_SEND_STATUS", "FAILURE");
1276 return 0;
1277 }
1278
1279 msg = ds->data;
1280 ao2_ref(msg, +1);
1281 ast_channel_unlock(chan);
1282
1283 tech_name = ast_strdupa(args.destination);
1284 tech_name = strsep(&tech_name, ":");
1285
1287 msg_tech = msg_find_by_tech_name(tech_name);
1288
1289 if (!msg_tech) {
1290 ast_log(LOG_WARNING, "No message technology '%s' found.\n", tech_name);
1291 pbx_builtin_setvar_helper(chan, "MESSAGE_SEND_STATUS", "INVALID_PROTOCOL");
1292 goto exit_cleanup;
1293 }
1294
1295 /*
1296 * If there was a "to" in the call to MessageSend,
1297 * replace the to already in the channel datastore.
1298 */
1299 if (!ast_strlen_zero(args.to)) {
1300 ast_string_field_set(msg, to, args.to);
1301 }
1302
1303 /*
1304 * The message lock is held here to safely allow the technology
1305 * implementation to access the message fields without worrying
1306 * that they could change.
1307 */
1308 ao2_lock(msg);
1309 res = msg_tech->msg_send(msg, S_OR(args.destination, ""), S_OR(args.from, ""));
1310 ao2_unlock(msg);
1311
1312 pbx_builtin_setvar_helper(chan, "MESSAGE_SEND_STATUS", res ? "FAILURE" : "SUCCESS");
1313
1314exit_cleanup:
1316 ao2_ref(msg, -1);
1317
1318 return 0;
1319}
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
const char * args

References ao2_lock, ao2_ref, ao2_unlock, args, AST_APP_ARG, ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, AST_DECLARE_APP_ARGS, ast_log, ast_rwlock_rdlock, ast_rwlock_unlock, AST_STANDARD_APP_ARGS, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_datastore::data, LOG_WARNING, msg_datastore, msg_find_by_tech_name(), ast_msg_tech::msg_send, msg_tech, msg_techs_lock, NULL, pbx_builtin_setvar_helper(), S_OR, and strsep().

Referenced by ast_msg_init().

◆ msg_set_var_full()

static int msg_set_var_full ( struct ast_msg msg,
const char *  name,
const char *  value,
unsigned int  outbound 
)
static

Definition at line 594 of file main/message.c.

595{
596 struct msg_data *data;
597
598 if (!(data = msg_data_find(msg->vars, name))) {
599 if (ast_strlen_zero(value)) {
600 return 0;
601 }
602 if (!(data = msg_data_alloc())) {
603 return -1;
604 };
605
608 data->send = outbound;
609 ao2_link(msg->vars, data);
610 } else {
611 if (ast_strlen_zero(value)) {
612 ao2_unlink(msg->vars, data);
613 } else {
615 data->send = outbound;
616 }
617 }
618
619 ao2_ref(data, -1);
620
621 return 0;
622}
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition: astobj2.h:1578
static struct msg_data * msg_data_alloc(void)
Definition: main/message.c:570

References ao2_link, ao2_ref, ao2_unlink, ast_string_field_set, ast_strlen_zero(), msg_data::msg, msg_data_alloc(), msg_data_find(), name, msg_data::send, value, and ast_msg::vars.

Referenced by ast_msg_set_var(), and ast_msg_set_var_outbound().

◆ msg_tech_cmp()

static int msg_tech_cmp ( const struct ast_msg_tech vec_elem,
const struct ast_msg_tech srch 
)
static

Comparison callback for ast_msg_tech vector removal.

Parameters
vec_elemThe element in the vector being compared
srchThe element being looked up
Return values
non-zeroThe items are equal
0The items are not equal

Definition at line 1633 of file main/message.c.

1634{
1635 return !strcmp(vec_elem->name, srch->name);
1636}

References ast_msg_tech::name.

Referenced by ast_msg_tech_unregister().

Variable Documentation

◆ app_msg_send

const char app_msg_send[] = "MessageSend"
static

Definition at line 282 of file main/message.c.

Referenced by ast_msg_init(), and message_shutdown().

◆ current

size_t current

Definition at line 272 of file main/message.c.

Referenced by msg_find_by_tech_name(), and msg_handler_find_by_tech_name().

◆ dialplan_msg_handler

struct ast_msg_handler dialplan_msg_handler
static
Initial value:
= {
.name = "dialplan",
.handle_msg = dialplan_handle_msg_cb,
.has_destination = dialplan_has_destination_cb,
}
static int dialplan_handle_msg_cb(struct ast_msg *msg)
Definition: main/message.c:866
static int dialplan_has_destination_cb(const struct ast_msg *msg)
Definition: main/message.c:897

Definition at line 906 of file main/message.c.

Referenced by ast_msg_init(), and message_shutdown().

◆ elems

const struct ast_msg_handler* * elems

Definition at line 272 of file main/message.c.

◆ max

size_t max

Definition at line 272 of file main/message.c.

◆ msg_chan_tech_hack

struct ast_channel_tech msg_chan_tech_hack
static

Definition at line 328 of file main/message.c.

Referenced by create_msg_q_chan().

◆ msg_data_function

struct ast_custom_function msg_data_function
static
Initial value:
= {
.name = "MESSAGE_DATA",
}
static int msg_data_func_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
static int msg_data_func_write(struct ast_channel *chan, const char *function, char *data, const char *value)

Definition at line 307 of file main/message.c.

Referenced by ast_msg_init(), and message_shutdown().

◆ msg_datastore

const struct ast_datastore_info msg_datastore
static
Initial value:
= {
.type = "message",
.destroy = msg_ds_destroy,
}
static void msg_ds_destroy(void *data)
Definition: main/message.c:405

Definition at line 286 of file main/message.c.

Referenced by chan_cleanup(), create_msg_q_chan(), dialplan_handle_msg_cb(), msg_data_func_read(), msg_datastore_find_or_create(), msg_func_read(), and msg_send_exec().

◆ msg_function

struct ast_custom_function msg_function
static
Initial value:
= {
.name = "MESSAGE",
.read = msg_func_read,
.write = msg_func_write,
}
static int msg_func_write(struct ast_channel *chan, const char *function, char *data, const char *value)
static int msg_func_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)

Definition at line 296 of file main/message.c.

Referenced by ast_msg_init(), and message_shutdown().

◆ 

struct { ... } msg_handlers

◆ msg_handlers_lock

ast_rwlock_t msg_handlers_lock
static

◆ msg_q_chan

struct ast_threadstorage msg_q_chan = { .once = PTHREAD_ONCE_INIT , .key_init = __init_msg_q_chan , .custom_init = NULL , }
static

Definition at line 863 of file main/message.c.

Referenced by dialplan_handle_msg_cb().

◆ msg_q_tp

struct ast_taskprocessor* msg_q_tp
static

Definition at line 280 of file main/message.c.

Referenced by ast_msg_init(), ast_msg_queue(), and ast_msg_shutdown().

◆ 

struct { ... } msg_techs

◆ msg_techs_lock

ast_rwlock_t msg_techs_lock
static