]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Dial: Combine frame handling functions. 19/2619/1
authorMark Michelson <mmichelson@digium.com>
Tue, 12 Apr 2016 19:55:42 +0000 (14:55 -0500)
committerMark Michelson <mmichelson@digium.com>
Thu, 14 Apr 2016 22:39:41 +0000 (17:39 -0500)
There is a good amount of repetition in the two frame handling routines
in the Dial API. This commit combines the two functions into one.

This is in preparation for an upcoming commit that adds the ability to
handle frames for a channel in a bridge.

ASTERISK-25925
Reported by Mark Michelson

Change-Id: Iaae2f174e3058e774cb44e10659fcdfb85345c58

main/dial.c

index 80247588d924d57f378ec37d20dfc17ac07112e9..fc66af5a7665ad01bd3a2f11a1b125586de9185c 100644 (file)
@@ -583,13 +583,17 @@ static void set_state(struct ast_dial *dial, enum ast_dial_result state)
                dial->state_callback(dial);
 }
 
-/*! \brief Helper function that handles control frames WITH owner */
+/*! \brief Helper function that handles frames */
 static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel, struct ast_frame *fr, struct ast_channel *chan)
 {
        if (fr->frametype == AST_FRAME_CONTROL) {
                switch (fr->subclass.integer) {
                case AST_CONTROL_ANSWER:
-                       ast_verb(3, "%s answered %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
+                       if (chan) {
+                               ast_verb(3, "%s answered %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
+                       } else {
+                               ast_verb(3, "%s answered\n", ast_channel_name(channel->owner));
+                       }
                        AST_LIST_LOCK(&dial->channels);
                        AST_LIST_REMOVE(&dial->channels, channel, list);
                        AST_LIST_INSERT_HEAD(&dial->channels, channel, list);
@@ -613,28 +617,47 @@ static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel
                        break;
                case AST_CONTROL_INCOMPLETE:
                        ast_verb(3, "%s dialed Incomplete extension %s\n", ast_channel_name(channel->owner), ast_channel_exten(channel->owner));
-                       ast_indicate(chan, AST_CONTROL_INCOMPLETE);
+                       if (chan) {
+                               ast_indicate(chan, AST_CONTROL_INCOMPLETE);
+                       } else {
+                               ast_hangup(channel->owner);
+                               channel->cause = AST_CAUSE_UNALLOCATED;
+                               channel->owner = NULL;
+                       }
                        break;
                case AST_CONTROL_RINGING:
                        ast_verb(3, "%s is ringing\n", ast_channel_name(channel->owner));
-                       if (!dial->options[AST_DIAL_OPTION_MUSIC])
+                       if (chan && !dial->options[AST_DIAL_OPTION_MUSIC])
                                ast_indicate(chan, AST_CONTROL_RINGING);
                        set_state(dial, AST_DIAL_RESULT_RINGING);
                        break;
                case AST_CONTROL_PROGRESS:
-                       ast_verb(3, "%s is making progress, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
-                       ast_indicate(chan, AST_CONTROL_PROGRESS);
+                       if (chan) {
+                               ast_verb(3, "%s is making progress, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
+                               ast_indicate(chan, AST_CONTROL_PROGRESS);
+                       } else {
+                               ast_verb(3, "%s is making progress\n", ast_channel_name(channel->owner));
+                       }
                        set_state(dial, AST_DIAL_RESULT_PROGRESS);
                        break;
                case AST_CONTROL_VIDUPDATE:
+                       if (!chan) {
+                               break;
+                       }
                        ast_verb(3, "%s requested a video update, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
                        ast_indicate(chan, AST_CONTROL_VIDUPDATE);
                        break;
                case AST_CONTROL_SRCUPDATE:
+                       if (!chan) {
+                               break;
+                       }
                        ast_verb(3, "%s requested a source update, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
                        ast_indicate(chan, AST_CONTROL_SRCUPDATE);
                        break;
                case AST_CONTROL_CONNECTED_LINE:
+                       if (!chan) {
+                               break;
+                       }
                        ast_verb(3, "%s connected line has changed, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
                        if (ast_channel_connected_line_sub(channel->owner, chan, fr, 1) &&
                                ast_channel_connected_line_macro(channel->owner, chan, fr, 1, 1)) {
@@ -642,6 +665,9 @@ static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel
                        }
                        break;
                case AST_CONTROL_REDIRECTING:
+                       if (!chan) {
+                               break;
+                       }
                        ast_verb(3, "%s redirecting info has changed, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
                        if (ast_channel_redirecting_sub(channel->owner, chan, fr, 1) &&
                                ast_channel_redirecting_macro(channel->owner, chan, fr, 1, 1)) {
@@ -649,15 +675,25 @@ static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel
                        }
                        break;
                case AST_CONTROL_PROCEEDING:
-                       ast_verb(3, "%s is proceeding, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
-                       ast_indicate(chan, AST_CONTROL_PROCEEDING);
+                       if (chan) {
+                               ast_verb(3, "%s is proceeding, passing it to %s\n", ast_channel_name(channel->owner), ast_channel_name(chan));
+                               ast_indicate(chan, AST_CONTROL_PROCEEDING);
+                       } else {
+                               ast_verb(3, "%s is proceeding\n", ast_channel_name(channel->owner));
+                       }
                        set_state(dial, AST_DIAL_RESULT_PROCEEDING);
                        break;
                case AST_CONTROL_HOLD:
+                       if (!chan) {
+                               break;
+                       }
                        ast_verb(3, "Call on %s placed on hold\n", ast_channel_name(chan));
                        ast_indicate_data(chan, AST_CONTROL_HOLD, fr->data.ptr, fr->datalen);
                        break;
                case AST_CONTROL_UNHOLD:
+                       if (!chan) {
+                               break;
+                       }
                        ast_verb(3, "Call on %s left from hold\n", ast_channel_name(chan));
                        ast_indicate(chan, AST_CONTROL_UNHOLD);
                        break;
@@ -665,11 +701,15 @@ static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel
                case AST_CONTROL_FLASH:
                        break;
                case AST_CONTROL_PVT_CAUSE_CODE:
-                       ast_indicate_data(chan, AST_CONTROL_PVT_CAUSE_CODE, fr->data.ptr, fr->datalen);
+                       if (chan) {
+                               ast_indicate_data(chan, AST_CONTROL_PVT_CAUSE_CODE, fr->data.ptr, fr->datalen);
+                       }
                        break;
                case -1:
-                       /* Prod the channel */
-                       ast_indicate(chan, -1);
+                       if (chan) {
+                               /* Prod the channel */
+                               ast_indicate(chan, -1);
+                       }
                        break;
                default:
                        break;
@@ -677,65 +717,6 @@ static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel
        }
 }
 
-/*! \brief Helper function that handles control frames WITHOUT owner */
-static void handle_frame_ownerless(struct ast_dial *dial, struct ast_dial_channel *channel, struct ast_frame *fr)
-{
-       /* If we have no owner we can only update the state of the dial structure, so only look at control frames */
-       if (fr->frametype != AST_FRAME_CONTROL)
-               return;
-
-       switch (fr->subclass.integer) {
-       case AST_CONTROL_ANSWER:
-               ast_verb(3, "%s answered\n", ast_channel_name(channel->owner));
-               AST_LIST_LOCK(&dial->channels);
-               AST_LIST_REMOVE(&dial->channels, channel, list);
-               AST_LIST_INSERT_HEAD(&dial->channels, channel, list);
-               AST_LIST_UNLOCK(&dial->channels);
-               ast_channel_publish_dial(NULL, channel->owner, channel->device, "ANSWER");
-               set_state(dial, AST_DIAL_RESULT_ANSWERED);
-               break;
-       case AST_CONTROL_BUSY:
-               ast_verb(3, "%s is busy\n", ast_channel_name(channel->owner));
-               ast_channel_publish_dial(NULL, channel->owner, channel->device, "BUSY");
-               ast_hangup(channel->owner);
-               channel->cause = AST_CAUSE_USER_BUSY;
-               channel->owner = NULL;
-               break;
-       case AST_CONTROL_CONGESTION:
-               ast_verb(3, "%s is circuit-busy\n", ast_channel_name(channel->owner));
-               ast_channel_publish_dial(NULL, channel->owner, channel->device, "CONGESTION");
-               ast_hangup(channel->owner);
-               channel->cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
-               channel->owner = NULL;
-               break;
-       case AST_CONTROL_INCOMPLETE:
-               /*
-                * Nothing to do but abort the call since we have no
-                * controlling channel to ask for more digits.
-                */
-               ast_verb(3, "%s dialed Incomplete extension %s\n",
-                       ast_channel_name(channel->owner), ast_channel_exten(channel->owner));
-               ast_hangup(channel->owner);
-               channel->cause = AST_CAUSE_UNALLOCATED;
-               channel->owner = NULL;
-               break;
-       case AST_CONTROL_RINGING:
-               ast_verb(3, "%s is ringing\n", ast_channel_name(channel->owner));
-               set_state(dial, AST_DIAL_RESULT_RINGING);
-               break;
-       case AST_CONTROL_PROGRESS:
-               ast_verb(3, "%s is making progress\n", ast_channel_name(channel->owner));
-               set_state(dial, AST_DIAL_RESULT_PROGRESS);
-               break;
-       case AST_CONTROL_PROCEEDING:
-               ast_verb(3, "%s is proceeding\n", ast_channel_name(channel->owner));
-               set_state(dial, AST_DIAL_RESULT_PROCEEDING);
-               break;
-       default:
-               break;
-       }
-}
-
 /*! \brief Helper function to handle when a timeout occurs on dialing attempt */
 static int handle_timeout_trip(struct ast_dial *dial, struct timeval start)
 {
@@ -887,10 +868,7 @@ static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_chann
                }
 
                /* Process the frame */
-               if (chan)
-                       handle_frame(dial, channel, fr, chan);
-               else
-                       handle_frame_ownerless(dial, channel, fr);
+               handle_frame(dial, channel, fr, chan);
 
                /* Free the received frame and start all over */
                ast_frfree(fr);