[svn-commits] rmudgett: branch 10 r332101 - in /branches/10: ./ configs/ main/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Aug 16 12:17:36 CDT 2011


Author: rmudgett
Date: Tue Aug 16 12:17:28 2011
New Revision: 332101

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=332101
Log:
Merged revisions 332100 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.8

........
  r332100 | rmudgett | 2011-08-16 11:31:36 -0500 (Tue, 16 Aug 2011) | 133 lines
  
  Fix multiple parking issues.
  
  JIRA ASTERISK-17183
  Multi-parkinglot directs calls to wrong parkinglot.
  JIRA ASTERISK-17870
  Cannot retrieve parked calls.
  JIRA ASTERISK-17430
  ParkedCall() with no extension should pickup first available call and does not.
  JIRA AST-576
  Issues with parking lots
  
  * Removed searching for parking lots by extension.  Parking lots can only
  be found by the parking lot name since parking lot access extensions and
  spaces are not guaranteed to be unique.
  
  * Added parking_lot_name option to the Park and ParkedCall applications.
  Updated documentation for Park and ParkedCall applications.
  
  * Add parkext_exclusive configuration option to make parking entry
  extensions specify which parking lot they access.
  
  (closes issue ASTERISK-17183)
  Reported by: David Cabrejos
  Tested by: rmudgett, David Cabrejos
  
  (closes issue ASTERISK-17870)
  Reported by: Remi Quezada
  
  (closes issue ASTERISK-17430)
  Reported by: Philippe Lindheimer
  
  
  JIRA ASTERISK-17452
  Parking_offset not used
  JIRA AST-624
  'next' setting for findslot does nothing
  
  * Reimplemented since findslot feature option broken by -r114655.
  
  (closes issue ASTERISK-17452)
  Reported by: David Woolley
  Tested by: rmudgett
  
  
  JIRA ASTERISK-15792
  Dialplan continues execution after transfer to park.
  
  This happens for DTMF attended transfer, DTMF blind transfer, and DTMF
  one-touch-parking if the party initiating these features also initiated
  the call.
  
  * Fixed the return code from the affected builtin features when parking a
  call.
  
  (closes issue ASTERISK-15792)
  Reported by: Mat Murdock
  Tested by: rmudgett, twilson
  
  
  JIRA AST-607
  The courtesytone is not playing to the expected call when picking up a
  parked call.
  
  This is mostly a documentation problem.  However, the option is not reset
  to the default when features.conf is reloaded.
  
  * Updated features.conf.sample documentation for courtesytone and
  parkedplay options.
  
  * Reset the parkedplay option to default when features.conf is reloaded.
  
  
  JIRA AST-615
  AMI Park action followed by features reload results in orphaned channels
  in parking lot.
  
  * Reloading features.conf will not touch parking lots that have calls
  still parked in them.  Reload again at a later time.
  
  
  Misc additional fixes:
  
  * Added unit test for parking lot dialplan usage checking.
  
  * Made update connected line when a parked call is retrieved from a
  parking lot.
  
  * Made retrieved parked call stop ringing or MOH depending upon how the
  call was waiting in the parking lot.
  
  * Made CLI "features show" indicate if the parking lot is enabled for use.
  
  * Added PARKINGDYNEXTEN channel variable to allow dynamic parking lots to
  specify the parking lot access extension.
  
  * Made AMI ParkedCalls action ParkedCall events have a Parkinglot header.
  
  * Made AMI ParkedCalls action ParkedCallsComplete event have a Total
  header.
  
  * Fixed potential deadlock from AMI Park action holding channel locks
  while calling masq_park_call().
  
  * Fixed several places where ast_strdupa() were used inside of loops.
  (Mostly fixed by refactoring the loop body into its own function.)
  
  * Fixed copy_parkinglot() copying too much from the source parking lot.
  Extracted the parking lot configuration settings into struct
  parkinglot_cfg.
  
  * Refactored courtesytone playing code to put the channel not playing the
  tone in autoservice.
  
  * Fix when pbx-parkingfailed is played that the other channel is put in
  autoservice if it exists.
  
  * Fixed parkinglot reference leak in parked_call_exec() error paths.
  
  * Fixed parkinglot_unref() use of parkinglot after it was unreffed.
  
  * Made destroy the struct ast_parkinglot parkings lock when done.
  
  * Refactored the features.conf parking lot configuration code to eliminate
  redundancy.
  
  * Fixed feature reload to better protect parking lots.
  
  * Fixed parking lot container reference leak in handle_parkedcalls().
  
  * Fixed the total count in handle_parkedcalls().
  
  Review: https://reviewboard.asterisk.org/r/1358/
........

Modified:
    branches/10/   (props changed)
    branches/10/CHANGES
    branches/10/configs/features.conf.sample
    branches/10/main/asterisk.c
    branches/10/main/features.c

Propchange: branches/10/
------------------------------------------------------------------------------
Binary property 'branch-1.8-merged' - no diff available.

