[asterisk-commits] moy: branch moy/mfcr2 r176494 - in /team/moy/mfcr2: channels/ configs/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Feb 16 23:30:08 CST 2009


Author: moy
Date: Mon Feb 16 23:30:08 2009
New Revision: 176494

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=176494
Log:
added mfcr2_accept_on_offer parameter and improved hangup cause management

Modified:
    team/moy/mfcr2/channels/chan_dahdi.c
    team/moy/mfcr2/configs/chan_dahdi.conf.sample

Modified: team/moy/mfcr2/channels/chan_dahdi.c
URL: http://svn.digium.com/svn-view/asterisk/team/moy/mfcr2/channels/chan_dahdi.c?view=diff&rev=176494&r1=176493&r2=176494
==============================================================================
--- team/moy/mfcr2/channels/chan_dahdi.c (original)
+++ team/moy/mfcr2/channels/chan_dahdi.c Mon Feb 16 23:30:08 2009
@@ -140,6 +140,23 @@
 			current channel.</para>
 		</description>
 	</application>
+	<application name="DAHDIAcceptR2Call" language="en_US">
+		<synopsis>
+			Accept an R2 call if its not already accepted (you still need to answer it)
+		</synopsis>
+		<syntax>
+			<parameter name="charge" required="true">
+				<para>Yes or No.</para>
+				<para>Whether you want to accept the call with charge or without charge.</para>
+			</parameter>
+		</syntax>
+		<description>
+			<para>This application will Accept the R2 call either with charge or no charge.</para>
+		</description>
+		<description>
+			<para>This application will Accept the R2 call either with charge or no charge.</para>
+		</description>
+	</application>
  ***/
 
 #define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
@@ -464,6 +481,7 @@
 	int call_files:1;
 	int allow_collect_calls:1;
 	int charge_calls:1;
+	int accept_on_offer:1;
 	int forced_release:1;
 	int double_answer:1;
 	int immediate_accept:1;
@@ -1191,17 +1209,20 @@
 	unsigned int loopedback:1;
 #endif
 #ifdef HAVE_OPENR2
-	int mfcr2call;
 	struct dahdi_mfcr2 *mfcr2;
 	openr2_chan_t *r2chan;
 	openr2_calling_party_category_t mfcr2_recvd_category;
 	openr2_calling_party_category_t mfcr2_category;
-	int mfcr2_charge_calls;
-	int mfcr2_allow_collect_calls;
-	int mfcr2_forced_release;
 	int mfcr2_dnis_index;
 	int mfcr2_ani_index;
-	int mfcr2_dnis_matched;
+	int mfcr2call:1;
+	int mfcr2_answer_pending:1;
+	int mfcr2_charge_calls:1;
+	int mfcr2_allow_collect_calls:1;
+	int mfcr2_forced_release:1;
+	int mfcr2_dnis_matched:1;
+	int mfcr2_call_accepted:1;
+	int mfcr2_accept_on_offer:1;
 #endif
 	/*! \brief DTMF digit in progress.  0 when no digit in progress. */
 	char begindigit;
@@ -1290,6 +1311,7 @@
 			.call_files = 0,
 			.allow_collect_calls = 0,
 			.charge_calls = 1,
+			.accept_on_offer = 1,
 			.forced_release = 0,
 			.double_answer = 0,
 			.immediate_accept = -1,
@@ -1624,7 +1646,9 @@
 	p->exten[0] = '\0';
 	p->mfcr2_ani_index = '\0';
 	p->mfcr2_dnis_index = '\0';
-	p->mfcr2_dnis_matched = '\0';
+	p->mfcr2_dnis_matched = 0;
+	p->mfcr2_answer_pending = 0;
+	p->mfcr2_call_accepted = 0;
 	ast_mutex_unlock(&p->lock);
 	ast_log(LOG_NOTICE, "New MFC/R2 call detected on chan %d.\n", openr2_chan_get_number(r2chan));
 }
@@ -1665,9 +1689,28 @@
 	ast_mutex_unlock(&p->lock);
 }
 
