[asterisk-commits] may: branch may/ooh323_ipv6_direct_rtp r321271 - in /team/may/ooh323_ipv6_dir...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri May 27 08:40:30 CDT 2011


Author: may
Date: Fri May 27 08:40:18 2011
New Revision: 321271

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=321271
Log:
Merged revisions 313383,313437-313438,313527-313528,313606,313629,313659,313701,313744 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

................
  r313383 | rmudgett | 2011-04-12 03:20:39 +0400 (Tue, 12 Apr 2011) | 24 lines
  
  Merged revisions 313368-313369 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.8
  
  ........
    r313368 | rmudgett | 2011-04-11 18:03:02 -0500 (Mon, 11 Apr 2011) | 2 lines
    
    Backport a restructuring change from trunk to make the next change stand out.
  ........
    r313369 | rmudgett | 2011-04-11 18:08:02 -0500 (Mon, 11 Apr 2011) | 13 lines
    
    Frames from the inbound channel should go to all outbound channels in app_dial.c.
    
    In app_dial.c:wait_for_answer() frames from the inbound channel should be
    sent to all outbound channels instead of only if there is just one
    outbound channel.
    
    Control frames like AST_CONTROL_CONNECTED_LINE need to be passed to all of
    the the outbound channels.  This can happen if a blond transfer is done by
    a remote switch on the inbound channel.
    
    JIRA AST-443
    JIRA SWP-2730
  ........
