[asterisk-commits] kmoore: branch kmoore/bridge_construction-cel_bridging r389250 - in /team/kmo...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon May 20 12:58:13 CDT 2013


Author: kmoore
Date: Mon May 20 12:58:06 2013
New Revision: 389250

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=389250
Log:
Multiple revisions 389081,389092,389109,389120,389136,389152,389168,389184,389210,389229

........
  r389081 | root | 2013-05-18 16:17:33 -0500 (Sat, 18 May 2013) | 10 lines
  
  Migrate chan_mgcp over to using the new attended transfer API.
  
  (closes issue ASTERISK-21525)
  Reported by: Matt Jordan
  
  Review: https://reviewboard.asterisk.org/r/2536/
  ........
  
  Merged revisions 389073 from file:///srv/subversion/repos/asterisk/team/group/bridge_construction
........
  r389092 | root | 2013-05-18 18:18:47 -0500 (Sat, 18 May 2013) | 8 lines
  
  Fix a bug where synchronous origination (oddly enough triggered by doing an async manager Originate) would not work properly.
  ........
  
  Merged revisions 389085 from file:///srv/subversion/repos/asterisk/trunk
  ........
  
  Merged revisions 389087 from file:///srv/subversion/repos/asterisk/team/group/bridge_construction
........
  r389109 | root | 2013-05-18 19:18:16 -0500 (Sat, 18 May 2013) | 22 lines
  
  Add call forward no answer to skinny and cleanup general callfwd handling.
  
  CallforwardNoAnswer uses a sched to determine when to forward the call. 
  Defaults to 20secs but configurable in skinny.conf.
  
  Adds dialType to each subchannel structure to be used to differentiate
  between normal dials that result in a call being placed (default) and
  other uses for the skinny_dialer (such as cfwd digit collection).
  Restructured all cfwd handling to use this new arrangement.
  
  (closes issue ASTERISK-21292)
  Reported by: wedhorn
  Tested by: myself
  Patches: 
      skinny-callfwdnoans03.diff uploaded by wedhorn (license 5019)
  ........
  
  Merged revisions 389097 from file:///srv/subversion/repos/asterisk/trunk
  ........
  
  Merged revisions 389106 from file:///srv/subversion/repos/asterisk/team/group/bridge_construction
........
  r389120 | root | 2013-05-18 20:18:16 -0500 (Sat, 18 May 2013) | 8 lines
  
  If the caller of the originate API calls wants the channel ensure it has been requested and dialed.
  ........
  
  Merged revisions 389116 from file:///srv/subversion/repos/asterisk/trunk
  ........
  
  Merged revisions 389117 from file:///srv/subversion/repos/asterisk/team/group/bridge_construction
........
  r389136 | root | 2013-05-18 22:18:16 -0500 (Sat, 18 May 2013) | 8 lines
  
  Don't hold the outgoing lock for a prolonged period of time as it may block the originator.
  ........
  
  Merged revisions 389132 from file:///srv/subversion/repos/asterisk/trunk
  ........
  
  Merged revisions 389133 from file:///srv/subversion/repos/asterisk/team/group/bridge_construction
........
  r389152 | root | 2013-05-19 13:18:51 -0500 (Sun, 19 May 2013) | 15 lines
  
  Add base XML documentation for res_sip
  
  Thanks to Brad Latus, this patch adds a significant amount much-needed
  documentation to res_sip. It should cover all existing configuration
  options currently in Asterisk trunk.
  
  Patch-by: Brad Latus (snuffy)
  Review: https://reviewboard.asterisk.org/r/2471/
  ........
  
  Merged revisions 389148 from file:///srv/subversion/repos/asterisk/trunk
  ........
  
  Merged revisions 389149 from file:///srv/subversion/repos/asterisk/team/group/bridge_construction
........
  r389168 | root | 2013-05-19 15:18:19 -0500 (Sun, 19 May 2013) | 14 lines
  
  Add transfer softkey to ringout state to enable blond transfers.
  
  (closes issue ASTERISK-21327)
  Reported by: wedhorn
  Tested by: myself
  Patches: 
      skinny-blindxfer01.diff uploaded by wedhorn (license 5019)
  ........
  
  Merged revisions 389164 from file:///srv/subversion/repos/asterisk/trunk
  ........
  
  Merged revisions 389165 from file:///srv/subversion/repos/asterisk/team/group/bridge_construction
........
  r389184 | root | 2013-05-19 16:18:16 -0500 (Sun, 19 May 2013) | 8 lines
  
  add ast_publish_channel_state according new event framework
  ........
  
  Merged revisions 389180 from file:///srv/subversion/repos/asterisk/trunk
  ........
  
  Merged revisions 389181 from file:///srv/subversion/repos/asterisk/team/group/bridge_construction
........
  r389210 | root | 2013-05-20 09:18:39 -0500 (Mon, 20 May 2013) | 23 lines
  
  Multiple revisions 389202,389204
  
  ........
    r389202 | kmoore | 2013-05-20 08:45:50 -0500 (Mon, 20 May 2013) | 8 lines
    
    Add documentation for record_file_append
    
    When this option was added, it was noted in CHANGES, but was missing
    the XML documentation that this patch adds.
    
    (closes issue ASTERISK-21780)
    Patch-by: Brad Latus (snuffy)
  ........
    r389204 | file | 2013-05-20 09:02:37 -0500 (Mon, 20 May 2013) | 2 lines
    
    In Sorcery pass the name of the object being allocated to the allocator.
  ........
  
  Merged revisions 389202,389204 from file:///srv/subversion/repos/asterisk/trunk
  ........
  
  Merged revisions 389206 from file:///srv/subversion/repos/asterisk/team/group/bridge_construction
........
  r389229 | root | 2013-05-20 10:18:29 -0500 (Mon, 20 May 2013) | 11 lines
  
  Add missing exports file
  
  This exposes stasis_app_control_answer and allows
  res_stasis_http_channels to load properly.
  ........
  
  Merged revisions 389217 from file:///srv/subversion/repos/asterisk/trunk
  ........
  
  Merged revisions 389225 from file:///srv/subversion/repos/asterisk/team/group/bridge_construction
