Asterisk - The Open Source Telephony Project GIT-master-7805f28
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
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 1456 of file main/message.c.

Function Documentation

◆ __init_msg_q_chan()

static void __init_msg_q_chan ( void  )
static

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

879{

◆ action_messagesend()

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

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

1334{
1335 const char *destination = astman_get_header(m, "Destination");
1336 const char *to = astman_get_header(m, "To");
1337 const char *from = astman_get_header(m, "From");
1338 const char *body = astman_get_header(m, "Body");
1339 const char *base64body = astman_get_header(m, "Base64Body");
1340 const char *to_override = NULL;
1341 char base64decoded[1301] = { 0, };
1342 char *tech_name = NULL;
1343 struct ast_variable *vars = NULL;
1344 struct ast_variable *data = NULL;
1345 const struct ast_msg_tech *msg_tech;
1346 struct ast_msg *msg;
1347 int res = -1;
1348
1349 if (!ast_strlen_zero(destination)) {
1350 if (!ast_strlen_zero(to)) {
1351 to_override = to;
1352 }
1353 to = destination;
1354 } else {
1355 if (ast_strlen_zero(to)) {
1356 astman_send_error(s, m, "No 'To' address specified.");
1357 return 0;
1358 }
1359 }
1360
1361 if (!ast_strlen_zero(base64body)) {
1362 ast_base64decode((unsigned char *) base64decoded, base64body, sizeof(base64decoded) - 1);
1363 body = base64decoded;
1364 }
1365
1366 tech_name = ast_strdupa(to);
1367 tech_name = strsep(&tech_name, ":");
1368
1370 msg_tech = msg_find_by_tech_name(tech_name);
1371 if (!msg_tech) {
1373 astman_send_error(s, m, "Message technology not found.");
1374 return 0;
1375 }
1376
1377 if (!(msg = ast_msg_alloc())) {
1379 astman_send_error(s, m, "Internal failure\n");
1380 return 0;
1381 }
1382
1384 for (vars = data; vars; vars = vars->next) {
1385 ast_msg_set_var_outbound(msg, vars->name, vars->value);
1386 }
1387
1388 ast_msg_set_body(msg, "%s", body);
1389
1390 if (to_override) {
1391 ast_string_field_set(msg, to, to_override);
1392 }
1393
1394 res = msg_tech->msg_send(msg, S_OR(to, ""), S_OR(from, ""));
1395
1397
1399 ao2_ref(msg, -1);
1400
1401 if (res) {
1402 astman_send_error(s, m, "Message failed to send.");
1403 } else {
1404 astman_send_ack(s, m, "Message successfully sent");
1405 }
1406 return 0;
1407}
char * strsep(char **str, const char *delims)
#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:1986
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2018
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:1738
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:1647
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
#define ast_rwlock_rdlock(a)
Definition: lock.h:242
#define ast_rwlock_unlock(a)
Definition: lock.h:241
static ast_rwlock_t msg_techs_lock
Lock for msg_techs vector.
Definition: main/message.c:281
struct ast_msg * ast_msg_alloc(void)
Allocate a message.
Definition: main/message.c:444
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:502
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:636
@ ORDER_NATURAL
Definition: manager.h:289
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:259
struct ao2_container * vars
Definition: main/message.c:277
const ast_string_field from
Definition: main/message.c:275
const ast_string_field to
Definition: main/message.c:275
const ast_string_field body
Definition: main/message.c:275
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 444 of file main/message.c.

445{
446 struct ast_msg *msg;
447
448 if (!(msg = ao2_alloc(sizeof(*msg), msg_destructor))) {
449 return NULL;
450 }
451
452 if (ast_string_field_init(msg, 128)) {
453 ao2_ref(msg, -1);
454 return NULL;
455 }
456
459 if (!msg->vars) {
460 ao2_ref(msg, -1);
461 return NULL;
462 }
463 ast_string_field_set(msg, context, "default");
464
465 return msg;
466}
@ 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:436
static int msg_data_cmp_fn(void *obj, void *arg, int flags)
Definition: main/message.c:424
#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 474 of file main/message.c.

475{
476 ao2_ref(msg, -1);
477 return NULL;
478}

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 557 of file main/message.c.

558{
559 return msg->body;
560}

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 577 of file main/message.c.

578{
579 return msg->endpoint;
580}
const ast_string_field endpoint
Definition: main/message.c:275

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 562 of file main/message.c.

563{
564 return msg->from;
565}

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 572 of file main/message.c.

573{
574 return msg->tech;
575}
const ast_string_field tech
Definition: main/message.c:275

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 567 of file main/message.c.

568{
569 return msg->to;
570}

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 646 of file main/message.c.

647{
648 struct msg_data *data;
649 const char *val = NULL;
650
651 if (!(data = msg_data_find(msg->vars, name))) {
652 return NULL;
653 }
654
655 /* Yep, this definitely looks like val would be a dangling pointer
656 * after the ref count is decremented. As long as the message structure
657 * is used in a thread safe manner, this will not be the case though.
658 * The ast_msg holds a reference to this object in the msg->vars container. */
659 val = data->value;
660 ao2_ref(data, -1);
661
662 return val;
663}
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:598
struct ast_msg * msg
const ast_string_field value
Definition: main/message.c:250
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 1669 of file main/message.c.

1670{
1671 const struct ast_msg_handler *match;
1672
1674
1676 if (match) {
1677 ast_log(LOG_ERROR, "Message handler already registered for '%s'\n",
1678 handler->name);
1680 return -1;
1681 }
1682
1684 ast_log(LOG_ERROR, "Failed to register message handler for '%s'\n",
1685 handler->name);
1687 return -1;
1688 }
1689 ast_verb(5, "Message handler '%s' registered.\n", handler->name);
1690
1692
1693 return 0;
1694
1695}
#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:2388
#define LOG_ERROR
#define ast_verb(level,...)
#define ast_rwlock_wrlock(a)
Definition: lock.h:243
struct @377 msg_handlers
Vector of received message handlers.
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:287
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 1711 of file main/message.c.