Modified: branches/10/CHANGES
URL: http://svnview.digium.com/svn/asterisk/branches/10/CHANGES?view=diff&rev=332101&r1=332100&r2=332101
==============================================================================
--- branches/10/CHANGES (original)
+++ branches/10/CHANGES Tue Aug 16 12:17:28 2011
@@ -385,6 +385,7 @@
    notices a change.
  * Voicemail now includes rdnis within msgXXXX.txt file.
  * Added 'D' command to ExternalIVR full details in doc/externalivr.txt
+ * ParkedCall and Park can now specify the parking lot to use.
 
 Dialplan Functions
 ------------------
@@ -465,6 +466,8 @@
  * Added PARKINGDYNAMIC which represents the template parkinglot defined in
    features.conf that should be the base for dynamic parkinglots.
  * Added PARKINGDYNCONTEXT which tells what context a newly created dynamic
+   parkinglot should have.
+ * Added PARKINGDYNEXTEN which tells what parking exten a newly created dynamic
    parkinglot should have.
  * Added PARKINGDYNPOS which holds what parking positions a dynamic parkinglot
    should have.

Modified: branches/10/configs/features.conf.sample
URL: http://svnview.digium.com/svn/asterisk/branches/10/configs/features.conf.sample?view=diff&rev=332101&r1=332100&r2=332101
==============================================================================
--- branches/10/configs/features.conf.sample (original)
+++ branches/10/configs/features.conf.sample Tue Aug 16 12:17:28 2011
@@ -3,17 +3,23 @@
 ;
 
 [general]
-parkext => 700			; What extension to dial to park
-parkpos => 701-720		; What extensions to park calls on. (defafult parking lot)
-				; These needs to be numeric, as Asterisk starts from the start position
-				; and increments with one for the next parked call.
-context => parkedcalls		; Which context parked calls are in (default parking lot)
-;parkinghints = no		; Add hints priorities automatically for parking slots (default is no).
-;parkingtime => 45		; Number of seconds a call can be parked for
-				; (default is 45 seconds)
+parkext => 700                  ; What extension to dial to park.  Set per parking lot.
+;parkext_exclusive=yes          ; Specify that the parkext created for this parking lot
+                                ; will only access this parking lot. (default is no)
+parkpos => 701-720              ; What extensions to park calls on. (defafult parking lot)
+                                ; These need to be numeric, as Asterisk starts from the start position
+                                ; and increments with one for the next parked call.
+                                ; Set per parking lot.
+context => parkedcalls          ; Which context parked calls are in (default parking lot)
+                                ; Set per parking lot.
+;parkinghints = no              ; Add hints priorities automatically for parking slots (default is no).
+                                ; Set per parking lot.
+;parkingtime => 45              ; Number of seconds a call can be parked before returning.
+                                ; Set per parking lot. (default is 45 seconds)
 
 ;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.
                                 ;
                                 ; '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
@@ -38,48 +44,57 @@
                                 ;         Dial() to 'SIP/0004F2040001'.
                                 ;
 
-;courtesytone = beep		; Sound file to play to the parked caller
-				; when someone dials a parked call
-				; or the Touch Monitor is activated/deactivated.
-;parkedplay = caller		; Who to play the courtesy tone to when picking up a parked call
-				; one of: parked, caller, both  (default is caller)
+;courtesytone = beep            ; Sound file to play to when someone picks up a parked call
+                                ; and also when the Touch Monitor is activated/deactivated.
+                                ; Default is no tone.
+;parkedplay = caller            ; Who to play courtesytone to when picking up a parked call.
+                                ; One of: parked, caller, both  (default is caller)
+                                ; Operates on all parking lots.
 ;parkedcalltransfers = caller   ; Enables or disables DTMF based transfers when picking up a parked call.
                                 ; one of: callee, caller, both, no (default is no)
+                                ; Set per parking lot.
 ;parkedcallreparking = caller   ; Enables or disables DTMF based parking when picking up a parked call.
                                 ; one of: callee, caller, both, no (default is no)
+                                ; Set per parking lot.
 ;parkedcallhangup = caller      ; Enables or disables DTMF based hangups when picking up a parked call.
                                 ; one of: callee, caller, both, no (default is no)
+                                ; Set per parking lot.
 ;parkedcallrecording = caller   ; Enables or disables DTMF based one-touch recording when picking up a parked call.
                                 ; one of: callee, caller, both, no (default is no)
+                                ; Set per parking lot.
 ;parkeddynamic = yes            ; Enables dynamically created parkinglots. (default is no)