........

Merged revisions 389081,389092,389109,389120,389136,389152,389168,389184,389210,389229 from http://svn.asterisk.org/svn/asterisk/team/kmoore/bridge_construction-cel_channels

Added:
    team/kmoore/bridge_construction-cel_bridging/res/res_stasis_answer.exports.in
      - copied unchanged from r389229, team/kmoore/bridge_construction-cel_channels/res/res_stasis_answer.exports.in
Modified:
    team/kmoore/bridge_construction-cel_bridging/   (props changed)
    team/kmoore/bridge_construction-cel_bridging/addons/chan_ooh323.c
    team/kmoore/bridge_construction-cel_bridging/addons/chan_ooh323.h
    team/kmoore/bridge_construction-cel_bridging/apps/confbridge/conf_config_parser.c
    team/kmoore/bridge_construction-cel_bridging/channels/chan_mgcp.c
    team/kmoore/bridge_construction-cel_bridging/channels/chan_skinny.c
    team/kmoore/bridge_construction-cel_bridging/configs/skinny.conf.sample
    team/kmoore/bridge_construction-cel_bridging/main/pbx.c
    team/kmoore/bridge_construction-cel_bridging/main/sorcery.c
    team/kmoore/bridge_construction-cel_bridging/res/res_sip.c
    team/kmoore/bridge_construction-cel_bridging/res/res_sip_acl.c
    team/kmoore/bridge_construction-cel_bridging/res/res_sip_endpoint_identifier_ip.c
    team/kmoore/bridge_construction-cel_bridging/res/res_sip_outbound_registration.c

Propchange: team/kmoore/bridge_construction-cel_bridging/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/kmoore/bridge_construction-cel_bridging/
------------------------------------------------------------------------------
--- bc-cel_bridging-integrated (original)
+++ bc-cel_bridging-integrated Mon May 20 12:58:06 2013
@@ -1,1 +1,1 @@
-/team/kmoore/bridge_construction-cel_channels:1-389079
+/team/kmoore/bridge_construction-cel_channels:1-389249

Propchange: team/kmoore/bridge_construction-cel_bridging/
------------------------------------------------------------------------------
--- bridge_construction-integrated (original)
+++ bridge_construction-integrated Mon May 20 12:58:06 2013
@@ -1,1 +1,1 @@
-/trunk:1-389054
+/trunk:1-389224

Propchange: team/kmoore/bridge_construction-cel_bridging/
------------------------------------------------------------------------------
--- svnmerge-integrated (added)
+++ svnmerge-integrated Mon May 20 12:58:06 2013
@@ -1,0 +1,1 @@
+/team/group/bridge_construction:1-389228

Modified: team/kmoore/bridge_construction-cel_bridging/addons/chan_ooh323.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/bridge_construction-cel_bridging/addons/chan_ooh323.c?view=diff&rev=389250&r1=389249&r2=389250
==============================================================================
--- team/kmoore/bridge_construction-cel_bridging/addons/chan_ooh323.c (original)
+++ team/kmoore/bridge_construction-cel_bridging/addons/chan_ooh323.c Mon May 20 12:58:06 2013
@@ -489,9 +489,8 @@
 	 	}
 
 		if (ch) {
-			manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 
-				"Channel: %s\r\nChanneltype: %s\r\n"
-				"CallRef: %d\r\n", ast_channel_name(ch), "OOH323", i->call_reference);
+			ast_publish_channel_state(ch);
+
 		}
 	} else
 		ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
@@ -2148,8 +2147,7 @@
 
 			ast_queue_control(c, AST_CONTROL_ANSWER);
    			ast_channel_unlock(p->owner);
-			manager_event(EVENT_FLAG_SYSTEM,"ChannelUpdate","Channel: %s\r\nChanneltype: %s\r\n"
-				"CallRef: %d\r\n", ast_channel_name(c), "OOH323", p->call_reference);
+			ast_publish_channel_state(c);
 		}
 		ast_mutex_unlock(&p->lock);
 

Modified: team/kmoore/bridge_construction-cel_bridging/addons/chan_ooh323.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/bridge_construction-cel_bridging/addons/chan_ooh323.h?view=diff&rev=389250&r1=389249&r2=389250
==============================================================================
--- team/kmoore/bridge_construction-cel_bridging/addons/chan_ooh323.h (original)
+++ team/kmoore/bridge_construction-cel_bridging/addons/chan_ooh323.h Mon May 20 12:58:06 2013
@@ -64,6 +64,7 @@
 #include "asterisk/format.h"
 #include "asterisk/format_cap.h"
 #include "asterisk/udptl.h"
+#include "asterisk/stasis_channels.h"
 
 #include "ootypes.h"
 #include "ooUtils.h"

Modified: team/kmoore/bridge_construction-cel_bridging/apps/confbridge/conf_config_parser.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/bridge_construction-cel_bridging/apps/confbridge/conf_config_parser.c?view=diff&rev=389250&r1=389249&r2=389250
==============================================================================
--- team/kmoore/bridge_construction-cel_bridging/apps/confbridge/conf_config_parser.c (original)
+++ team/kmoore/bridge_construction-cel_bridging/apps/confbridge/conf_config_parser.c Mon May 20 12:58:06 2013
@@ -290,6 +290,15 @@
 						allows the record name to be specified and a unique name to be chosen.
 						By default, the record_file is stored in Asterisk's spool/monitor directory
 						with a unique filename starting with the 'confbridge' prefix.
+					</para></description>
+				</configOption>
+				<configOption name="record_file_append" default="yes">
+					<synopsis>Append record file when starting/stopping on same conference recording</synopsis>
+					<description><para>
+						When record_file_append is set to yes, stopping and starting recording on a
+						conference adds the new portion to end of current record_file. When this is
+						set to no, a new record_file is generated every time you start then stop recording
+						on a conference.
 					</para></description>
 				</configOption>
 				<configOption name="video_mode">

