From 8135558bab0ed52464fce31f325be17e4da00c2f Mon Sep 17 00:00:00 2001 From: George Joseph Date: Tue, 10 Apr 2018 15:09:49 -0600 Subject: app_sendtext: Enhance SendText to support Enhanced Messaging SendText now accepts new channel variables that can be used to override the To and From display names and set the Content-Type of a message. Since you can now set Content-Type, other text/* content types are now valid. Change-Id: I648b4574478119f95de09d9f08e9595831b02830 --- CHANGES | 7 ++ apps/app_sendtext.c | 179 ++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 159 insertions(+), 27 deletions(-) diff --git a/CHANGES b/CHANGES index 7fdae7066..19c8f86a4 100644 --- a/CHANGES +++ b/CHANGES @@ -117,6 +117,13 @@ Core MESSAGE message from a user in a conference call, it's relayed to all other participants in the call. +app_sendtext +------------------ + Support Enhanced Messaging. SendText now accepts new channel variables + that can be used to override the To and From display names and set the + Content-Type of a message. Since you can now set Content-Type, other + text/* content types are now valid. + ------------------------------------------------------------------------------ --- Functionality changes from Asterisk 15.3.0 to Asterisk 15.4.0 ------------ ------------------------------------------------------------------------------ diff --git a/apps/app_sendtext.c b/apps/app_sendtext.c index a8fe96dae..1cefb6c68 100644 --- a/apps/app_sendtext.c +++ b/apps/app_sendtext.c @@ -38,19 +38,60 @@ #include "asterisk/pbx.h" #include "asterisk/module.h" #include "asterisk/app.h" +#include "asterisk/message.h" /*** DOCUMENTATION - Send a Text Message. + Send a Text Message on a channel. - + - Sends text to current channel (callee). - Result of transmission will be stored in the SENDTEXTSTATUS + Sends text to the current channel. + current channel could be the caller or callee depending + on the context in which this application is called. + + + The following variables can be set: + + If set and this channel supports enhanced messaging, this value will be + used as the From display name. + + + If set and this channel supports enhanced messaging, this value will be + used as the To display name. + + + If set and this channel supports enhanced messaging, this value will be + used as the message Content-Type. It MUST + be a text/* content type. If not specified, the + default of text/plain will be used. + + + If set this value will be used as the message body and any text supplied + as a function parameter will be ignored. + + + + + + Result of transmission will be stored in the following variables: + + + + No message sent. + + + Message body sent without attributes because the channel driver + doesn't support enhanced messaging. + + + The message was sent using enhanced messaging. + + Transmission succeeded. @@ -63,7 +104,34 @@ - At this moment, text is supposed to be 7 bit ASCII in most channels. + + + The text encoding and transmission method is completely at the + discretion of the channel driver. chan_pjsip will use in-dialog SIP MESSAGE + messages always. chan_sip will use T.140 via RTP if a text media type was + negotiated and in-dialog SIP MESSAGE messages otherwise. + + + Examples: + + + same => n,SendText(Your Text Here) + + If the channel driver supports enhanced messaging (currently only chan_pjsip), + you can set additional variables: + + same => n,Set(SENDTEXT_FROM_DISPLAYNAME=Really From Bob) + same => n,SendText(Your Text Here) + + + same => n,Set(SENDTEXT_CONTENT_TYPE=text/json) + same => n,SendText({"foo":a, "bar":23}) + + + same => n,Set(SENDTEXT_CONTENT_TYPE=text/json) + same => n,Set(SENDTEXT_BODY={"foo":a, "bar":23}) + same => n,SendText() + SendImage @@ -76,36 +144,93 @@ static const char * const app = "SendText"; static int sendtext_exec(struct ast_channel *chan, const char *data) { - char *status = "UNSUPPORTED"; + char *status; + char *msg_type; struct ast_str *str; + const char *from; + const char *to; + const char *content_type; + const char *body; + int rc = 0; - /* NOT ast_strlen_zero, because some protocols (e.g. SIP) MUST be able to - * send a zero-length message. */ - if (!data) { - ast_log(LOG_WARNING, "SendText requires an argument (text)\n"); - return -1; - } + ast_channel_lock(chan); + from = pbx_builtin_getvar_helper(chan, "SENDTEXT_FROM_DISPLAYNAME"); + to = pbx_builtin_getvar_helper(chan, "SENDTEXT_TO_DISPLAYNAME"); + content_type = pbx_builtin_getvar_helper(chan, "SENDTEXT_CONTENT_TYPE"); + body = S_OR(pbx_builtin_getvar_helper(chan, "SENDTEXT_BODY"), data); + body = S_OR(body, ""); - if (!(str = ast_str_alloca(strlen(data) + 1))) { - return -1; + if (!(str = ast_str_alloca(strlen(body) + 1))) { + rc = -1; + goto cleanup; } + ast_str_get_encoded_str(&str, -1, body); + body = ast_str_buffer(str); - ast_str_get_encoded_str(&str, -1, data); + msg_type = "NONE"; + status = "UNSUPPORTED"; + if (ast_channel_tech(chan)->send_text_data) { + struct ast_msg_data *msg; + struct ast_msg_data_attribute attrs[] = + { + { + .type = AST_MSG_DATA_ATTR_FROM, + .value = (char *)S_OR(from, ""), + }, + { + .type = AST_MSG_DATA_ATTR_TO, + .value = (char *)S_OR(to, ""), + }, + { + .type = AST_MSG_DATA_ATTR_CONTENT_TYPE, + .value = (char *)S_OR(content_type, ""), + }, + { + .type = AST_MSG_DATA_ATTR_BODY, + .value = (char *)S_OR(body, ""), + }, + }; - ast_channel_lock(chan); - if (!ast_channel_tech(chan)->send_text) { - ast_channel_unlock(chan); - /* Does not support transport */ - pbx_builtin_setvar_helper(chan, "SENDTEXTSTATUS", status); - return 0; - } - status = "FAILURE"; - if (!ast_sendtext(chan, ast_str_buffer(str))) { - status = "SUCCESS"; + if (!ast_strlen_zero(content_type) && !ast_begins_with(content_type, "text/")) { + ast_log(LOG_ERROR, "SENDTEXT_CONTENT_TYPE must begin with 'text/'\n"); + rc = -1; + goto cleanup; + } + msg_type = "ENHANCED"; + msg = ast_msg_data_alloc(AST_MSG_DATA_SOURCE_TYPE_IN_DIALOG, attrs, ARRAY_LEN(attrs)); + if (msg) { + if (ast_sendtext_data(chan, msg) == 0) { + status = "SUCCESS"; + } else { + status = "FAILURE"; + } + + ast_free(msg); + } else { + rc = -1; + goto cleanup; + } + + } else if (ast_channel_tech(chan)->send_text) { + msg_type = "BASIC"; + if (ast_sendtext(chan, body) == 0) { + status = "SUCCESS"; + } else { + status = "FAILURE"; + } } - ast_channel_unlock(chan); + + pbx_builtin_setvar_helper(chan, "SENDTEXTTYPE", msg_type); pbx_builtin_setvar_helper(chan, "SENDTEXTSTATUS", status); - return 0; + +cleanup: + pbx_builtin_setvar_helper(chan, "SENDTEXT_FROM_DISPLAYNAME", NULL); + pbx_builtin_setvar_helper(chan, "SENDTEXT_TO_DISPLAYNAME", NULL); + pbx_builtin_setvar_helper(chan, "SENDTEXT_CONTENT_TYPE", NULL); + pbx_builtin_setvar_helper(chan, "SENDTEXT_BODY", NULL); + ast_channel_unlock(chan); + + return rc; } static int unload_module(void) -- cgit v1.2.3