[Asterisk-code-review] manager - Add Content-Type parameter to the SendText action (asterisk[master])

Friendly Automation asteriskteam at digium.com
Mon Jul 6 05:27:45 CDT 2020


Friendly Automation has submitted this change. ( https://gerrit.asterisk.org/c/asterisk/+/14516 )

Change subject: manager - Add Content-Type parameter to the SendText action
......................................................................

manager - Add Content-Type parameter to the SendText action

This patch allows a user of AMI to now specify the type of message
content contained within by setting the 'Content-Type' parameter.

Note, the AMI version has been bumped for this change.

ASTERISK-28945 #close

Change-Id: Ibb5315702532c6b954e1498beddc8855fabdf4bb
---
A doc/CHANGES-staging/ami_sendtext_content_type.txt
M include/asterisk/frame.h
M include/asterisk/message.h
M main/channel.c
M main/manager.c
M main/message.c
6 files changed, 157 insertions(+), 20 deletions(-)

Approvals:
  Joshua Colp: Looks good to me, approved
  Benjamin Keith Ford: Looks good to me, but someone else must approve
  George Joseph: Looks good to me, but someone else must approve
  Friendly Automation: Approved for Submit



diff --git a/doc/CHANGES-staging/ami_sendtext_content_type.txt b/doc/CHANGES-staging/ami_sendtext_content_type.txt
new file mode 100644
index 0000000..45037ff
--- /dev/null
+++ b/doc/CHANGES-staging/ami_sendtext_content_type.txt
@@ -0,0 +1,4 @@
+Subject: AMI
+
+You can now specify an optional 'Content-Type' as an argument for the Asterisk
+SendText manager action.
diff --git a/include/asterisk/frame.h b/include/asterisk/frame.h
index 0ead3b8..9c18227 100644
--- a/include/asterisk/frame.h
+++ b/include/asterisk/frame.h
@@ -335,9 +335,16 @@
 	AST_CONTROL_RECORD_MUTE = 1103,	/*!< Indicated to a channel in record to mute/unmute (i.e. write silence) recording */
 };
 