-;adsipark = yes			; if you want ADSI parking announcements
-;findslot => next		; Continue to the 'next' free parking space.
-				; Defaults to 'first' available
-;parkedmusicclass=default	; This is the MOH class to use for the parked channel
-				; as long as the class is not set on the channel directly
-				; using Set(CHANNEL(musicclass)=whatever) in the dialplan
-
-;transferdigittimeout => 3	; Number of seconds to wait between digits when transferring a call
-				; (default is 3 seconds)
-;xfersound = beep		; to indicate an attended transfer is complete
-;xferfailsound = beeperr	; to indicate a failed transfer
-;pickupexten = *8		; Configure the pickup extension. (default is *8)
-;pickupsound = beep		; to indicate a successful pickup (default: no sound)
-;pickupfailsound = beeperr	; to indicate that the pickup failed (default: no sound)
-;featuredigittimeout = 1000	; Max time (ms) between digits for
-                            ; feature activation  (default is 1000 ms)
-;atxfernoanswertimeout = 15 ; Timeout for answer on attended transfer default is 15 seconds.
-;atxferdropcall = no        ; If someone does an attended transfer, then hangs up before the transferred
-                            ; caller is connected, then by default, the system will try to call back the
-                            ; person that did the transfer.  If this is set to "yes", the callback will
-                            ; not be attempted and the transfer will just fail.
-                            ; For atxferdropcall=no to work properly, you also need to
-                            ; define ATXFER_NULL_TECH in main/features.c.  The reason the
-                            ; code is not enabled by default is spelled out in the comment
-                            ; block near the top of main/features.c describing ATXFER_NULL_TECH.
-;atxferloopdelay = 10       ; Number of seconds to sleep between retries (if atxferdropcall = no)
-;atxfercallbackretries = 2  ; Number of times to attempt to send the call back to the transferer.
-                            ; By default, this is 2.
+                                ; Operates on all parking lots.
+;adsipark = yes                 ; if you want ADSI parking announcements
+                                ; Operates on all parking lots.
+;findslot => next               ; Continue to the 'next' free parking space.
+                                ; Defaults to 'first' available
+                                ; Set per parking lot.
+;parkedmusicclass=default       ; This is the MOH class to use for the parked channel
+                                ; as long as the class is not set on the channel directly
+                                ; using Set(CHANNEL(musicclass)=whatever) in the dialplan
+                                ; Set per parking lot.
+
+;transferdigittimeout => 3      ; Number of seconds to wait between digits when transferring a call
+                                ; (default is 3 seconds)
+;xfersound = beep               ; to indicate an attended transfer is complete
+;xferfailsound = beeperr        ; to indicate a failed transfer
+;pickupexten = *8               ; Configure the pickup extension. (default is *8)
+;pickupsound = beep             ; to indicate a successful pickup (default: no sound)
+;pickupfailsound = beeperr      ; to indicate that the pickup failed (default: no sound)
+;featuredigittimeout = 1000     ; Max time (ms) between digits for
+                                ; feature activation  (default is 1000 ms)
+;atxfernoanswertimeout = 15     ; Timeout for answer on attended transfer default is 15 seconds.
+;atxferdropcall = no            ; If someone does an attended transfer, then hangs up before the transferred
+                                ; caller is connected, then by default, the system will try to call back the
+                                ; person that did the transfer.  If this is set to "yes", the callback will
+                                ; not be attempted and the transfer will just fail.
+                                ; For atxferdropcall=no to work properly, you also need to
+                                ; define ATXFER_NULL_TECH in main/features.c.  The reason the
+                                ; code is not enabled by default is spelled out in the comment
+                                ; block near the top of main/features.c describing ATXFER_NULL_TECH.
+;atxferloopdelay = 10           ; Number of seconds to sleep between retries (if atxferdropcall = no)
+;atxfercallbackretries = 2      ; Number of times to attempt to send the call back to the transferer.
+                                ; By default, this is 2.
 
 ;
 ;*** Define another parking lot
@@ -102,12 +117,12 @@
 
 
 [featuremap]
-;blindxfer => #1		; Blind transfer  (default is #) -- Make sure to set the T and/or t option in the Dial() or Queue() app call!
-;disconnect => *0		; Disconnect  (default is *) -- Make sure to set the H and/or h option in the Dial() or Queue() app call!
-;automon => *1			; One Touch Record a.k.a. Touch Monitor -- Make sure to set the W and/or w option in the Dial() or Queue() app call!
-;atxfer => *2			; Attended transfer  -- Make sure to set the T and/or t option in the Dial() or Queue()  app call!
-;parkcall => #72        ; Park call (one step parking)  -- Make sure to set the K and/or k option in the Dial() app call!
-;automixmon => *3		; One Touch Record a.k.a. Touch MixMonitor -- Make sure to set the X and/or x option in the Dial() or Queue() app call!
+;blindxfer => #1                ; Blind transfer  (default is #) -- Make sure to set the T and/or t option in the Dial() or Queue() app call!
+;disconnect => *0               ; Disconnect  (default is *) -- Make sure to set the H and/or h option in the Dial() or Queue() app call!
+;automon => *1                  ; One Touch Record a.k.a. Touch Monitor -- Make sure to set the W and/or w option in the Dial() or Queue() app call!
+;atxfer => *2                   ; Attended transfer  -- Make sure to set the T and/or t option in the Dial() or Queue()  app call!
+;parkcall => #72                ; Park call (one step parking)  -- Make sure to set the K and/or k option in the Dial() app call!
+;automixmon => *3               ; One Touch Record a.k.a. Touch MixMonitor -- Make sure to set the X and/or x option in the Dial() or Queue() app call!
 
 [applicationmap]
 ; Note that the DYNAMIC_FEATURES channel variable must be set to use the features