1712{
1713 int match;
1714
1719
1720 if (match) {
1721 ast_log(LOG_ERROR, "No '%s' message handler found.\n", handler->name);
1722 return -1;
1723 }
1724
1725 ast_verb(5, "Message handler '%s' unregistered.\n", handler->name);
1726 return 0;
1727}
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 963 of file main/message.c.

964{
965 int i;
966 int result = 0;
967
969 for (i = 0; i < AST_VECTOR_SIZE(&msg_handlers); i++) {
971
972 ast_debug(5, "Seeing if %s can handle message\n", handler->name);
973 if (handler->has_destination(msg)) {
974 ast_debug(5, "%s can handle message\n", handler->name);
975 result = 1;
976 break;
977 }
978 }
980
981 return result;
982}
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 1770 of file main/message.c.

1771{
1772 int res;
1773
1775 if (!msg_q_tp) {
1776 return -1;
1777 }
1778
1780 if (AST_VECTOR_INIT(&msg_techs, 8)) {
1781 return -1;
1782 }
1783
1785 if (AST_VECTOR_INIT(&msg_handlers, 4)) {
1786 return -1;
1787 }
1788
1790
1795
1797
1798 return res;
1799}
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:231
struct @376 msg_techs
Vector of message technologies.
static const char app_msg_send[]
Definition: main/message.c:294
static struct ast_msg_handler dialplan_msg_handler
Definition: main/message.c:918
static struct ast_custom_function msg_function
Definition: main/message.c:308
static struct ast_taskprocessor * msg_q_tp
Definition: main/message.c:292
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:319
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:203
#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:104
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 984 of file main/message.c.

985{
986 int res;
988 if (res == -1) {
989 ao2_ref(msg, -1);
990 }
991
992 return res;
993}
static int msg_q_cb(void *data)
Definition: main/message.c:933
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 468 of file main/message.c.

469{
470 ao2_ref(msg, 1);
471 return msg;
472}

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 1409 of file main/message.c.

