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
This commit is contained in:
Richard Mudgett
2018-06-28 12:07:01 -05:00
parent 6b6fa461d6
commit d0e4cbfc51
3 changed files with 30 additions and 5 deletions

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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");