@@ -127,7 +142,7 @@
 ;<FeatureName> => <DTMF_sequence>,<ActivateOn>[/<ActivatedBy>],<Application>([<AppArguments>])[,MOH_Class]
 
 ;
-;  FeatureName   -> This is the name of the feature used in when setting the
+;  FeatureName   -> This is the name of the feature used when setting the
 ;                   DYNAMIC_FEATURES variable to enable usage of this feature.
 ;  DTMF_sequence -> This is the key sequence used to activate this feature.
 ;  ActivateOn    -> This is the channel of the call that the application will be executed
@@ -179,7 +194,7 @@
 ;   feature group, add the group name to the value of the DYNAMIC_FEATURES variable.
 ;
 ; example:
-; [myGroupName]        ; defines the group named myGroupName
-; testfeature => #9    ; associates testfeature with the group and the keycode '#9'.
-; pauseMonitor =>      ; associates pauseMonitor with the group and uses the keycode specified
-;                      ; in the [applicationmap].
+; [myGroupName]         ; defines the group named myGroupName
+; testfeature => #9     ; associates testfeature with the group and the keycode '#9'.
+; pauseMonitor =>       ; associates pauseMonitor with the group and uses the keycode specified
+;                       ; in the [applicationmap].

Modified: branches/10/main/asterisk.c
URL: http://svnview.digium.com/svn/asterisk/branches/10/main/asterisk.c?view=diff&rev=332101&r1=332100&r2=332101
==============================================================================
--- branches/10/main/asterisk.c (original)
+++ branches/10/main/asterisk.c Tue Aug 16 12:17:28 2011
@@ -3841,7 +3841,10 @@
 		exit(1);
 	}
 
-	ast_features_init();
+	if (ast_features_init()) {
+		printf("%s", term_quit());
+		exit(1);
+	}
 
 	if (init_framer()) {
 		printf("%s", term_quit());

Modified: branches/10/main/features.c
URL: http://svnview.digium.com/svn/asterisk/branches/10/main/features.c?view=diff&rev=332101&r1=332100&r2=332101
==============================================================================
--- branches/10/main/features.c (original)
+++ branches/10/main/features.c Tue Aug 16 12:17:28 2011
@@ -137,11 +137,11 @@
 					</option>
 					<option name="k">
 						<para>Allow the called party to enable parking of the call by sending
-						the DTMF sequence defined for call parking in features.conf.</para>
+						the DTMF sequence defined for call parking in <filename>features.conf</filename>.</para>
 					</option>
 					<option name="K">
 						<para>Allow the calling party to enable parking of the call by sending
-						 the DTMF sequence defined for call parking in features.conf.</para>
+						 the DTMF sequence defined for call parking in <filename>features.conf</filename>.</para>
 					</option>
 					<option name="L(x[:y][:z])">
 						<para>Limit the call to <replaceable>x</replaceable> ms. Play a warning
@@ -172,19 +172,19 @@
 					</option>
 					<option name="t">
 						<para>Allow the called party to transfer the calling party by sending the
-						DTMF sequence defined in features.conf.</para>
+						DTMF sequence defined in <filename>features.conf</filename>.</para>
 					</option>
 					<option name="T">
 						<para>Allow the calling party to transfer the called party by sending the
-						DTMF sequence defined in features.conf.</para>
+						DTMF sequence defined in <filename>features.conf</filename>.</para>
 					</option>
 					<option name="w">
 						<para>Allow the called party to enable recording of the call by sending
-						the DTMF sequence defined for one-touch recording in features.conf.</para>
+						the DTMF sequence defined for one-touch recording in <filename>features.conf</filename>.</para>
 					</option>
 					<option name="W">
 						<para>Allow the calling party to enable recording of the call by sending
-						the DTMF sequence defined for one-touch recording in features.conf.</para>
+						the DTMF sequence defined for one-touch recording in <filename>features.conf</filename>.</para>
 					</option>
 					<option name="x">
 						<para>Cause the called party to be hung up after the bridge, instead of being
@@ -210,17 +210,32 @@
 	</application>
 	<application name="ParkedCall" language="en_US">
 		<synopsis>
-			Answer a parked call.
+			Retrieve a parked call.
 		</synopsis>
 		<syntax>
-			<parameter name="exten" required="true" />
+			<parameter name="exten">
+				<para>Parking space extension to retrieve a parked call.
+				If not provided then the first available parked call in the
+				parking lot will be retrieved.</para>
+			</parameter>
+			<parameter name="parking_lot_name">
+				<para>Specify from which parking lot to retrieve a parked call.</para>
+				<para>The parking lot used is selected in the following order:</para>
+				<para>1) parking_lot_name option</para>
+				<para>2) <variable>PARKINGLOT</variable> variable</para>
+				<para>3) <literal>CHANNEL(parkinglot)</literal> function
+				(Possibly preset by the channel driver.)</para>
+				<para>4) Default parking lot.</para>
+			</parameter>
 		</syntax>
 		<description>