1410{
1411 char *tech_name = NULL;
1412 const struct ast_msg_tech *msg_tech;
1413 int res = -1;
1414
1415 if (ast_strlen_zero(to)) {
1416 ao2_ref(msg, -1);
1417 return -1;
1418 }
1419
1420 tech_name = ast_strdupa(to);
1421 tech_name = strsep(&tech_name, ":");
1422
1424 msg_tech = msg_find_by_tech_name(tech_name);
1425
1426 if (!msg_tech) {
1427 ast_log(LOG_ERROR, "Unknown message tech: %s\n", tech_name);
1429 return -1;
1430 }
1431
1432 res = msg_tech->msg_send(msg, S_OR(to, ""), S_OR(from, ""));
1433
1435
1436 ao2_ref(msg, -1);
1437
1438 return res;
1439}

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 502 of file main/message.c.

503{
504 va_list ap;
505
506 va_start(ap, fmt);
507 ast_string_field_build_va(msg, body, fmt, ap);
508 va_end(ap);
509
510 return 0;
511}
#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 513 of file main/message.c.

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

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 546 of file main/message.c.

547{
548 va_list ap;
549
550 va_start(ap, fmt);
551 ast_string_field_build_va(msg, endpoint, fmt, ap);
552 va_end(ap);
553
554 return 0;
555}

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 524 of file main/message.c.

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

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 491 of file main/message.c.

492{
493 va_list ap;
494
495 va_start(ap, fmt);
496 ast_string_field_build_va(msg, from, fmt, ap);
497 va_end(ap);
498
499 return 0;
500}

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 535 of file main/message.c.

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

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 480 of file main/message.c.

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

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 641 of file main/message.c.

642{
643 return msg_set_var_full(msg, name, value, 0);
644}
static int msg_set_var_full(struct ast_msg *msg, const char *name, const char *value, unsigned int outbound)
Definition: main/message.c:606
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 636 of file main/message.c.

637{
638 return msg_set_var_full(msg, name, value, 1);
639}

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 1729 of file main/message.c.

1730{
1731 if (msg_q_tp) {
1733 }
1734}
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 1609 of file main/message.c.

1610{
1611 const struct ast_msg_tech *match;
1612
1614
1616 if (match) {
1617 ast_log(LOG_ERROR, "Message technology already registered for '%s'\n",
1618 tech->name);
1620 return -1;
1621 }
1622
1623 if (AST_VECTOR_APPEND(&msg_techs, tech)) {
1624 ast_log(LOG_ERROR, "Failed to register message technology for '%s'\n",
1625 tech->name);
1627 return -1;
1628 }
1629 ast_verb(5, "Message technology '%s' registered.\n", tech->name);
1630
1632
1633 return 0;
1634}
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 1650 of file main/message.c.

1651{
1652 int match;
1653
1658
1659 if (match) {
1660 ast_log(LOG_ERROR, "No '%s' message technology found.\n", tech->name);
1661 return -1;
1662 }
1663
1664 ast_verb(5, "Message technology '%s' unregistered.\n", tech->name);
1665
1666 return 0;
1667}
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 732 of file main/message.c.

733{
734 if (iter) {
737 ast_free(iter);
738 }
739}
#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:726
struct ao2_iterator iter
Definition: main/message.c:666

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 684 of file main/message.c.

687{
688 struct msg_data *data;
689
690 if (!iter) {
691 return 0;
692 }
693
694 /* Skip any that we're told to */
695 while ((data = ao2_iterator_next(&iter->iter)) && (data->send != send)) {
696 ao2_ref(data, -1);
697 }
698
699 if (!data) {
700 return 0;
701 }
702
703 if (data->send == send) {
704 *name = data->name;
705 *value = data->value;
706 }
707
708 /* Leave the refcount to be cleaned up by the caller with
709 * ast_msg_var_unref_current after they finish with the pointers to the data */
710 iter->current_used = data;
711
712 return 1;
713}
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct msg_data * current_used
Definition: main/message.c:667
unsigned int send
Definition: main/message.c:251
const ast_string_field name
Definition: main/message.c:250

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 670 of file main/message.c.

