From 778fa4abafbb19eeb7690c51d886908c0040cf9c Mon Sep 17 00:00:00 2001 From: Mark Michelson Date: Fri, 20 Jan 2012 20:47:42 +0000 Subject: Various parking improvements. * Adds per-parking lot options comebackcontext and comebackdialtime * Makes comebacktoorigin settable per parking lot * Sets a PARKER channel variable when comebacktoorigin is disabled (closes issue ASTERISK-16643) Reported by: Mitch Sharp (bluecrow76) Patches: asterisk-1.6.2.17.2-park-features-comebackcontext-consolidated-v3.diff by Mitch Sharp (bluecrow76) license 5231 with updates by me. Review: https://reviewboard.asterisk.org/r/1674 Review: https://reviewboard.asterisk.org/r/963 Reviewed by Richard Mudgett git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@351913 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- CHANGES | 8 ++++++ UPGRADE.txt | 4 +++ configs/features.conf.sample | 30 ++++++++++++++++++---- main/features.c | 61 +++++++++++++++++++++++++++++++++++++------- 4 files changed, 89 insertions(+), 14 deletions(-) diff --git a/CHANGES b/CHANGES index 67cddb520..b7d01aed4 100644 --- a/CHANGES +++ b/CHANGES @@ -74,6 +74,14 @@ Applications manually specify timezone and format) There are other beneftis eg. format can now be used without specifying time zone as well. +Parking +------------ + * New per parking lot options: comebackcontext and comebackdialtime. See + configs/features.conf.sample for more details. + + * Channel variable PARKER is now set when comebacktoorigin is disabled in + a parking lot. + CDR postgresql driver changes ----------------------------- * Added command "cdr show pgsql status" to check connection status diff --git a/UPGRADE.txt b/UPGRADE.txt index a876d0773..e5a81a98d 100644 --- a/UPGRADE.txt +++ b/UPGRADE.txt @@ -22,6 +22,10 @@ From 10 to 11: +Parking: + - The comebacktoorigin setting must now be set per parking lot. The setting in + the general section will not be applied automatically to each parking lot. + Dialplan Functions: - MAILBOX_EXISTS has been deprecated. Use VM_INFO with the 'exists' parameter instead. diff --git a/configs/features.conf.sample b/configs/features.conf.sample index 904c5d937..7f00fab94 100644 --- a/configs/features.conf.sample +++ b/configs/features.conf.sample @@ -19,19 +19,23 @@ context => parkedcalls ; Which context parked calls are in (default par ;comebacktoorigin = yes ; Setting this option configures the behavior of call parking when the ; parked call times out (See the parkingtime option). The default value is 'yes'. - ; Operates on all parking lots. + ; Set per parking lot. ; ; 'yes' - When the parked call times out, attempt to send the call back to the peer - ; that parked this call. This is done by saving off the name of the channel - ; that parked the call. + ; that parked this call. This is done by saving off the name of the channel + ; that parked the call. The call will return to the context 'park-dial' and + ; an extension created based on the name of the channel that originally parked + ; the call. This extension will be created automatically to do a Dial() to the + ; device that originally parked the call for comebacktodialtime seconds. If the + ; call is not answered, the call will proceed to 'park-dial,t,1'. ; ; 'no' - This option is useful for performing custom dialplan functionality prior to ; sending the call back to the extension that initially parked the call, or to ; an entirely different destination. ; ; When the parked call times out, send it back to the dialplan. The location - ; will be the 'parkedcallstimeout' context. The extension will be built from - ; the saved channel name that parked the call. For example, if a SIP peer named + ; will be defined by the comebackcontext option. The extension will be built from + ; the saved channel name that parked the call. For example, if a SIP peer named ; '0004F2040001' parked this call, the extension will be 'SIP_0004F2040001'. ; (Note that an underscore is used here because the '/' character has a special ; meaning in extension names for CallerID matching.) If this extension does not @@ -46,6 +50,18 @@ context => parkedcalls ; Which context parked calls are in (default par ; During the timeout procedure, the following variables are set ; PARKINGSLOT - extension that the call was parked in prior to timing out ; PARKEDLOT - name of the lot that the call was parked in prior to timing out + ; PARKER - name of the device that parked the call + +;comebackdialtime = 30 ; When a parked call times out, this is the number of seconds to dial the device that + ; originally parked the call. It is also available as a channel variable COMEBACKDIALTIME + ; after a parked call has timed out. + ; The default value is 30 seconds. + ; Set per parking lot. + +;comebackcontext = parkedcallstimeout + ; The context a timed out call will return to if comebcktoorigin=no. + ; The default value is 'parkedcallstimeout'. + ; Set per parking lot. ;courtesytone = beep ; Sound file to play to when someone picks up a parked call ; and also when the Touch Monitor is activated/deactivated. @@ -113,6 +129,10 @@ context => parkedcalls ; Which context parked calls are in (default par ;parkext => 799 ;parkpos => 800-850 ;findslot => next +;comebacktoorigin = no +;comebackdialtime = 90 +;comebackcontext = edvinapark-timeout ; Make sure you create the context! +;parkedmusicclass = edvina ; Note that the DTMF features listed below only work when two channels have answered and are bridged together. ; They can not be used while the remote party is ringing or in progress. If you require this feature you can use diff --git a/main/features.c b/main/features.c index 1e0eaf1b6..b4b779dcc 100644 --- a/main/features.c +++ b/main/features.c @@ -388,6 +388,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #define DEFAULT_ATXFER_DROP_CALL 0 /*!< Do not drop call. */ #define DEFAULT_ATXFER_LOOP_DELAY 10000 /*!< ms */ #define DEFAULT_ATXFER_CALLBACK_RETRIES 2 +#define DEFAULT_COMEBACK_CONTEXT "parkedcallstimeout" +#define DEFAULT_COMEBACK_TO_ORIGIN 1 +#define DEFAULT_COMEBACK_DIAL_TIME 30 #define AST_MAX_WATCHERS 256 #define MAX_DIAL_FEATURE_OPTIONS 30 @@ -494,7 +497,9 @@ struct parkinglot_cfg { /*! Extension to park calls in this parking lot. */ char parkext[AST_MAX_EXTENSION]; /*! Context for which parking is made accessible */ - char parking_con[AST_MAX_EXTENSION]; + char parking_con[AST_MAX_CONTEXT]; + /*! Context that timed-out parked calls are called back on when comebacktoorigin=no */ + char comebackcontext[AST_MAX_CONTEXT]; /*! First available extension for parking */ int parking_start; /*! Last available extension for parking */ @@ -542,6 +547,8 @@ struct parkinglot_cfg { */ int parkedcallrecording; + /*! Time in seconds to dial the device that parked a timedout parked call */ + unsigned int comebackdialtime; /*! TRUE if findslot is set to next */ unsigned int parkfindnext:1; /*! TRUE if the parking lot is exclusively accessed by parkext */ @@ -550,6 +557,8 @@ struct parkinglot_cfg { unsigned int parkaddhints:1; /*! TRUE if configuration is invalid and the parking lot should not be used. */ unsigned int is_invalid:1; + /*! TRUE if a timed out parked call goes back to the parker */ + unsigned int comebacktoorigin:1; }; /*! \brief Structure for parking lots which are put in a container. */ @@ -609,7 +618,6 @@ static int adsipark; static int transferdigittimeout; static int featuredigittimeout; -static int comebacktoorigin = 1; static int atxfernoanswertimeout; static unsigned int atxferdropcall; @@ -4600,6 +4608,7 @@ static int manage_parked_call(struct parkeduser *pu, const struct pollfd *pfds, parking_con_dial); } else { char returnexten[AST_MAX_EXTENSION]; + char comebackdialtime[AST_MAX_EXTENSION]; struct ast_datastore *features_datastore; struct ast_dial_features *dialfeatures; @@ -4613,16 +4622,24 @@ static int manage_parked_call(struct parkeduser *pu, const struct pollfd *pfds, if (features_datastore && (dialfeatures = features_datastore->data)) { char buf[MAX_DIAL_FEATURE_OPTIONS] = {0,}; - snprintf(returnexten, sizeof(returnexten), "%s,30,%s", peername, + snprintf(returnexten, sizeof(returnexten), "%s,%u,%s", peername, + pu->parkinglot->cfg.comebackdialtime, callback_dialoptions(&(dialfeatures->features_callee), &(dialfeatures->features_caller), buf, sizeof(buf))); } else { /* Existing default */ ast_log(LOG_NOTICE, "Dial features not found on %s, using default!\n", ast_channel_name(chan)); - snprintf(returnexten, sizeof(returnexten), "%s,30,t", peername); + snprintf(returnexten, sizeof(returnexten), "%s,%u,t", peername, + pu->parkinglot->cfg.comebackdialtime); } ast_channel_unlock(chan); + snprintf(comebackdialtime, sizeof(comebackdialtime), "%u", + pu->parkinglot->cfg.comebackdialtime); + pbx_builtin_setvar_helper(chan, "COMEBACKDIALTIME", comebackdialtime); + + pbx_builtin_setvar_helper(chan, "PARKER", peername); + if (ast_add_extension(parking_con_dial, 1, peername_flat, 1, NULL, NULL, "Dial", ast_strdup(returnexten), ast_free_ptr, registrar)) { ast_log(LOG_ERROR, @@ -4636,7 +4653,7 @@ static int manage_parked_call(struct parkeduser *pu, const struct pollfd *pfds, * those arguments. */ set_c_e_p(chan, pu->context, pu->exten, pu->priority); - } else if (comebacktoorigin) { + } else if (pu->parkinglot->cfg.comebacktoorigin) { set_c_e_p(chan, parking_con_dial, peername_flat, 1); } else { char parkingslot[AST_MAX_EXTENSION]; @@ -4644,7 +4661,7 @@ static int manage_parked_call(struct parkeduser *pu, const struct pollfd *pfds, snprintf(parkingslot, sizeof(parkingslot), "%d", pu->parkingnum); pbx_builtin_setvar_helper(chan, "PARKINGSLOT", parkingslot); pbx_builtin_setvar_helper(chan, "PARKEDLOT", pu->parkinglot->name); - set_c_e_p(chan, "parkedcallstimeout", peername_flat, 1); + set_c_e_p(chan, pu->parkinglot->cfg.comebackcontext, peername_flat, 1); } } else { /* @@ -5331,12 +5348,18 @@ static const struct parkinglot_cfg parkinglot_cfg_default_default = { .parking_start = 701, .parking_stop = 750, .parkingtime = DEFAULT_PARK_TIME, + .comebackdialtime = DEFAULT_COMEBACK_DIAL_TIME, + .comebackcontext = DEFAULT_COMEBACK_CONTEXT, + .comebacktoorigin = DEFAULT_COMEBACK_TO_ORIGIN, }; /*! Default configuration for normal parking lots. */ static const struct parkinglot_cfg parkinglot_cfg_default = { .parkext = DEFAULT_PARK_EXTENSION, .parkingtime = DEFAULT_PARK_TIME, + .comebackdialtime = DEFAULT_COMEBACK_DIAL_TIME, + .comebackcontext = DEFAULT_COMEBACK_CONTEXT, + .comebacktoorigin = DEFAULT_COMEBACK_TO_ORIGIN, }; /*! @@ -5423,6 +5446,16 @@ static int parkinglot_config_read(const char *pl_name, struct parkinglot_cfg *cf parkinglot_feature_flag_cfg(pl_name, &cfg->parkedcallhangup, var); } else if (!strcasecmp(var->name, "parkedcallrecording")) { parkinglot_feature_flag_cfg(pl_name, &cfg->parkedcallrecording, var); + } else if (!strcasecmp(var->name, "comebackcontext")) { + ast_copy_string(cfg->comebackcontext, var->value, sizeof(cfg->comebackcontext)); + } else if (!strcasecmp(var->name, "comebacktoorigin")) { + cfg->comebacktoorigin = ast_true(var->value); + } else if (!strcasecmp(var->name, "comebackdialtime")) { + if ((sscanf(var->value, "%30u", &cfg->comebackdialtime) != 1) + || (cfg->comebackdialtime < 1)) { + ast_log(LOG_WARNING, "%s is not a valid comebackdialtime\n", var->value); + cfg->parkingtime = DEFAULT_COMEBACK_DIAL_TIME; + } } var = var->next; } @@ -5440,6 +5473,12 @@ static int parkinglot_config_read(const char *pl_name, struct parkinglot_cfg *cf ast_log(LOG_WARNING, "Parking lot %s needs parkpos\n", pl_name); error = -1; } + if (!cfg->comebacktoorigin && ast_strlen_zero(cfg->comebackcontext)) { + ast_log(LOG_WARNING, "Parking lot %s has comebacktoorigin set false" + "but has no comebackcontext.\n", + pl_name); + error = -1; + } if (error) { cfg->is_invalid = 1; } @@ -5718,7 +5757,6 @@ static int process_config(struct ast_config *cfg) atxfercallbackretries = DEFAULT_ATXFER_CALLBACK_RETRIES; /* Set global call parking defaults. */ - comebacktoorigin = 1; courtesytone[0] = '\0'; parkedplay = 0; adsipark = 0; @@ -5784,8 +5822,6 @@ static int process_config(struct ast_config *cfg) ast_copy_string(pickupsound, var->value, sizeof(pickupsound)); } else if (!strcasecmp(var->name, "pickupfailsound")) { ast_copy_string(pickupfailsound, var->value, sizeof(pickupfailsound)); - } else if (!strcasecmp(var->name, "comebacktoorigin")) { - comebacktoorigin = ast_true(var->value); } } @@ -6688,6 +6724,13 @@ static char *handle_feature_show(struct ast_cli_entry *e, int cmd, struct ast_cl ast_cli(a->fd,"%-22s: %d-%d\n", "Parked call extensions", curlot->cfg.parking_start, curlot->cfg.parking_stop); ast_cli(a->fd,"%-22s: %d ms\n", "Parkingtime", curlot->cfg.parkingtime); + ast_cli(a->fd,"%-22s: %s\n", "Comeback to origin", + (curlot->cfg.comebacktoorigin ? "yes" : "no")); + ast_cli(a->fd,"%-22s: %s%s\n", "Comeback context", + curlot->cfg.comebackcontext, (curlot->cfg.comebacktoorigin ? + " (comebacktoorigin=yes, not used)" : "")); + ast_cli(a->fd,"%-22s: %d\n", "Comeback dial time", + curlot->cfg.comebackdialtime); ast_cli(a->fd,"%-22s: %s\n", "MusicOnHold class", curlot->cfg.mohclass); ast_cli(a->fd,"%-22s: %s\n", "Enabled", AST_CLI_YESNO(!curlot->disabled)); ast_cli(a->fd,"\n"); -- cgit v1.2.3