-			<para>Used to connect to a parked call. This application is always
-			registered internally and does not need to be explicitly added
-			into the dialplan, although you should include the <literal>parkedcalls</literal>
-			context. If no extension is provided, then the first available
-			parked call will be acquired.</para>
+			<para>Used to retrieve a parked call from a parking lot.</para>
+			<note>
+				<para>Parking lots automatically create and manage dialplan extensions in
+				the parking lot context.  You do not need to explicitly use this
+				application in your dialplan.  Instead, all you should do is include the
+				parking lot context in your dialplan.</para>
+			</note>
 		</description>
 		<see-also>
 			<ref type="application">Park</ref>
@@ -258,27 +273,47 @@
 					</option>
 				</optionlist>
 			</parameter>
+			<parameter name="parking_lot_name">
+				<para>Specify in which parking lot to park a call.</para>
+				<para>The parking lot used is selected in the following order:</para>
+				<para>1) parking_lot_name option</para>
+				<para>2) <variable>PARKINGLOT</variable> variable</para>
+				<para>3) <literal>CHANNEL(parkinglot)</literal> function
+				(Possibly preset by the channel driver.)</para>
+				<para>4) Default parking lot.</para>
+			</parameter>
 		</syntax>
 		<description>
 			<para>Used to park yourself (typically in combination with a supervised
-			transfer to know the parking space). This application is always
-			registered internally and does not need to be explicitly added
-			into the dialplan, although you should include the <literal>parkedcalls</literal>
-			context (or the context specified in <filename>features.conf</filename>).</para>
-			<para>If you set the <variable>PARKINGLOT</variable> variable, the call will be parked
-			in the specifed parking context. Note setting this variable overrides the <variable>
-			PARKINGLOT</variable> set by the <literal>CHANNEL</literal> function.</para>
-			<para>If you set the <variable>PARKINGEXTEN</variable> variable to an extension in your
-			parking context, Park() will park the call on that extension, unless
-			it already exists. In that case, execution will continue at next priority.</para>
-			<para>If you set the <variable>PARKINGLOT</variable> variable, Park() will park the call
-			in that parkinglot.</para>
-			<para>If you set the <variable>PARKINGDYNAMIC</variable> variable, this parkinglot from features.conf
-			will be used as template for the newly created dynamic lot.</para>
-			<para>If you set the <variable>PARKINGDYNCONTEXT</variable> variable the newly created dynamic
+			transfer to know the parking space).</para>
+			<para>If you set the <variable>PARKINGEXTEN</variable> variable to a
+			parking space extension in the parking lot, Park() will attempt to park the call
+			on that extension.  If the extension is already is in use then execution
+			will continue at the next priority.</para>
+			<para>If the <literal>parkeddynamic</literal> option is enabled in <filename>features.conf</filename>
+			the following variables can be used to dynamically create new parking lots.</para>
+			<para>If you set the <variable>PARKINGDYNAMIC</variable> variable and this parking lot
+			exists then it will be used as a template for the newly created dynamic lot.  Otherwise,
+			the default parking lot will be used.</para>
+			<para>If you set the <variable>PARKINGDYNCONTEXT</variable> variable then the newly created dynamic
 			parking lot will use this context.</para>
-			<para>If you set the <variable>PARKINGDYNPOS</variable> variable the newly created dynamic parkinglot
+			<para>If you set the <variable>PARKINGDYNEXTEN</variable> variable then the newly created dynamic
+			parking lot will use this extension to access the parking lot.</para>
+			<para>If you set the <variable>PARKINGDYNPOS</variable> variable then the newly created dynamic parking lot
 			will use those parking postitions.</para>
+			<note>
+				<para>This application must be used as the first extension priority
+				to be recognized as a parking access extension.  DTMF transfers
+				and some channel drivers need this distinction to operate properly.
+				The parking access extension in this case is treated like a dialplan
+				hint.</para>
+			</note>
+			<note>
+				<para>Parking lots automatically create and manage dialplan extensions in
+				the parking lot context.  You do not need to explicitly use this
+				application in your dialplan.  Instead, all you should do is include the
+				parking lot context in your dialplan.</para>
+			</note>
 		</description>
 		<see-also>
 			<ref type="application">ParkAndAnnounce</ref>
@@ -312,7 +347,7 @@
 				<para>Number of milliseconds to wait before callback.</para>
 			</parameter>
 			<parameter name="Parkinglot">
