Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
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 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...
 
 AST_VECTOR (const struct ast_msg_tech *)
 Vector of message technologies. 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 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 struct ast_custom_function msg_function
 
static struct ast_threadstorage msg_q_chan = { .once = PTHREAD_ONCE_INIT , .key_init = __init_msg_q_chan , .custom_init = NULL , }
 
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 message.c.

Macro Definition Documentation

◆ ATTRIBUTE_UNSET

#define ATTRIBUTE_UNSET   -1

Definition at line 1416 of file message.c.

Referenced by ast_msg_data_alloc(), and ast_msg_data_get_attribute().

Function Documentation

◆ __init_msg_q_chan()

static void __init_msg_q_chan ( void  )
static

Definition at line 849 of file message.c.

853 {

◆ action_messagesend()

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

Definition at line 1306 of file message.c.

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_strlen_zero, ast_variables_destroy(), astman_get_header(), astman_get_variables_order(), astman_send_ack(), astman_send_error(), msg_data::from, msg_data::msg, msg_find_by_tech_name(), ast_msg_tech::msg_send, msg_tech, ast_variable::name, ast_variable::next, NULL, ORDER_NATURAL, S_OR, strsep(), ast_variable::value, and ast_msg::vars.

Referenced by ast_msg_init().

1307 {
1308  const char *to = ast_strdupa(astman_get_header(m, "To"));
1309  const char *from = astman_get_header(m, "From");
1310  const char *body = astman_get_header(m, "Body");
1311  const char *base64body = astman_get_header(m, "Base64Body");
1312  char base64decoded[1301] = { 0, };
1313  char *tech_name = NULL;
1314  struct ast_variable *vars = NULL;
1315  struct ast_variable *data = NULL;
1316  const struct ast_msg_tech *msg_tech;
1317  struct ast_msg *msg;
1318  int res = -1;
1319 
1320  if (ast_strlen_zero(to)) {
1321  astman_send_error(s, m, "No 'To' address specified.");
1322  return 0;
1323  }
1324 
1325  if (!ast_strlen_zero(base64body)) {
1326  ast_base64decode((unsigned char *) base64decoded, base64body, sizeof(base64decoded) - 1);
1327  body = base64decoded;
1328  }
1329 
1330  tech_name = ast_strdupa(to);
1331  tech_name = strsep(&tech_name, ":");
1332 
1334  msg_tech = msg_find_by_tech_name(tech_name);
1335  if (!msg_tech) {
1337  astman_send_error(s, m, "Message technology not found.");
1338  return 0;
1339  }
1340 
1341  if (!(msg = ast_msg_alloc())) {
1343  astman_send_error(s, m, "Internal failure\n");
1344  return 0;
1345  }
1346 
1348  for (vars = data; vars; vars = vars->next) {
1349  ast_msg_set_var_outbound(msg, vars->name, vars->value);
1350  }
1351 
1352  ast_msg_set_body(msg, "%s", body);
1353 
1354  res = msg_tech->msg_send(msg, S_OR(to, ""), S_OR(from, ""));
1355 
1357 
1358  ast_variables_destroy(vars);
1359  ao2_ref(msg, -1);
1360 
1361  if (res) {
1362  astman_send_error(s, m, "Message failed to send.");
1363  } else {
1364  astman_send_ack(s, m, "Message successfully sent");
1365  }
1366  return 0;
1367 }
struct ast_variable * next
#define ast_rwlock_rdlock(a)
Definition: lock.h:233
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
struct ast_msg * ast_msg_alloc(void)
Allocate a message.
Definition: message.c:418
Structure for variables, used for configurations and for channel variables.
static const struct ast_msg_tech * msg_find_by_tech_name(const char *tech_name)
Definition: message.c:1181
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
static const struct ast_msg_tech msg_tech
#define NULL
Definition: resample.c:96
#define ast_rwlock_unlock(a)
Definition: lock.h:232
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
int ast_base64decode(unsigned char *dst, const char *src, int max)
Decode data from base64.
Definition: main/utils.c:294
struct ao2_container * vars
Definition: message.c:251
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
A message technology.
Definition: message.h:52
static ast_rwlock_t msg_techs_lock
Lock for msg_techs vector.
Definition: message.c:255
char * strsep(char **str, const char *delims)
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:2911
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
int(*const msg_send)(const struct ast_msg *msg, const char *to, const char *from)
Send a message.
Definition: message.h:75
A message.
Definition: message.c:233
int ast_msg_set_body(struct ast_msg *msg, const char *fmt,...)
Set the 'body' text of a message (in UTF-8)
Definition: message.c:476
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
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: message.c:610

◆ 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 418 of file message.c.

References ao2_alloc, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_list, ao2_ref, ast_string_field_init, ast_string_field_set, context, msg_data::msg, 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(), receive_message(), send_message(), and xmpp_pak_message().

419 {
420  struct ast_msg *msg;
421 
422  if (!(msg = ao2_alloc(sizeof(*msg), msg_destructor))) {
423  return NULL;
424  }
425 
426  if (ast_string_field_init(msg, 128)) {
427  ao2_ref(msg, -1);
428  return NULL;
429  }
430 
433  if (!msg->vars) {
434  ao2_ref(msg, -1);
435  return NULL;
436  }
437  ast_string_field_set(msg, context, "default");
438 
439  return msg;
440 }
static int msg_data_cmp_fn(void *obj, void *arg, int flags)
Definition: message.c:398
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1335
#define NULL
Definition: resample.c:96
static void msg_destructor(void *obj)
Definition: message.c:410
struct ao2_container * vars
Definition: message.c:251
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
A message.
Definition: message.c:233
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

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

Returns
NULL, always.

Definition at line 448 of file message.c.

References ao2_ref, and NULL.

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

449 {
450  ao2_ref(msg, -1);
451  return NULL;
452 }
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464

◆ 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 531 of file message.c.

References ast_msg::body.

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

532 {
533  return msg->body;
534 }
const ast_string_field body
Definition: message.c:249

◆ 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
Return values
Theendpoint associated with the message
NULLor empty string if the message has no associated endpoint

Definition at line 551 of file message.c.

References ast_msg::endpoint.

Referenced by AST_TEST_DEFINE(), and msg_to_endpoint().

552 {
553  return msg->endpoint;
554 }
const ast_string_field endpoint
Definition: message.c:249

◆ 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
Return values
Thesource of the message
NULLor empty string if the message has no source

Definition at line 536 of file message.c.

References ast_msg::from.

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

537 {
538  return msg->from;
539 }
const ast_string_field from
Definition: message.c:249

◆ 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
Return values
Thetechnology of the message
NULLor empty string if the message has no associated technology

Definition at line 546 of file message.c.

References ast_msg::tech.

Referenced by AST_TEST_DEFINE(), and msg_to_endpoint().

547 {
548  return msg->tech;
549 }
const ast_string_field tech
Definition: message.c:249

◆ 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
Return values
Thedestination of the message
NULLor empty string if the message has no destination

Definition at line 541 of file message.c.

References ast_msg::to.

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

542 {
543  return msg->to;
544 }
const ast_string_field to
Definition: message.c:249

◆ 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 620 of file message.c.

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

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

621 {
622  struct msg_data *data;
623  const char *val = NULL;
624 
625  if (!(data = msg_data_find(msg->vars, name))) {
626  return NULL;
627  }
628 
629  /* Yep, this definitely looks like val would be a dangling pointer
630  * after the ref count is decremented. As long as the message structure
631  * is used in a thread safe manner, this will not be the case though.
632  * The ast_msg holds a reference to this object in the msg->vars container. */
633  val = data->value;
634  ao2_ref(data, -1);
635 
636  return val;
637 }
Definition: ast_expr2.c:325
#define NULL
Definition: resample.c:96
struct ao2_container * vars
Definition: message.c:251
static struct msg_data * msg_data_find(struct ao2_container *vars, const char *name)
Definition: message.c:572
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static const char name[]
Definition: cdr_mysql.c:74
const ast_string_field value
Definition: message.c:224

◆ 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 1629 of file message.c.

References ast_log, ast_rwlock_unlock, ast_rwlock_wrlock, AST_VECTOR_APPEND, ast_verb, LOG_ERROR, match(), msg_handler_find_by_tech_name(), and ast_msg_handler::name.

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

1630 {
1631  const struct ast_msg_handler *match;
1632 
1633  ast_rwlock_wrlock(&msg_handlers_lock);
1634 
1635  match = msg_handler_find_by_tech_name(handler->name);
1636  if (match) {
1637  ast_log(LOG_ERROR, "Message handler already registered for '%s'\n",
1638  handler->name);
1639  ast_rwlock_unlock(&msg_handlers_lock);
1640  return -1;
1641  }
1642 
1643  if (AST_VECTOR_APPEND(&msg_handlers, handler)) {
1644  ast_log(LOG_ERROR, "Failed to register message handler for '%s'\n",
1645  handler->name);
1646  ast_rwlock_unlock(&msg_handlers_lock);
1647  return -1;
1648  }
1649  ast_verb(2, "Message handler '%s' registered.\n", handler->name);
1650 
1651  ast_rwlock_unlock(&msg_handlers_lock);
1652 
1653  return 0;
1654 
1655 }
An external processor of received messages.
Definition: message.h:98
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2315
#define ast_rwlock_unlock(a)
Definition: lock.h:232
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
const char * name
Name of the message handler.
Definition: message.h:102
#define ast_rwlock_wrlock(a)
Definition: lock.h:234
static const struct ast_msg_handler * msg_handler_find_by_tech_name(const char *tech_name)
Definition: message.c:1207

◆ 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 1671 of file message.c.

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_handler_cmp(), and ast_msg_handler::name.

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

1672 {
1673  int match;
1674 
1675  ast_rwlock_wrlock(&msg_handlers_lock);
1676  match = AST_VECTOR_REMOVE_CMP_UNORDERED(&msg_handlers, handler, msg_handler_cmp,
1678  ast_rwlock_unlock(&msg_handlers_lock);
1679 
1680  if (match) {
1681  ast_log(LOG_ERROR, "No '%s' message handler found.\n", handler->name);
1682  return -1;
1683  }
1684 
1685  ast_verb(3, "Message handler '%s' unregistered.\n", handler->name);
1686  return 0;
1687 }
#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
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2315
#define ast_rwlock_unlock(a)
Definition: lock.h:232
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_log
Definition: astobj2.c:42
#define AST_VECTOR_ELEM_CLEANUP_NOOP(elem)
Vector element cleanup that does nothing.
Definition: vector.h:573
#define LOG_ERROR
Definition: logger.h:285
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.
Definition: message.c:1666
const char * name
Name of the message handler.
Definition: message.h:102
#define ast_rwlock_wrlock(a)
Definition: lock.h:234

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

References ast_debug, ast_rwlock_rdlock, ast_rwlock_unlock, AST_VECTOR_GET, AST_VECTOR_SIZE, handler(), ast_msg_handler::has_destination, ast_msg_handler::name, and result.

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

938 {
939  int i;
940  int result = 0;
941 
942  ast_rwlock_rdlock(&msg_handlers_lock);
943  for (i = 0; i < AST_VECTOR_SIZE(&msg_handlers); i++) {
944  const struct ast_msg_handler *handler = AST_VECTOR_GET(&msg_handlers, i);
945 
946  ast_debug(5, "Seeing if %s can handle message\n", handler->name);
947  if (handler->has_destination(msg)) {
948  ast_debug(5, "%s can handle message\n", handler->name);
949  result = 1;
950  break;
951  }
952  }
953  ast_rwlock_unlock(&msg_handlers_lock);
954 
955  return result;
956 }
#define ast_rwlock_rdlock(a)
Definition: lock.h:233
An external processor of received messages.
Definition: message.h:98
int(*const has_destination)(const struct ast_msg *msg)
Return whether or not the message has a valid destination.
Definition: message.h:127
#define ast_rwlock_unlock(a)
Definition: lock.h:232
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
const char * name
Name of the message handler.
Definition: message.h:102
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
static void handler(const char *name, int response_code, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Definition: test_ari.c:59
static PGresult * result
Definition: cel_pgsql.c:88
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ ast_msg_init()

int ast_msg_init ( void  )

Provided by message.c

Definition at line 1730 of file message.c.

References __ast_custom_function_register(), action_messagesend(), ast_manager_register_xml_core, ast_msg_handler_register(), ast_register_application2(), ast_register_cleanup(), ast_rwlock_init, ast_taskprocessor_get(), AST_VECTOR_INIT, EVENT_FLAG_MESSAGE, message_shutdown(), msg_send_exec(), NULL, and TPS_REF_DEFAULT.

Referenced by asterisk_daemon().

1731 {
1732  int res;
1733 
1734  msg_q_tp = ast_taskprocessor_get("ast_msg_queue", TPS_REF_DEFAULT);
1735  if (!msg_q_tp) {
1736  return -1;
1737  }
1738 
1740  if (AST_VECTOR_INIT(&msg_techs, 8)) {
1741  return -1;
1742  }
1743 
1744  ast_rwlock_init(&msg_handlers_lock);
1745  if (AST_VECTOR_INIT(&msg_handlers, 4)) {
1746  return -1;
1747  }
1748 
1750 
1753  res |= ast_register_application2(app_msg_send, msg_send_exec, NULL, NULL, NULL);
1755 
1757 
1758  return res;
1759 }
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...
int ast_msg_handler_register(const struct ast_msg_handler *handler)
Register a ast_msg_handler.
Definition: message.c:1629
return a reference to a taskprocessor, create one if it does not exist
Definition: taskprocessor.h:75
static void message_shutdown(void)
Definition: message.c:1704
static struct ast_custom_function msg_function
Definition: message.c:282
#define NULL
Definition: resample.c:96
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:197
static struct ast_custom_function msg_data_function
Definition: message.c:293
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
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:222
static int msg_send_exec(struct ast_channel *chan, const char *data)
Definition: message.c:1226
static struct ast_msg_handler dialplan_msg_handler
Definition: message.c:892
static ast_rwlock_t msg_techs_lock
Lock for msg_techs vector.
Definition: message.c:255
int __ast_custom_function_register(struct ast_custom_function *acf, struct ast_module *mod)
Register a custom function.
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
static int action_messagesend(struct mansession *s, const struct message *m)
Definition: message.c:1306
#define EVENT_FLAG_MESSAGE
Definition: manager.h:91

◆ 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 958 of file message.c.

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

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

959 {
960  int res;
961  res = ast_taskprocessor_push(msg_q_tp, msg_q_cb, msg);
962  if (res == -1) {
963  ao2_ref(msg, -1);
964  }
965 
966  return res;
967 }
static int msg_q_cb(void *data)
Definition: message.c:907
#define ao2_ref(o, delta)
Definition: astobj2.h:464
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.

◆ ast_msg_ref()

struct ast_msg* ast_msg_ref ( struct ast_msg msg)

Bump a msg's ref count.

Definition at line 442 of file message.c.

References ao2_ref, and msg_data::msg.

Referenced by msg_data_create().

443 {
444  ao2_ref(msg, 1);
445  return msg;
446 }
#define ao2_ref(o, delta)
Definition: astobj2.h:464

◆ 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 1369 of file message.c.

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, NULL, S_OR, and strsep().

Referenced by AST_TEST_DEFINE(), and send_message().

1370 {
1371  char *tech_name = NULL;
1372  const struct ast_msg_tech *msg_tech;
1373  int res = -1;
1374 
1375  if (ast_strlen_zero(to)) {
1376  ao2_ref(msg, -1);
1377  return -1;
1378  }
1379 
1380  tech_name = ast_strdupa(to);
1381  tech_name = strsep(&tech_name, ":");
1382 
1384  msg_tech = msg_find_by_tech_name(tech_name);
1385 
1386  if (!msg_tech) {
1387  ast_log(LOG_ERROR, "Unknown message tech: %s\n", tech_name);
1389  return -1;
1390  }
1391 
1392  res = msg_tech->msg_send(msg, S_OR(to, ""), S_OR(from, ""));
1393 
1395 
1396  ao2_ref(msg, -1);
1397 
1398  return res;
1399 }
#define ast_rwlock_rdlock(a)
Definition: lock.h:233
static const struct ast_msg_tech * msg_find_by_tech_name(const char *tech_name)
Definition: message.c:1181
static const struct ast_msg_tech msg_tech
#define NULL
Definition: resample.c:96
#define ast_rwlock_unlock(a)
Definition: lock.h:232
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define LOG_ERROR
Definition: logger.h:285
A message technology.
Definition: message.h:52
static ast_rwlock_t msg_techs_lock
Lock for msg_techs vector.
Definition: message.c:255
char * strsep(char **str, const char *delims)
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
int(*const msg_send)(const struct ast_msg *msg, const char *to, const char *from)
Send a message.
Definition: message.h:75

◆ 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 476 of file message.c.

References ast_string_field_build_va, and ast_msg::body.

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

477 {
478  va_list ap;
479 
480  va_start(ap, fmt);
481  ast_string_field_build_va(msg, body, fmt, ap);
482  va_end(ap);
483 
484  return 0;
485 }
#define ast_string_field_build_va(x, field, fmt, args)
Set a field to a complex (built) value.
Definition: stringfields.h:588

◆ 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 487 of file message.c.

References ast_string_field_build_va, and context.

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

488 {
489  va_list ap;
490 
491  va_start(ap, fmt);
492  ast_string_field_build_va(msg, context, fmt, ap);
493  va_end(ap);
494 
495  return 0;
496 }
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
#define ast_string_field_build_va(x, field, fmt, args)
Set a field to a complex (built) value.
Definition: stringfields.h:588

◆ 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 520 of file message.c.

References ast_string_field_build_va, and ast_msg::endpoint.

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

521 {
522  va_list ap;
523 
524  va_start(ap, fmt);
525  ast_string_field_build_va(msg, endpoint, fmt, ap);
526  va_end(ap);
527 
528  return 0;
529 }
#define ast_string_field_build_va(x, field, fmt, args)
Set a field to a complex (built) value.
Definition: stringfields.h:588

◆ 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 498 of file message.c.

References ast_string_field_build_va, and exten.

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

499 {
500  va_list ap;
501 
502  va_start(ap, fmt);
503  ast_string_field_build_va(msg, exten, fmt, ap);
504  va_end(ap);
505 
506  return 0;
507 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
#define ast_string_field_build_va(x, field, fmt, args)
Set a field to a complex (built) value.
Definition: stringfields.h:588

◆ 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 465 of file message.c.

References ast_string_field_build_va, and msg_data::from.

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

466 {
467  va_list ap;
468 
469  va_start(ap, fmt);
470  ast_string_field_build_va(msg, from, fmt, ap);
471  va_end(ap);
472 
473  return 0;
474 }
#define ast_string_field_build_va(x, field, fmt, args)
Set a field to a complex (built) value.
Definition: stringfields.h:588

◆ 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 509 of file message.c.

References ast_string_field_build_va, and ast_msg::tech.

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

510 {
511  va_list ap;
512 
513  va_start(ap, fmt);
514  ast_string_field_build_va(msg, tech, fmt, ap);
515  va_end(ap);
516 
517  return 0;
518 }
#define ast_string_field_build_va(x, field, fmt, args)
Set a field to a complex (built) value.
Definition: stringfields.h:588

◆ 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 454 of file message.c.

References ast_string_field_build_va, and ast_msg::to.

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

455 {
456  va_list ap;
457 
458  va_start(ap, fmt);
459  ast_string_field_build_va(msg, to, fmt, ap);
460  va_end(ap);
461 
462  return 0;
463 }
#define ast_string_field_build_va(x, field, fmt, args)
Set a field to a complex (built) value.
Definition: stringfields.h:588

◆ 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 615 of file message.c.

References msg_set_var_full().

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

616 {
617  return msg_set_var_full(msg, name, value, 0);
618 }
int value
Definition: syslog.c:37
static int msg_set_var_full(struct ast_msg *msg, const char *name, const char *value, unsigned int outbound)
Definition: message.c:580
static const char name[]
Definition: cdr_mysql.c:74

◆ 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 610 of file message.c.

References msg_set_var_full().

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

611 {
612  return msg_set_var_full(msg, name, value, 1);
613 }
int value
Definition: syslog.c:37
static int msg_set_var_full(struct ast_msg *msg, const char *name, const char *value, unsigned int outbound)
Definition: message.c:580
static const char name[]
Definition: cdr_mysql.c:74

◆ ast_msg_shutdown()

void ast_msg_shutdown ( void  )

Provided by message.c

Definition at line 1689 of file message.c.

References ast_taskprocessor_unreference().

Referenced by can_safely_quit().

1690 {
1691  if (msg_q_tp) {
1692  msg_q_tp = ast_taskprocessor_unreference(msg_q_tp);
1693  }
1694 }
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.

◆ 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 1569 of file message.c.

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

Referenced by AST_TEST_DEFINE(), and load_module().

1570 {
1571  const struct ast_msg_tech *match;
1572 
1574 
1575  match = msg_find_by_tech_name(tech->name);
1576  if (match) {
1577  ast_log(LOG_ERROR, "Message technology already registered for '%s'\n",
1578  tech->name);
1580  return -1;
1581  }
1582 
1583  if (AST_VECTOR_APPEND(&msg_techs, tech)) {
1584  ast_log(LOG_ERROR, "Failed to register message technology for '%s'\n",
1585  tech->name);
1587  return -1;
1588  }
1589  ast_verb(3, "Message technology '%s' registered.\n", tech->name);
1590 
1592 
1593  return 0;
1594 }
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
const char *const name
Name of this message technology.
Definition: message.h:61
static const struct ast_msg_tech * msg_find_by_tech_name(const char *tech_name)
Definition: message.c:1181
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2315
#define ast_rwlock_unlock(a)
Definition: lock.h:232
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
A message technology.
Definition: message.h:52
static ast_rwlock_t msg_techs_lock
Lock for msg_techs vector.
Definition: message.c:255
#define ast_rwlock_wrlock(a)
Definition: lock.h:234

◆ 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 1610 of file message.c.

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(), and ast_msg_tech::name.

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

1611 {
1612  int match;
1613 
1615  match = AST_VECTOR_REMOVE_CMP_UNORDERED(&msg_techs, tech, msg_tech_cmp,
1618 
1619  if (match) {
1620  ast_log(LOG_ERROR, "No '%s' message technology found.\n", tech->name);
1621  return -1;
1622  }
1623 
1624  ast_verb(2, "Message technology '%s' unregistered.\n", tech->name);
1625 
1626  return 0;
1627 }
#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
const char *const name
Name of this message technology.
Definition: message.h:61
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2315
#define ast_rwlock_unlock(a)
Definition: lock.h:232
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_log
Definition: astobj2.c:42
#define AST_VECTOR_ELEM_CLEANUP_NOOP(elem)
Vector element cleanup that does nothing.
Definition: vector.h:573
#define LOG_ERROR
Definition: logger.h:285
static ast_rwlock_t msg_techs_lock
Lock for msg_techs vector.
Definition: message.c:255
#define ast_rwlock_wrlock(a)
Definition: lock.h:234
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.
Definition: message.c:1605

◆ 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 706 of file message.c.

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(), sip_msg_send(), and vars_to_headers().

707 {
708  if (iter) {
709  ao2_iterator_destroy(&iter->iter);
711  ast_free(iter);
712  }
713 }
struct ao2_iterator iter
Definition: message.c:640
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: message.c:700
#define ast_free(a)
Definition: astmm.h:182

◆ 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 658 of file message.c.

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

Referenced by ast_msg_var_iterator_next(), and ast_msg_var_iterator_next_received().

661 {
662  struct msg_data *data;
663 
664  if (!iter) {
665  return 0;
666  }
667 
668  /* Skip any that we're told to */
669  while ((data = ao2_iterator_next(&iter->iter)) && (data->send != send)) {
670  ao2_ref(data, -1);
671  }
672 
673  if (!data) {
674  return 0;
675  }
676 
677  if (data->send == send) {
678  *name = data->name;
679  *value = data->value;
680  }
681 
682  /* Leave the refcount to be cleaned up by the caller with
683  * ast_msg_var_unref_current after they finish with the pointers to the data */
684  iter->current_used = data;
685 
686  return 1;
687 }
struct ao2_iterator iter
Definition: message.c:640
unsigned int send
Definition: message.c:225
int value
Definition: syslog.c:37
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const ast_string_field name
Definition: message.c:224
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
static const char name[]
Definition: cdr_mysql.c:74
struct msg_data * current_used
Definition: message.c:641
const ast_string_field value
Definition: message.c:224

◆ 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 644 of file message.c.

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

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

645 {
646  struct ast_msg_var_iterator *iter;
647 
648  iter = ast_calloc(1, sizeof(*iter));
649  if (!iter) {
650  return NULL;
651  }
652 
653  iter->iter = ao2_iterator_init(msg->vars, 0);
654 
655  return iter;
656 }
struct ao2_iterator iter
Definition: message.c:640
#define NULL
Definition: resample.c:96
struct ao2_container * vars
Definition: message.c:251
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ 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 689 of file message.c.

References ast_msg_var_iterator_get_next().

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

690 {
691  return ast_msg_var_iterator_get_next(msg, iter, name, value, 1);
692 }
int value
Definition: syslog.c:37
static const char name[]
Definition: cdr_mysql.c:74
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: message.c:658

◆ 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 694 of file message.c.

References ast_msg_var_iterator_get_next().

Referenced by msg_to_json().

696 {
697  return ast_msg_var_iterator_get_next(msg, iter, name, value, 0);
698 }
int value
Definition: syslog.c:37
static const char name[]
Definition: cdr_mysql.c:74
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: message.c:658

◆ 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 700 of file message.c.

References ao2_cleanup, ast_msg_var_iterator::current_used, and NULL.

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

701 {
702  ao2_cleanup(iter->current_used);
703  iter->current_used = NULL;
704 }
#define NULL
Definition: resample.c:96
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct msg_data * current_used
Definition: message.c:641

◆ AST_VECTOR()

AST_VECTOR ( const struct ast_msg_tech )

Vector of message technologies.

Definition at line 258 of file message.c.

272  {
273  .type = "message",
274  .destroy = msg_ds_destroy,
275 };
static void msg_ds_destroy(void *data)
Definition: message.c:391

◆ chan_cleanup()

static void chan_cleanup ( struct ast_channel chan)
static

Definition at line 774 of file message.c.

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, and NULL.

Referenced by dialplan_handle_msg_cb().

775 {
776  struct ast_datastore *msg_ds, *ds;
777  struct varshead *headp;
778  struct ast_var_t *vardata;
779  struct ast_frame *cur;
780 
781  ast_channel_lock(chan);
782 
783  /*
784  * Remove the msg datastore. Free its data but keep around the datastore
785  * object and just reuse it.
786  */
787  if ((msg_ds = ast_channel_datastore_find(chan, &msg_datastore, NULL)) && msg_ds->data) {
788  ast_channel_datastore_remove(chan, msg_ds);
789  ao2_ref(msg_ds->data, -1);
790  msg_ds->data = NULL;
791  }
792 
793  /*
794  * Destroy all other datastores.
795  */
796  while ((ds = AST_LIST_REMOVE_HEAD(ast_channel_datastores(chan), entry))) {
797  ast_datastore_free(ds);
798  }
799 
800  /*
801  * Destroy all channel variables.
802  */
803  headp = ast_channel_varshead(chan);
804  while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) {
805  ast_var_delete(vardata);
806  }
807 
808  /*
809  * Remove frames from read queue
810  */
811  while ((cur = AST_LIST_REMOVE_HEAD(ast_channel_readq(chan), frame_list))) {
812  ast_frfree(cur);
813  }
814 
815  /*
816  * Restore msg datastore.
817  */
818  if (msg_ds) {
819  ast_channel_datastore_add(chan, msg_ds);
820  }
821 
822  /*
823  * Clear softhangup flags.
824  */
826 
827  /*
828  * Flush the alert pipe in case we miscounted somewhere when
829  * messing with frames on the read queue, we had to flush the
830  * read queue above, or we had an "Exceptionally long queue
831  * length" event.
832  */
834 
835  ast_channel_unlock(chan);
836 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Structure for a data store object.
Definition: datastore.h:68
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:2404
struct varshead * ast_channel_varshead(struct ast_channel *chan)
#define NULL
Definition: resample.c:96
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
ast_alert_status_t ast_channel_internal_alert_flush(struct ast_channel *chan)
struct ast_readq_list * ast_channel_readq(struct ast_channel *chan)
void ast_channel_clear_softhangup(struct ast_channel *chan, int flag)
Clear a set of softhangup flags from a channel.
Definition: channel.c:2437
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_datastore_list * ast_channel_datastores(struct ast_channel *chan)
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
void ast_var_delete(struct ast_var_t *var)
Definition: extconf.c:2473
#define ast_channel_unlock(chan)
Definition: channel.h:2946
All softhangup flags.
Definition: channel.h:1162
void * data
Definition: datastore.h:70
#define ast_frfree(fr)
Data structure associated with a single frame of data.
Definition: search.h:40
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2390
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2399

◆ chan_msg_indicate()

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

Definition at line 358 of file message.c.

360 {
361  return 0;
362 }

◆ chan_msg_read()

static struct ast_frame * chan_msg_read ( struct ast_channel chan)
static

Definition at line 332 of file message.c.

References ast_null_frame.

333 {
334  return &ast_null_frame;
335 }
struct ast_frame ast_null_frame
Definition: main/frame.c:79

◆ chan_msg_send_digit_begin()

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

Definition at line 372 of file message.c.

373 {
374  return 0;
375 }

◆ 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 385 of file message.c.

387 {
388  return 0;
389 }

◆ chan_msg_write()

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

Definition at line 343 of file message.c.

344 {
345  return 0;
346 }

◆ create_msg_q_chan()

static struct ast_channel* create_msg_q_chan ( void  )
static

Definition at line 715 of file message.c.

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, NULL, and ast_channel_tech::properties.

Referenced by dialplan_handle_msg_cb().

716 {
717  struct ast_channel *chan;
718  struct ast_datastore *ds;
719 
721  NULL, NULL, NULL,
722  NULL, NULL, NULL, NULL, 0,
723  "%s", "Message/ast_msg_queue");
724 
725  if (!chan) {
726  return NULL;
727  }
728 
731  }
732 
734  ast_channel_unlock(chan);
735  ast_channel_unlink(chan);
736 
737  if (!(ds = ast_datastore_alloc(&msg_datastore, NULL))) {
738  ast_hangup(chan);
739  return NULL;
740  }
741 
742  ast_channel_lock(chan);
743  ast_channel_datastore_add(chan, ds);
744  ast_channel_unlock(chan);
745 
746  return chan;
747 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
static struct ast_channel_tech msg_chan_tech_hack
Definition: message.c:314
Structure for a data store object.
Definition: datastore.h:68
#define NULL
Definition: resample.c:96
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
#define ast_opt_hide_messaging_ami_events
Definition: options.h:137
Channels with this particular technology are an implementation detail of Asterisk and should generall...
Definition: channel.h:972
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:89
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1259
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2390
void ast_channel_unlink(struct ast_channel *chan)
Remove a channel from the global channels container.
Definition: channel.c:10730

◆ destroy_msg_q_chan()

static void destroy_msg_q_chan ( void *  data)
static

Definition at line 838 of file message.c.

References ast_channel_release(), and ast_channel::data.

839 {
840  struct ast_channel **chan = data;
841 
842  if (!*chan) {
843  return;
844  }
845 
846  ast_channel_release(*chan);
847 }
Main Channel structure associated with a channel.
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
Definition: channel.c:1584
const char * data

◆ dialplan_handle_msg_cb()

static int dialplan_handle_msg_cb ( struct ast_msg msg)
static

Definition at line 852 of file message.c.

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_data::msg, msg_q_chan, msg_route(), and NULL.

853 {
854  struct ast_channel **chan_p, *chan;
855  struct ast_datastore *ds;
856 
857  if (!(chan_p = ast_threadstorage_get(&msg_q_chan, sizeof(struct ast_channel *)))) {
858  return -1;
859  }
860  if (!*chan_p) {
861  if (!(*chan_p = create_msg_q_chan())) {
862  return -1;
863  }
864  }
865  chan = *chan_p;
866 
867  ast_channel_lock(chan);
868  if (!(ds = ast_channel_datastore_find(chan, &msg_datastore, NULL))) {
869  ast_channel_unlock(chan);
870  return -1;
871  }
872  ao2_ref(msg, +1);
873  ds->data = msg;
874  ast_channel_unlock(chan);
875 
876  msg_route(chan, msg);
877  chan_cleanup(chan);
878 
879  return 0;
880 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
static void msg_route(struct ast_channel *chan, struct ast_msg *msg)
Definition: message.c:756
static struct ast_threadstorage msg_q_chan
Definition: message.c:849
Structure for a data store object.
Definition: datastore.h:68
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:2404
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static struct ast_channel * create_msg_q_chan(void)
Definition: message.c:715
void * data
Definition: datastore.h:70
static void chan_cleanup(struct ast_channel *chan)
Definition: message.c:774

◆ dialplan_has_destination_cb()

static int dialplan_has_destination_cb ( const struct ast_msg msg)
static

Definition at line 883 of file message.c.

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

884 {
885  if (ast_strlen_zero(msg->context)) {
886  return 0;
887  }
888 
889  return ast_exists_extension(NULL, msg->context, S_OR(msg->exten, "s"), 1, NULL);
890 }
#define NULL
Definition: resample.c:96
const ast_string_field exten
Definition: message.c:249
#define ast_strlen_zero(foo)
Definition: strings.h:52
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:4179
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const ast_string_field context
Definition: message.c:249

◆ message_shutdown()

static void message_shutdown ( void  )
static

Definition at line 1704 of file message.c.

References ast_custom_function_unregister(), ast_manager_unregister(), ast_msg_handler_unregister(), ast_rwlock_destroy, ast_unregister_application(), and AST_VECTOR_FREE.

Referenced by ast_msg_init().

1705 {
1707 
1710  ast_unregister_application(app_msg_send);
1711  ast_manager_unregister("MessageSend");
1712 
1713  AST_VECTOR_FREE(&msg_techs);
1715 
1716  AST_VECTOR_FREE(&msg_handlers);
1717  ast_rwlock_destroy(&msg_handlers_lock);
1718 }
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
#define ast_rwlock_destroy(rwlock)
Definition: lock.h:231
int ast_msg_handler_unregister(const struct ast_msg_handler *handler)
Unregister a ast_msg_handler.
Definition: message.c:1671
static struct ast_custom_function msg_function
Definition: message.c:282
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
static struct ast_custom_function msg_data_function
Definition: message.c:293
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7258
static struct ast_msg_handler dialplan_msg_handler
Definition: message.c:892
static ast_rwlock_t msg_techs_lock
Lock for msg_techs vector.
Definition: message.c:255

◆ msg_data_alloc()

static struct msg_data* msg_data_alloc ( void  )
static

Definition at line 556 of file message.c.

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

Referenced by msg_set_var_full().

557 {
558  struct msg_data *data;
559 
560  if (!(data = ao2_alloc(sizeof(*data), msg_data_destructor))) {
561  return NULL;
562  }
563 
564  if (ast_string_field_init(data, 32)) {
565  ao2_ref(data, -1);
566  return NULL;
567  }
568 
569  return data;
570 }
static void msg_data_destructor(void *obj)
Definition: message.c:404
#define NULL
Definition: resample.c:96
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411

◆ msg_data_cmp_fn()

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

Definition at line 398 of file message.c.

References CMP_MATCH, CMP_STOP, and msg_data::name.

Referenced by ast_msg_alloc().

399 {
400  const struct msg_data *one = obj, *two = arg;
401  return !strcasecmp(one->name, two->name) ? CMP_MATCH | CMP_STOP : 0;
402 }
const ast_string_field name
Definition: message.c:224

◆ msg_data_destructor()

static void msg_data_destructor ( void *  obj)
static

Definition at line 404 of file message.c.

References ast_string_field_free_memory.

Referenced by msg_data_alloc().

405 {
406  struct msg_data *data = obj;
408 }
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368

◆ msg_data_find()

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

Definition at line 572 of file message.c.

References ao2_find, msg_data::name, and OBJ_POINTER.

Referenced by ast_msg_get_var(), and msg_set_var_full().

573 {
574  struct msg_data tmp = {
575  .name = name,
576  };
577  return ao2_find(vars, &tmp, OBJ_POINTER);
578 }
#define OBJ_POINTER
Definition: astobj2.h:1154
static int tmp()
Definition: bt_open.c:389
static const char name[]
Definition: cdr_mysql.c:74
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756

◆ 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 1102 of file message.c.

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(), ast_datastore::data, LOG_ERROR, LOG_WARNING, msg_data::msg, and NULL.

1104 {
1105  struct ast_datastore *ds;
1106  struct ast_msg *msg;
1107  const char *val;
1108 
1109  if (!chan) {
1110  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
1111  return -1;
1112  }
1113 
1114  ast_channel_lock(chan);
1115 
1116  if (!(ds = ast_channel_datastore_find(chan, &msg_datastore, NULL))) {
1117  ast_channel_unlock(chan);
1118  ast_log(LOG_ERROR, "No MESSAGE data found on the channel to read.\n");
1119  return -1;
1120  }
1121 
1122  msg = ds->data;
1123  ao2_ref(msg, +1);
1124  ast_channel_unlock(chan);
1125 
1126  ao2_lock(msg);
1127 
1128  if ((val = ast_msg_get_var(msg, data))) {
1129  ast_copy_string(buf, val, len);
1130  }
1131 
1132  ao2_unlock(msg);
1133  ao2_ref(msg, -1);
1134 
1135  return 0;
1136 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Definition: ast_expr2.c:325
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
#define ao2_unlock(a)
Definition: astobj2.h:730
Structure for a data store object.
Definition: datastore.h:68
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:2404
const char * ast_msg_get_var(struct ast_msg *msg, const char *name)
Get the specified variable on the message.
Definition: message.c:620
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
#define LOG_ERROR
Definition: logger.h:285
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void * data
Definition: datastore.h:70
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
A message.
Definition: message.c:233

◆ 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 1138 of file message.c.

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_data::msg, and msg_datastore_find_or_create().

1140 {
1141  struct ast_datastore *ds;
1142  struct ast_msg *msg;
1143 
1144  if (!chan) {
1145  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
1146  return -1;
1147  }
1148 
1149  ast_channel_lock(chan);
1150 
1151  if (!(ds = msg_datastore_find_or_create(chan))) {
1152  ast_channel_unlock(chan);
1153  return -1;
1154  }
1155 
1156  msg = ds->data;
1157  ao2_ref(msg, +1);
1158  ast_channel_unlock(chan);
1159 
1160  ao2_lock(msg);
1161 
1162  ast_msg_set_var_outbound(msg, data, value);
1163 
1164  ao2_unlock(msg);
1165  ao2_ref(msg, -1);
1166 
1167  return 0;
1168 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define LOG_WARNING
Definition: logger.h:274
#define ao2_unlock(a)
Definition: astobj2.h:730
Structure for a data store object.
Definition: datastore.h:68
int value
Definition: syslog.c:37
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
static struct ast_datastore * msg_datastore_find_or_create(struct ast_channel *chan)
Definition: message.c:979
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void * data
Definition: datastore.h:70
A message.
Definition: message.c:233
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: message.c:610

◆ msg_datastore_find_or_create()

static struct ast_datastore* msg_datastore_find_or_create ( struct ast_channel chan)
static

Definition at line 979 of file message.c.

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

Referenced by msg_data_func_write(), and msg_func_write().

980 {
981  struct ast_datastore *ds;
982 
983  if ((ds = ast_channel_datastore_find(chan, &msg_datastore, NULL))) {
984  return ds;
985  }
986 
987  if (!(ds = ast_datastore_alloc(&msg_datastore, NULL))) {
988  return NULL;
989  }
990 
991  if (!(ds->data = ast_msg_alloc())) {
992  ast_datastore_free(ds);
993  return NULL;
994  }
995 
996  ast_channel_datastore_add(chan, ds);
997 
998  return ds;
999 }
struct ast_msg * ast_msg_alloc(void)
Allocate a message.
Definition: message.c:418
Structure for a data store object.
Definition: datastore.h:68
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:2404
#define NULL
Definition: resample.c:96
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
void * data
Definition: datastore.h:70
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:89
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2390

◆ msg_destructor()

static void msg_destructor ( void *  obj)
static

Definition at line 410 of file message.c.

References ao2_cleanup, ast_string_field_free_memory, msg_data::msg, and ast_msg::vars.

Referenced by ast_msg_alloc().

411 {
412  struct ast_msg *msg = obj;
413 
415  ao2_cleanup(msg->vars);
416 }
struct ao2_container * vars
Definition: message.c:251
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
A message.
Definition: message.c:233
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368

◆ msg_ds_destroy()

static void msg_ds_destroy ( void *  data)
static

Definition at line 391 of file message.c.

References ao2_ref, and msg_data::msg.

392 {
393  struct ast_msg *msg = data;
394 
395  ao2_ref(msg, -1);
396 }
#define ao2_ref(o, delta)
Definition: astobj2.h:464
A message.
Definition: message.c:233

◆ msg_find_by_tech_name()

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

Definition at line 1181 of file message.c.

References AST_VECTOR_GET, AST_VECTOR_SIZE, ast_msg_tech::name, and NULL.

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

1182 {
1183  const struct ast_msg_tech *current;
1184  int i;
1185 
1186  for (i = 0; i < AST_VECTOR_SIZE(&msg_techs); i++) {
1187  current = AST_VECTOR_GET(&msg_techs, i);
1188  if (!strcmp(current->name, tech_name)) {
1189  return current;
1190  }
1191  }
1192 
1193  return NULL;
1194 }
const char *const name
Name of this message technology.
Definition: message.h:61
#define NULL
Definition: resample.c:96
A message technology.
Definition: message.h:52
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

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

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, ast_datastore::data, ast_msg::from, LOG_ERROR, LOG_WARNING, msg_data::msg, NULL, and ast_msg::to.

1003 {
1004  struct ast_datastore *ds;
1005  struct ast_msg *msg;
1006 
1007  if (!chan) {
1008  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
1009  return -1;
1010  }
1011 
1012  ast_channel_lock(chan);
1013 
1014  if (!(ds = ast_channel_datastore_find(chan, &msg_datastore, NULL))) {
1015  ast_channel_unlock(chan);
1016  ast_log(LOG_ERROR, "No MESSAGE data found on the channel to read.\n");
1017  return -1;
1018  }
1019 
1020  msg = ds->data;
1021  ao2_ref(msg, +1);
1022  ast_channel_unlock(chan);
1023 
1024  ao2_lock(msg);
1025 
1026  if (!strcasecmp(data, "to")) {
1027  ast_copy_string(buf, msg->to, len);
1028  } else if (!strcasecmp(data, "from")) {
1029  ast_copy_string(buf, msg->from, len);
1030  } else if (!strcasecmp(data, "body")) {
1031  ast_copy_string(buf, msg->body, len);
1032  } else {
1033  ast_log(LOG_WARNING, "Invalid argument to MESSAGE(): '%s'\n", data);
1034  }
1035 
1036  ao2_unlock(msg);
1037  ao2_ref(msg, -1);
1038 
1039  return 0;
1040 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
const ast_string_field to
Definition: message.c:249
#define ao2_unlock(a)
Definition: astobj2.h:730
Structure for a data store object.
Definition: datastore.h:68
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:2404
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
const ast_string_field body
Definition: message.c:249
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
#define LOG_ERROR
Definition: logger.h:285
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_channel_unlock(chan)
Definition: channel.h:2946
const ast_string_field from
Definition: message.c:249
void * data
Definition: datastore.h:70
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
A message.
Definition: message.c:233

◆ msg_func_write()

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

Definition at line 1042 of file message.c.

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_data::msg, msg_datastore_find_or_create(), msg_data::send, and ast_msg::vars.

1044 {
1045  struct ast_datastore *ds;
1046  struct ast_msg *msg;
1047 
1048  if (!chan) {
1049  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", function);
1050  return -1;
1051  }
1052 
1053  ast_channel_lock(chan);
1054 
1055  if (!(ds = msg_datastore_find_or_create(chan))) {
1056  ast_channel_unlock(chan);
1057  return -1;
1058  }
1059 
1060  msg = ds->data;
1061  ao2_ref(msg, +1);
1062  ast_channel_unlock(chan);
1063 
1064  ao2_lock(msg);
1065 
1066  if (!strcasecmp(data, "to")) {
1067  ast_msg_set_to(msg, "%s", value);
1068  } else if (!strcasecmp(data, "from")) {
1069  ast_msg_set_from(msg, "%s", value);
1070  } else if (!strcasecmp(data, "body")) {
1071  ast_msg_set_body(msg, "%s", value);
1072  } else if (!strcasecmp(data, "custom_data")) {
1073  int outbound = -1;
1074  if (!strcasecmp(value, "mark_all_outbound")) {
1075  outbound = 1;
1076  } else if (!strcasecmp(value, "clear_all_outbound")) {
1077  outbound = 0;
1078  } else {
1079  ast_log(LOG_WARNING, "'%s' is not a valid value for custom_data\n", value);
1080  }
1081 
1082  if (outbound != -1) {
1083  struct msg_data *hdr_data;
1084  struct ao2_iterator iter = ao2_iterator_init(msg->vars, 0);
1085 
1086  while ((hdr_data = ao2_iterator_next(&iter))) {
1087  hdr_data->send = outbound;
1088  ao2_ref(hdr_data, -1);
1089  }
1090  ao2_iterator_destroy(&iter);
1091  }
1092  } else {
1093  ast_log(LOG_WARNING, "'%s' is not a valid write argument.\n", data);
1094  }
1095 
1096  ao2_unlock(msg);
1097  ao2_ref(msg, -1);
1098 
1099  return 0;
1100 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define LOG_WARNING
Definition: logger.h:274
unsigned int send
Definition: message.c:225
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_unlock(a)
Definition: astobj2.h:730
Structure for a data store object.
Definition: datastore.h:68
int value
Definition: syslog.c:37
#define ast_log
Definition: astobj2.c:42
struct ao2_container * vars
Definition: message.c:251
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
static struct ast_datastore * msg_datastore_find_or_create(struct ast_channel *chan)
Definition: message.c:979
int ast_msg_set_from(struct ast_msg *msg, const char *fmt,...)
Set the &#39;from&#39; URI of a message.
Definition: message.c:465
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void * data
Definition: datastore.h:70
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
A message.
Definition: message.c:233
int ast_msg_set_body(struct ast_msg *msg, const char *fmt,...)
Set the &#39;body&#39; text of a message (in UTF-8)
Definition: message.c:476
int ast_msg_set_to(struct ast_msg *msg, const char *fmt,...)
Set the &#39;to&#39; URI of a message.
Definition: message.c:454
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ 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 1666 of file message.c.

References ast_msg_handler::name.

Referenced by ast_msg_handler_unregister().

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

◆ 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 1207 of file message.c.

References AST_VECTOR_GET, AST_VECTOR_SIZE, ast_msg_handler::name, and NULL.

Referenced by ast_msg_handler_register().

1208 {
1209  const struct ast_msg_handler *current;
1210  int i;
1211 
1212  for (i = 0; i < AST_VECTOR_SIZE(&msg_handlers); i++) {
1213  current = AST_VECTOR_GET(&msg_handlers, i);
1214  if (!strcmp(current->name, tech_name)) {
1215  return current;
1216  }
1217  }
1218 
1219  return NULL;
1220 }
An external processor of received messages.
Definition: message.h:98
#define NULL
Definition: resample.c:96
const char * name
Name of the message handler.
Definition: message.h:102
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ msg_q_cb()

static int msg_q_cb ( void *  data)
static

Definition at line 907 of file message.c.

References ao2_ref, ast_debug, ast_log, ast_rwlock_rdlock, ast_rwlock_unlock, AST_VECTOR_GET, AST_VECTOR_SIZE, ast_msg::from, ast_msg_handler::handle_msg, handler(), ast_msg_handler::has_destination, LOG_WARNING, msg_data::msg, ast_msg_handler::name, S_OR, and ast_msg::to.

Referenced by ast_msg_queue().

908 {
909  struct ast_msg *msg = data;
910  int res = 1;
911  int i;
912 
913  ast_rwlock_rdlock(&msg_handlers_lock);
914  for (i = 0; i < AST_VECTOR_SIZE(&msg_handlers); i++) {
915  const struct ast_msg_handler *handler = AST_VECTOR_GET(&msg_handlers, i);
916 
917  if (!handler->has_destination(msg)) {
918  ast_debug(5, "Handler %s doesn't want message, moving on\n", handler->name);
919  continue;
920  }
921 
922  ast_debug(5, "Dispatching message to %s handler\n", handler->name);
923  res &= handler->handle_msg(msg);
924  }
925  ast_rwlock_unlock(&msg_handlers_lock);
926 
927  if (res != 0) {
928  ast_log(LOG_WARNING, "No handler processed message from %s to %s\n",
929  S_OR(msg->from, "<unknown>"), S_OR(msg->to, "<unknown>"));
930  }
931 
932  ao2_ref(msg, -1);
933 
934  return res;
935 }
#define ast_rwlock_rdlock(a)
Definition: lock.h:233
int(*const handle_msg)(struct ast_msg *msg)
The function callback that will handle the message.
Definition: message.h:112
An external processor of received messages.
Definition: message.h:98
#define LOG_WARNING
Definition: logger.h:274
const ast_string_field to
Definition: message.c:249
int(*const has_destination)(const struct ast_msg *msg)
Return whether or not the message has a valid destination.
Definition: message.h:127
#define ast_rwlock_unlock(a)
Definition: lock.h:232
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const ast_string_field from
Definition: message.c:249
const char * name
Name of the message handler.
Definition: message.h:102
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
static void 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
A message.
Definition: message.c:233
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ msg_route()

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

Definition at line 756 of file message.c.

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

757 {
758  struct ast_pbx_args pbx_args;
759 
760  ast_explicit_goto(chan, msg->context, S_OR(msg->exten, "s"), 1);
761 
762  memset(&pbx_args, 0, sizeof(pbx_args));
763  pbx_args.no_hangup_chan = 1,
764  ast_pbx_run_args(chan, &pbx_args);
765 }
Options for ast_pbx_run()
Definition: pbx.h:391
int ast_explicit_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:6987
const ast_string_field exten
Definition: message.c:249
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:4739
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const ast_string_field context
Definition: message.c:249

◆ msg_send_exec()

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

Definition at line 1226 of file message.c.

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, msg_data::destination, msg_data::from, LOG_WARNING, msg_data::msg, msg_find_by_tech_name(), ast_msg_tech::msg_send, msg_tech, NULL, parse(), pbx_builtin_setvar_helper(), S_OR, and strsep().

Referenced by ast_msg_init().

1227 {
1228  struct ast_datastore *ds;
1229  struct ast_msg *msg;
1230  char *tech_name;
1231  const struct ast_msg_tech *msg_tech;
1232  char *parse;
1233  int res = -1;
1235  AST_APP_ARG(destination);
1236  AST_APP_ARG(from);
1237  AST_APP_ARG(to);
1238  );
1239 
1240  if (ast_strlen_zero(data)) {
1241  ast_log(LOG_WARNING, "An argument is required to MessageSend()\n");
1242  pbx_builtin_setvar_helper(chan, "MESSAGE_SEND_STATUS", "INVALID_URI");
1243  return 0;
1244  }
1245 
1246  parse = ast_strdupa(data);
1247  AST_STANDARD_APP_ARGS(args, parse);
1248 
1249  if (ast_strlen_zero(args.destination)) {
1250  ast_log(LOG_WARNING, "A 'to' URI is required for MessageSend()\n");
1251  pbx_builtin_setvar_helper(chan, "MESSAGE_SEND_STATUS", "INVALID_URI");
1252  return 0;
1253  }
1254 
1255  ast_channel_lock(chan);
1256 
1257  if (!(ds = ast_channel_datastore_find(chan, &msg_datastore, NULL))) {
1258  ast_channel_unlock(chan);
1259  ast_log(LOG_WARNING, "No message data found on channel to send.\n");
1260  pbx_builtin_setvar_helper(chan, "MESSAGE_SEND_STATUS", "FAILURE");
1261  return 0;
1262  }
1263 
1264  msg = ds->data;
1265  ao2_ref(msg, +1);
1266  ast_channel_unlock(chan);
1267 
1268  tech_name = ast_strdupa(args.destination);
1269  tech_name = strsep(&tech_name, ":");
1270 
1272  msg_tech = msg_find_by_tech_name(tech_name);
1273 
1274  if (!msg_tech) {
1275  ast_log(LOG_WARNING, "No message technology '%s' found.\n", tech_name);
1276  pbx_builtin_setvar_helper(chan, "MESSAGE_SEND_STATUS", "INVALID_PROTOCOL");
1277  goto exit_cleanup;
1278  }
1279 
1280  /*
1281  * If there was a "to" in the call to MessageSend,
1282  * replace the to already in the channel datastore.
1283  */
1284  if (!ast_strlen_zero(args.to)) {
1285  ast_string_field_set(msg, to, args.to);
1286  }
1287 
1288  /*
1289  * The message lock is held here to safely allow the technology
1290  * implementation to access the message fields without worrying
1291  * that they could change.
1292  */
1293  ao2_lock(msg);
1294  res = msg_tech->msg_send(msg, S_OR(args.destination, ""), S_OR(args.from, ""));
1295  ao2_unlock(msg);
1296 
1297  pbx_builtin_setvar_helper(chan, "MESSAGE_SEND_STATUS", res ? "FAILURE" : "SUCCESS");
1298 
1299 exit_cleanup:
1301  ao2_ref(msg, -1);
1302 
1303  return 0;
1304 }
#define ast_rwlock_rdlock(a)
Definition: lock.h:233
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
static const struct ast_msg_tech * msg_find_by_tech_name(const char *tech_name)
Definition: message.c:1181
#define ao2_unlock(a)
Definition: astobj2.h:730
static const struct ast_msg_tech msg_tech
Structure for a data store object.
Definition: datastore.h:68
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:2404
const char * args
#define NULL
Definition: resample.c:96
#define ast_rwlock_unlock(a)
Definition: lock.h:232
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
A message technology.
Definition: message.h:52
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
static ast_rwlock_t msg_techs_lock
Lock for msg_techs vector.
Definition: message.c:255
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...
void * data
Definition: datastore.h:70
char * strsep(char **str, const char *delims)
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
int(*const msg_send)(const struct ast_msg *msg, const char *to, const char *from)
Send a message.
Definition: message.h:75
A message.
Definition: message.c:233
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ 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 580 of file message.c.

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

Referenced by ast_msg_set_var(), and ast_msg_set_var_outbound().

581 {
582  struct msg_data *data;
583 
584  if (!(data = msg_data_find(msg->vars, name))) {
585  if (ast_strlen_zero(value)) {
586  return 0;
587  }
588  if (!(data = msg_data_alloc())) {
589  return -1;
590  };
591 
594  data->send = outbound;
595  ao2_link(msg->vars, data);
596  } else {
597  if (ast_strlen_zero(value)) {
598  ao2_unlink(msg->vars, data);
599  } else {
601  data->send = outbound;
602  }
603  }
604 
605  ao2_ref(data, -1);
606 
607  return 0;
608 }
unsigned int send
Definition: message.c:225
static struct msg_data * msg_data_alloc(void)
Definition: message.c:556
int value
Definition: syslog.c:37
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ao2_container * vars
Definition: message.c:251
static struct msg_data * msg_data_find(struct ao2_container *vars, const char *name)
Definition: message.c:572
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598
static const char name[]
Definition: cdr_mysql.c:74
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ 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 1605 of file message.c.

References ast_msg_tech::name.

Referenced by ast_msg_tech_unregister().

1606 {
1607  return !strcmp(vec_elem->name, srch->name);
1608 }
const char *const name
Name of this message technology.
Definition: message.h:61

Variable Documentation

◆ 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_has_destination_cb(const struct ast_msg *msg)
Definition: message.c:883
static int dialplan_handle_msg_cb(struct ast_msg *msg)
Definition: message.c:852

Definition at line 892 of file message.c.

◆ msg_chan_tech_hack

struct ast_channel_tech msg_chan_tech_hack
static

Definition at line 314 of file message.c.

◆ 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)
Definition: message.c:1102
static int msg_data_func_write(struct ast_channel *chan, const char *function, char *data, const char *value)
Definition: message.c:1138

Definition at line 293 of file message.c.

◆ 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)
Definition: message.c:1042
static int msg_func_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
Definition: message.c:1001

Definition at line 282 of file message.c.

◆ 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 849 of file message.c.

Referenced by dialplan_handle_msg_cb().

◆ msg_techs_lock

ast_rwlock_t msg_techs_lock
static

Lock for msg_techs vector.

Definition at line 255 of file message.c.