+static void dahdi_r2_update_monitor_count(struct dahdi_mfcr2 *mfcr2, int increment)
+{
+	ast_mutex_lock(&mfcr2->monitored_count_lock);
+	if (increment) {
+		mfcr2->monitored_count++;
+		if (mfcr2->monitored_count == 1) {
+			ast_log(LOG_DEBUG, "At least one device needs monitoring, let's wake up the monitor thread.\n");
+			ast_cond_signal(&mfcr2->do_monitor);
+		}
+	} else {
+		mfcr2->monitored_count--;
+		if (mfcr2->monitored_count < 0) {
+			ast_log(LOG_ERROR, "we have a bug here!.\n");
+		}
+	}
+	ast_mutex_unlock(&mfcr2->monitored_count_lock);
+}
+
 static void dahdi_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, const char *dnis, openr2_calling_party_category_t category)
 {
 	struct dahdi_pvt *p;
+	struct ast_channel *c;
 	ast_log(LOG_NOTICE, "MFC/R2 call offered on chan %d. ANI = %s, DNIS = %s, Category = %s\n",
 			openr2_chan_get_number(r2chan), ani ? ani : "(restricted)", dnis,
 			openr2_proto_get_category_string(category));
@@ -1697,12 +1740,27 @@
 		ast_log(LOG_NOTICE, "MFC/R2 call on channel %d requested non-existent extension '%s' in context '%s'. Rejecting call.\n",
 				p->channel, p->exten, p->context);
 		openr2_chan_disconnect_call(r2chan, OR2_CAUSE_UNALLOCATED_NUMBER);
+		return;
+	} 
+	if (!p->mfcr2_accept_on_offer) {
+		/* The user wants us to start the PBX thread right away without accepting the call first */
+		c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, 0);
+		if (c) {
+			dahdi_r2_update_monitor_count(p->mfcr2, 0);
+			pbx_builtin_setvar_helper(c, "MFCR2_CATEGORY", openr2_proto_get_category_string(p->mfcr2_recvd_category));
+			/* Done here, don't disable reading now since we still need to generate MF tones to accept
+			   the call or reject it and detect the tone off condition of the other end, all of this
+			   will be done in the PBX thread now */
+			return;
+		} 
+		ast_log(LOG_WARNING, "Unable to create PBX channel in DAHDI channel %d\n", p->channel);
+		openr2_chan_disconnect_call(r2chan, OR2_CAUSE_OUT_OF_ORDER);
+	} else if (p->mfcr2_charge_calls) {
+		ast_log(LOG_DEBUG, "Accepting MFC/R2 call with charge on chan %d\n", p->channel);
+		openr2_chan_accept_call(r2chan, OR2_CALL_WITH_CHARGE);
 	} else {
-		if (p->mfcr2_charge_calls) {
-			openr2_chan_accept_call(r2chan, OR2_CALL_WITH_CHARGE);
-		} else {
-			openr2_chan_accept_call(r2chan, OR2_CALL_NO_CHARGE);
-		}
+		ast_log(LOG_DEBUG, "Accepting MFC/R2 call with no charge on chan %d\n", p->channel);
+		openr2_chan_accept_call(r2chan, OR2_CALL_NO_CHARGE);
 	}
 }
 
@@ -1715,23 +1773,6 @@
 	ast_mutex_unlock(&p->lock);
 }
 