-				<para>Parking lot to park channel in.</para>
+				<para>Specify in which parking lot to park the channel.</para>
 			</parameter>
 		</syntax>
 		<description>
@@ -385,62 +420,191 @@
 
 static char pickup_ext[AST_MAX_EXTENSION];                 /*!< Call pickup extension */
 
+/*! Parking lot access ramp dialplan usage entry. */
+struct parking_dp_ramp {
+	/*! Next node in the parking lot spaces dialplan list. */
+	AST_LIST_ENTRY(parking_dp_ramp) node;
+	/*! TRUE if the parking lot access extension is exclusive. */
+	unsigned int exclusive:1;
+	/*! Parking lot access extension */
+	char exten[1];
+};
+
+/*! Parking lot dialplan access ramp map */
+AST_LIST_HEAD_NOLOCK(parking_dp_ramp_map, parking_dp_ramp);
+
+/*! Parking lot spaces dialplan usage entry. */
+struct parking_dp_spaces {
+	/*! Next node in the parking lot spaces dialplan list. */
+	AST_LIST_ENTRY(parking_dp_spaces) node;
+	/*! First parking space */
+	int start;
+	/*! Last parking space */
+	int stop;
+};
+
+/*! Parking lot dialplan context space map */
+AST_LIST_HEAD_NOLOCK(parking_dp_space_map, parking_dp_spaces);
+
+/*! Parking lot context dialplan usage entry. */
+struct parking_dp_context {
+	/*! Next node in the parking lot contexts dialplan list. */
+	AST_LIST_ENTRY(parking_dp_context) node;
+	/*! Parking access extensions defined in this context. */
+	struct parking_dp_ramp_map access_extens;
+	/*! Parking spaces defined in this context. */
+	struct parking_dp_space_map spaces;
+	/*! Parking hints defined in this context. */
+	struct parking_dp_space_map hints;
+	/*! Parking lot context name */
+	char context[1];
+};
+
+/*! Parking lot dialplan usage map. */
+AST_LIST_HEAD_NOLOCK(parking_dp_map, parking_dp_context);
+
 /*!
  * \brief Description of one parked call, added to a list while active, then removed.
  * The list belongs to a parkinglot.
  */
 struct parkeduser {
-	struct ast_channel *chan;                   /*!< Parking channel */
-	struct timeval start;                       /*!< Time the parking started */
-	int parkingnum;                             /*!< Parking lot */
+	struct ast_channel *chan;                   /*!< Parked channel */
+	struct timeval start;                       /*!< Time the park started */
+	int parkingnum;                             /*!< Parking lot space used */
 	char parkingexten[AST_MAX_EXTENSION];       /*!< If set beforehand, parking extension used for this call */
 	char context[AST_MAX_CONTEXT];              /*!< Where to go if our parking time expires */
 	char exten[AST_MAX_EXTENSION];
 	int priority;
 	int parkingtime;                            /*!< Maximum length in parking lot before return */
+	/*! Method to entertain the caller when parked: AST_CONTROL_RINGING, AST_CONTROL_HOLD, or 0(none) */
+	enum ast_control_frame_type hold_method;
 	unsigned int notquiteyet:1;
 	unsigned int options_specified:1;
 	char peername[1024];
 	unsigned char moh_trys;
+	/*! Parking lot this entry belongs to.  Holds a parking lot reference. */
 	struct ast_parkinglot *parkinglot;
 	AST_LIST_ENTRY(parkeduser) list;
 };
 