Modified: team/kmoore/bridge_construction-cel_bridging/channels/chan_mgcp.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/bridge_construction-cel_bridging/channels/chan_mgcp.c?view=diff&rev=389250&r1=389249&r2=389250
==============================================================================
--- team/kmoore/bridge_construction-cel_bridging/channels/chan_mgcp.c (original)
+++ team/kmoore/bridge_construction-cel_bridging/channels/chan_mgcp.c Mon May 20 12:58:06 2013
@@ -83,6 +83,7 @@
 #include "asterisk/chanvars.h"
 #include "asterisk/pktccops.h"
 #include "asterisk/stasis.h"
+#include "asterisk/bridging.h"
 
 /*
  * Define to work around buggy dlink MGCP phone firmware which
@@ -3212,56 +3213,55 @@
 	return NULL;
 }
 
-static int attempt_transfer(struct mgcp_endpoint *p)
-{
-	/* *************************
-	 * I hope this works.
-	 * Copied out of chan_zap
-	 * Cross your fingers
-	 * *************************/
-
-	/* In order to transfer, we need at least one of the channels to
-	   actually be in a call bridge.  We can't conference two applications
-	   together (but then, why would we want to?) */
-	if (ast_bridged_channel(p->sub->owner)) {
-		/* The three-way person we're about to transfer to could still be in MOH, so
-		   stop it now */
-		ast_queue_control(p->sub->next->owner, AST_CONTROL_UNHOLD);
-		if (ast_channel_state(p->sub->owner) == AST_STATE_RINGING) {
-			ast_queue_control(p->sub->next->owner, AST_CONTROL_RINGING);
-		}
-		if (ast_channel_masquerade(p->sub->next->owner, ast_bridged_channel(p->sub->owner))) {
-			ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
-				ast_channel_name(ast_bridged_channel(p->sub->owner)), ast_channel_name(p->sub->next->owner));
-			return -1;
-		}
-		/* Orphan the channel */
-		unalloc_sub(p->sub->next);
-	} else if (ast_bridged_channel(p->sub->next->owner)) {
-		if (ast_channel_state(p->sub->owner) == AST_STATE_RINGING) {
-			ast_queue_control(p->sub->next->owner, AST_CONTROL_RINGING);
-		}
-		ast_queue_control(p->sub->next->owner, AST_CONTROL_UNHOLD);
-		if (ast_channel_masquerade(p->sub->owner, ast_bridged_channel(p->sub->next->owner))) {
-			ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
-				ast_channel_name(ast_bridged_channel(p->sub->next->owner)), ast_channel_name(p->sub->owner));
-			return -1;
-		}
-		/*swap_subs(p, SUB_THREEWAY, SUB_REAL);*/
-		ast_verb(3, "Swapping %d for %d on %s@%s\n", p->sub->id, p->sub->next->id, p->name, p->parent->name);
-		p->sub = p->sub->next;
-		unalloc_sub(p->sub->next);
-		/* Tell the caller not to hangup */
+/*! \brief Complete an attended transfer
+ *
+ * \param p The endpoint performing the attended transfer
+ * \param sub The sub-channel completing the attended transfer
+ *
+ * \note p->sub is the currently active sub-channel (the channel the phone is using)
+ * \note p->sub->next is the sub-channel not in use, potentially on hold
+ *
+ * \retval 0 when channel should be hung up
+ * \retval 1 when channel should not be hung up
+ */
+static int attempt_transfer(struct mgcp_endpoint *p, struct mgcp_subchannel *sub)
+{
+	enum ast_transfer_result res;
+
+	/* Ensure that the other channel goes off hold and that it is indicating properly */
+	ast_queue_control(sub->next->owner, AST_CONTROL_UNHOLD);
+	if (ast_channel_state(sub->owner) == AST_STATE_RINGING) {
+		ast_queue_control(sub->next->owner, AST_CONTROL_RINGING);
+	}
+
+	ast_mutex_unlock(&p->sub->next->lock);
+	ast_mutex_unlock(&p->sub->lock);
+	res = ast_bridge_transfer_attended(sub->owner, sub->next->owner, NULL);
+
+	/* Subs are only freed when the endpoint itself is destroyed, so they will continue to exist
+	 * after ast_bridge_transfer_attended returns making this safe without reference counting
+	 */
+	ast_mutex_lock(&p->sub->lock);
+	ast_mutex_lock(&p->sub->next->lock);
+
+	if (res != AST_BRIDGE_TRANSFER_SUCCESS) {
+		/* If transferring fails hang up the other channel if present and us */
+		if (sub->next->owner) {
+			ast_channel_softhangup_internal_flag_add(sub->next->owner, AST_SOFTHANGUP_DEV);
+			mgcp_queue_hangup(sub->next);
+		}
+		sub->next->alreadygone = 1;
+		return 0;
+	}
+
+	unalloc_sub(sub->next);
+
+	/* If the active sub is NOT the one completing the transfer change it to be, and hang up the other sub */
+	if (p->sub != sub) {
+		p->sub = sub;
 		return 1;
-	} else {
-		ast_debug(1, "Neither %s nor %s are in a bridge, nothing to transfer\n",
-			ast_channel_name(p->sub->owner), ast_channel_name(p->sub->next->owner));
-		ast_channel_softhangup_internal_flag_add(p->sub->next->owner, AST_SOFTHANGUP_DEV);
-		if (p->sub->next->owner) {
-			p->sub->next->alreadygone = 1;
-			mgcp_queue_hangup(p->sub->next);
-		}
-	}
+	}
+
 	return 0;
 }
 
@@ -3510,13 +3510,8 @@
 				/* We're allowed to transfer, we have two avtive calls and */
 				/* we made at least one of the calls.  Let's try and transfer */
 				ast_mutex_lock(&p->sub->next->lock);
