]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
AMI SendText action: Fix to use correct thread to send the text.
authorRichard Mudgett <rmudgett@digium.com>
Thu, 28 Jun 2018 17:07:01 +0000 (12:07 -0500)
committerRichard Mudgett <rmudgett@digium.com>
Thu, 28 Jun 2018 18:20:19 +0000 (12:20 -0600)
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

include/asterisk/frame.h
main/channel.c
main/manager.c

index 542407ecc93dbe5fa50281d0be5db1c30f0464bc..b618d1965f239375ad32729f35db6c938fed8f7b 100644 (file)
@@ -337,6 +337,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 {
index 141a8a551d94aa8fff4d7e1c6d5134867885bdde..140d8e90e3d5c2eec77bda1f4c54de6e85bb97ef 100644 (file)
@@ -3795,6 +3795,11 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio, int
                                        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;
index 34cb5b91b6b655f2463c5675f45658a46ad018e8..909e4baac72f8d0c139736a7a8f908c29021a91f 100644 (file)
@@ -4736,10 +4736,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");
@@ -4751,13 +4754,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");