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

Go to the source code of this file.
Data Structures | |
| struct | ast_msg_tech |
| A message technology. More... | |
Functions | |
| struct ast_msg * | ast_msg_alloc (void) |
| Allocate a message. | |
| struct ast_msg * | ast_msg_destroy (struct ast_msg *msg) |
| Destroy an ast_msg. | |
| const char * | ast_msg_get_body (const struct ast_msg *msg) |
| Get the body of a message. | |
| const char * | ast_msg_get_var (struct ast_msg *msg, const char *name) |
| Get the specified variable on the message. | |
| int | ast_msg_queue (struct ast_msg *msg) |
| Queue a message for routing through the dialplan. | |
| struct ast_msg * | ast_msg_ref (struct ast_msg *msg) |
| Bump a msg's ref count. | |
| int | ast_msg_send (struct ast_msg *msg, const char *to, const char *from) |
| Send a msg directly to an endpoint. | |
| int | ast_msg_set_body (struct ast_msg *msg, const char *fmt,...) |
| Set the 'body' text of a message (in UTF-8) | |
| int | ast_msg_set_context (struct ast_msg *msg, const char *fmt,...) |
| Set the dialplan context for this message. | |
| int | ast_msg_set_exten (struct ast_msg *msg, const char *fmt,...) |
| Set the dialplan extension for this message. | |
| int | ast_msg_set_from (struct ast_msg *msg, const char *fmt,...) |
| Set the 'from' URI of a message. | |
| int | ast_msg_set_to (struct ast_msg *msg, const char *fmt,...) |
| Set the 'to' URI of a message. | |
| 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. | |
| 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. | |
| int | ast_msg_tech_register (const struct ast_msg_tech *tech) |
| Register a message technology. | |
| int | ast_msg_tech_unregister (const struct ast_msg_tech *tech) |
| Unregister a message technology. | |
| void | ast_msg_var_iterator_destroy (struct ast_msg_var_iterator *i) |
| Destroy a message variable iterator. | |
| struct ast_msg_var_iterator * | ast_msg_var_iterator_init (const struct ast_msg *msg) |
| Create a new message variable iterator. | |
| int | ast_msg_var_iterator_next (const struct ast_msg *msg, struct ast_msg_var_iterator *i, const char **name, const char **value) |
| Get the next variable name and value that is set for sending outbound. | |
| void | ast_msg_var_unref_current (struct ast_msg_var_iterator *i) |
| Unref a message var from inside an iterator loop. | |
Out-of-call text message support.
The purpose of this API is to provide support for text messages that are not session based. The messages are passed into the Asterisk core to be routed through the dialplan and potentially sent back out through a message technology that has been registered through this API.
Definition in file message.h.
| struct ast_msg* ast_msg_alloc | ( | void | ) | [read] |
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.
Definition at line 404 of file message.c.
References ao2_alloc, ao2_container_alloc, ao2_ref, ast_str_create(), ast_str_set(), ast_msg::body, ast_msg::context, ast_msg::exten, ast_msg::from, msg_data_cmp_fn(), msg_data_hash_fn(), msg_destructor(), ast_msg::to, and ast_msg::vars.
Referenced by action_messagesend(), aji_handle_message(), msg_datastore_find_or_create(), receive_message(), and xmpp_pak_message().
{
struct ast_msg *msg;
if (!(msg = ao2_alloc(sizeof(*msg), msg_destructor))) {
return NULL;
}
if (!(msg->to = ast_str_create(32))) {
ao2_ref(msg, -1);
return NULL;
}
if (!(msg->from = ast_str_create(32))) {
ao2_ref(msg, -1);
return NULL;
}
if (!(msg->body = ast_str_create(128))) {
ao2_ref(msg, -1);
return NULL;
}
if (!(msg->context = ast_str_create(16))) {
ao2_ref(msg, -1);
return NULL;
}
if (!(msg->exten = ast_str_create(16))) {
ao2_ref(msg, -1);
return NULL;
}
if (!(msg->vars = ao2_container_alloc(1, msg_data_hash_fn, msg_data_cmp_fn))) {
ao2_ref(msg, -1);
return NULL;
}
ast_str_set(&msg->context, 0, "default");
return msg;
}
| struct ast_msg* ast_msg_destroy | ( | struct ast_msg * | msg | ) | [read] |
Destroy an ast_msg.
This should only be called on a message if it was not passed on to ast_msg_queue().
Definition at line 453 of file message.c.
References ao2_ref.
Referenced by aji_handle_message(), receive_message(), and xmpp_pak_message().
{
ao2_ref(msg, -1);
return NULL;
}
| const char* ast_msg_get_body | ( | const struct ast_msg * | msg | ) |
Get the body of a message.
Definition at line 520 of file message.c.
References ast_str_buffer(), and ast_msg::body.
Referenced by msg_func_read(), msg_send_cb(), sip_msg_send(), and xmpp_send_cb().
{
return ast_str_buffer(msg->body);
}
| const char* ast_msg_get_var | ( | struct ast_msg * | msg, |
| const char * | name | ||
| ) |
Get the specified variable on the message.
Definition at line 589 of file message.c.
References ao2_ref, msg_data_find(), msg_data::value, and ast_msg::vars.
Referenced by msg_data_func_read().
{
struct msg_data *data;
const char *val = NULL;
if (!(data = msg_data_find(msg->vars, name))) {
return NULL;
}
/* Yep, this definitely looks like val would be a dangling pointer
* after the ref count is decremented. As long as the message structure
* is used in a thread safe manner, this will not be the case though.
* The ast_msg holds a reference to this object in the msg->vars container. */
val = data->value;
ao2_ref(data, -1);
return val;
}
| 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.
| 0 | message successfully queued |
| non-zero | failure, message not sent to dialplan |
Definition at line 820 of file message.c.
References ao2_ref, ast_taskprocessor_push(), and msg_q_cb().
Referenced by aji_handle_message(), receive_message(), and xmpp_pak_message().
{
int res;
res = ast_taskprocessor_push(msg_q_tp, msg_q_cb, msg);
if (res == -1) {
ao2_ref(msg, -1);
}
return res;
}
| struct ast_msg* ast_msg_ref | ( | struct ast_msg * | msg | ) | [read] |
| 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.
| 0 | message successfully queued to be sent out |
| non-zero | failure, message not get sent out. |
Definition at line 1233 of file message.c.
References ao2_ref, ast_rwlock_rdlock, ast_rwlock_unlock, ast_strlen_zero(), msg_find_by_tech_name(), ast_msg_tech::msg_send, OBJ_POINTER, S_OR, ast_msg_tech_holder::tech, and ast_msg_tech_holder::tech_lock.
{
char *tech_name = NULL;
struct ast_msg_tech_holder *tech_holder = NULL;
int res = -1;
if (ast_strlen_zero(to)) {
ao2_ref(msg, -1);
return -1;
}
tech_name = ast_strdupa(to);
tech_name = strsep(&tech_name, ":");
tech_holder = msg_find_by_tech_name(tech_name, OBJ_POINTER);
if (!tech_holder) {
ao2_ref(msg, -1);
return -1;
}
ast_rwlock_rdlock(&tech_holder->tech_lock);
if (tech_holder->tech) {
res = tech_holder->tech->msg_send(msg, S_OR(to, ""), S_OR(from, ""));
}
ast_rwlock_unlock(&tech_holder->tech_lock);
ao2_ref(tech_holder, -1);
ao2_ref(msg, -1);
return res;
}
| int ast_msg_set_body | ( | struct ast_msg * | msg, |
| const char * | fmt, | ||
| ... | |||
| ) |
Set the 'body' text of a message (in UTF-8)
| 0 | success |
| -1 | failure |
Definition at line 484 of file message.c.
References ast_str_set_va(), and ast_msg::body.
Referenced by action_messagesend(), aji_handle_message(), msg_func_write(), receive_message(), and xmpp_pak_message().
{
va_list ap;
int res;
va_start(ap, fmt);
res = ast_str_set_va(&msg->body, 0, fmt, ap);
va_end(ap);
return res < 0 ? -1 : 0;
}
| int ast_msg_set_context | ( | struct ast_msg * | msg, |
| const char * | fmt, | ||
| ... | |||
| ) |
Set the dialplan context for this message.
| 0 | success |
| -1 | failure |
Definition at line 496 of file message.c.
References ast_str_set_va(), and ast_msg::context.
Referenced by aji_handle_message(), receive_message(), and xmpp_pak_message().
{
va_list ap;
int res;
va_start(ap, fmt);
res = ast_str_set_va(&msg->context, 0, fmt, ap);
va_end(ap);
return res < 0 ? -1 : 0;
}
| int ast_msg_set_exten | ( | struct ast_msg * | msg, |
| const char * | fmt, | ||
| ... | |||
| ) |
Set the dialplan extension for this message.
| 0 | success |
| -1 | failure |
Definition at line 508 of file message.c.
References ast_str_set_va(), and ast_msg::exten.
Referenced by receive_message().
{
va_list ap;
int res;
va_start(ap, fmt);
res = ast_str_set_va(&msg->exten, 0, fmt, ap);
va_end(ap);
return res < 0 ? -1 : 0;
}
| int ast_msg_set_from | ( | struct ast_msg * | msg, |
| const char * | fmt, | ||
| ... | |||
| ) |
Set the 'from' URI of a message.
| 0 | success |
| -1 | failure |
Definition at line 472 of file message.c.
References ast_str_set_va(), and ast_msg::from.
Referenced by aji_handle_message(), msg_func_write(), receive_message(), and xmpp_pak_message().
{
va_list ap;
int res;
va_start(ap, fmt);
res = ast_str_set_va(&msg->from, 0, fmt, ap);
va_end(ap);
return res < 0 ? -1 : 0;
}
| int ast_msg_set_to | ( | struct ast_msg * | msg, |
| const char * | fmt, | ||
| ... | |||
| ) |
Set the 'to' URI of a message.
| 0 | success |
| -1 | failure |
Definition at line 460 of file message.c.
References ast_str_set_va(), and ast_msg::to.
Referenced by aji_handle_message(), msg_func_write(), receive_message(), and xmpp_pak_message().
{
va_list ap;
int res;
va_start(ap, fmt);
res = ast_str_set_va(&msg->to, 0, fmt, ap);
va_end(ap);
return res < 0 ? -1 : 0;
}
| 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.
| name | Name of variable to set |
| value | Value of variable to set |
| 0 | success |
| -1 | failure |
Definition at line 584 of file message.c.
References msg_set_var_full().
Referenced by receive_message(), and set_message_vars_from_req().
{
return msg_set_var_full(msg, name, value, 0);
}
| 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.
| name | Name of variable to set |
| value | Value of variable to set |
| 0 | success |
| -1 | failure |
Definition at line 579 of file message.c.
References msg_set_var_full().
Referenced by action_messagesend(), and msg_data_func_write().
{
return msg_set_var_full(msg, name, value, 1);
}
| int ast_msg_tech_register | ( | const struct ast_msg_tech * | tech | ) |
Register a message technology.
| 0 | success |
| non-zero | failure |
Definition at line 1266 of file message.c.
References ao2_alloc, ao2_link, ao2_ref, ast_log(), ast_rwlock_init, ast_verb, LOG_ERROR, msg_find_by_tech(), ast_msg_tech::name, OBJ_POINTER, ast_msg_tech_holder::tech, and ast_msg_tech_holder::tech_lock.
Referenced by load_module().
{
struct ast_msg_tech_holder *tech_holder;
if ((tech_holder = msg_find_by_tech(tech, OBJ_POINTER))) {
ao2_ref(tech_holder, -1);
ast_log(LOG_ERROR, "Message technology already registered for '%s'\n",
tech->name);
return -1;
}
if (!(tech_holder = ao2_alloc(sizeof(*tech_holder), NULL))) {
return -1;
}
ast_rwlock_init(&tech_holder->tech_lock);
tech_holder->tech = tech;
ao2_link(msg_techs, tech_holder);
ao2_ref(tech_holder, -1);
tech_holder = NULL;
ast_verb(3, "Message technology handler '%s' registered.\n", tech->name);
return 0;
}
| int ast_msg_tech_unregister | ( | const struct ast_msg_tech * | tech | ) |
Unregister a message technology.
| 0 | success |
| non-zero | failure |
Definition at line 1294 of file message.c.
References ao2_ref, ast_log(), ast_rwlock_unlock, ast_rwlock_wrlock, ast_verb, LOG_ERROR, msg_find_by_tech(), ast_msg_tech::name, OBJ_POINTER, OBJ_UNLINK, ast_msg_tech_holder::tech, and ast_msg_tech_holder::tech_lock.
Referenced by unload_module().
{
struct ast_msg_tech_holder *tech_holder;
tech_holder = msg_find_by_tech(tech, OBJ_POINTER | OBJ_UNLINK);
if (!tech_holder) {
ast_log(LOG_ERROR, "No '%s' message technology found.\n", tech->name);
return -1;
}
ast_rwlock_wrlock(&tech_holder->tech_lock);
tech_holder->tech = NULL;
ast_rwlock_unlock(&tech_holder->tech_lock);
ao2_ref(tech_holder, -1);
tech_holder = NULL;
ast_verb(3, "Message technology handler '%s' unregistered.\n", tech->name);
return 0;
}
| void ast_msg_var_iterator_destroy | ( | struct ast_msg_var_iterator * | i | ) |
Destroy a message variable iterator.
| i | Iterator to be destroyed |
Definition at line 657 of file message.c.
References ao2_iterator_destroy(), ast_free, and ast_msg_var_iterator::i.
Referenced by sip_msg_send().
{
ao2_iterator_destroy(&i->i);
ast_free(i);
}
| struct ast_msg_var_iterator* ast_msg_var_iterator_init | ( | const struct ast_msg * | msg | ) | [read] |
Create a new message variable iterator.
| msg | A message whose variables are to be iterated over |
Definition at line 613 of file message.c.
References ao2_iterator_init(), ast_calloc, ast_msg_var_iterator::i, and ast_msg::vars.
Referenced by sip_msg_send().
{
struct ast_msg_var_iterator *i;
if (!(i = ast_calloc(1, sizeof(*i)))) {
return NULL;
}
i->i = ao2_iterator_init(msg->vars, 0);
return i;
}
| int ast_msg_var_iterator_next | ( | const struct ast_msg * | msg, |
| struct ast_msg_var_iterator * | i, | ||
| const char ** | name, | ||
| const char ** | value | ||
| ) |
Get the next variable name and value that is set for sending outbound.
| msg | The message with the variables |
| i | An iterator created with ast_msg_var_iterator_init |
| name | A pointer to the name result pointer |
| value | A pointer to the value result pointer |
| 0 | No more entries |
| 1 | Valid entry |
Definition at line 625 of file message.c.
References ao2_iterator_next, ao2_ref, ast_msg_var_iterator::current_used, ast_msg_var_iterator::i, msg_data::name, msg_data::send, and msg_data::value.
Referenced by sip_msg_send().
{
struct msg_data *data;
/* Skip any that aren't marked for sending out */
while ((data = ao2_iterator_next(&i->i)) && !data->send) {
ao2_ref(data, -1);
}
if (!data) {
return 0;
}
if (data->send) {
*name = data->name;
*value = data->value;
}
/* Leave the refcount to be cleaned up by the caller with
* ast_msg_var_unref_current after they finish with the pointers to the data */
i->current_used = data;
return 1;
}
| void ast_msg_var_unref_current | ( | struct ast_msg_var_iterator * | i | ) |
Unref a message var from inside an iterator loop.
Definition at line 650 of file message.c.
References ao2_ref, and ast_msg_var_iterator::current_used.
Referenced by sip_msg_send().
{
if (i->current_used) {
ao2_ref(i->current_used, -1);
}
i->current_used = NULL;
}