................
  r313437 | jrose | 2011-04-12 22:50:11 +0400 (Tue, 12 Apr 2011) | 39 lines
  
  Merged revisions 313435 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.6.2
  
  also went ahead and fixed the problem it introduces before committing.
  
  ........
    r313435 | jrose | 2011-04-12 13:44:44 -0500 (Tue, 12 Apr 2011) | 1 line
  
    fixing stupid mistake with putting code before variable declaration
    ........
  
      Merged revisions 313433 via svnmerge from 
      https://origsvn.digium.com/svn/asterisk/branches/1.6.2
  	
      ........
  
        r313432 | jrose | 2011-04-12 13:12:29 -0500 (Tue, 12 Apr 2011) | 14 lines
  
        reload Chan_dahdi memory leak caused by variables
  
        chan_dahdi reloading with variables set via setvar in chan_dahdi.conf would
        stay in the dahdi_pvt structs for individual channels (causing them to just
        continue adding the new ones to the list) and also there was a memory leak
        causes by the conf objects. This patch resolves both of these by using 
        ast_variables_destroy during the loading process.
  
        (closes issue #17450)
        Reported by: nahuelgreco
        Patches:
            patch.diff uploaded by jrose (license 1225)
            Tested by: tilghman, jrose
        Review: https://reviewboard.asterisk.org/r/1170/
      
      ........
  																	  
    ........																							
    
  ........
................
  r313438 | jrose | 2011-04-12 22:53:58 +0400 (Tue, 12 Apr 2011) | 2 lines
  
  blocking fix from 313436 that was already made in this commit
................
  r313527 | rmudgett | 2011-04-13 19:23:23 +0400 (Wed, 13 Apr 2011) | 19 lines
  
  Merged revisions 313517 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.8
  
  ........
    r313517 | rmudgett | 2011-04-12 17:35:53 -0500 (Tue, 12 Apr 2011) | 12 lines
    
    Bring the dumpchan application inline with "core show channel".
    
    * Added fields that are in "core show channel" to dumpchan output.
    
    * Fixed reuse of formatbuf before the previous string stored there was
    used by snprintf.  All output strings now have their own buffer.
    
    * Adjusted the buffer sizes to not be so abusive of the stack now that
    there are more buffers.
    
    Change requested by oej.
  ........
................
  r313528 | lmadsen | 2011-04-13 19:49:33 +0400 (Wed, 13 Apr 2011) | 9 lines
  
  Add 'description' field for CLI and Manager output
  
  (closes issue #19076)
  Reported by: lmadsen
  Patches: 
        __20110408-channel-description.txt uploaded by lmadsen (license 10)
  Tested by: lmadsen
  
  Review: https://reviewboard.asterisk.org/r/1163/
................
  r313606 | rmudgett | 2011-04-13 20:37:06 +0400 (Wed, 13 Apr 2011) | 62 lines
  
  Merged revisions 313588 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.8
  
  ................
    r313588 | rmudgett | 2011-04-13 11:31:50 -0500 (Wed, 13 Apr 2011) | 55 lines
    
    Merged revisions 313579 via svnmerge from 
    https://origsvn.digium.com/svn/asterisk/branches/1.6.2
    
    ................
      r313579 | rmudgett | 2011-04-13 11:29:49 -0500 (Wed, 13 Apr 2011) | 48 lines
      
      Merged revisions 313545 via svnmerge from 
      https://origsvn.digium.com/svn/asterisk/branches/1.4
      
      ........
        r313545 | rmudgett | 2011-04-13 11:21:24 -0500 (Wed, 13 Apr 2011) | 41 lines
        
        Asterisk does not hangup a channel after endpoint hangs up.
        
        If the call that the dialplan started an AGI script for is hungup while
        the AGI script is in the middle of a command then the AGI script is not
        notified of the hangup.  There are many AGI Exec commands that this can
        happen with.  The reported applications have been: Background, Wait, Read,
        and Dial.  Also the AGI Get Data command.
        
        * Don't wait on the Asterisk channel after it has hung up.  The channel is
        likely to never need servicing again.
        
        * Restored the AGI script's ability to return the AGI_RESULT_HANGUP value
        in run_agi().  It previously only could return AGI_RESULT_SUCCESS or
        AGI_RESULT_FAILURE after the DeadAGI and AGI applications were merged.
        
        (closes issue #17954)
        Reported by: mn3250
        Patches:
              issue17954_v1.8.patch uploaded by rmudgett (license 664)
              issue17954_v1.6.2.patch uploaded by rmudgett (license 664)
              issue17954_v1.4.patch uploaded by rmudgett (license 664)
        Tested by: rmudgett
        JIRA SWP-2171
        
        (closes issue #18492)
        Reported by: devmod
        Tested by: rmudgett
        JIRA SWP-2761
        
        (closes issue #18935)
        Reported by: nvitaly
        Tested by: astmiv, rmudgett
        JIRA SWP-3216
        
        (closes issue #17393)
        Reported by: siby
        Tested by: rmudgett
        JIRA SWP-2727
        
        Review: https://reviewboard.asterisk.org/r/1165/
      ........
    ................
  ................
................
  r313629 | rmudgett | 2011-04-13 21:21:50 +0400 (Wed, 13 Apr 2011) | 12 lines
  
  Merged revisions 313615 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.8
  
  ........
    r313615 | rmudgett | 2011-04-13 12:18:49 -0500 (Wed, 13 Apr 2011) | 5 lines
    
    * Add missing channel lock to handle_cli_agi_add_cmd().
    
    * Flush any Async AGI commands left over from earlier Async AGI control of
    the call.
  ........
................
  r313659 | rmudgett | 2011-04-13 21:51:14 +0400 (Wed, 13 Apr 2011) | 9 lines
  
  Merged revisions 313658 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.8
  
  ........
    r313658 | rmudgett | 2011-04-13 12:47:43 -0500 (Wed, 13 Apr 2011) | 2 lines
    
    Miscellaneous AGI diagnostic message cleanup and code optimization.
  ........
................
  r313701 | rmudgett | 2011-04-14 02:54:08 +0400 (Thu, 14 Apr 2011) | 12 lines
  
  Merged revisions 313700 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.8
  
  ........
    r313700 | rmudgett | 2011-04-13 17:52:47 -0500 (Wed, 13 Apr 2011) | 5 lines
    
    Revert flushing stale AsyncAGI commands from -r313615.
    
    It looks like it was intentional to leave any commands or in-flight
    commands in the queue in case Async AGI is run again on the call.
  ........
................
  r313744 | rmudgett | 2011-04-14 22:22:35 +0400 (Thu, 14 Apr 2011) | 67 lines
  
  Add Device State Information CCSS for Generic Devices.
  
  Add Asterisk Device State information and callbacks to the Call Completion
  Supplemental Services for generic agents.
  
  There are currently not many devices that have native support for CCSS.
  Even as the devices become available there may be other reasons why one
  may choose to not take advantage of the native abilities and stick with
  the generic implementation.  The generic implementation is quite capable
  and could be greatly enhanced by adding device state capabilities.  A
  phone could then subscribe to the device state with a BLF key in
  conjunction with Asterisk hints.
  
  The advantages of the device state information would allow a single button
  to: request CCSS, cancel a CCSS request, and display the current state of
  a CCSS request.
  
  For example, you may have a single button that when not lit, there is no
  active CCSS request.  When you press that button, the dialplan can query
  the DEVICE_STATE() associated with that caller to determine whether they
  should be calling CallCompletionRequest() or CallCompletionCancel().  If
  there is currently a pending request, then the dialplan would cancel it.
  This also has the advantage of showing the true state of a request, which
  is an asynchronous call, even when CallCompletionRequest() thinks it was
  successful.  The actual request could ultimately fail.  Once lit, further
  feedback can be provided to the caller about the current state of their
  request since it will be updated by the CCSS State Machine as appropriate.
  
  The DEVICE_STATE mapping is configurable since the BLF being used on a
  given phone type may vary.  The idea is to allow some level of
  customization as to the phone's behavior.
  
  As an example, you may want the BLF key to go solid once you have
  requested a callback.  You may then want the LED to blink (typically
  ringing) when either the callback is in process, which is a visual
  indication that the incoming call is the desired callback.  You may want
  it to blink when the callee is ready but you are busy, giving you a visual
  indication that the target is available as you may want to get off the
  line so that the callback can be successful.
  
  Device state information is sent back via the ast_devstate_prov_add()
  callback for any generic CCSS device as it traverses through the state
  machine.  You simply provide a map between CC_STATE values and the
  corresponding AST_DEVICE state values.
  
  You could then generate hints against these states similar to what is
  possible today with Custom Devstates or MeetMe states.  For example, you
  may have an extension 3000 that is currently associated with device
  SIP/3000.  You could then create a feature code for that extension that
  may look something like:
  
  exten => *823000,hint,ccss:sip/3000
  
  You would then subscribe a BLF button to *823000 which would point to the
  dialplan that handled CCSS requests/cancels using the available
  DEVICE_STATE() information about ccss:sip/3000 to make the decision about
  what to do.
  
  (closes issue #18788)
  Reported by: p_lindheimer
  Patches:
        ccss.trunk.18788.patch uploaded by p lindheimer (license 558)
        Modified with final reviewboard comments.
  Tested by: p_lindheimer, loloski
  
  Review: https://reviewboard.asterisk.org/r/1105/
................

Modified:
    team/may/ooh323_ipv6_direct_rtp/   (props changed)
    team/may/ooh323_ipv6_direct_rtp/addons/ooh323c/src/ooSocket.c
    team/may/ooh323_ipv6_direct_rtp/configs/ccss.conf.sample
    team/may/ooh323_ipv6_direct_rtp/configs/chan_dahdi.conf.sample
    team/may/ooh323_ipv6_direct_rtp/configs/iax.conf.sample
    team/may/ooh323_ipv6_direct_rtp/configs/sip.conf.sample
    team/may/ooh323_ipv6_direct_rtp/configs/users.conf.sample
    team/may/ooh323_ipv6_direct_rtp/main/ccss.c
    team/may/ooh323_ipv6_direct_rtp/main/channel.c
    team/may/ooh323_ipv6_direct_rtp/res/res_agi.c

Propchange: team/may/ooh323_ipv6_direct_rtp/
------------------------------------------------------------------------------
--- branch-1.8-blocked (original)
+++ branch-1.8-blocked Fri May 27 08:40:18 2011
@@ -1,1 +1,1 @@
-/branches/1.8:299531
+/branches/1.8:299531,313436

Propchange: team/may/ooh323_ipv6_direct_rtp/
------------------------------------------------------------------------------
Binary property 'branch-1.8-merged' - no diff available.

Propchange: team/may/ooh323_ipv6_direct_rtp/
------------------------------------------------------------------------------
    svnmerge-blocked = /trunk:313482,313907,313944

Propchange: team/may/ooh323_ipv6_direct_rtp/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Fri May 27 08:40:18 2011
@@ -1,1 +1,1 @@
-/trunk:1-313143,313191,313280,313367
+/trunk:1-313143,313191,313280,313367,313383-313481,313483-313744

Modified: team/may/ooh323_ipv6_direct_rtp/addons/ooh323c/src/ooSocket.c
URL: http://svnview.digium.com/svn/asterisk/team/may/ooh323_ipv6_direct_rtp/addons/ooh323c/src/ooSocket.c?view=diff&rev=321271&r1=321270&r2=321271
==============================================================================
--- team/may/ooh323_ipv6_direct_rtp/addons/ooh323c/src/ooSocket.c (original)
+++ team/may/ooh323_ipv6_direct_rtp/addons/ooh323c/src/ooSocket.c Fri May 27 08:40:18 2011
@@ -407,8 +407,6 @@
    ast_parse_arg(host, PARSE_ADDR, &m_addr);
    ast_sockaddr_set_port(&m_addr, port);
 
-   if (connect (socket, (struct sockaddr *) (void*) &m_addr, 
-                sizeof (struct sockaddr_in)) == -1)
    if (ast_connect(socket, &m_addr))
    {
       return ASN_E_INVSOCKET;

Modified: team/may/ooh323_ipv6_direct_rtp/configs/ccss.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/may/ooh323_ipv6_direct_rtp/configs/ccss.conf.sample?view=diff&rev=321271&r1=321270&r2=321271
==============================================================================
--- team/may/ooh323_ipv6_direct_rtp/configs/ccss.conf.sample (original)
+++ team/may/ooh323_ipv6_direct_rtp/configs/ccss.conf.sample Fri May 27 08:40:18 2011
@@ -6,12 +6,54 @@
 ;
 
 [general]
-; There is only a single option that may be defined in this file.
 ; The cc_max_requests option is a global limit on the number of
 ; CC requests that may be in the Asterisk system at any time.
 ;
 ;cc_max_requests = 20
 ;
+; The cc_STATE_devstate variables listed below can be used to change the
+; default mapping of the internal state machine tracking the state of
+; call completion to an Asterisk Device State value. The acceptable values
+; that can be provided are as follows, with a description of what the
+; equivalent device BLF that this maps to:
+;
+;	UNKNOWN      ; Device is valid but channel didn't know state
+;	NOT_INUSE    ; Device is not used
+;	INUSE        ; Device is in use
+;	BUSY         ; Device is busy
+;	INVALID      ; Device is invalid
+;	UNAVAILABLE  ; Device is unavailable
+;	RINGING      ; Device is ringing
+;	RINGINUSE    ; Device is ringing *and* in use
+;	ONHOLD       ; Device is on hold
+;
+; These states are used to generate DEVICE_STATE information that can be
+; included with Asterisk hints for phones to subscribe to the state information
+; or dialplan to check the state using the EXTENSION_STATE() function or
+; the DEVICE_STATE() function.
+;
+; The states are in the format of: "ccss:TECH/ID" so an example of device
+; SIP/3000 making a CallCompletionRequest() could be checked  by looking at
+; DEVICE_STATE(ccss:SIP/3000) or an Asterisk Hint could be generated such as
+;
+; [hint-context]
+; exten => *843000,hint,ccss:SIP/3000
+;
+; and then accessed with EXTENSION_STATE(*843000 at hint-context)
+; or subscribed to with a BLF button on a phone.
+;
+; The available state mapping and default values are:
+;
+; cc_available_devstate = NOT_INUSE
+; cc_offered_devstate = NOT_INUSE
+; cc_caller_requested_devstate = NOT_INUSE
+; cc_active_devstate = INUSE
+; cc_callee_ready_devstate = INUSE
+; cc_caller_busy_devstate = ONHOLD
+; cc_recalling_devstate = RINGING
+; cc_complete_devstate = NOT_INUSE
+; cc_failed_devstate = NOT_INUSE
+
 ;
 ;============================================
 ;           PLEASE READ THIS!!!

Modified: team/may/ooh323_ipv6_direct_rtp/configs/chan_dahdi.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/may/ooh323_ipv6_direct_rtp/configs/chan_dahdi.conf.sample?view=diff&rev=321271&r1=321270&r2=321271
==============================================================================
--- team/may/ooh323_ipv6_direct_rtp/configs/chan_dahdi.conf.sample (original)
+++ team/may/ooh323_ipv6_direct_rtp/configs/chan_dahdi.conf.sample Fri May 27 08:40:18 2011
@@ -820,6 +820,11 @@
 ;
 ;useincomingcalleridondahditransfer = yes
 ;
+; Add a description for the channel which can be shown through the Asterisk
+; console  when executing the 'dahdi show channels' command is run.
+;
+;description=Phone located in lobby
+;
 ; AMA flags affects the recording of Call Detail Records.  If specified
 ; it may be 'default', 'omit', 'billing', or 'documentation'.
 ;
@@ -1068,10 +1073,13 @@
 ;
 ;
 ;callerid="Green Phone"<(256) 428-6121>
+;description=Reception Phone			; add a description for 'dahdi show channels'
 ;channel => 1
 ;callerid="Black Phone"<(256) 428-6122>
+;description=Courtesy Phone
 ;channel => 2
 ;callerid="CallerID Phone" <(630) 372-1564>
+;description=					; reset the description for following channels
 ;channel => 3
 ;callerid="Pac Tel Phone" <(256) 428-6124>
 ;channel => 4

Modified: team/may/ooh323_ipv6_direct_rtp/configs/iax.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/may/ooh323_ipv6_direct_rtp/configs/iax.conf.sample?view=diff&rev=321271&r1=321270&r2=321271
==============================================================================
--- team/may/ooh323_ipv6_direct_rtp/configs/iax.conf.sample (original)
+++ team/may/ooh323_ipv6_direct_rtp/configs/iax.conf.sample Fri May 27 08:40:18 2011
@@ -504,6 +504,7 @@
 username=asterisk
 secret=supersecret
 host=216.207.245.47
+description=Demo System At Digium	; Description of this peer, as listed by 'iax2 show peers'
 ;sendani=no
 ;host=asterisk.linux-support.net
 ;port=5036
@@ -544,6 +545,7 @@
 ;[biggateway]
 ;type=peer
 ;host=192.168.0.1
+;description=Gateway to PSTN
 ;context=*
 ;secret=myscret
 ;trunk=yes			; Use IAX2 trunking with this host

Modified: team/may/ooh323_ipv6_direct_rtp/configs/sip.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/may/ooh323_ipv6_direct_rtp/configs/sip.conf.sample?view=diff&rev=321271&r1=321270&r2=321271
==============================================================================
--- team/may/ooh323_ipv6_direct_rtp/configs/sip.conf.sample (original)
+++ team/may/ooh323_ipv6_direct_rtp/configs/sip.conf.sample Fri May 27 08:40:18 2011
@@ -1100,6 +1100,7 @@
 ; use_q850_reason
 ; maxforwards
 ; encryption
+; description		; Used to provide a description of the peer in console output
 
 ;[sip_proxy]
 ; For incoming calls only. Example: FWD (Free World Dialup)
@@ -1195,6 +1196,7 @@
 ;context=from-sip                ; Where to start in the dialplan when this phone calls
 ;callerid=John Doe <1234>        ; Full caller ID, to override the phones config
                                  ; on incoming calls to Asterisk
+;description=Courtesy Phone      ; Description of the peer. Shown when doing 'sip show peers'.
 ;host=192.168.0.23               ; we have a static but private IP address
                                  ; No registration allowed
 ;nat=no                          ; there is not NAT between phone and Asterisk

Modified: team/may/ooh323_ipv6_direct_rtp/configs/users.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/may/ooh323_ipv6_direct_rtp/configs/users.conf.sample?view=diff&rev=321271&r1=321270&r2=321271
==============================================================================
--- team/may/ooh323_ipv6_direct_rtp/configs/users.conf.sample (original)
+++ team/may/ooh323_ipv6_direct_rtp/configs/users.conf.sample Fri May 27 08:40:18 2011
@@ -87,6 +87,8 @@
 
 ;[6000]
 ;fullname = Joe User
+;description = Courtesy Phone In Lobby    ; Used to provide a description of the
+                                          ; peer in console output
 ;email = joe at foo.bar
 ;secret = 1234
 ;dahdichan = 1

Modified: team/may/ooh323_ipv6_direct_rtp/main/ccss.c
URL: http://svnview.digium.com/svn/asterisk/team/may/ooh323_ipv6_direct_rtp/main/ccss.c?view=diff&rev=321271&r1=321270&r2=321271
==============================================================================
--- team/may/ooh323_ipv6_direct_rtp/main/ccss.c (original)
+++ team/may/ooh323_ipv6_direct_rtp/main/ccss.c Fri May 27 08:40:18 2011
@@ -33,6 +33,7 @@
 #include "asterisk/utils.h"
 #include "asterisk/taskprocessor.h"
 #include "asterisk/event.h"
+#include "asterisk/devicestate.h"
 #include "asterisk/module.h"
 #include "asterisk/app.h"
 #include "asterisk/cli.h"
@@ -530,6 +531,111 @@
 	return 0;
 }
 
+/* default values mapping from cc_state to ast_dev_state */
+
+#define CC_AVAILABLE_DEVSTATE_DEFAULT        AST_DEVICE_NOT_INUSE
+#define CC_CALLER_OFFERED_DEVSTATE_DEFAULT   AST_DEVICE_NOT_INUSE
+#define CC_CALLER_REQUESTED_DEVSTATE_DEFAULT AST_DEVICE_NOT_INUSE
+#define CC_ACTIVE_DEVSTATE_DEFAULT           AST_DEVICE_INUSE
+#define CC_CALLEE_READY_DEVSTATE_DEFAULT     AST_DEVICE_RINGING
+#define CC_CALLER_BUSY_DEVSTATE_DEFAULT      AST_DEVICE_ONHOLD
+#define CC_RECALLING_DEVSTATE_DEFAULT        AST_DEVICE_RINGING
+#define CC_COMPLETE_DEVSTATE_DEFAULT         AST_DEVICE_NOT_INUSE
+#define CC_FAILED_DEVSTATE_DEFAULT           AST_DEVICE_NOT_INUSE
+
+/*!
+ * \internal
+ * \brief initialization of defaults for CC_STATE to DEVICE_STATE map
+ */
+static enum ast_device_state cc_state_to_devstate_map[] = {
+	[CC_AVAILABLE] =        CC_AVAILABLE_DEVSTATE_DEFAULT,
+	[CC_CALLER_OFFERED] =   CC_CALLER_OFFERED_DEVSTATE_DEFAULT,
+	[CC_CALLER_REQUESTED] = CC_CALLER_REQUESTED_DEVSTATE_DEFAULT,
+	[CC_ACTIVE] =           CC_ACTIVE_DEVSTATE_DEFAULT,
+	[CC_CALLEE_READY] =     CC_CALLEE_READY_DEVSTATE_DEFAULT,
+	[CC_CALLER_BUSY] =      CC_CALLER_BUSY_DEVSTATE_DEFAULT,
+	[CC_RECALLING] =        CC_RECALLING_DEVSTATE_DEFAULT,
+	[CC_COMPLETE] =         CC_COMPLETE_DEVSTATE_DEFAULT,
+	[CC_FAILED] =           CC_FAILED_DEVSTATE_DEFAULT,
+};
+
+/*!
+ * \intenral
+ * \brief lookup the ast_device_state mapped to cc_state
+ *
+ * \return the correponding DEVICE STATE from the cc_state_to_devstate_map
+ * when passed an internal state.
+ */
+static enum ast_device_state cc_state_to_devstate(enum cc_state state)
+{
+	return cc_state_to_devstate_map[state];
+}
+
+/*!
+ * \internal
+ * \brief Callback for devicestate providers
+ *
+ * \details
+ * Initialize with ast_devstate_prov_add() and returns the corresponding
+ * DEVICE STATE based on the current CC_STATE state machine if the requested
+ * device is found and is a generic device. Returns the equivalent of
+ * CC_FAILED, which defaults to NOT_INUSE, if no device is found.  NOT_INUSE would
+ * indicate that there is no presence of any pending call back.
+ */
+static enum ast_device_state ccss_device_state(const char *device_name)
+{
+	struct cc_core_instance *core_instance;
+	unsigned long match_flags;
+	enum ast_device_state cc_current_state;
+
+	match_flags = MATCH_NO_REQUEST;
+	core_instance = ao2_t_callback_data(cc_core_instances, 0, match_agent,
+		(char *) device_name, &match_flags,
+		"Find Core Instance for ccss_device_state reqeust.");
+	if (!core_instance) {
+		ast_log_dynamic_level(cc_logger_level,
+			"Couldn't find a core instance for caller %s\n", device_name);
+		return cc_state_to_devstate(CC_FAILED);
+	}
+
+	ast_log_dynamic_level(cc_logger_level,
+		"Core %d: Found core_instance for caller %s in state %s\n",
+		core_instance->core_id, device_name, cc_state_to_string(core_instance->current_state));
+
+	if (strcmp(core_instance->agent->callbacks->type, "generic")) {
+		ast_log_dynamic_level(cc_logger_level,
+			"Core %d: Device State is only for generic agent types.\n",
+			core_instance->core_id);
+		cc_unref(core_instance, "Unref core_instance since ccss_device_state was called with native agent");
+		return cc_state_to_devstate(CC_FAILED);
+	}
+	cc_current_state = cc_state_to_devstate(core_instance->current_state);
+	cc_unref(core_instance, "Unref core_instance done with ccss_device_state");
+	return cc_current_state;
+}
+
+/*!
+ * \internal
+ * \brief Notify Device State Changes from CC STATE MACHINE
+ *
+ * \details
+ * Any time a state is changed, we call this function to notify the DEVICE STATE
+ * subsystem of the change so that subscribed phones to any corresponding hints that
+ * are using that state are updated.
+ */
+static void ccss_notify_device_state_change(const char *device, enum cc_state state)
+{
+	enum ast_device_state devstate;
+
+	devstate = cc_state_to_devstate(state);
+
+	ast_log_dynamic_level(cc_logger_level,
+		"Notification of CCSS state change to '%s', device state '%s' for device '%s'",
+		cc_state_to_string(state), ast_devstate2str(devstate), device);
+
+	ast_devstate_changed(devstate, "ccss:%s", device);
+}
+
 #define CC_OFFER_TIMER_DEFAULT			20		/* Seconds */
 #define CCNR_AVAILABLE_TIMER_DEFAULT	7200	/* Seconds */
 #define CCBS_AVAILABLE_TIMER_DEFAULT	4800	/* Seconds */
@@ -3014,6 +3120,11 @@
 	core_instance->current_state = args->state;
 	res = state_change_funcs[core_instance->current_state](core_instance, args, previous_state);
 
+	/* If state change successful then notify any device state watchers of the change */
+	if (!res && !strcmp(core_instance->agent->callbacks->type, "generic")) {
+		ccss_notify_device_state_change(core_instance->agent->device_name, core_instance->current_state);
+	}
+
 	ast_free(args);
 	cc_unref(core_instance, "Unref since state change has completed"); /* From ao2_find */
 	return res;
@@ -4102,6 +4213,59 @@
 	return;
 }
 
+/*!
+ * \internal
+ * \brief helper function to parse and configure each devstate map
+ */
+static void initialize_cc_devstate_map_helper(struct ast_config *cc_config, enum cc_state state, const char *cc_setting)
+{
+	const char *cc_devstate_str;
+	enum ast_device_state this_devstate;
+
+	if ((cc_devstate_str = ast_variable_retrieve(cc_config, "general", cc_setting))) {
+		this_devstate = ast_devstate_val(cc_devstate_str);
+		if (this_devstate != AST_DEVICE_UNKNOWN) {
+			cc_state_to_devstate_map[state] = this_devstate;
+		}
+	}
+}
+
+/*!
+ * \internal
+ * \brief initializes cc_state_to_devstate_map from ccss.conf
+ *
+ * \details
+ * The cc_state_to_devstate_map[] is already initialized with all the
+ * default values. This will update that structure with any changes
+ * from the ccss.conf file. The configuration parameters in ccss.conf
+ * should use any valid device state form that is recognized by
+ * ast_devstate_val() function.
+ */
+static void initialize_cc_devstate_map(void)
+{
+	struct ast_config *cc_config;
+	struct ast_flags config_flags = { 0, };
+
+	cc_config = ast_config_load2("ccss.conf", "ccss", config_flags);
+	if (!cc_config || cc_config == CONFIG_STATUS_FILEINVALID) {
+		ast_log(LOG_WARNING,
+			"Could not find valid ccss.conf file. Using cc_[state]_devstate defaults\n");
+		return;
+	}
+
+	initialize_cc_devstate_map_helper(cc_config, CC_AVAILABLE, "cc_available_devstate");
+	initialize_cc_devstate_map_helper(cc_config, CC_CALLER_OFFERED, "cc_caller_offered_devstate");
+	initialize_cc_devstate_map_helper(cc_config, CC_CALLER_REQUESTED, "cc_caller_requested_devstate");
+	initialize_cc_devstate_map_helper(cc_config, CC_ACTIVE, "cc_active_devstate");
+	initialize_cc_devstate_map_helper(cc_config, CC_CALLEE_READY, "cc_callee_ready_devstate");
+	initialize_cc_devstate_map_helper(cc_config, CC_CALLER_BUSY, "cc_caller_busy_devstate");
+	initialize_cc_devstate_map_helper(cc_config, CC_RECALLING, "cc_recalling_devstate");
+	initialize_cc_devstate_map_helper(cc_config, CC_COMPLETE, "cc_complete_devstate");
+	initialize_cc_devstate_map_helper(cc_config, CC_FAILED, "cc_failed_devstate");
+
+	ast_config_destroy(cc_config);
+}
+
 static void cc_cli_print_monitor_stats(struct ast_cc_monitor *monitor, int fd, int parent_id)
 {
 	struct ast_cc_monitor *child_monitor_iter = monitor;
@@ -4297,9 +4461,15 @@
 	res |= ast_register_application2(cccancel_app, cccancel_exec, NULL, NULL, NULL);
 	res |= ast_cc_monitor_register(&generic_monitor_cbs);
 	res |= ast_cc_agent_register(&generic_agent_callbacks);
+
 	ast_cli_register_multiple(cc_cli, ARRAY_LEN(cc_cli));
 	cc_logger_level = ast_logger_register_level(CC_LOGGER_LEVEL_NAME);
 	dialed_cc_interface_counter = 1;
 	initialize_cc_max_requests();
+
+	/* Read the map and register the device state callback for generic agents */
+	initialize_cc_devstate_map();
+	res |= ast_devstate_prov_add("ccss", ccss_device_state);
+
 	return res;
 }

Modified: team/may/ooh323_ipv6_direct_rtp/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/may/ooh323_ipv6_direct_rtp/main/channel.c?view=diff&rev=321271&r1=321270&r2=321271
==============================================================================
--- team/may/ooh323_ipv6_direct_rtp/main/channel.c (original)
+++ team/may/ooh323_ipv6_direct_rtp/main/channel.c Fri May 27 08:40:18 2011
@@ -3722,23 +3722,27 @@
 		} else {
 			goto done;
 		}
-	}
-
+	} else {
 #ifdef AST_DEVMODE
-	/* 
-	 * The ast_waitfor() code records which of the channel's file descriptors reported that
-	 * data is available.  In theory, ast_read() should only be called after ast_waitfor()
-	 * reports that a channel has data available for reading.  However, there still may be
-	 * some edge cases throughout the code where ast_read() is called improperly.  This can
-	 * potentially cause problems, so if this is a developer build, make a lot of noise if
-	 * this happens so that it can be addressed. 
-	 */
-	if (chan->fdno == -1) {
-		ast_log(LOG_ERROR,
-			"ast_read() on chan '%s' called with no recorded file descriptor.\n",
-			chan->name);
-	}
+		/*
+		 * The ast_waitfor() code records which of the channel's file
+		 * descriptors reported that data is available.  In theory,
+		 * ast_read() should only be called after ast_waitfor() reports
+		 * that a channel has data available for reading.  However,
+		 * there still may be some edge cases throughout the code where
+		 * ast_read() is called improperly.  This can potentially cause
+		 * problems, so if this is a developer build, make a lot of
+		 * noise if this happens so that it can be addressed.
+		 *
+		 * One of the potential problems is blocking on a dead channel.
+		 */
+		if (chan->fdno == -1) {
+			ast_log(LOG_ERROR,
+				"ast_read() on chan '%s' called with no recorded file descriptor.\n",
+				chan->name);
+		}
 #endif
+	}
 
 	prestate = chan->_state;
 

Modified: team/may/ooh323_ipv6_direct_rtp/res/res_agi.c
URL: http://svnview.digium.com/svn/asterisk/team/may/ooh323_ipv6_direct_rtp/res/res_agi.c?view=diff&rev=321271&r1=321270&r2=321271
==============================================================================
--- team/may/ooh323_ipv6_direct_rtp/res/res_agi.c (original)
+++ team/may/ooh323_ipv6_direct_rtp/res/res_agi.c Fri May 27 08:40:18 2011
@@ -1003,7 +1003,8 @@
 	store = ast_channel_datastore_find(chan, &agi_commands_datastore_info, NULL);
 	ast_channel_unlock(chan);
 	if (!store) {
-		ast_log(LOG_ERROR, "Hu? datastore disappeared at Async AGI on Channel %s!\n", chan->name);
+		ast_log(LOG_ERROR, "Huh? Async AGI datastore disappeared on Channel %s!\n",
+			chan->name);
 		return NULL;
 	}
 	agi_commands = store->data;
@@ -1022,7 +1023,7 @@
 
 	store = ast_channel_datastore_find(chan, &agi_commands_datastore_info, NULL);
 	if (!store) {
-		ast_log(LOG_WARNING, "Channel %s is not at Async AGI.\n", chan->name);
+		ast_log(LOG_WARNING, "Channel %s is not setup for Async AGI.\n", chan->name);
 		return -1;
 	}
 	agi_commands = store->data;
@@ -1111,12 +1112,14 @@
 	}
 
 	if (!(chan = ast_channel_get_by_name(a->argv[2]))) {
-		ast_log(LOG_WARNING, "Channel %s does not exists or cannot lock it\n", a->argv[2]);
+		ast_cli(a->fd, "Channel %s does not exist.\n", a->argv[2]);
 		return CLI_FAILURE;
 	}
 
+	ast_channel_lock(chan);
+
 	if (add_agi_cmd(chan, a->argv[3], (a->argc > 4 ? a->argv[4] : ""))) {
-		ast_log(LOG_WARNING, "failed to add AGI command to queue of channel %s\n", chan->name);
+		ast_cli(a->fd, "Failed to add AGI command to queue of channel %s\n", chan->name);
 		ast_channel_unlock(chan);
 		chan = ast_channel_unref(chan);
 		return CLI_FAILURE;
@@ -1155,7 +1158,7 @@
 	}
 
 	if (!(chan = ast_channel_get_by_name(channel))) {
-		snprintf(buf, sizeof(buf), "Channel %s does not exists or cannot get its lock", channel);
+		snprintf(buf, sizeof(buf), "Channel %s does not exist.", channel);
 		astman_send_error(s, m, buf);
 		return 0;
 	}
@@ -1178,8 +1181,9 @@
 	return 0;
 }
 
-static int agi_handle_command(struct ast_channel *chan, AGI *agi, char *buf, int dead);
+static enum agi_result agi_handle_command(struct ast_channel *chan, AGI *agi, char *buf, int dead);
 static void setup_env(struct ast_channel *chan, char *request, int fd, int enhanced, int argc, char *argv[]);
+
 static enum agi_result launch_asyncagi(struct ast_channel *chan, char *argv[], int *efd)
 {
 /* This buffer sizes might cause truncation if the AGI command writes more data
@@ -1217,7 +1221,7 @@
 
 	/* add AsyncAGI datastore to the channel */
 	if (add_to_agi(chan)) {
-		ast_log(LOG_ERROR, "failed to start Async AGI on channel %s\n", chan->name);
+		ast_log(LOG_ERROR, "Failed to start Async AGI on channel %s\n", chan->name);
 		return AGI_RESULT_FAILURE;
 	}
 
@@ -1225,10 +1229,12 @@
 	   the AGI commands */
 	res = pipe(fds);
 	if (res) {
-		ast_log(LOG_ERROR, "failed to create Async AGI pipe\n");
-		/* intentionally do not remove datastore, added with
-		   add_to_agi(), from channel. It will be removed when
-		   the channel is hung up anyways */
+		ast_log(LOG_ERROR, "Failed to create Async AGI pipe\n");
+		/*
+		 * Intentionally do not remove the datastore added with
+		 * add_to_agi() the from channel.  It will be removed when the
+		 * channel is hung up anyway.
+		 */
 		return AGI_RESULT_FAILURE;
 	}
 
@@ -1246,7 +1252,8 @@
 	/* read the environment */
 	res = read(fds[0], agi_buffer, AGI_BUF_SIZE);
 	if (!res) {
-		ast_log(LOG_ERROR, "failed to read from Async AGI pipe on channel %s\n", chan->name);
+		ast_log(LOG_ERROR, "Failed to read from Async AGI pipe on channel %s\n",
+			chan->name);
 		returnstatus = AGI_RESULT_FAILURE;
 		goto quit;
 	}
@@ -1278,7 +1285,8 @@
 			res = read(fds[0], agi_buffer, AGI_BUF_SIZE);
 			if (!res) {
 				returnstatus = AGI_RESULT_FAILURE;
-				ast_log(LOG_ERROR, "failed to read from AsyncAGI pipe on channel %s\n", chan->name);
+				ast_log(LOG_ERROR, "Failed to read from Async AGI pipe on channel %s\n",
+					chan->name);
 				free_agi_cmd(cmd);
 				break;
 			}
@@ -1330,9 +1338,13 @@
 	close(fds[0]);
 	close(fds[1]);
 
-	/* intentionally don't get rid of the datastore. So commands can be
-	   still in the queue in case AsyncAGI gets called again.
-	   Datastore destructor will be called on channel destroy anyway  */
+	/*
+	 * Intentionally do not remove the datastore added with
+	 * add_to_agi() the from channel.  There might be commands still
+	 * in the queue or in-flight to us and AsyncAGI may get called
+	 * again.  The datastore destructor will be called on channel
+	 * destruction anyway.
+	 */
 
 	return returnstatus;
 
@@ -1764,7 +1776,8 @@
 		x = 1;
 	}
 	res = ast_channel_setoption(chan, AST_OPTION_TDD, &x, sizeof(char), 0);
-	if (res != RESULT_SUCCESS) {
+	if (res) {
+		/* Set channel option failed */
 		ast_agi_send(agi->fd, chan, "200 result=0\n");
 	} else {
 		ast_agi_send(agi->fd, chan, "200 result=1\n");
@@ -2181,12 +2194,14 @@
 		res = ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
 		if (res < 0) {
 			ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
-			return -1;
+			ast_agi_send(agi->fd, chan, "200 result=%d\n", res);
+			return RESULT_FAILURE;
 		}
 		sildet = ast_dsp_new();
 		if (!sildet) {
 			ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
-			return -1;
+			ast_agi_send(agi->fd, chan, "200 result=-1\n");
+			return RESULT_FAILURE;
 		}
 		ast_dsp_set_threshold(sildet, ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE));
 	}
@@ -3257,14 +3272,16 @@
 	return 0;
 }
 