+/*! Parking lot configuration options. */
+struct parkinglot_cfg {
+	/*! Music class used for parking */
+	char mohclass[MAX_MUSICCLASS];
+	/*! 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];
+	/*! First available extension for parking */
+	int parking_start;
+	/*! Last available extension for parking */
+	int parking_stop;
+	/*! Default parking time in ms. */
+	int parkingtime;
+	/*!
+	 * \brief Enable DTMF based transfers on bridge when picking up parked calls.
+	 *
+	 * \details
+	 * none(0)
+	 * AST_FEATURE_FLAG_BYCALLEE
+	 * AST_FEATURE_FLAG_BYCALLER
+	 * AST_FEATURE_FLAG_BYBOTH
+	 */
+	int parkedcalltransfers;
+	/*!
+	 * \brief Enable DTMF based parking on bridge when picking up parked calls.
+	 *
+	 * \details
+	 * none(0)
+	 * AST_FEATURE_FLAG_BYCALLEE
+	 * AST_FEATURE_FLAG_BYCALLER
+	 * AST_FEATURE_FLAG_BYBOTH
+	 */
+	int parkedcallreparking;
+	/*!
+	 * \brief Enable DTMF based hangup on a bridge when pickup up parked calls.
+	 *
+	 * \details
+	 * none(0)
+	 * AST_FEATURE_FLAG_BYCALLEE
+	 * AST_FEATURE_FLAG_BYCALLER
+	 * AST_FEATURE_FLAG_BYBOTH
+	 */
+	int parkedcallhangup;
+	/*!
+	 * \brief Enable DTMF based recording on a bridge when picking up parked calls.
+	 *
+	 * \details
+	 * none(0)
+	 * AST_FEATURE_FLAG_BYCALLEE
+	 * AST_FEATURE_FLAG_BYCALLER
+	 * AST_FEATURE_FLAG_BYBOTH
+	 */
+	int parkedcallrecording;
+
+	/*! TRUE if findslot is set to next */
+	unsigned int parkfindnext:1;
+	/*! TRUE if the parking lot is exclusively accessed by parkext */
+	unsigned int parkext_exclusive:1;
+	/*! Add parking hints automatically */
+	unsigned int parkaddhints:1;
+	/*! TRUE if configuration is invalid and the parking lot should not be used. */
+	unsigned int is_invalid:1;
+};
+
 /*! \brief Structure for parking lots which are put in a container. */
 struct ast_parkinglot {
+	/*! Name of the parking lot. */
 	char name[AST_MAX_CONTEXT];
-	char parkext[AST_MAX_EXTENSION];				/*!< Parkingextension */
-	char parking_con[AST_MAX_EXTENSION];		/*!< Context for which parking is made accessible */
-	char parking_con_dial[AST_MAX_EXTENSION];	/*!< Context for dialback for parking (KLUDGE) */
-	int parking_start;				/*!< First available extension for parking */
-	int parking_stop;				/*!< Last available extension for parking */
-	int parking_offset;
-	int parkfindnext;
-	int parkingtime;				/*!< Default parking time */
-	char mohclass[MAX_MUSICCLASS];                  /*!< Music class used for parking */
-	int parkaddhints;                               /*!< Add parking hints automatically */
-	int parkedcalltransfers;                        /*!< Enable DTMF based transfers on bridge when picking up parked calls */
-	int parkedcallreparking;                        /*!< Enable DTMF based parking on bridge when picking up parked calls */
-	int parkedcallhangup;                           /*!< Enable DTMF based hangup on a bridge when pickup up parked calls */
-	int parkedcallrecording;                        /*!< Enable DTMF based recording on a bridge when picking up parked calls */
-	unsigned short the_mark:1;                      /*!< Used during reloads, that which bears the_mark shall be deleted! */
-	AST_LIST_HEAD(parkinglot_parklist, parkeduser) parkings; /*!< List of active parkings in this parkinglot */
+	/*! Parking lot user configuration. */
+	struct parkinglot_cfg cfg;
+
+	/*! Parking space to start next park search. */
+	int next_parking_space;
+
+	/*! That which bears the_mark shall be deleted if parking lot empty! (Used during reloads.) */
+	unsigned int the_mark:1;
+	/*! TRUE if the parking lot is disabled. */
+	unsigned int disabled:1;
+
+	/*! List of active parkings in this parkinglot */
+	AST_LIST_HEAD(parkinglot_parklist, parkeduser) parkings;
 };
 
-/*! \brief The list of parking lots configured. Always at least one  - the default parking lot */
+/*! \brief The configured parking lots container. Always at least one  - the default parking lot */
 static struct ao2_container *parkinglots;
- 
-struct ast_parkinglot *default_parkinglot;
-char parking_ext[AST_MAX_EXTENSION];            /*!< Extension you type to park the call */
-
-static char courtesytone[256];                             /*!< Courtesy tone */
-static int parkedplay = 0;                                 /*!< Who to play the courtesy tone to */
+
+/*!
+ * \brief Default parking lot.
+ * \note Holds a parkinglot reference.
+ * \note Will not be NULL while running.
+ */
+static struct ast_parkinglot *default_parkinglot;
+
+/*! Force a config reload to reload regardless of config file timestamp. */
+static int force_reload_load;
+
+static int parkedplay = 0;                                 /*!< Who to play courtesytone to when someone picks up a parked call. */
 static int parkeddynamic = 0;                              /*!< Enable creation of parkinglots dynamically */
+static char courtesytone[256];                             /*!< Courtesy tone used to pickup parked calls and on-touch-record */
 static char xfersound[256];                                /*!< Call transfer sound */
 static char xferfailsound[256];                            /*!< Call transfer failure sound */
 static char pickupsound[256];                              /*!< Pickup sound */
 static char pickupfailsound[256];                          /*!< Pickup failure sound */
 
+/*!
+ * \brief Context for parking dialback to parker.
+ * \note The need for the context is a KLUDGE.
+ *
+ * \todo Might be able to eliminate the parking_con_dial context
+ * kludge by running app_dial directly in its own thread to
+ * simulate a PBX.
+ */
+static char parking_con_dial[] = "park-dial";
+
+/*! Ensure that features.conf reloads on one thread at a time. */
+AST_MUTEX_DEFINE_STATIC(features_reload_lock);
+
 static int adsipark;
 
 static int transferdigittimeout;
