[asterisk-commits] moy: branch moy/mfcr2-1.4 r172068 - in /team/moy/mfcr2-1.4: channels/ configs/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Jan 28 15:09:59 CST 2009
Author: moy
Date: Wed Jan 28 15:09:58 2009
New Revision: 172068
URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=172068
Log:
added mfcr2_accept_on_offer experimental option
Modified:
team/moy/mfcr2-1.4/channels/chan_dahdi.c
team/moy/mfcr2-1.4/configs/chan_dahdi.conf.sample
Modified: team/moy/mfcr2-1.4/channels/chan_dahdi.c
URL: http://svn.digium.com/svn-view/asterisk/team/moy/mfcr2-1.4/channels/chan_dahdi.c?view=diff&rev=172068&r1=172067&r2=172068
==============================================================================
--- team/moy/mfcr2-1.4/channels/chan_dahdi.c (original)
+++ team/moy/mfcr2-1.4/channels/chan_dahdi.c Wed Jan 28 15:09:58 2009
@@ -320,6 +320,7 @@
static int mfcr2_cur_context_index = 0;
static int mfcr2_cur_call_files = 0;
static int mfcr2_cur_allow_collect_calls = 0;
+static int mfcr2_cur_accept_on_offer = 1;
static int mfcr2_cur_charge_calls = 1;
static int mfcr2_cur_forced_release = 0;
static int mfcr2_cur_double_answer = 0;
@@ -625,12 +626,14 @@
openr2_chan_t *r2chan;
openr2_calling_party_category_t mfcr2_recvd_category;
openr2_calling_party_category_t mfcr2_category;
+ int mfcr2_accept_on_offer;
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 mfcr2_call_accepted;
#endif
int polarity;
int dsp_features;
@@ -989,6 +992,7 @@
p->mfcr2_ani_index = 0;
p->mfcr2_dnis_index = 0;
p->mfcr2_dnis_matched = 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));
}
@@ -1035,9 +1039,28 @@
ast_mutex_unlock(&p->lock);
}
+static void dahdi_r2_update_monitor_count(struct zt_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 that lazy bastard.\n");
+ ast_cond_signal(&mfcr2->do_monitor);
+ }
+ } else {
+ mfcr2->monitored_count--;
+ if (mfcr2->monitored_count < 0) {
+ ast_log(LOG_ERROR, "wtf? 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));
p = openr2_chan_get_client_data(r2chan);
@@ -1066,9 +1089,23 @@
p->channel, p->exten, p->context);
openr2_chan_disconnect_call(r2chan, OR2_CAUSE_UNALLOCATED_NUMBER);
} else {
- if (p->mfcr2_charge_calls) {
+ /* if the user does not want to accept on offer, then we should launch the PBX thread now */
+ if (!p->mfcr2_accept_on_offer) {
+ 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));
+ /* Don't disable reading since we still need to generate MF tone to accept
+ the call or reject it and detect the tone off condition of the other end */
+ } else {
+ ast_log(LOG_WARNING, "Unable to start PBX on chan %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 on offer with charge on chan %d\n", p->channel);
openr2_chan_accept_call(r2chan, OR2_CALL_WITH_CHARGE);
} else {
+ ast_log(LOG_DEBUG, "Accepting MFC/R2 call on offer with no charge on chan %d\n", p->channel);
openr2_chan_accept_call(r2chan, OR2_CALL_NO_CHARGE);
}
}
@@ -1083,24 +1120,6 @@
ast_mutex_unlock(&p->lock);
}
-static void dahdi_r2_update_monitor_count(struct zt_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 that lazy bastard.\n");
- ast_cond_signal(&mfcr2->do_monitor);
- }
- } else {
- mfcr2->monitored_count--;
- if (mfcr2->monitored_count < 0) {
- ast_log(LOG_ERROR, "wtf? 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)
{
@@ -1109,18 +1128,29 @@
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 (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 and therefore this callback is being executed in the PBX thread rather than
+ the monitor thread, don't launch any other thread, just disable the R2 reading and
+ answer the call */
+ if (!p->mfcr2_accept_on_offer) {
+ openr2_chan_disable_read(r2chan);
+ ast_log(LOG_NOTICE, "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 */
openr2_chan_disable_read(r2chan);
+ pbx_builtin_setvar_helper(c, "MFCR2_CATEGORY", openr2_proto_get_category_string(p->mfcr2_recvd_category));
} else {
ast_log(LOG_WARNING, "Unable to start PBX on chan %d\n", p->channel);
openr2_chan_disconnect_call(r2chan, OR2_CAUSE_OUT_OF_ORDER);
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;
@@ -3005,6 +3035,46 @@
}
#endif
+#ifdef HAVE_OPENR2
+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;
@@ -3184,10 +3254,16 @@
#ifdef HAVE_OPENR2
if (p->mfcr2) {
ast_log(LOG_DEBUG, "disconnecting MFC/R2 call on chan %d\n", p->channel);
+ ast_log(LOG_DEBUG, "ast->hangupcause is %d\n", ast->hangupcause);
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);
}
@@ -3426,8 +3502,20 @@
#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_accept_on_offer) {
+ /* the call was not accepted on offer, so it must be accepted now before answering,
+ the answer will be executed when the callback on_call_accepted is executed */
+ if (p->mfcr2_charge_calls) {
+ ast_log(LOG_DEBUG, "Accepting MFC/R2 call before answering with charge 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 before answering with no charge 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:
@@ -5712,8 +5800,15 @@
int func = DAHDI_FLASH;
ast_mutex_lock(&p->lock);
index = dahdi_get_index(chan, p, 0);
- if (option_debug)
- ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name);
+ ast_log(LOG_DEBUG, "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 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 (index == SUB_REAL) {
switch (condition) {
case AST_CONTROL_BUSY:
@@ -8148,6 +8243,7 @@
tmp->mfcr2_category = mfcr2_cur_category;
tmp->mfcr2 = dahdi_r2;
tmp->mfcr2call = 0;
+ tmp->mfcr2_accept_on_offer = mfcr2_cur_accept_on_offer;
tmp->mfcr2_charge_calls = mfcr2_cur_charge_calls;
tmp->mfcr2_ani_index = 0;
tmp->mfcr2_dnis_index = 0;
@@ -11423,6 +11519,7 @@
ast_cli(fd, "MFC/R2 Max DNIS: %d\n", openr2_context_get_max_dnis(r2context));
ast_cli(fd, "MFC/R2 Get ANI First: %s\n", openr2_context_get_ani_first(r2context) ? "Yes" : "No");
ast_cli(fd, "MFC/R2 Immediate Accept: %s\n", openr2_context_get_immediate_accept(r2context) ? "Yes" : "No");
+ ast_cli(fd, "MFC/R2 Accept On Offer: %s\n", tmp->mfcr2_accept_on_offer ? "Yes" : "No");
ast_cli(fd, "MFC/R2 Charge Calls: %s\n", tmp->mfcr2_charge_calls ? "Yes" : "No");
ast_cli(fd, "MFC/R2 Allow Collect Calls: %s\n", tmp->mfcr2_allow_collect_calls ? "Yes" : "No");
ast_cli(fd, "MFC/R2 Forced Release: %s\n", tmp->mfcr2_forced_release ? "Yes" : "No");
@@ -12674,6 +12771,8 @@
mfcr2_cur_get_ani_first = ast_true(v->value);
} else if (!strcasecmp(v->name, "mfcr2_double_answer")) {
mfcr2_cur_double_answer = ast_true(v->value);
+ } else if (!strcasecmp(v->name, "mfcr2_accept_on_offer")) {
+ mfcr2_cur_accept_on_offer = ast_true(v->value);
} else if (!strcasecmp(v->name, "mfcr2_charge_calls")) {
mfcr2_cur_charge_calls = ast_true(v->value);
} else if (!strcasecmp(v->name, "mfcr2_allow_collect_calls")) {
Modified: team/moy/mfcr2-1.4/configs/chan_dahdi.conf.sample
URL: http://svn.digium.com/svn-view/asterisk/team/moy/mfcr2-1.4/configs/chan_dahdi.conf.sample?view=diff&rev=172068&r1=172067&r2=172068
==============================================================================
--- team/moy/mfcr2-1.4/configs/chan_dahdi.conf.sample (original)
+++ team/moy/mfcr2-1.4/configs/chan_dahdi.conf.sample Wed Jan 28 15:09:58 2009
@@ -770,6 +770,17 @@
; 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 is required to be 'no' if your telco needs the hangup cause to be set properly, or the PBX you
+; are connecting Asterisk to relies on the hangup cause to be used for billing purposes
+; 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
More information about the asterisk-commits
mailing list