-				res = attempt_transfer(p);
-				if (res < 0) {
-					if (p->sub->next->owner) {
-						sub->next->alreadygone = 1;
-						mgcp_queue_hangup(sub->next);
-					}
-				} else if (res) {
+				res = attempt_transfer(p, sub);
+				if (res) {
 					ast_log(LOG_WARNING, "Transfer attempt failed\n");
 					ast_mutex_unlock(&p->sub->next->lock);
 					return -1;

Modified: team/kmoore/bridge_construction-cel_bridging/channels/chan_skinny.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/bridge_construction-cel_bridging/channels/chan_skinny.c?view=diff&rev=389250&r1=389249&r2=389250
==============================================================================
--- team/kmoore/bridge_construction-cel_bridging/channels/chan_skinny.c (original)
+++ team/kmoore/bridge_construction-cel_bridging/channels/chan_skinny.c Mon May 20 12:58:06 2013
@@ -704,6 +704,7 @@
 #define KEYDEF_UNKNOWN 10
 #define KEYDEF_SLAHOLD 11
 #define KEYDEF_SLACONNECTEDNOTACTIVE 12
+#define KEYDEF_RINGOUTWITHTRANS 13
 
 #define SOFTKEY_NONE 0x00
 #define SOFTKEY_REDIAL 0x01
@@ -919,6 +920,7 @@
 	SOFTKEY_NEWCALL,
 	SOFTKEY_CFWDALL,
 	SOFTKEY_CFWDBUSY,
+	SOFTKEY_CFWDNOANSWER,
 	SOFTKEY_DND,
 	SOFTKEY_GPICKUP,
 	/*SOFTKEY_CONFRN,*/
@@ -931,6 +933,7 @@
 	SOFTKEY_PARK,
 	SOFTKEY_CFWDALL,
 	SOFTKEY_CFWDBUSY,
+	SOFTKEY_CFWDNOANSWER,
 };
 
 static const uint8_t soft_key_default_onhold[] = {
@@ -951,6 +954,7 @@
 	SOFTKEY_ENDCALL,
 	SOFTKEY_CFWDALL,
 	SOFTKEY_CFWDBUSY,
+	SOFTKEY_CFWDNOANSWER,
 	SOFTKEY_GPICKUP,
 };
 
@@ -961,6 +965,7 @@
 	SOFTKEY_PARK,
 	SOFTKEY_CFWDALL,
 	SOFTKEY_CFWDBUSY,
+	SOFTKEY_CFWDNOANSWER,
 };
 
 static const uint8_t soft_key_default_dadfd[] = {
@@ -976,6 +981,12 @@
 static const uint8_t soft_key_default_ringout[] = {
 	SOFTKEY_NONE,
 	SOFTKEY_ENDCALL,
+};
+
+static const uint8_t soft_key_default_ringoutwithtransfer[] = {
+	SOFTKEY_NONE,
+	SOFTKEY_ENDCALL,
+	SOFTKEY_TRNSFER,
 };
 
 static const uint8_t soft_key_default_offhookwithfeat[] = {
@@ -1010,6 +1021,7 @@
 	{KEYDEF_DADFD, soft_key_default_dadfd, sizeof(soft_key_default_dadfd) / sizeof(uint8_t)},
 	{KEYDEF_CONNWITHCONF, soft_key_default_connwithconf, sizeof(soft_key_default_connwithconf) / sizeof(uint8_t)},
 	{KEYDEF_RINGOUT, soft_key_default_ringout, sizeof(soft_key_default_ringout) / sizeof(uint8_t)},
+	{KEYDEF_RINGOUTWITHTRANS, soft_key_default_ringoutwithtransfer, sizeof(soft_key_default_ringoutwithtransfer) / sizeof(uint8_t)},
 	{KEYDEF_OFFHOOKWITHFEAT, soft_key_default_offhookwithfeat, sizeof(soft_key_default_offhookwithfeat) / sizeof(uint8_t)},
 	{KEYDEF_UNKNOWN, soft_key_default_unknown, sizeof(soft_key_default_unknown) / sizeof(uint8_t)},
 	{KEYDEF_SLAHOLD, soft_key_default_SLAhold, sizeof(soft_key_default_SLAhold) / sizeof(uint8_t)},
@@ -1361,6 +1373,9 @@
 #define SUBSTATE_PROGRESS 12
 #define SUBSTATE_DIALING 101
 
+#define DIALTYPE_NORMAL      1<<0
+#define DIALTYPE_CFWD        1<<1
+
 struct skinny_subchannel {
 	ast_mutex_t lock;
 	struct ast_channel *owner;
@@ -1382,6 +1397,9 @@
 	int aa_beep;
 	int aa_mute;
 	int dialer_sched;
+	int cfwd_sched;
+	int dialType;
+	int getforward;
 	char *origtonum;
 	char *origtoname;
 
@@ -1424,7 +1442,7 @@
 	int threewaycalling;				\
 	int mwiblink;					\
 	int cancallforward;				\
-	int getforward;					\
+	int callfwdtimeout;				\
 	int dnd;					\
 	int hidecallerid;				\
 	int amaflags;					\
@@ -1467,7 +1485,7 @@
 	.instance = 0,
 	.directmedia = 0,
 	.nat = 0,
-	.getforward = 0,
+	.callfwdtimeout = 20000,
 	.prune = 0,
 };
 static struct skinny_line_options *default_line = &default_line_struct;
@@ -2256,7 +2274,7 @@
 				l->prefs = d->prefs; */
 				l->instance = instance;
 				l->newmsgs = ast_app_has_voicemail(l->mailbox, NULL);
-				set_callforwards(l, NULL, 0);
+				set_callforwards(l, NULL, SKINNY_CFWD_ALL|SKINNY_CFWD_BUSY|SKINNY_CFWD_NOANSWER);
 				manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Registered\r\n", l->name, d->name);
 				register_exten(l);
 				/* initialize MWI on line and device */
@@ -4463,6 +4481,7 @@
 				ast_cli(fd, "CFwdAll:          %s\n", S_COR((l->cfwdtype & SKINNY_CFWD_ALL), l->call_forward_all, "<not set>"));
 				ast_cli(fd, "CFwdBusy:         %s\n", S_COR((l->cfwdtype & SKINNY_CFWD_BUSY), l->call_forward_busy, "<not set>"));
 				ast_cli(fd, "CFwdNoAnswer:     %s\n", S_COR((l->cfwdtype & SKINNY_CFWD_NOANSWER), l->call_forward_noanswer, "<not set>"));
+				ast_cli(fd, "CFwdTimeout:      %dms\n", l->callfwdtimeout);
 				ast_cli(fd, "VoicemailBox:     %s\n", S_OR(l->mailbox, "<not set>"));
 				ast_cli(fd, "VoicemailNumber:  %s\n", S_OR(l->vmexten, "<not set>"));
 				ast_cli(fd, "MWIblink:         %d\n", l->mwiblink);
@@ -4881,6 +4900,17 @@
 	return 0;
 }
 
+static int skinny_cfwd_cb(const void *data)
+{
+	struct skinny_subchannel *sub = (struct skinny_subchannel *)data;
+	struct skinny_line *l = sub->line;
+	sub->cfwd_sched = 0;
+	SKINNY_DEBUG(DEBUG_SUB, 3, "Sub %d - CFWDNOANS to %s.\n", sub->callid, l->call_forward_noanswer);
+	ast_channel_call_forward_set(sub->owner, l->call_forward_noanswer);
+	ast_queue_control(sub->owner, AST_CONTROL_REDIRECTING);
+	return 0;
+}
+
 static int skinny_call(struct ast_channel *ast, const char *dest, int timeout)
 {
 	int res = 0;
@@ -5264,7 +5294,6 @@
 					ast_channel_name(ast_bridged_channel(xferee->owner)), ast_channel_name(xferor->owner));
 				return -1;
 			}