-static void dahdi_r2_update_monitor_count(struct dahdi_mfcr2 *mfcr2, int increment)
-{
-	ast_mutex_lock(&mfcr2->monitored_count_lock);
-	if (increment) {
-		mfcr2->monitored_count++;
-		if (mfcr2->monitored_count == 1) {
-			ast_log(LOG_DEBUG, "At least one device needs monitoring, let's wake up the monitor thread.\n");
-			ast_cond_signal(&mfcr2->do_monitor);
-		}
-	} else {
-		mfcr2->monitored_count--;
-		if (mfcr2->monitored_count < 0) {
-			ast_log(LOG_ERROR, "we have a bug here!.\n");
-		}
-	}
-	ast_mutex_unlock(&mfcr2->monitored_count_lock);
-}
 static void dahdi_enable_ec(struct dahdi_pvt *p);
 static void dahdi_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t mode)
 {
@@ -1740,24 +1781,42 @@
 	ast_log(LOG_NOTICE, "MFC/R2 call has been accepted on chan %d\n", openr2_chan_get_number(r2chan));
 	p = openr2_chan_get_client_data(r2chan);
 	dahdi_enable_ec(p);
+	p->mfcr2_call_accepted = 1;
+	/* if it's an incoming call ... */
 	if (OR2_DIR_BACKWARD == openr2_chan_get_direction(r2chan)) {
+		/* If accept on offer is not set, it means at this point the PBX thread is already
+		   launched (was launched in the 'on call offered' handler) and therefore this callback
+		   is being executed already in the PBX thread rather than the monitor thread, don't launch
+		   any other thread, just disable the openr2 reading and answer the call if needed */
+		if (!p->mfcr2_accept_on_offer) {
+			openr2_chan_disable_read(r2chan);
+			if (p->mfcr2_answer_pending) {
+				ast_log(LOG_DEBUG, "Answering MFC/R2 call after accepting it on chan %d\n", openr2_chan_get_number(r2chan));
+				openr2_chan_answer_call(r2chan);
+			}	
+			return;
+		} 
 		c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, 0);
 		if (c) {
 			dahdi_r2_update_monitor_count(p->mfcr2, 0);
-			/* chan_dahdi will take care of reading from now on, tell the library to forget about it */
+			/* chan_dahdi will take care of reading from now on in the PBX thread, tell the 
+			   library to forget about it */
 			openr2_chan_disable_read(r2chan);
-		} else {
-			openr2_chan_disconnect_call(r2chan, OR2_CAUSE_OUT_OF_ORDER);
+			pbx_builtin_setvar_helper(c, "MFCR2_CATEGORY", openr2_proto_get_category_string(p->mfcr2_recvd_category));
 			return;
 		}
-		pbx_builtin_setvar_helper(c, "MFCR2_CATEGORY", openr2_proto_get_category_string(p->mfcr2_recvd_category));
-	} else {
-		ast_log(LOG_NOTICE, "Call accepted on forward channel %d\n", p->channel);
-		p->subs[SUB_REAL].needringing = 1;
-		p->dialing = 0;
-		/* chan_dahdi will take care of reading from now on, tell the library to forget about it */
-		openr2_chan_disable_read(r2chan);
-	}
+		ast_log(LOG_WARNING, "Unable to create PBX channel in DAHDI channel %d\n", p->channel);
+		/* failed to create the channel, bail out and report it as an out of order line */
+		openr2_chan_disconnect_call(r2chan, OR2_CAUSE_OUT_OF_ORDER);
+		return;
+	} 
+	/* this is an outgoing call, no need to launch the PBX thread, most likely we're in one already */
+	ast_log(LOG_NOTICE, "Call accepted on forward channel %d\n", p->channel);
+	p->subs[SUB_REAL].needringing = 1;
+	p->dialing = 0;
+	/* chan_dahdi will take care of reading from now on in the PBX thread, tell the 
+	   library to forget about it */
+	openr2_chan_disable_read(r2chan);
 }
 
 static void dahdi_r2_on_call_answered(openr2_chan_t *r2chan)
@@ -4080,6 +4139,149 @@
 }
 #endif	/* defined(HAVE_PRI) */
 
