[asterisk-commits] file: branch file/dialing_api r49344 - in
/team/file/dialing_api: apps/ inclu...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Wed Jan 3 14:26:38 MST 2007
Author: file
Date: Wed Jan 3 15:26:37 2007
New Revision: 49344
URL: http://svn.digium.com/view/asterisk?view=rev&rev=49344
Log:
Yay major updates. Drop second async function, just add an async option to ast_dial_run. I also made 1 single function that handles the channels that are dialing out, and depending on whether it's sync or async forwards back data or changes the status.
Modified:
team/file/dialing_api/apps/app_dial2.c
team/file/dialing_api/include/asterisk/dial.h
team/file/dialing_api/main/dial.c
Modified: team/file/dialing_api/apps/app_dial2.c
URL: http://svn.digium.com/view/asterisk/team/file/dialing_api/apps/app_dial2.c?view=diff&rev=49344&r1=49343&r2=49344
==============================================================================
--- team/file/dialing_api/apps/app_dial2.c (original)
+++ team/file/dialing_api/apps/app_dial2.c Wed Jan 3 15:26:37 2007
@@ -96,7 +96,7 @@
memset(&bridge_config, 0, sizeof(bridge_config));
/* Attempt to dial all the channels and bridge to the one that answered */
- if ((ast_dial_run(dial, chan) == AST_DIAL_RESULT_ANSWERED) && (answered = ast_dial_answered(dial)))
+ if ((ast_dial_run(dial, chan, 0) == AST_DIAL_RESULT_ANSWERED) && (answered = ast_dial_answered(dial)))
ast_bridge_call(chan, answered, &bridge_config);
/* Hangup all calls in the dialing structure */
Modified: team/file/dialing_api/include/asterisk/dial.h
URL: http://svn.digium.com/view/asterisk/team/file/dialing_api/include/asterisk/dial.h?view=diff&rev=49344&r1=49343&r2=49344
==============================================================================
--- team/file/dialing_api/include/asterisk/dial.h (original)
+++ team/file/dialing_api/include/asterisk/dial.h Wed Jan 3 15:26:37 2007
@@ -65,23 +65,23 @@
*/
int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device);
-/*! \brief Execute dialing synchronously
- * \note Dials channels in a dial structure and does not return until one is answered or timeout is reached. Will also forward progress/ringing.
- * \return Returns 0 on success, -1 on failure
+/*! \brief Execute dialing synchronously or asynchronously
+ * \note Dials channels in a dial structure.
+ * \return Returns dial result code. (TRYING/INVALID/FAILED/ANSWERED/TIMEOUT/UNANSWERED).
*/
-enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *chan);
-
-/*! \brief Execute dialing asynchronously
- * \note Dials channels in a dial structure in a separate thread, returns almost immediately
- * \return Returns 0 on success, -1 on failure
- */
-enum ast_dial_result ast_dial_run_async(struct ast_dial *dial, struct ast_channel *chan);
+enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *chan, int async);
/*! \brief Return channel that answered
* \note Returns the Asterisk channel that answered
* \param dial Dialing structure
*/
struct ast_channel *ast_dial_answered(struct ast_dial *dial);
+
+/*! \brief Return status of dial
+ * \note Returns the status of the dial attempt
+ * \param dial Dialing structure
+ */
+enum ast_dial_result ast_dial_status(struct ast_dial *dial);
/*! \brief Hangup channels
* \note Hangup all active channels
Modified: team/file/dialing_api/main/dial.c
URL: http://svn.digium.com/view/asterisk/team/file/dialing_api/main/dial.c?view=diff&rev=49344&r1=49343&r2=49344
==============================================================================
--- team/file/dialing_api/main/dial.c (original)
+++ team/file/dialing_api/main/dial.c Wed Jan 3 15:26:37 2007
@@ -213,198 +213,209 @@
return channel;
}
-/*! \brief Execute dialing synchronously
- * \note Dials channels in a dial structure and does not return until one is answered or timeout is reached. Will also forward progress/ringing.
- * \return Returns 0 on success, -1 on failure
- */
-enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *chan)
-{
- int to_monitor = 0, single = 0, timeout = 0;
- struct ast_channel *cs[AST_MAX_WATCHERS] = {NULL, }, *who = NULL;
+/*! \brief Helper function that handles control frames WITH owner */
+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) {
+ case AST_CONTROL_ANSWER:
+ if (option_verbose > 2)
+ ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", channel->owner->name, chan->name);
+ AST_LIST_REMOVE(&dial->channels, channel, list);
+ AST_LIST_INSERT_HEAD(&dial->channels, channel, list);
+ dial->status = AST_DIAL_RESULT_ANSWERED;
+ break;
+ case AST_CONTROL_BUSY:
+ if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", channel->owner->name);
+ ast_hangup(channel->owner);
+ channel->owner = NULL;
+ break;
+ case AST_CONTROL_CONGESTION:
+ if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", channel->owner->name);
+ ast_hangup(channel->owner);
+ channel->owner = NULL;
+ break;
+ case AST_CONTROL_RINGING:
+ if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", channel->owner->name);
+ ast_indicate(chan, AST_CONTROL_RINGING);
+ break;
+ case AST_CONTROL_PROGRESS:
+ if (option_verbose > 2)
+ ast_verbose (VERBOSE_PREFIX_3 "%s is making progress, passing it to %s\n", channel->owner->name, chan->name);
+ ast_indicate(chan, AST_CONTROL_PROGRESS);
+ break;
+ case AST_CONTROL_VIDUPDATE:
+ if (option_verbose > 2)
+ ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", channel->owner->name, chan->name);
+ ast_indicate(chan, AST_CONTROL_VIDUPDATE);
+ break;
+ case AST_CONTROL_PROCEEDING:
+ if (option_verbose > 2)
+ ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding, passing it to %s\n", channel->owner->name, chan->name);
+ ast_indicate(chan, AST_CONTROL_PROCEEDING);
+ break;
+ case AST_CONTROL_HOLD:
+ if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", chan->name);
+ ast_indicate(chan, AST_CONTROL_HOLD);
+ break;
+ case AST_CONTROL_UNHOLD:
+ if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", chan->name);
+ ast_indicate(chan, AST_CONTROL_UNHOLD);
+ break;
+ case AST_CONTROL_OFFHOOK:
+ case AST_CONTROL_FLASH:
+ break;
+ case -1:
+ /* Prod the channel */
+ ast_indicate(chan, -1);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return;
+}
+
+/*! \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 status of the dial structure, so only look at control frames */
+ if (fr->frametype != AST_FRAME_CONTROL)
+ return;
+
+ switch (fr->subclass) {
+ default:
+ break;
+ }
+
+ return;
+}
+
+/*! \brief Helper function that basically keeps tabs on dialing attempts */
+static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_channel *chan)
+{
+ int single = 0, timeout = -1, count = 0;
+ struct ast_channel *cs[AST_MAX_WATCHERS], *who = NULL;
struct ast_dial_channel *channel = NULL;
- /* Ensure required arguments are passed */
- if (!dial || !chan)
- return AST_DIAL_RESULT_INVALID;
-
- /* If there are no channels to dial we can't very well try to dial them */
- if (AST_LIST_EMPTY(&dial->channels))
- return AST_DIAL_RESULT_INVALID;
-
- /* Dial each requested channel */
- if (!(to_monitor = begin_dial(dial, chan)))
- return AST_DIAL_RESULT_FAILED;
-
- /* Increment by one since we have to monitor our own channel */
- to_monitor++;
-
- /* Set status to be in progress */
+ /* Switch dialing status to trying */
dial->status = AST_DIAL_RESULT_TRYING;
- /* See if this is just a single dial */
+ /* See if this is a single dial attempt */
if (AST_LIST_FIRST(&dial->channels) == AST_LIST_LAST(&dial->channels))
single = 1;
- /* If no timeout is specified, then assume infinite */
- if (!timeout)
- timeout = -1;
-
- /* Go into a loop monitoring channels */
- while (dial->status == AST_DIAL_RESULT_INVALID) {
- int pos = 1;
+ /* Go into an infinite loop while we are trying */
+ while (dial->status == AST_DIAL_RESULT_TRYING) {
+ int pos = 0;
struct ast_frame *fr = NULL;
-
- /* If we are down to a single channel to monitor then our attempts have failed */
- if (to_monitor == 1) {
+
+ /* Set up channel structure array */
+ pos = count = 0;
+ if (chan)
+ cs[pos++] = chan;
+
+ /* Add channels we are attempting to dial */
+ AST_LIST_TRAVERSE(&dial->channels, channel, list) {
+ if (channel->owner) {
+ cs[pos++] = channel->owner;
+ count++;
+ }
+ }
+
+ /* If we have no outbound channels in progress, switch status to unanswered and stop */
+ if (!count) {
dial->status = AST_DIAL_RESULT_UNANSWERED;
break;
}
-
- /* Put ourselves into the structure */
- cs[0] = chan;
- /* Now everyone else! */
- pos = 1;
- AST_LIST_TRAVERSE(&dial->channels, channel, list) {
- if (!channel->owner)
- continue;
- cs[pos++] = channel->owner;
- }
-
- if (!(who = ast_waitfor_n(cs, pos, &timeout)))
+
+ /* Wait for frames from channels */
+ if (!(who = ast_waitfor_n(cs, pos, &timeout))) {
+ /* We need to handle timeouts here when it is implemented */
continue;
-
- /* Find relative dial channel... just in case */
- if (!IS_CALLER(chan, who))
+ }
+
+ /* Find relative dial channel */
+ if (!chan || !IS_CALLER(chan, who))
channel = find_relative_dial_channel(dial, who);
- /* Try to read in a frame */
+ /* Attempt to read in a frame */
if (!(fr = ast_read(who))) {
- if (IS_CALLER(chan, who)) {
- /* This is the caller who hung up */
+ /* If this is the caller then we switch status to hangup and stop */
+ if (chan && IS_CALLER(chan, who)) {
dial->status = AST_DIAL_RESULT_HANGUP;
break;
}
ast_hangup(who);
channel->owner = NULL;
- to_monitor--;
continue;
}
- /* Process control frames first */
- if (fr->frametype == AST_FRAME_CONTROL) {
- switch (fr->subclass) {
- case AST_CONTROL_ANSWER:
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", who->name, chan->name);
- /* This is sort of cheeky but what we do is make the first channel in the list the answered channel */
- AST_LIST_REMOVE(&dial->channels, channel, list);
- AST_LIST_INSERT_HEAD(&dial->channels, channel, list);
- dial->status = AST_DIAL_RESULT_ANSWERED;
- break;
- case AST_CONTROL_BUSY:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", who->name);
- ast_hangup(who);
- channel->owner = NULL;
- to_monitor--;
- break;
- case AST_CONTROL_CONGESTION:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", who->name);
- ast_hangup(who);
- channel->owner = NULL;
- to_monitor--;
- break;
- case AST_CONTROL_RINGING:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", who->name);
- ast_indicate(chan, AST_CONTROL_RINGING);
- break;
- case AST_CONTROL_PROGRESS:
- if (option_verbose > 2)
- ast_verbose (VERBOSE_PREFIX_3 "%s is making progress, passing it to %s\n", who->name, chan->name);
- ast_indicate(chan, AST_CONTROL_PROGRESS);
- break;
- case AST_CONTROL_VIDUPDATE:
- if (option_verbose > 2)
- ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", who->name, chan->name);
- ast_indicate(chan, AST_CONTROL_VIDUPDATE);
- break;
- case AST_CONTROL_PROCEEDING:
- if (option_verbose > 2)
- ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding, passing it to %s\n", who->name, chan->name);
- ast_indicate(chan, AST_CONTROL_PROCEEDING);
- break;
- case AST_CONTROL_HOLD:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", chan->name);
- ast_indicate(chan, AST_CONTROL_HOLD);
- break;
- case AST_CONTROL_UNHOLD:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", chan->name);
- ast_indicate(chan, AST_CONTROL_UNHOLD);
- break;
- case AST_CONTROL_OFFHOOK:
- case AST_CONTROL_FLASH:
- break;
- case -1:
- /* Prod the channel */
- ast_indicate(chan, -1);
- break;
- default:
- break;
- }
- }
-
- /* Free the frame */
+ /* Process the frame */
+ if (chan)
+ handle_frame(dial, channel, fr, chan);
+ else
+ handle_frame_ownerless(dial, channel, fr);
+
+ /* Free the received frame and start all over */
ast_frfree(fr);
}
- /* Based on the result code we can determine what to do next */
- switch (dial->status) {
- case AST_DIAL_RESULT_ANSWERED:
- /* A channel was answered, so hang up all our other attempts */
+ /* Do post-processing from loop */
+ if (dial->status == AST_DIAL_RESULT_ANSWERED) {
+ /* Hangup everything except that which answered */
AST_LIST_TRAVERSE(&dial->channels, channel, list) {
- if (channel->owner && channel->owner != who) {
- ast_hangup(channel->owner);
- channel->owner = NULL;
- }
- }
- break;
- case AST_DIAL_RESULT_HANGUP:
- case AST_DIAL_RESULT_UNANSWERED:
- case AST_DIAL_RESULT_TIMEOUT:
- /* No channels were answered, hangup everyone */
+ if (!channel->owner || channel->owner == who)
+ continue;
+ ast_hangup(channel->owner);
+ channel->owner = NULL;
+ }
+ } else {
+ /* Hangup everything */
AST_LIST_TRAVERSE(&dial->channels, channel, list) {
- if (channel->owner) {
- ast_hangup(channel->owner);
- channel->owner = NULL;
- }
- }
- break;
- default:
- break;
+ if (!channel->owner)
+ continue;
+ ast_hangup(channel->owner);
+ channel->owner = NULL;
+ }
}
return dial->status;
}
-/*! \brief Execute dialing asynchronously
- * \note Dials channels in a dial structure in a separate thread, returns almost immediately
- * \return Returns 0 on success, -1 on failure
- */
-enum ast_dial_result ast_dial_run_async(struct ast_dial *dial, struct ast_channel *chan)
-{
+/*! \brief Execute dialing synchronously or asynchronously
+ * \note Dials channels in a dial structure.
+ * \return Returns dial result code. (TRYING/INVALID/FAILED/ANSWERED/TIMEOUT/UNANSWERED).
+ */
+enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *chan, int async)
+{
+ enum ast_dial_result res = AST_DIAL_RESULT_TRYING;
+
+ /* Ensure required arguments are passed */
+ if (!dial || !chan)
+ return AST_DIAL_RESULT_INVALID;
+
/* If there are no channels to dial we can't very well try to dial them */
if (AST_LIST_EMPTY(&dial->channels))
return AST_DIAL_RESULT_INVALID;
-
- /* If we failed to dial any channels, then return a failed result */
+
+ /* Dial each requested channel */
if (!begin_dial(dial, chan))
return AST_DIAL_RESULT_FAILED;
- return AST_DIAL_RESULT_TRYING;
+ /* If we are running async spawn a thread and send it away... otherwise block here */
+ if (async) {
+ } else {
+ res = monitor_dial(dial, chan);
+ }
+
+ return res;
}
/*! \brief Return channel that answered
@@ -417,6 +428,15 @@
return NULL;
return ((dial->status == AST_DIAL_RESULT_ANSWERED) ? AST_LIST_FIRST(&dial->channels)->owner : NULL);
+}
+
+/*! \brief Return status of dial
+ * \note Returns the status of the dial attempt
+ * \param dial Dialing structure
+ */
+enum ast_dial_result ast_dial_status(struct ast_dial *dial)
+{
+ return dial->status;
}
/*! \brief Hangup channels
More information about the asterisk-commits
mailing list