671{
673
674 iter = ast_calloc(1, sizeof(*iter));
675 if (!iter) {
676 return NULL;
677 }
678
679 iter->iter = ao2_iterator_init(msg->vars, 0);
680
681 return iter;
682}
#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 715 of file main/message.c.

716{
717 return ast_msg_var_iterator_get_next(msg, iter, name, value, 1);
718}
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:684

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 720 of file main/message.c.

722{
723 return ast_msg_var_iterator_get_next(msg, iter, name, value, 0);
724}

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 726 of file main/message.c.

727{
729 iter->current_used = NULL;
730}
#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 800 of file main/message.c.

801{
802 struct ast_datastore *msg_ds, *ds;
803 struct varshead *headp;
804 struct ast_var_t *vardata;
805 struct ast_frame *cur;
806
807 ast_channel_lock(chan);
808
809 /*
810 * Remove the msg datastore. Free its data but keep around the datastore
811 * object and just reuse it.
812 */
813 if ((msg_ds = ast_channel_datastore_find(chan, &msg_datastore, NULL)) && msg_ds->data) {
814 ast_channel_datastore_remove(chan, msg_ds);
815 ao2_ref(msg_ds->data, -1);
816 msg_ds->data = NULL;
817 }
818
819 /*
820 * Destroy all other datastores.
821 */
822 while ((ds = AST_LIST_REMOVE_HEAD(ast_channel_datastores(chan), entry))) {
824 }
825
826 /*
827 * Destroy all channel variables.
828 */
829 headp = ast_channel_varshead(chan);
830 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) {
831 ast_var_delete(vardata);
832 }
833
834 /*
835 * Remove frames from read queue
836 */
837 while ((cur = AST_LIST_REMOVE_HEAD(ast_channel_readq(chan), frame_list))) {
838 ast_frfree(cur);
839 }
840
841 /*
842 * Restore msg datastore.
843 */
844 if (msg_ds) {
845 ast_channel_datastore_add(chan, msg_ds);
846 }
847
848 /*
849 * Clear softhangup flags.
850 */
852
853 /*
854 * Flush the alert pipe in case we miscounted somewhere when
855 * messing with frames on the read queue, we had to flush the
856 * read queue above, or we had an "Exceptionally long queue
857 * length" event.
858 */
860
861 ast_channel_unlock(chan);
862}
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2354
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2363
void ast_channel_clear_softhangup(struct ast_channel *chan, int flag)
Clear a set of softhangup flags from a channel.
Definition: channel.c:2401
struct varshead * ast_channel_varshead(struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2972
ast_alert_status_t ast_channel_internal_alert_flush(struct ast_channel *chan)
struct ast_readq_list * ast_channel_readq(struct ast_channel *chan)
struct ast_datastore_list * ast_channel_datastores(struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2973
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:2368
@ AST_SOFTHANGUP_ALL
All softhangup flags.
Definition: channel.h:1181
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:298
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.

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 384 of file main/message.c.

386{
387 return 0;
388}

◆ chan_msg_read()

static struct ast_frame * chan_msg_read ( struct ast_channel chan)
static

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

359{
360 return &ast_null_frame;
361}
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 398 of file main/message.c.

399{
400 return 0;
401}

◆ 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 411 of file main/message.c.

413{
414 return 0;
415}

◆ chan_msg_write()

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

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

370{
371 return 0;
372}

◆ create_msg_q_chan()

static struct ast_channel * create_msg_q_chan ( void  )
static

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

742{
743 struct ast_channel *chan;
744 struct ast_datastore *ds;
745
747 NULL, NULL, NULL,
748 NULL, NULL, NULL, NULL, 0,
749 "%s", "Message/ast_msg_queue");
750
751 if (!chan) {
752 return NULL;
753 }
754
757 }
758
760 ast_channel_unlock(chan);
761 ast_channel_unlink(chan);
762
763 if (!(ds = ast_datastore_alloc(&msg_datastore, NULL))) {
764 ast_hangup(chan);
765 return NULL;
766 }
767
768 ast_channel_lock(chan);
770 ast_channel_unlock(chan);
771
772 return chan;
773}
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2510
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1299
void ast_channel_unlink(struct ast_channel *chan)
Remove a channel from the global channels container.
Definition: channel.c:10534
@ AST_CHAN_TP_INTERNAL
Channels with this particular technology are an implementation detail of Asterisk and should generall...
Definition: channel.h:991
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:340
#define ast_opt_hide_messaging_ami_events
Definition: options.h:138
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 864 of file main/message.c.