+#if defined(HAVE_OPENR2)
+static const char *dahdi_accept_r2_call_app = "DAHDIAcceptR2Call";
+
+static int dahdi_accept_r2_call_exec(struct ast_channel *chan, void *data)
+{
+	/* data is whether to accept with charge or no charge */
+	openr2_call_mode_t accept_mode;
+	int res, timeout, maxloops;
+	struct ast_frame *f;
+	struct dahdi_pvt *p;
+	char *parse;
+	AST_DECLARE_APP_ARGS(args,
+			AST_APP_ARG(charge);
+	);
+
+	if (ast_strlen_zero(data)) {
+		ast_log(LOG_DEBUG, "No data sent to application!\n");
+		return -1;
+	}
+
+	if (chan->tech != &dahdi_tech) {
+		ast_log(LOG_DEBUG, "Only DAHDI technology accepted!\n");
+		return -1;
+	}
+
+	p = (struct dahdi_pvt *)chan->tech_pvt;
+	if (!p) {
+		ast_log(LOG_DEBUG, "Unable to find technology private!\n");
+		return -1;
+	}
+
+	parse = ast_strdupa(data);
+	AST_STANDARD_APP_ARGS(args, parse);
+
+	if (ast_strlen_zero(args.charge)) {
+		ast_log(LOG_WARNING, "DAHDIAcceptR2Call requires 'yes' or 'no' for the charge parameter\n");
+		return -1;
+	}
+
+	ast_mutex_lock(&p->lock);
+	if (!p->mfcr2 || !p->mfcr2call) {
+		ast_mutex_unlock(&p->lock);
+		ast_log(LOG_DEBUG, "Channel %s does not seems to be an R2 active channel!\n", chan->name);
+		return -1;
+	}
+
+	if (p->mfcr2_call_accepted) {
+		ast_mutex_unlock(&p->lock);
+		ast_log(LOG_DEBUG, "MFC/R2 call already accepted on channel %s!\n", chan->name);
+		return 0;
+	}
+	accept_mode = ast_true(args.charge) ? OR2_CALL_WITH_CHARGE : OR2_CALL_NO_CHARGE;
+	if (openr2_chan_accept_call(p->r2chan, accept_mode)) {
+		ast_mutex_unlock(&p->lock);
+		ast_log(LOG_WARNING, "Failed to accept MFC/R2 call!\n");
+		return -1;
+	}
+	ast_mutex_unlock(&p->lock);
+
+	res = 0;
+	timeout = 100;
+	maxloops = 50; /* wait up to 5 seconds */
+	/* we need to read() until the call is accepted */
+	while (maxloops > 0) {
+		maxloops--;
+		if (ast_check_hangup(chan)) {
+			break;
+		}
+		res = ast_waitfor(chan, timeout);
+		if (res < 0) {
+			ast_log(LOG_DEBUG, "ast_waitfor failed on channel %s, going out ...\n", chan->name);
+			res = -1;
+			break;
+		}
+		if (res == 0) {
+			continue;
+		}
+		f = ast_read(chan);
+		if (!f) {
+			ast_log(LOG_DEBUG, "No frame read on channel %s, going out ...\n", chan->name);
+			res = -1;
+			break;
+		}
+		if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) {
+			ast_log(LOG_DEBUG, "Got HANGUP frame on channel %s, going out ...\n", chan->name);
+			ast_frfree(f);
+			res = -1;
+			break;
+		}
+		ast_frfree(f);
+		ast_mutex_lock(&p->lock);
+		if (p->mfcr2_call_accepted) {
+			ast_mutex_unlock(&p->lock);
+			ast_log(LOG_DEBUG, "Accepted MFC/R2 call!\n");
+			break;
+		}
+		ast_mutex_unlock(&p->lock);
+	}
+	if (res == -1) {
+		ast_log(LOG_WARNING, "Failed to accept MFC/R2 call!\n");
+	}
+	return res;
+}
+
+static openr2_call_disconnect_cause_t dahdi_ast_cause_to_r2_cause(int cause)
+{
+	openr2_call_disconnect_cause_t r2cause = OR2_CAUSE_NORMAL_CLEARING;
+	switch (cause) {
+	case AST_CAUSE_USER_BUSY:
+	case AST_CAUSE_CALL_REJECTED:
+	case AST_CAUSE_INTERWORKING: /* I don't know wtf is this but is used sometimes when ekiga rejects a call */
+		r2cause = OR2_CAUSE_BUSY_NUMBER;
+		break;
+
+	case AST_CAUSE_NORMAL_CIRCUIT_CONGESTION:
+	case AST_CAUSE_SWITCH_CONGESTION:
+		r2cause = OR2_CAUSE_NETWORK_CONGESTION;
+		break;
+
+	case AST_CAUSE_UNALLOCATED:
+		r2cause = OR2_CAUSE_UNALLOCATED_NUMBER;
+		break;
+
+	case AST_CAUSE_NETWORK_OUT_OF_ORDER:
+	case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
+		r2cause = OR2_CAUSE_OUT_OF_ORDER;
+		break;
+
+	case AST_CAUSE_NO_ANSWER:
+	case AST_CAUSE_NO_USER_RESPONSE:
+		r2cause = OR2_CAUSE_NO_ANSWER;
+		break;
+
+	default:
+		r2cause = OR2_CAUSE_NORMAL_CLEARING;
+		break;
+	}
+	ast_log(LOG_DEBUG, "dahdi_ast_cause_to_r2_cause returned %d/%s for ast cause %d\n", 
+			r2cause, openr2_proto_get_disconnect_string(r2cause), cause);
+	return r2cause;
+}
+#endif
+
 static int dahdi_hangup(struct ast_channel *ast)
 {
 	int res;
@@ -4298,10 +4500,15 @@
 #ifdef HAVE_OPENR2
 		if (p->mfcr2) {
 			ast_log(LOG_DEBUG, "disconnecting MFC/R2 call on chan %d\n", p->channel);
+			/* If it's an incoming call, check the mfcr2_forced_release setting */
 			if (openr2_chan_get_direction(p->r2chan) == OR2_DIR_BACKWARD && p->mfcr2_forced_release) {
 				openr2_chan_disconnect_call(p->r2chan, OR2_CAUSE_FORCED_RELEASE);
 			} else {
-				openr2_chan_disconnect_call(p->r2chan, OR2_CAUSE_NORMAL_CLEARING);
+				const char *r2causestr = pbx_builtin_getvar_helper(ast, "MFCR2_CAUSE");
+				int r2cause_user = r2causestr ? atoi(r2causestr) : 0;
+				openr2_call_disconnect_cause_t r2cause = r2cause_user ? dahdi_ast_cause_to_r2_cause(r2cause_user)
+					                                              : dahdi_ast_cause_to_r2_cause(ast->hangupcause);
+				openr2_chan_disconnect_call(p->r2chan, r2cause);
 			}
 			dahdi_r2_update_monitor_count(p->mfcr2, 1);
 		}
@@ -4558,8 +4765,21 @@
 #endif
 #ifdef HAVE_OPENR2
 	case SIG_MFCR2:
-		ast_log(LOG_DEBUG, "Accepting MFC/R2 call on chan %d\n", p->channel);
-		openr2_chan_answer_call(p->r2chan);
+		if (!p->mfcr2_call_accepted) {
+			/* The call was not accepted on offer nor the user, so it must be accepted now before answering,
+			   openr2_chan_answer_call will be called when the callback on_call_accepted is executed */
+			p->mfcr2_answer_pending = 1;
+			if (p->mfcr2_charge_calls) {
+				ast_log(LOG_DEBUG, "Accepting MFC/R2 call with charge before answering on chan %d\n", p->channel);
+				openr2_chan_accept_call(p->r2chan, OR2_CALL_WITH_CHARGE);
+			} else {
+				ast_log(LOG_DEBUG, "Accepting MFC/R2 call with no charge before answering on chan %d\n", p->channel);
+				openr2_chan_accept_call(p->r2chan, OR2_CALL_NO_CHARGE);
+			}
+		} else {
+			ast_log(LOG_DEBUG, "Answering MFC/R2 call on chan %d\n", p->channel);
+			openr2_chan_answer_call(p->r2chan);
+		}
 		break;
 #endif
 	case 0:
@@ -6871,6 +7091,14 @@
 	ast_mutex_lock(&p->lock);
 	idx = dahdi_get_index(chan, p, 0);
 	ast_debug(1, "Requested indication %d on channel %s\n", condition, chan->name);
+#ifdef HAVE_OPENR2
+	if (p->mfcr2 && !p->mfcr2_call_accepted) {
+		ast_mutex_unlock(&p->lock);
+		/* if this is an R2 call and the call is not yet accepted, we don't want the
+		   tone indications to mess up with the MF tones */
+		return 0;
+	}	
+#endif
 	if (idx == SUB_REAL) {
 		switch (condition) {
 		case AST_CONTROL_BUSY:
@@ -9821,6 +10049,7 @@
 				tmp->mfcr2_charge_calls = conf->mfcr2.charge_calls;
 				tmp->mfcr2_allow_collect_calls = conf->mfcr2.allow_collect_calls;
 				tmp->mfcr2_forced_release = conf->mfcr2.forced_release;
+				tmp->mfcr2_accept_on_offer = conf->mfcr2.accept_on_offer;
 				tmp->mfcr2call = 0;
 				tmp->mfcr2_dnis_index = 0;
 				tmp->mfcr2_ani_index = 0;
@@ -14336,6 +14565,7 @@
 				ast_cli(a->fd, "MFC/R2 Max DNIS: %d\n", openr2_context_get_max_dnis(r2context));
 				ast_cli(a->fd, "MFC/R2 Get ANI First: %s\n", openr2_context_get_ani_first(r2context) ? "Yes" : "No");
 				ast_cli(a->fd, "MFC/R2 Immediate Accept: %s\n", openr2_context_get_immediate_accept(r2context) ? "Yes" : "No");
+				ast_cli(a->fd, "MFC/R2 Accept on Offer: %s\n", tmp->mfcr2_accept_on_offer ? "Yes" : "No");
 				ast_cli(a->fd, "MFC/R2 Charge Calls: %s\n", tmp->mfcr2_charge_calls ? "Yes" : "No");
 				ast_cli(a->fd, "MFC/R2 Allow Collect Calls: %s\n", tmp->mfcr2_allow_collect_calls ? "Yes" : "No");
 				ast_cli(a->fd, "MFC/R2 Forced Release: %s\n", tmp->mfcr2_forced_release ? "Yes" : "No");
@@ -15453,6 +15683,7 @@
 #if defined(HAVE_OPENR2)
 	dahdi_r2_destroy_links();
 	ast_cli_unregister_multiple(dahdi_mfcr2_cli, ARRAY_LEN(dahdi_mfcr2_cli));
+	ast_unregister_application(dahdi_accept_r2_call_app);
 #endif
 
 	ast_cli_unregister_multiple(dahdi_cli, ARRAY_LEN(dahdi_cli));
@@ -16443,6 +16674,8 @@
 				confp->mfcr2.double_answer = ast_true(v->value);
 			} else if (!strcasecmp(v->name, "mfcr2_charge_calls")) {
 				confp->mfcr2.charge_calls = ast_true(v->value);
+			} else if (!strcasecmp(v->name, "mfcr2_accept_on_offer")) {
+				confp->mfcr2.accept_on_offer = ast_true(v->value);
 			} else if (!strcasecmp(v->name, "mfcr2_allow_collect_calls")) {
 				confp->mfcr2.allow_collect_calls = ast_true(v->value);
 			} else if (!strcasecmp(v->name, "mfcr2_forced_release")) {
@@ -16922,6 +17155,7 @@
 #endif
 #ifdef HAVE_OPENR2
 	ast_cli_register_multiple(dahdi_mfcr2_cli, sizeof(dahdi_mfcr2_cli)/sizeof(dahdi_mfcr2_cli[0]));
+	ast_register_application_xml(dahdi_accept_r2_call_app, dahdi_accept_r2_call_exec);
 #endif
 
 	ast_cli_register_multiple(dahdi_cli, ARRAY_LEN(dahdi_cli));

Modified: team/moy/mfcr2/configs/chan_dahdi.conf.sample
URL: http://svn.digium.com/svn-view/asterisk/team/moy/mfcr2/configs/chan_dahdi.conf.sample?view=diff&rev=176494&r1=176493&r2=176494
==============================================================================
--- team/moy/mfcr2/configs/chan_dahdi.conf.sample (original)
+++ team/moy/mfcr2/configs/chan_dahdi.conf.sample Mon Feb 16 23:30:08 2009
@@ -1104,6 +1104,18 @@
 ; to the accepted state for incoming calls
 ; mfcr2_immediate_accept=no
 
+; You most likely dont need this feature. Default is yes.
+; When this is set to yes, all calls that are offered (incoming calls) which
+; DNIS is valid (exists in extensions.conf) and pass collect call validation 
+; will be accepted with a Group B tone (either call with charge or not, depending on mfcr2_charge_calls)
+; with this set to 'no' then the call will NOT be accepted on offered, and the call will start its
+; execution in extensions.conf without being accepted until the channel is answered (either with Answer() or
+; any other application resulting in the channel being answered). 
+; This can be set to 'no' if your telco or PBX needs the hangup cause to be set accurately
+; when this option is set to no you must explicitly accept the call with DAHDIAcceptR2Call
+; or implicitly through the Answer() application. 
+; mfcr2_accept_on_offer=yes
+
 ; WARNING: advanced users only! I really mean it
 ; this parameter is commented by default because
 ; YOU DON'T NEED IT UNLESS YOU REALLY GROK MFC/R2
@@ -1124,6 +1136,8 @@
 ; leave the default (yes), but once in a while when interconnecting with
 ; old PBXs this may be useful.
 ; Concretely this affects the Group B signal used to accept calls
+; The application DAHDIAcceptR2Call can also be used to decide this
+; in the dial plan in a per-call basis instead of doing it here for all calls
 ; mfcr2_charge_calls=yes
 
 ; ---------------- END of options to be used with signalling=mfcr2




More information about the asterisk-commits mailing list