+/*!
+ * \brief Actions to indicate to, and be handled on channel read
+ *
+ * The subtype to specify for an AST_CONTROL_READ_ACTION frame. These
+ * frames are then to be enacted on within a channel's read thread.
+ */
 enum ast_frame_read_action {
 	AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO,
 	AST_FRAME_READ_ACTION_SEND_TEXT,
+	AST_FRAME_READ_ACTION_SEND_TEXT_DATA,
 };
 
 struct ast_control_read_action_payload {
diff --git a/include/asterisk/message.h b/include/asterisk/message.h
index f5b7a75..94b5e91 100644
--- a/include/asterisk/message.h
+++ b/include/asterisk/message.h
@@ -480,6 +480,24 @@
 	struct ast_msg_data_attribute attributes[], size_t count);
 
 /*!
+ * \brief Allocates an ast_msg_data structure.
+ * \since 13.35.0
+ * \since 16.12.0
+ * \since 17.6.0
+ *
+ * \param source The source type of the message
+ * \param to Where the message is sent to
+ * \param from Where the message is sent from
+ * \param content_type Content type of the body
+ * \param body The message body
+ *
+ * \return Pointer to msg structure or NULL on allocation failure.
+ *         Caller must call ast_free when done.
+ */
+struct ast_msg_data *ast_msg_data_alloc2(enum ast_msg_data_source_type source_type,
+	const char *to, const char *from, const char *content_type, const char *body);
+
+/*!
  * \brief Clone an ast_msg_data structure
  * \since 13.22.0
  * \since 15.5.0
diff --git a/main/channel.c b/main/channel.c
index 40d7724..2f3aad1 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -3812,7 +3812,12 @@
 					break;
 				case AST_FRAME_READ_ACTION_SEND_TEXT:
 					ast_channel_unlock(chan);
-					ast_sendtext(chan, (const char *) read_action_payload->payload);
+					ast_sendtext(chan, (const char *)read_action_payload->payload);
+					ast_channel_lock(chan);
+					break;
+				case AST_FRAME_READ_ACTION_SEND_TEXT_DATA:
+					ast_channel_unlock(chan);
+					ast_sendtext_data(chan, (struct ast_msg_data *)read_action_payload->payload);
 					ast_channel_lock(chan);
 					break;
 				}
diff --git a/main/manager.c b/main/manager.c
index e7a7f0f..562a7ea 100644
--- a/main/manager.c
+++ b/main/manager.c
@@ -100,6 +100,7 @@
 #include "asterisk/format_cache.h"
 #include "asterisk/translate.h"
 #include "asterisk/taskprocessor.h"
+#include "asterisk/message.h"
 
 /*** DOCUMENTATION
 	<manager name="Ping" language="en_US">
@@ -873,7 +874,8 @@
 	</manager>
 	<manager name="SendText" language="en_US">
 		<synopsis>
-			Send text message to channel.
+			Sends a text message to channel. A content type	can be optionally specified. If not set
+			it is set to an empty string allowing a custom handler to default it as it sees fit.
 		</synopsis>
 		<syntax>
 			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
@@ -883,10 +885,16 @@
 			<parameter name="Message" required="true">
 				<para>Message to send.</para>
 			</parameter>
+			<parameter name="Content-Type" required="false" default="">
+				<para>The type of content in the message</para>
+			</parameter>
 		</syntax>
 		<description>
 			<para>Sends A Text Message to a channel while in a call.</para>
 		</description>
+		<see-also>
+			<ref type="application">SendText</ref>
+		</see-also>
 	</manager>
 	<manager name="UserEvent" language="en_US">
 		<synopsis>
@@ -4839,14 +4847,92 @@
 	return 0;
 }
 
+/*!
+ * \brief Queue a given read action containing a payload onto a channel
+ *
+ * This queues a READ_ACTION control frame that contains a given "payload", or
+ * data to be triggered and handled on the channel's read side. This ensures
+ * the "action" is handled by the channel's media reading thread.
+ *
+ * \param chan The channel to queue the action on
+ * \param payload The read action's payload
+ * \param payload_size The size of the given payload
+ * \param action The type of read action to queue
+ *
+ * \return -1 on error, 0 on success
+ */
+static int queue_read_action_payload(struct ast_channel *chan, const unsigned char *payload,
+	size_t payload_size, enum ast_frame_read_action action)
+{
+	struct ast_control_read_action_payload *obj;
+	size_t obj_size;
+	int res;
+
+	obj_size = payload_size + sizeof(*obj);
+
+	obj = ast_malloc(obj_size);
+	if (!obj) {
+		return -1;
+	}
+
+	obj->action = action;
+	obj->payload_size = payload_size;
+	memcpy(obj->payload, payload, payload_size);
+
+	res = ast_queue_control_data(chan, AST_CONTROL_READ_ACTION, obj, obj_size);
+
+	ast_free(obj);
+	return res;
+}
+
+/*!
+ * \brief Queue a read action to send a text message
+ *
+ * \param chan The channel to queue the action on
+ * \param body The body of the message
+ *
+ * \return -1 on error, 0 on success
+ */
+static int queue_sendtext(struct ast_channel *chan, const char *body)
+{
+	return queue_read_action_payload(chan, (const unsigned char *)body,
+		strlen(body) + 1, AST_FRAME_READ_ACTION_SEND_TEXT);
+}
+
+/*!
+ * \brief Queue a read action to send a text data message
+ *
+ * \param chan The channel to queue the action on
+ * \param body The body of the message
+ * \param content_type The message's content type
+ *
+ * \return -1 on error, 0 on success
+ */
+static int queue_sendtext_data(struct ast_channel *chan, const char *body,
+	const char *content_type)
+{
+	int res;
+	struct ast_msg_data *obj;
+
+	obj = ast_msg_data_alloc2(AST_MSG_DATA_SOURCE_TYPE_UNKNOWN,
+							NULL, NULL, content_type, body);
+	if (!obj) {
+		return -1;
+	}
+
+	res = queue_read_action_payload(chan, (const unsigned char *)obj,
+		ast_msg_data_get_length(obj), AST_FRAME_READ_ACTION_SEND_TEXT_DATA);
+
+	ast_free(obj);
+	return res;
+}
+
 static int action_sendtext(struct mansession *s, const struct message *m)
 {
 	struct ast_channel *c;
 	const char *name = astman_get_header(m, "Channel");
 	const char *textmsg = astman_get_header(m, "Message");
-	struct ast_control_read_action_payload *frame_payload;
-	int payload_size;
-	int frame_size;
+	const char *content_type = astman_get_header(m, "Content-Type");
 	int res;
 
 	if (ast_strlen_zero(name)) {
@@ -4865,22 +4951,13 @@
 		return 0;
 	}
 
-	payload_size = strlen(textmsg) + 1;
-	frame_size = payload_size + sizeof(*frame_payload);
+	/*
+	 * If the "extra" data is not available, then send using "string" only.
+	 * Doing such maintains backward compatibilities.
+	 */
+	res = ast_strlen_zero(content_type) ? queue_sendtext(c, textmsg) :
+		queue_sendtext_data(c, textmsg, content_type);
 
-	frame_payload = ast_malloc(frame_size);
-	if (!frame_payload) {
-		ast_channel_unref(c);
-		astman_send_error(s, m, "Failure");
-		return 0;
-	}
-
-	frame_payload->action = AST_FRAME_READ_ACTION_SEND_TEXT;
-	frame_payload->payload_size = payload_size;
-	memcpy(frame_payload->payload, textmsg, payload_size);
-	res = ast_queue_control_data(c, AST_CONTROL_READ_ACTION, frame_payload, frame_size);
-
-	ast_free(frame_payload);
 	ast_channel_unref(c);
 
 	if (res >= 0) {
diff --git a/main/message.c b/main/message.c
index 66d051c..b6f254d 100644
--- a/main/message.c
+++ b/main/message.c
@@ -1429,6 +1429,32 @@
 	return msg;
 }
 
+struct ast_msg_data *ast_msg_data_alloc2(enum ast_msg_data_source_type source_type,
+	const char *to, const char *from, const char *content_type, const char *body)
+{
+	struct ast_msg_data_attribute attrs[] =
+	{
+		{
+			.type = AST_MSG_DATA_ATTR_TO,
+			.value = (char *)S_OR(to, ""),
+		},
+		{
+			.type = AST_MSG_DATA_ATTR_FROM,
+			.value = (char *)S_OR(from, ""),
+		},
+		{
+			.type = AST_MSG_DATA_ATTR_CONTENT_TYPE,
+			.value = (char *)S_OR(content_type, ""),
+		},
+		{
+			.type = AST_MSG_DATA_ATTR_BODY,
+			.value = (char *)S_OR(body, ""),
+		},
+	};
+
+	return ast_msg_data_alloc(source_type, attrs, ARRAY_LEN(attrs));
+}
+
 struct ast_msg_data *ast_msg_data_dup(struct ast_msg_data *msg)
 {
 	struct ast_msg_data *dest;

-- 
To view, visit https://gerrit.asterisk.org/c/asterisk/+/14516
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Change-Id: Ibb5315702532c6b954e1498beddc8855fabdf4bb
Gerrit-Change-Number: 14516
Gerrit-PatchSet: 7
Gerrit-Owner: Kevin Harwell <kharwell at digium.com>
Gerrit-Reviewer: Benjamin Keith Ford <bford at digium.com>
Gerrit-Reviewer: Friendly Automation
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Joshua Colp <jcolp at sangoma.com>
Gerrit-Reviewer: Kevin Harwell <kharwell at digium.com>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20200706/5804f601/attachment-0001.html>


More information about the asterisk-code-review mailing list