865{
866 struct ast_channel **chan = data;
867
868 if (!*chan) {
869 return;
870 }
871
872 ast_channel_release(*chan);
873}
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
Definition: channel.c:1551
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 878 of file main/message.c.

879{
880 struct ast_channel **chan_p, *chan;
881 struct ast_datastore *ds;
882
883 if (!(chan_p = ast_threadstorage_get(&msg_q_chan, sizeof(struct ast_channel *)))) {
884 return -1;
885 }
886 if (!*chan_p) {
887 if (!(*chan_p = create_msg_q_chan())) {
888 return -1;
889 }
890 }
891 chan = *chan_p;
892
893 ast_channel_lock(chan);
894 if (!(ds = ast_channel_datastore_find(chan, &msg_datastore, NULL))) {
895 ast_channel_unlock(chan);
896 return -1;
897 }
898 ao2_ref(msg, +1);
899 ds->data = msg;
900 ast_channel_unlock(chan);
901
902 msg_route(chan, msg);
903 chan_cleanup(chan);
904
905 return 0;
906}
static void chan_cleanup(struct ast_channel *chan)
Definition: main/message.c:800
static struct ast_channel * create_msg_q_chan(void)
Definition: main/message.c:741
static struct ast_threadstorage msg_q_chan
Definition: main/message.c:875
static void msg_route(struct ast_channel *chan, struct ast_msg *msg)
Definition: main/message.c:782
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 909 of file main/message.c.

910{
911 if (ast_strlen_zero(msg->context)) {
912 return 0;
913 }
914
915 return ast_exists_extension(NULL, msg->context, S_OR(msg->exten, "s"), 1, NULL);
916}
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:4190
const ast_string_field context
Definition: main/message.c:275
const ast_string_field exten
Definition: main/message.c:275

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 1744 of file main/message.c.

1745{
1747
1751 ast_manager_unregister("MessageSend");
1752
1755
1758}
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7699
#define ast_rwlock_destroy(rwlock)
Definition: lock.h:240
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 582 of file main/message.c.

583{
584 struct msg_data *data;
585
586 if (!(data = ao2_alloc(sizeof(*data), msg_data_destructor))) {
587 return NULL;
588 }
589
590 if (ast_string_field_init(data, 32)) {
591 ao2_ref(data, -1);
592 return NULL;
593 }
594
595 return data;
596}
static void msg_data_destructor(void *obj)
Definition: main/message.c:430

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 424 of file main/message.c.

425{
426 const struct msg_data *one = obj, *two = arg;
427 return !strcasecmp(one->name, two->name) ? CMP_MATCH | CMP_STOP : 0;
428}
@ 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 430 of file main/message.c.

431{
432 struct msg_data *data = obj;
434}
#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 598 of file main/message.c.

599{
600 struct msg_data tmp = {
601 .name = name,
602 };
603 return ao2_find(vars, &tmp, OBJ_POINTER);
604}
#define OBJ_POINTER
Definition: astobj2.h:1150
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736

References ao2_find, name, msg_data::name, and OBJ_POINTER.

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 1129 of file main/message.c.

1131{
1132 struct ast_datastore *ds;
1133 struct ast_msg *msg;
1134 const char *val;
1135
1136 if (!chan) {
1137 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
1138 return -1;
1139 }
1140
1141 ast_channel_lock(chan);
1142
1143 if (!(ds = ast_channel_datastore_find(chan, &msg_datastore, NULL))) {
1144 ast_channel_unlock(chan);
1145 ast_log(LOG_ERROR, "No MESSAGE data found on the channel to read.\n");
1146 return -1;
1147 }
1148
1149 msg = ds->data;
1150 ao2_ref(msg, +1);
1151 ast_channel_unlock(chan);
1152
1153 ao2_lock(msg);
1154
1155 if ((val = ast_msg_get_var(msg, data))) {
1157 }
1158
1159 ao2_unlock(msg);
1160 ao2_ref(msg, -1);
1161
1162 return 0;
1163}
#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:646
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 1165 of file main/message.c.

