From: Richard Mudgett Date: Thu, 28 Jun 2018 17:07:01 +0000 (-0500) Subject: AMI SendText action: Fix to use correct thread to send the text. X-Git-Tag: 13.22.0-rc1~5^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d0e4cbfc512a5074e1b0daf846b5c211da3f0f61;p=thirdparty%2Fasterisk.git AMI SendText action: Fix to use correct thread to send the text. The AMI action was directly sending the text to the channel driver. However, this makes two threads attempt to handle media and runs afowl of CHECK_BLOCKING. * Queue a read action to make the channel's media handling thread actually send the text message. This changes the AMI actions success/fail response to just mean the text was queued to be sent not that the text actually got sent. The channel driver may not even support sending text messages. ASTERISK-27943 Change-Id: I9dce343d8fa634ba5a416a1326d8a6340f98c379 --- diff --git a/include/asterisk/frame.h b/include/asterisk/frame.h index 7193086763..9733600f00 100644 --- a/include/asterisk/frame.h +++ b/include/asterisk/frame.h @@ -330,6 +330,7 @@ enum ast_control_frame_type { enum ast_frame_read_action { AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO, + AST_FRAME_READ_ACTION_SEND_TEXT, }; struct ast_control_read_action_payload { diff --git a/main/channel.c b/main/channel.c index fe246955b0..ca50d4651c 100644 --- a/main/channel.c +++ b/main/channel.c @@ -4041,6 +4041,11 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio) ast_party_connected_line_free(&connected); ast_channel_lock(chan); break; + case AST_FRAME_READ_ACTION_SEND_TEXT: + ast_channel_unlock(chan); + ast_sendtext(chan, (const char *) read_action_payload->payload); + ast_channel_lock(chan); + break; } ast_frfree(f); f = &ast_null_frame; diff --git a/main/manager.c b/main/manager.c index 41a87474ed..b2d3c0e457 100644 --- a/main/manager.c +++ b/main/manager.c @@ -4715,10 +4715,13 @@ static int action_status(struct mansession *s, const struct message *m) static int action_sendtext(struct mansession *s, const struct message *m) { - struct ast_channel *c = NULL; + struct ast_channel *c; const char *name = astman_get_header(m, "Channel"); const char *textmsg = astman_get_header(m, "Message"); - int res = 0; + struct ast_control_read_action_payload *frame_payload; + int payload_size; + int frame_size; + int res; if (ast_strlen_zero(name)) { astman_send_error(s, m, "No channel specified"); @@ -4730,13 +4733,29 @@ static int action_sendtext(struct mansession *s, const struct message *m) return 0; } - if (!(c = ast_channel_get_by_name(name))) { + c = ast_channel_get_by_name(name); + if (!c) { astman_send_error(s, m, "No such channel"); return 0; } - res = ast_sendtext(c, textmsg); - c = ast_channel_unref(c); + payload_size = strlen(textmsg) + 1; + frame_size = payload_size + sizeof(*frame_payload); + + 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) { astman_send_ack(s, m, "Success");