-			return 0;
 		} else {
 			ast_debug(1, "Neither %s nor %s are in a bridge, nothing to transfer\n",
 				ast_channel_name(xferor->owner), ast_channel_name(xferee->owner));
@@ -5379,6 +5408,9 @@
 			sub->calldirection = direction;
 			sub->aa_sched = 0;
 			sub->dialer_sched = 0;
+			sub->cfwd_sched = 0;
+			sub->dialType = DIALTYPE_NORMAL;
+			sub->getforward = 0;
 
 			if (subline) {
 				sub->subline = subline;
@@ -5428,13 +5460,15 @@
 		ast_channel_named_callgroups_set(tmp, l->named_callgroups);
 		ast_channel_named_pickupgroups_set(tmp, l->named_pickupgroups);
 
-		/* XXX Need to figure out how to handle CFwdNoAnswer */
 		if (l->cfwdtype & SKINNY_CFWD_ALL) {
+			SKINNY_DEBUG(DEBUG_SUB, 3, "Sub %d - CFWDALL to %s.\n", sub->callid, l->call_forward_all);
 			ast_channel_call_forward_set(tmp, l->call_forward_all);
-		} else if (l->cfwdtype & SKINNY_CFWD_BUSY) {
-			if (get_devicestate(l) != AST_DEVICE_NOT_INUSE) {
-				ast_channel_call_forward_set(tmp, l->call_forward_busy);
-			}
+		} else if ((l->cfwdtype & SKINNY_CFWD_BUSY) && (get_devicestate(l) != AST_DEVICE_NOT_INUSE)) {
+			SKINNY_DEBUG(DEBUG_SUB, 3, "Sub %d - CFWDBUSY to %s.\n", sub->callid, l->call_forward_busy);
+			ast_channel_call_forward_set(tmp, l->call_forward_busy);
+		} else if (l->cfwdtype & SKINNY_CFWD_NOANSWER) {
+			SKINNY_DEBUG(DEBUG_SUB, 3, "Sub %d - CFWDNOANS Scheduling for %d seconds.\n", sub->callid, l->callfwdtimeout/1000);
+			sub->cfwd_sched = skinny_sched_add(l->callfwdtimeout, skinny_cfwd_cb, sub);
 		}
 
 		if (subline) {
@@ -5534,6 +5568,19 @@
 		sub->aa_mute = 0;
 	}
 
+	if (sub->cfwd_sched) {
+		if (state == SUBSTATE_CONNECTED) {
+			if (skinny_sched_del(sub->cfwd_sched, sub)) {
+				SKINNY_DEBUG(DEBUG_SUB, 3, "Sub %d - trying to change state from %s to %s, but already forwarded because no answer.\n",
+					sub->callid, substate2str(sub->substate), substate2str(actualstate));
+				return;
+			}
+			sub->cfwd_sched = 0;
+		} else if (state == SUBSTATE_ONHOOK) {
+			skinny_sched_del(sub->cfwd_sched, sub);
+		}
+	}
+
 	if ((state == SUBSTATE_RINGIN) && ((d->hookstate == SKINNY_OFFHOOK) || (AST_LIST_NEXT(AST_LIST_FIRST(&l->sub), list)))) {
 		actualstate = SUBSTATE_CALLWAIT;
 	}
@@ -5664,8 +5711,6 @@
 		sub->callid, substate2str(sub->substate), substate2str(actualstate));
 
 	if (actualstate == sub->substate) {
-		send_callinfo(sub);
-		transmit_callstate(d, l->instance, sub->callid, SKINNY_HOLD);
 		return;
 	}
 
@@ -5775,6 +5820,11 @@
 			transmit_start_tone(d, SKINNY_ALERT, l->instance, sub->callid);
 		}
 		transmit_callstate(d, l->instance, sub->callid, SKINNY_RINGOUT);
+		if (sub->related) {
+			transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUTWITHTRANS, KEYMASK_ALL);
+		} else {
+			transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT, KEYMASK_ALL);
+		}
 		transmit_dialednumber(d, sub->exten, l->instance, sub->callid);
 		send_displaypromptstatus(d, OCTAL_RINGOUT, "", 0, l->instance, sub->callid);
 		send_callinfo(sub);