1167{
1168 struct ast_datastore *ds;
1169 struct ast_msg *msg;
1170
1171 if (!chan) {
1172 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
1173 return -1;
1174 }
1175
1176 ast_channel_lock(chan);
1177
1178 if (!(ds = msg_datastore_find_or_create(chan))) {
1179 ast_channel_unlock(chan);
1180 return -1;
1181 }
1182
1183 msg = ds->data;
1184 ao2_ref(msg, +1);
1185 ast_channel_unlock(chan);
1186
1187 ao2_lock(msg);
1188
1189 ast_msg_set_var_outbound(msg, data, value);
1190
1191 ao2_unlock(msg);
1192 ao2_ref(msg, -1);
1193
1194 return 0;
1195}
static struct ast_datastore * msg_datastore_find_or_create(struct ast_channel *chan)

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 1006 of file main/message.c.

1007{
1008 struct ast_datastore *ds;
1009
1010 if ((ds = ast_channel_datastore_find(chan, &msg_datastore, NULL))) {
1011 return ds;
1012 }
1013
1014 if (!(ds = ast_datastore_alloc(&msg_datastore, NULL))) {
1015 return NULL;
1016 }
1017
1018 if (!(ds->data = ast_msg_alloc())) {
1020 return NULL;
1021 }
1022
1023 ast_channel_datastore_add(chan, ds);
1024
1025 return ds;
1026}

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 436 of file main/message.c.

437{
438 struct ast_msg *msg = obj;
439
441 ao2_cleanup(msg->vars);
442}

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 417 of file main/message.c.

418{
419 struct ast_msg *msg = data;
420
421 ao2_ref(msg, -1);
422}

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 1208 of file main/message.c.

1209{
1210 const struct ast_msg_tech *current;
1211 int i;
1212
1213 for (i = 0; i < AST_VECTOR_SIZE(&msg_techs); i++) {
1215 if (!strcmp(current->name, tech_name)) {
1216 return current;
1217 }
1218 }
1219
1220 return NULL;
1221}
size_t current
Definition: main/message.c:284

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 1028 of file main/message.c.

1030{
1031 struct ast_datastore *ds;
1032 struct ast_msg *msg;
1033
1034 if (!chan) {
1035 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
1036 return -1;
1037 }
1038
1039 ast_channel_lock(chan);
1040
1041 if (!(ds = ast_channel_datastore_find(chan, &msg_datastore, NULL))) {
1042 ast_channel_unlock(chan);
1043 ast_log(LOG_ERROR, "No MESSAGE data found on the channel to read.\n");
1044 return -1;
1045 }
1046
1047 msg = ds->data;
1048 ao2_ref(msg, +1);
1049 ast_channel_unlock(chan);
1050
1051 ao2_lock(msg);
1052
1053 if (!strcasecmp(data, "to")) {
1054 ast_copy_string(buf, msg->to, len);
1055 } else if (!strcasecmp(data, "from")) {
1056 ast_copy_string(buf, msg->from, len);
1057 } else if (!strcasecmp(data, "body")) {
1058 ast_copy_string(buf, msg->body, len);
1059 } else {
1060 ast_log(LOG_WARNING, "Invalid argument to MESSAGE(): '%s'\n", data);
1061 }
1062
1063 ao2_unlock(msg);
1064 ao2_ref(msg, -1);
1065
1066 return 0;
1067}

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 1069 of file main/message.c.