@@ -453,6 +617,17 @@
 static unsigned int atxfercallbackretries;
 
 static char *registrar = "features";		   /*!< Registrar for operations */
+
+/*! PARK_APP_NAME application arguments */
+AST_DEFINE_APP_ARGS_TYPE(park_app_args,
+	AST_APP_ARG(timeout);		/*!< Time in ms to remain in the parking lot. */
+	AST_APP_ARG(return_con);	/*!< Context to return parked call if timeout. */
+	AST_APP_ARG(return_ext);	/*!< Exten to return parked call if timeout. */
+	AST_APP_ARG(return_pri);	/*!< Priority to return parked call if timeout. */
+	AST_APP_ARG(options);		/*!< Parking option flags. */
+	AST_APP_ARG(pl_name);		/*!< Parking lot name to use if present. */
+	AST_APP_ARG(dummy);			/*!< Place to put any remaining args string. */
+	);
 
 /* module and CLI command definitions */
 static char *parkcall = PARK_APP_NAME;
@@ -578,53 +753,46 @@
 /* Forward declarations */
 static struct ast_parkinglot *parkinglot_addref(struct ast_parkinglot *parkinglot);
 static void parkinglot_unref(struct ast_parkinglot *parkinglot);
-static void parkinglot_destroy(void *obj);
-int manage_parkinglot(struct ast_parkinglot *curlot, const struct pollfd *pfds, const int nfds, struct pollfd **new_pfds, int *new_nfds, int *fs);
-struct ast_parkinglot *find_parkinglot(const char *name);
+static struct ast_parkinglot *find_parkinglot(const char *name);
 static struct ast_parkinglot *create_parkinglot(const char *name);
 static struct ast_parkinglot *copy_parkinglot(const char *name, const struct ast_parkinglot *parkinglot);
-
-static int find_parkinglot_by_position_cb(void *obj, void *args, int flags)
-{
-	struct ast_parkinglot *parkinglot = obj;
-	int *parkpos = args;
-
-	if (*parkpos >= parkinglot->parking_start && *parkpos <= parkinglot->parking_stop) {
-		return CMP_MATCH | CMP_STOP;
-	}
-
-	return 0;
-}
-
-static int find_parkinglot_by_exten_cb(void *obj, void *args, int flags)
-{
-	struct ast_parkinglot *parkinglot = obj;
-	const char *parkext = args;
-
-	if (!strcmp(parkinglot->parkext, parkext)) {
-		return CMP_MATCH | CMP_STOP;
-	}
-
-	return 0;
-}
-
-int ast_parking_ext_valid(const char *exten_str, struct ast_channel *chan, const char *context)
+static int parkinglot_activate(struct ast_parkinglot *parkinglot);
+static int play_message_on_chan(struct ast_channel *play_to, struct ast_channel *other, const char *msg, const char *audiofile);
+
+/*!
+ * \internal
+ * \brief Get the parking extension if it exists.
+ *
+ * \param exten_str Parking extension to see if exists.
+ * \param chan Channel to autoservice while looking for exten.  (Could be NULL)
+ * \param context Parking context to look in for exten.
+ *
+ * \retval exten on success.
+ * \retval NULL on error or exten does not exist.
+ */
+static struct ast_exten *get_parking_exten(const char *exten_str, struct ast_channel *chan, const char *context)
 {
 	struct ast_exten *exten;
 	struct pbx_find_info q = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
 	const char *app_at_exten;
 
-	exten = pbx_find_extension(chan, NULL, &q, context, exten_str, 1, NULL, NULL, E_MATCH);
+	exten = pbx_find_extension(chan, NULL, &q, context, exten_str, 1, NULL, NULL,
+		E_MATCH);
 	if (!exten) {
-		return 0;
+		return NULL;
 	}
 
 	app_at_exten = ast_get_extension_app(exten);
-	if (!app_at_exten || strcmp(PARK_APP_NAME, app_at_exten)) {
-		return 0;
-	}
-
-	return 1;
+	if (!app_at_exten || strcasecmp(PARK_APP_NAME, app_at_exten)) {
+		return NULL;
+	}
+
+	return exten;
+}
+
+int ast_parking_ext_valid(const char *exten_str, struct ast_channel *chan, const char *context)
+{
+	return get_parking_exten(exten_str, chan, context) ? 1 : 0;
 }
 
 const char *ast_pickup_ext(void)
@@ -803,21 +971,21 @@
 	return ast_adsi_print(chan, message, justify, 1);
 }
 
-/*! \brief Find parking lot name from channel */
+/*!
+ * \brief Find parking lot name from channel
+ * \note Channel needs to be locked while the returned string is in use.
+ */
 static const char *findparkinglotname(struct ast_channel *chan)
 {
-	const char *temp, *parkinglot = NULL;
-
-	/* Check if the channel has a parking lot */

[... 4682 lines stripped ...]



More information about the svn-commits mailing list