@@ -6000,26 +6050,19 @@
 
 static void dialandactivatesub(struct skinny_subchannel *sub, char exten[AST_MAX_EXTENSION])
 {
-	if (sub->line->getforward) {
-		struct skinny_line *l = sub->line;
-		struct skinny_device *d = l->device;
-
-		// FIXME: needs some love and remove sleeps
-		SKINNY_DEBUG(DEBUG_SUB, 3, "Sub %d - Set callforward to %s\n", sub->callid, exten);
-		set_callforwards(l, sub->exten, l->getforward);
-		transmit_start_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
-		transmit_lamp_indication(d, STIMULUS_FORWARDALL, 1, SKINNY_LAMP_ON);
-		transmit_displaynotify(d, "CFwd enabled", 10);
-		transmit_cfwdstate(d, l);
-		ast_safe_sleep(sub->owner, 500);
-		ast_indicate(sub->owner, -1);
-		ast_safe_sleep(sub->owner, 1000);
-		l->getforward = 0;
-		dumpsub(sub, 0);
-	} else {
+	struct skinny_line *l = sub->line;
+	struct skinny_device *d = l->device;
+	
+	if (sub->dialType == DIALTYPE_NORMAL) {
 		SKINNY_DEBUG(DEBUG_SUB, 3, "Sub %d - Dial %s and Activate\n", sub->callid, exten);
 		ast_copy_string(sub->exten, exten, sizeof(sub->exten));
 		activatesub(sub, SUBSTATE_DIALING);
+	} else if (sub->dialType == DIALTYPE_CFWD) {
+		SKINNY_DEBUG(DEBUG_SUB, 3, "Sub %d - Set callforward(%d) to %s\n", sub->callid, sub->getforward, exten);
+		set_callforwards(l, sub->exten, sub->getforward);
+		dumpsub(sub, 1);
+		transmit_cfwdstate(d, l);
+		transmit_displaynotify(d, "CFwd enabled", 10);
 	}
 }
 
@@ -6098,48 +6141,38 @@
 	return 0;
 }
 