1071{
1072 struct ast_datastore *ds;
1073 struct ast_msg *msg;
1074
1075 if (!chan) {
1076 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
1077 return -1;
1078 }
1079
1080 ast_channel_lock(chan);
1081
1082 if (!(ds = msg_datastore_find_or_create(chan))) {
1083 ast_channel_unlock(chan);
1084 return -1;
1085 }
1086
1087 msg = ds->data;
1088 ao2_ref(msg, +1);
1089 ast_channel_unlock(chan);
1090
1091 ao2_lock(msg);
1092
1093 if (!strcasecmp(data, "to")) {
1094 ast_msg_set_to(msg, "%s", value);
1095 } else if (!strcasecmp(data, "from")) {
1096 ast_msg_set_from(msg, "%s", value);
1097 } else if (!strcasecmp(data, "body")) {
1098 ast_msg_set_body(msg, "%s", value);
1099 } else if (!strcasecmp(data, "custom_data")) {
1100 int outbound = -1;
1101 if (!strcasecmp(value, "mark_all_outbound")) {
1102 outbound = 1;
1103 } else if (!strcasecmp(value, "clear_all_outbound")) {
1104 outbound = 0;
1105 } else {
1106 ast_log(LOG_WARNING, "'%s' is not a valid value for custom_data\n", value);
1107 }
1108
1109 if (outbound != -1) {
1110 struct msg_data *hdr_data;
1111 struct ao2_iterator iter = ao2_iterator_init(msg->vars, 0);
1112
1113 while ((hdr_data = ao2_iterator_next(&iter))) {
1114 hdr_data->send = outbound;
1115 ao2_ref(hdr_data, -1);
1116 }
1117 ao2_iterator_destroy(&iter);
1118 }
1119 } else {
1120 ast_log(LOG_WARNING, "'%s' is not a valid write argument.\n", data);
1121 }
1122
1123 ao2_unlock(msg);
1124 ao2_ref(msg, -1);
1125
1126 return 0;
1127}
int ast_msg_set_from(struct ast_msg *msg, const char *fmt,...)
Set the 'from' URI of a message.
Definition: main/message.c:491
int ast_msg_set_to(struct ast_msg *msg, const char *fmt,...)
Set the 'to' URI of a message.
Definition: main/message.c:480
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 1706 of file main/message.c.

1707{
1708 return !strcmp(vec_elem->name, srch->name);
1709}
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 1234 of file main/message.c.

1235{
1236 const struct ast_msg_handler *current;
1237 int i;
1238
1239 for (i = 0; i < AST_VECTOR_SIZE(&msg_handlers); i++) {
1241 if (!strcmp(current->name, tech_name)) {
1242 return current;
1243 }
1244 }
1245
1246 return NULL;
1247}

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 933 of file main/message.c.

934{
935 struct ast_msg *msg = data;
936 int res = 1;
937 int i;
938
940 for (i = 0; i < AST_VECTOR_SIZE(&msg_handlers); i++) {
942
943 if (!handler->has_destination(msg)) {
944 ast_debug(5, "Handler %s doesn't want message, moving on\n", handler->name);
945 continue;
946 }
947
948 ast_debug(5, "Dispatching message to %s handler\n", handler->name);
949 res &= handler->handle_msg(msg);
950 }
952
953 if (res != 0) {
954 ast_log(LOG_WARNING, "No handler processed message from %s to %s\n",
955 S_OR(msg->from, "<unknown>"), S_OR(msg->to, "<unknown>"));
956 }
957
958 ao2_ref(msg, -1);
959
960 return res;
961}

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 782 of file main/message.c.

783{
784 struct ast_pbx_args pbx_args;
785
786 ast_explicit_goto(chan, msg->context, S_OR(msg->exten, "s"), 1);
787
788 memset(&pbx_args, 0, sizeof(pbx_args));
789 pbx_args.no_hangup_chan = 1,
790 ast_pbx_run_args(chan, &pbx_args);
791}
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:4750
int ast_explicit_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:6960
Options for ast_pbx_run()
Definition: pbx.h:408

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 1253 of file main/message.c.