-static int agi_handle_command(struct ast_channel *chan, AGI *agi, char *buf, int dead)
+static enum agi_result agi_handle_command(struct ast_channel *chan, AGI *agi, char *buf, int dead)
 {
 	const char *argv[MAX_ARGS];
-	int argc = MAX_ARGS, res;
+	int argc = MAX_ARGS;
+	int res;
 	agi_command *c;
-	const char *ami_res = "Unknown Result";
+	const char *ami_res;
 	char *ami_cmd = ast_strdupa(buf);
-	int command_id = ast_random(), resultcode = 200;
+	int command_id = ast_random();
+	int resultcode;
 
 	manager_event(EVENT_FLAG_AGI, "AGIExec",
 			"SubEvent: Start\r\n"
@@ -3272,8 +3289,9 @@
 			"CommandId: %d\r\n"
 			"Command: %s\r\n", chan->name, command_id, ami_cmd);
 	parse_args(buf, &argc, argv);
-	if ((c = find_command(argv, 0)) && (!dead || (dead && c->dead))) {
-		/* if this command wasnt registered by res_agi, be sure to usecount
+	c = find_command(argv, 0);
+	if (c && (!dead || (dead && c->dead))) {
+		/* if this command wasn't registered by res_agi, be sure to usecount
 		the module we are using */
 		if (c->mod != ast_module_info->self)
 			ast_module_ref(c->mod);
@@ -3286,9 +3304,22 @@
 		if (c->mod != ast_module_info->self)
 			ast_module_unref(c->mod);
 		switch (res) {
-		case RESULT_SHOWUSAGE: ami_res = "Usage"; resultcode = 520; break;
-		case RESULT_FAILURE: ami_res = "Failure"; resultcode = -1; break;
-		case RESULT_SUCCESS: ami_res = "Success"; resultcode = 200; break;
+		case RESULT_SHOWUSAGE:
+			ami_res = "Usage";
+			resultcode = 520;
+			break;
+		case RESULT_FAILURE:
+			ami_res = "Failure";
+			resultcode = -1;
+			break;
+		case RESULT_SUCCESS:
+			ami_res = "Success";
+			resultcode = 200;
+			break;
+		default:
+			ami_res = "Unknown Result";
+			resultcode = 200;
+			break;
 		}
 		manager_event(EVENT_FLAG_AGI, "AGIExec",
 				"SubEvent: End\r\n"
@@ -3297,7 +3328,7 @@
 				"Command: %s\r\n"
 				"ResultCode: %d\r\n"
 				"Result: %s\r\n", chan->name, command_id, ami_cmd, resultcode, ami_res);
-		switch(res) {
+		switch (res) {
 		case RESULT_SHOWUSAGE:
 			if (ast_strlen_zero(c->usage)) {
 				ast_agi_send(agi->fd, chan, "520 Invalid command syntax.  Proper usage not available.\n");
@@ -3308,11 +3339,12 @@
 			}
 			break;
 		case RESULT_FAILURE:
-			/* They've already given the failure.  We've been hung up on so handle this
-			   appropriately */
-			return -1;
-		}
-	} else if ((c = find_command(argv, 0))) {
+			/* The RESULT_FAILURE code is usually because the channel hungup. */
+			return AGI_RESULT_FAILURE;
+		default:
+			break;
+		}
+	} else if (c) {
 		ast_agi_send(agi->fd, chan, "511 Command Not Permitted on a dead channel\n");
 		manager_event(EVENT_FLAG_AGI, "AGIExec",
 				"SubEvent: End\r\n"
@@ -3331,12 +3363,14 @@
 				"ResultCode: 510\r\n"
 				"Result: Invalid or unknown command\r\n", chan->name, command_id, ami_cmd);
 	}
-	return 0;
+	return AGI_RESULT_SUCCESS;
 }
 static enum agi_result run_agi(struct ast_channel *chan, char *request, AGI *agi, int pid, int *status, int dead, int argc, char *argv[])
 {
 	struct ast_channel *c;
-	int outfd, ms, needhup = 0;
+	int outfd;
+	int ms;
+	int needhup = 0;
 	enum agi_result returnstatus = AGI_RESULT_SUCCESS;
 	struct ast_frame *f;
 	char buf[AGI_BUF_LEN];
@@ -3376,16 +3410,27 @@
 			}
 		}
 		ms = -1;
-		c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, &agi->ctrl, 1, NULL, &outfd, &ms);
+		if (dead) {
+			c = ast_waitfor_nandfds(&chan, 0, &agi->ctrl, 1, NULL, &outfd, &ms);
+		} else if (!ast_check_hangup(chan)) {
+			c = ast_waitfor_nandfds(&chan, 1, &agi->ctrl, 1, NULL, &outfd, &ms);
+		} else {
+			/*
+			 * Read the channel control queue until it is dry so we can
+			 * switch to dead mode.
+			 */
+			c = chan;
+		}

[... 65 lines stripped ...]



More information about the asterisk-commits mailing list