-static int handle_callforward_button(struct skinny_subchannel *sub, int cfwdtype)
-{
-	struct skinny_line *l = sub->line;
+static void handle_callforward_button(struct skinny_line *l, struct skinny_subchannel *sub, int cfwdtype)
+{
 	struct skinny_device *d = l->device;
-	struct ast_channel *c = sub->owner;
+	struct ast_channel *c;
 
 	if (!d->session) {
 		ast_log(LOG_WARNING, "Device for line %s is not registered.\n", l->name);
-		return 0;
-	}
-
-	if (d->hookstate == SKINNY_ONHOOK) {
-		d->hookstate = SKINNY_OFFHOOK;
-		transmit_speaker_mode(d, SKINNY_SPEAKERON);
-		transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK);
-		transmit_activatecallplane(d, l);
-	}
-	transmit_clear_display_message(d, l->instance, sub->callid);
-
-	if (l->cfwdtype & cfwdtype) {
+		return;
+	}
+
+	if (!sub && (l->cfwdtype & cfwdtype)) {
 		set_callforwards(l, NULL, cfwdtype);
-		ast_safe_sleep(c, 500);
-		transmit_speaker_mode(d, SKINNY_SPEAKEROFF);
-		transmit_closereceivechannel(d, sub);
-		transmit_stopmediatransmission(d, sub);
-		transmit_speaker_mode(d, SKINNY_SPEAKEROFF);
-		transmit_clearpromptmessage(d, l->instance, sub->callid);
-		transmit_callstate(d, l->instance, sub->callid, SKINNY_ONHOOK);
-		transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK, KEYMASK_ALL);
-		transmit_activatecallplane(d, l);
+		if (sub) {
+			dumpsub(sub, 1);
+		}
+		transmit_cfwdstate(d, l);
 		transmit_displaynotify(d, "CFwd disabled", 10);
-		if (sub->owner && ast_channel_state(sub->owner) != AST_STATE_UP) {
-			ast_indicate(c, -1);
-			ast_hangup(c);
-		}
-		transmit_cfwdstate(d, l);
 	} else {
-		l->getforward = cfwdtype;
-		setsubstate(sub, SUBSTATE_OFFHOOK);
-	}
-	return 0;
-}
+		if (!sub || !sub->owner) {
+			if (!(c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING))) {
+				ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
+				return;
+			}
+			sub = ast_channel_tech_pvt(c);
+			l->activesub = sub;
+			setsubstate(sub, SUBSTATE_OFFHOOK);
+		}
+		sub->getforward |= cfwdtype;
+		sub->dialType = DIALTYPE_CFWD;
+	}
+}
+
 static int handle_ip_port_message(struct skinny_req *req, struct skinnysession *s)
 {
 	/* no response necessary */
@@ -6399,55 +6432,17 @@
 	case STIMULUS_FORWARDALL:
 		SKINNY_DEBUG(DEBUG_PACKET, 3, "Received STIMULUS_FORWARDALL from %s, inst %d, callref %d\n",
 			d->name, instance, callreference);
-
-		if (!sub || !sub->owner) {
-			c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
-		} else {
-			c = sub->owner;
-		}
-
-		if (!c) {
-			ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
-		} else {
-			sub = ast_channel_tech_pvt(c);
-			handle_callforward_button(sub, SKINNY_CFWD_ALL);
-		}
+		handle_callforward_button(l, sub, SKINNY_CFWD_ALL);
 		break;
 	case STIMULUS_FORWARDBUSY:
 		SKINNY_DEBUG(DEBUG_PACKET, 3, "Received STIMULUS_FORWARDBUSY from %s, inst %d, callref %d\n",
 			d->name, instance, callreference);
-
-		if (!sub || !sub->owner) {
-			c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
-		} else {
-			c = sub->owner;
-		}
-
-		if (!c) {
-			ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
-		} else {
-			sub = ast_channel_tech_pvt(c);
-			handle_callforward_button(sub, SKINNY_CFWD_BUSY);
-		}
+		handle_callforward_button(l, sub, SKINNY_CFWD_BUSY);
 		break;
 	case STIMULUS_FORWARDNOANSWER:
 		SKINNY_DEBUG(DEBUG_PACKET, 3, "Received STIMULUS_FORWARDNOANSWER from %s, inst %d, callref %d\n",
 			d->name, instance, callreference);
-
-#if 0 /* Not sure how to handle this yet */
-		if (!sub || !sub->owner) {
-			c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
-		} else {
-			c = sub->owner;
-		}
-
-		if (!c) {
-			ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
-		} else {
-			sub = c->tech_pvt;
-			handle_callforward_button(sub, SKINNY_CFWD_NOANSWER);
-		}
-#endif
+		handle_callforward_button(l, sub, SKINNY_CFWD_NOANSWER);
 		break;
 	case STIMULUS_DISPLAY:
 		/* Not sure what this is */
@@ -7036,58 +7031,17 @@
 	case SOFTKEY_CFWDALL:
 		SKINNY_DEBUG(DEBUG_PACKET, 3, "Received SOFTKEY_CFWDALL from %s, inst %d, callref %d\n",
 			d->name, instance, callreference);
-
-		if (!sub || !sub->owner) {
-			c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
-		} else {
-			c = sub->owner;
-		}
-
-		if (!c) {
-			ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
-		} else {
-			sub = ast_channel_tech_pvt(c);
-			l->activesub = sub;
-			handle_callforward_button(sub, SKINNY_CFWD_ALL);
-		}
+		handle_callforward_button(l, sub, SKINNY_CFWD_ALL);
 		break;
 	case SOFTKEY_CFWDBUSY:
 		SKINNY_DEBUG(DEBUG_PACKET, 3, "Received SOFTKEY_CFWDBUSY from %s, inst %d, callref %d\n",
 			d->name, instance, callreference);
-
-		if (!sub || !sub->owner) {
-			c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
-		} else {
-			c = sub->owner;
-		}
-
-		if (!c) {
-			ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
-		} else {
-			sub = ast_channel_tech_pvt(c);
-			l->activesub = sub;
-			handle_callforward_button(sub, SKINNY_CFWD_BUSY);
-		}
+		handle_callforward_button(l, sub, SKINNY_CFWD_BUSY);
 		break;
 	case SOFTKEY_CFWDNOANSWER:
 		SKINNY_DEBUG(DEBUG_PACKET, 3, "Received SOFTKEY_CFWDNOANSWER from %s, inst %d, callref %d\n",
 			d->name, instance, callreference);
-
-#if 0 /* Not sure how to handle this yet */
-		if (!sub || !sub->owner) {
-			c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
-		} else {
-			c = sub->owner;
-		}
-
-		if (!c) {
-			ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
-		} else {
-			sub = c->tech_pvt;
-			l->activesub = sub;
-			handle_callforward_button(sub, SKINNY_CFWD_NOANSWER);
-		}
-#endif
+		handle_callforward_button(l, sub, SKINNY_CFWD_NOANSWER);
 		break;
 	case SOFTKEY_BKSPC:
 		SKINNY_DEBUG(DEBUG_PACKET, 3, "Received SOFTKEY_BKSPC from %s, inst %d, callref %d\n",
@@ -7949,6 +7903,11 @@
 				CLINE_OPTS->cancallforward = ast_true(v->value);
 				continue;
 			}
+		} else if (!strcasecmp(v->name, "callfwdtimeout")) {
+			if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
+				CLINE_OPTS->callfwdtimeout = atoi(v->value);
+				continue;
+			}
 		} else if (!strcasecmp(v->name, "mailbox")) {
 			if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
 				ast_copy_string(CLINE_OPTS->mailbox, v->value, sizeof(CLINE_OPTS->mailbox));

Modified: team/kmoore/bridge_construction-cel_bridging/configs/skinny.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/bridge_construction-cel_bridging/configs/skinny.conf.sample?view=diff&rev=389250&r1=389249&r2=389250
==============================================================================
--- team/kmoore/bridge_construction-cel_bridging/configs/skinny.conf.sample (original)
+++ team/kmoore/bridge_construction-cel_bridging/configs/skinny.conf.sample Mon May 20 12:58:06 2013
@@ -100,6 +100,7 @@
 ;                            ; (earlyrtp=1) or device generated (earlyrtp=0). default=yes
 ;transfer=1                  ; whether the device is allowed to transfer. default=yes
 ;context=default             ; context to use for this line.
+;callfwdtimeout=20000        ; ms before cfwd_noans occurs (default 20 secs)
 ;------------------------------- SPECIFIC LINE OPTIONS -----------------------------
 ;setvar=        	     ; allows for the setting of chanvars.
 ;-----------------------------------------------------------------------------------

Modified: team/kmoore/bridge_construction-cel_bridging/main/pbx.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/bridge_construction-cel_bridging/main/pbx.c?view=diff&rev=389250&r1=389249&r2=389250
==============================================================================
--- team/kmoore/bridge_construction-cel_bridging/main/pbx.c (original)
+++ team/kmoore/bridge_construction-cel_bridging/main/pbx.c Mon May 20 12:58:06 2013
@@ -9964,10 +9964,11 @@
 static void *pbx_outgoing_exec(void *data)
 {
 	RAII_VAR(struct pbx_outgoing *, outgoing, data, ao2_cleanup);
-	enum ast_dial_result res = ast_dial_run(outgoing->dial, NULL, 0);
+	enum ast_dial_result res;
 
 	/* Notify anyone interested that dialing is complete */
 	ast_mutex_lock(&outgoing->lock);
+	res = ast_dial_run(outgoing->dial, NULL, 0);
 	outgoing->dialed = 1;
 	ast_cond_signal(&outgoing->cond);
 	ast_mutex_unlock(&outgoing->lock);
@@ -10115,6 +10116,8 @@
 
 	ao2_ref(outgoing, +1);
 
+	ast_mutex_lock(&outgoing->lock);
+
 	if (ast_pthread_create_detached(&thread, NULL, pbx_outgoing_exec, outgoing)) {
 		ast_log(LOG_WARNING, "Unable to spawn dialing thread for '%s/%s'\n", type, addr);
 		if (channel) {
@@ -10125,22 +10128,26 @@
 	}
 
 	/* Wait for dialing to complete */
-	if (synchronous) {
-		ast_mutex_lock(&outgoing->lock);
+	if (channel || synchronous) {
+		if (channel) {
+			ast_channel_unlock(*channel);
+		}
 		while (!outgoing->dialed) {
 			ast_cond_wait(&outgoing->cond, &outgoing->lock);
 		}
-		ast_mutex_unlock(&outgoing->lock);
+		if (channel) {
+			ast_channel_lock(*channel);
+		}
 	}
 
 	/* Wait for execution to complete */
 	if (synchronous > 1) {
-		ast_mutex_lock(&outgoing->lock);
 		while (!outgoing->executed) {
 			ast_cond_wait(&outgoing->cond, &outgoing->lock);
 		}
-		ast_mutex_unlock(&outgoing->lock);
-	}
+	}
+
+	ast_mutex_unlock(&outgoing->lock);
 
 	if (reason) {
 		*reason = ast_dial_reason(outgoing->dial, 0);

Modified: team/kmoore/bridge_construction-cel_bridging/main/sorcery.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/bridge_construction-cel_bridging/main/sorcery.c?view=diff&rev=389250&r1=389249&r2=389250
==============================================================================
--- team/kmoore/bridge_construction-cel_bridging/main/sorcery.c (original)
+++ team/kmoore/bridge_construction-cel_bridging/main/sorcery.c Mon May 20 12:58:06 2013
@@ -983,7 +983,7 @@
 	struct ast_sorcery_object_details *details;
 
 	if (!object_type || !object_type->type.item_alloc ||
-	    !(details = object_type->type.item_alloc(""))) {
+	    !(details = object_type->type.item_alloc(id))) {
 		return NULL;
 	}
 

Modified: team/kmoore/bridge_construction-cel_bridging/res/res_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/bridge_construction-cel_bridging/res/res_sip.c?view=diff&rev=389250&r1=389249&r2=389250
==============================================================================
--- team/kmoore/bridge_construction-cel_bridging/res/res_sip.c (original)
+++ team/kmoore/bridge_construction-cel_bridging/res/res_sip.c Mon May 20 12:58:06 2013
@@ -42,6 +42,512 @@
 	<support_level>core</support_level>
  ***/
 
+/*** DOCUMENTATION
+	<configInfo name="res_sip" language="en_US">
+		<synopsis>SIP Resource using PJProject</synopsis>
+		<configFile name="res_sip.conf">
+			<configObject name="endpoint">
+				<synopsis>Endpoint</synopsis>
+				<description><para>
+					The <emphasis>Endpoint</emphasis> is the primary configuration object.
+					It contains the core SIP related options only, endpoints are <emphasis>NOT</emphasis>
+					dialable entries of their own. Communication with another SIP device is
+					accomplished via Addresses of Record (AoRs) which have one or more
+					contacts assicated with them. Endpoints <emphasis>NOT</emphasis> configured to 
+					use a <literal>transport</literal> will default to first transport found
+					in <filename>res_sip.conf</filename> that matches its type.
+					</para>
+					<para>Example: An Endpoint has been configured with no transport.
+					When it comes time to call an AoR, PJSIP will find the
+					first transport that matches the type. A SIP URI of <literal>sip:5000@[11::33]</literal>
+					will use the first IPv6 transport and try to send the request.
+					</para>
+				</description>
+				<configOption name="100rel" default="yes">
+					<synopsis>Allow support for RFC3262 provisional ACK tags</synopsis>
+					<description>
+						<enumlist>
+							<enum name="no" />
+							<enum name="required" />
+							<enum name="yes" />
+						</enumlist>
+					</description>
+				</configOption>
+				<configOption name="aggregate_mwi" default="yes">
+					<synopsis></synopsis>
+					<description><para>When enabled, <replaceable>aggregate_mwi</replaceable> condenses message
+					waiting notifications from multiple mailboxes into a single NOTIFY. If it is disabled,
+					individual NOTIFYs are sent for each mailbox.</para></description>
+				</configOption>
+				<configOption name="allow">
+					<synopsis>Media Codec(s) to allow</synopsis>
+				</configOption>
+				<configOption name="aors">
+					<synopsis>AoR(s) to be used with the endpoint</synopsis>
+					<description><para>
+						List of comma separated AoRs that the endpoint should be associated with.
+					</para></description>
+				</configOption>
+				<configOption name="auth">
+					<synopsis>Authentication Object(s) associated with the endpoint</synopsis>
+					<description><para>
+						This is a comma-delimited list of <replaceable>auth</replaceable> sections defined
+						in <filename>res_sip.conf</filename> to be used to verify inbound connection attempts.
+						</para><para>
+						Endpoints without an <literal>authentication</literal> object
+						configured will allow connections without vertification.
+					</para></description>
+				</configOption>
+				<configOption name="callerid">
+					<synopsis>CallerID information for the endpoint</synopsis>
+					<description><para>
+						Must be in the format <literal>Name &lt;Number&gt;</literal>,
+						or only <literal>&lt;Number&gt;</literal>.
+					</para></description>
+				</configOption>
+				<configOption name="callerid_privacy">
+					<synopsis>Default privacy level</synopsis>
+					<description>
+						<enumlist>
+							<enum name="allowed_not_screened" />
+							<enum name="allowed_passed_screened" />
+							<enum name="allowed_failed_screened" />
+							<enum name="allowed" />
+							<enum name="prohib_not_screened" />
+							<enum name="prohib_passed_screened" />

[... 608 lines stripped ...]



More information about the asterisk-commits mailing list