1254{
1255 struct ast_datastore *ds;
1256 struct ast_msg *msg;
1257 char *tech_name;
1258 const struct ast_msg_tech *msg_tech;
1259 char *parse;
1260 int res = -1;
1262 AST_APP_ARG(destination);
1263 AST_APP_ARG(from);
1264 AST_APP_ARG(to);
1265 );
1266
1267 if (ast_strlen_zero(data)) {
1268 ast_log(LOG_WARNING, "An argument is required to MessageSend()\n");
1269 pbx_builtin_setvar_helper(chan, "MESSAGE_SEND_STATUS", "INVALID_URI");
1270 return 0;
1271 }
1272
1273 parse = ast_strdupa(data);
1275
1276 if (ast_strlen_zero(args.destination)) {
1277 ast_log(LOG_WARNING, "A 'to' URI is required for MessageSend()\n");
1278 pbx_builtin_setvar_helper(chan, "MESSAGE_SEND_STATUS", "INVALID_URI");
1279 return 0;
1280 }
1281
1282 ast_channel_lock(chan);
1283
1284 if (!(ds = ast_channel_datastore_find(chan, &msg_datastore, NULL))) {
1285 ast_channel_unlock(chan);
1286 ast_log(LOG_WARNING, "No message data found on channel to send.\n");
1287 pbx_builtin_setvar_helper(chan, "MESSAGE_SEND_STATUS", "FAILURE");
1288 return 0;
1289 }
1290
1291 msg = ds->data;
1292 ao2_ref(msg, +1);
1293 ast_channel_unlock(chan);
1294
1295 tech_name = ast_strdupa(args.destination);
1296 tech_name = strsep(&tech_name, ":");
1297
1299 msg_tech = msg_find_by_tech_name(tech_name);
1300
1301 if (!msg_tech) {
1302 ast_log(LOG_WARNING, "No message technology '%s' found.\n", tech_name);
1303 pbx_builtin_setvar_helper(chan, "MESSAGE_SEND_STATUS", "INVALID_PROTOCOL");
1304 goto exit_cleanup;
1305 }
1306
1307 /*
1308 * If there was a "to" in the call to MessageSend,
1309 * replace the to already in the channel datastore.
1310 */
1311 if (!ast_strlen_zero(args.to)) {
1312 ast_string_field_set(msg, to, args.to);
1313 }
1314
1315 /*
1316 * The message lock is held here to safely allow the technology
1317 * implementation to access the message fields without worrying
1318 * that they could change.
1319 */
1320 ao2_lock(msg);
1321 res = msg_tech->msg_send(msg, S_OR(args.destination, ""), S_OR(args.from, ""));
1322 ao2_unlock(msg);
1323
1324 pbx_builtin_setvar_helper(chan, "MESSAGE_SEND_STATUS", res ? "FAILURE" : "SUCCESS");
1325
1326exit_cleanup:
1328 ao2_ref(msg, -1);
1329
1330 return 0;
1331}
#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 606 of file main/message.c.

607{
608 struct msg_data *data;
609
610 if (!(data = msg_data_find(msg->vars, name))) {
611 if (ast_strlen_zero(value)) {
612 return 0;
613 }
614 if (!(data = msg_data_alloc())) {
615 return -1;
616 };
617
620 data->send = outbound;
621 ao2_link(msg->vars, data);
622 } else {
623 if (ast_strlen_zero(value)) {
624 ao2_unlink(msg->vars, data);
625 } else {
627 data->send = outbound;
628 }
629 }
630
631 ao2_ref(data, -1);
632
633 return 0;
634}
#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:582

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 1645 of file main/message.c.

1646{
1647 return !strcmp(vec_elem->name, srch->name);
1648}

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 294 of file main/message.c.

Referenced by ast_msg_init(), and message_shutdown().

◆ current

size_t current

Definition at line 284 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:878
static int dialplan_has_destination_cb(const struct ast_msg *msg)
Definition: main/message.c:909

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

Referenced by ast_msg_init(), and message_shutdown().

◆ elems

const struct ast_msg_handler* * elems

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

◆ max

size_t max

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

◆ msg_chan_tech_hack

struct ast_channel_tech msg_chan_tech_hack
static

Definition at line 340 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 319 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:417

Definition at line 298 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 308 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 875 of file main/message.c.

Referenced by dialplan_handle_msg_cb().

◆ msg_q_tp

struct ast_taskprocessor* msg_q_tp
static

Definition at line 292 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