[asterisk-commits] moy: branch moy/mfcr2-1.2 r145016 - /team/moy/mfcr2-1.2/channels/chan_zap.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sat Sep 27 19:32:41 CDT 2008


Author: moy
Date: Sat Sep 27 19:32:40 2008
New Revision: 145016

URL: http://svn.digium.com/view/asterisk?view=rev&rev=145016
Log:
Added support to match extensions after each digit received. This will improve call setup time.

Modified:
    team/moy/mfcr2-1.2/channels/chan_zap.c

Modified: team/moy/mfcr2-1.2/channels/chan_zap.c
URL: http://svn.digium.com/view/asterisk/team/moy/mfcr2-1.2/channels/chan_zap.c?view=diff&rev=145016&r1=145015&r2=145016
==============================================================================
--- team/moy/mfcr2-1.2/channels/chan_zap.c (original)
+++ team/moy/mfcr2-1.2/channels/chan_zap.c Sat Sep 27 19:32:40 2008
@@ -807,6 +807,9 @@
 	openr2_calling_party_category_t mfcr2_category;
 	int mfcr2_allow_collect_calls;
 	int mfcr2_forced_release;
+	int mfcr2_dnis_index;
+	int mfcr2_ani_index;
+	int mfcr2_dnis_matched;
 #endif
 
 	struct zt_distRings drings;
@@ -1341,11 +1344,27 @@
 
 static void zt_r2_on_call_init(openr2_chan_t *r2chan)
 {
-	/* TODO: how do we know that an external thread (just finished zt_request) is not requesting this very same
-	   interface but has not yet seized the line, and if we DO know, what to do here? */
 	struct zt_pvt *p = openr2_chan_get_client_data(r2chan);
 	ast_mutex_lock(&p->lock);
+	if (p->mfcr2call) {
+		ast_mutex_unlock(&p->lock);
+		/* TODO: This can happen when some other thread just finished zt_request requesting this very same
+		interface but has not yet seized the line (zt_call), and the far end wins and seize the line,
+		can we avoid this somehow?, at this point when zt_call send the seize, it is likely that since
+		the other end will see our seize as a forced release and drop the call, we will see an invalid
+		pattern that will be seen and treated as protocol error. */
+		ast_log(LOG_ERROR, "Collision of calls on chan %d detected!.\n", openr2_chan_get_number(r2chan));
+		return;
+	}
 	p->mfcr2call = 1;
+	/* better safe than sorry ... */
+	p->cid_name[0] = 0;
+	p->cid_num[0] = 0;
+	p->rdnis[0] = 0;
+	p->exten[0] = 0;
+	p->mfcr2_ani_index = 0;
+	p->mfcr2_dnis_index = 0;
+	p->mfcr2_dnis_matched = 0;
 	ast_mutex_unlock(&p->lock);
 	ast_log(LOG_NOTICE, "New MFC/R2 call detected on chan %d.\n", openr2_chan_get_number(r2chan));
 }
@@ -1391,19 +1410,17 @@
 	}
 	ast_mutex_lock(&p->lock);
 	p->mfcr2_recvd_category = category;
-	if (p->use_callerid && ani) {
-		ast_copy_string(p->cid_num, ani, sizeof(p->cid_num));
-		ast_copy_string(p->cid_name, ani, sizeof(p->cid_name));
-	} else {
+	/* if we're not supposed to use CID, clear whatever we have */
+	if (!p->use_callerid) {
+		ast_log(LOG_DEBUG, "No CID allowed in configuration, CID is being cleared!\n");
 		p->cid_num[0] = 0;
-		p->cid_num[0] = 0;
-	}
-	ast_copy_string(p->rdnis, dnis, sizeof(p->rdnis));
+		p->cid_name[0] = 0;
+	}
+	/* if we're supposed to answer immediately, clear DNIS and set 's' exten */
 	if (p->immediate || !openr2_context_get_max_dnis(openr2_chan_get_context(r2chan))) {
-		ast_log(LOG_DEBUG, "setting exten => s because of immediate or 0 DNIS configured\n");
-		ast_copy_string(p->exten, "s", sizeof(p->exten));
-	} else {
-		ast_copy_string(p->exten, dnis, sizeof(p->exten));
+		ast_log(LOG_DEBUG, "Setting exten => s because of immediate or 0 DNIS configured\n");
+		p->exten[0] = 's';
+		p->exten[1] = 0;
 	}
 	ast_mutex_unlock(&p->lock);
 	if (!ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num)) {
@@ -1504,7 +1521,7 @@
 	}	
 }
 
-static void zt_r2_on_call_disconnected(openr2_chan_t *r2chan, openr2_call_disconnect_cause_t cause)
+static void zt_r2_on_call_disconnect(openr2_chan_t *r2chan, openr2_call_disconnect_cause_t cause)
 {
 	struct zt_pvt *p = openr2_chan_get_client_data(r2chan);
 	ast_log(LOG_NOTICE, "MFC/R2 call disconnected on chan %d\n", openr2_chan_get_number(r2chan));
@@ -1581,7 +1598,7 @@
 	ast_log(LOG_NOTICE, "Far end unblocked on chan %d\n", openr2_chan_get_number(r2chan));
 }
 
-static void zt_r2_on_context_logging(openr2_context_t *r2context, openr2_log_level_t level, const char *fmt, va_list ap)
+static void zt_r2_on_context_log(openr2_context_t *r2context, openr2_log_level_t level, const char *fmt, va_list ap)
 {
 	char logmsg[256];
 	char completemsg[sizeof(logmsg)+50];
@@ -1599,20 +1616,64 @@
 	zt_r2_write_log(level, completemsg);
 }
 
+static int zt_r2_on_dnis_digit_received(openr2_chan_t *r2chan, char digit)
+{
+	struct zt_pvt *p = openr2_chan_get_client_data(r2chan);
+	/* if 'immediate' is set, let's stop requesting DNIS */
+	if (p->immediate) {
+		return 0;
+	}
+	p->exten[p->mfcr2_dnis_index] = digit;
+	p->rdnis[p->mfcr2_dnis_index] = digit;
+	p->mfcr2_dnis_index++;
+	p->exten[p->mfcr2_dnis_index] = 0;
+	p->rdnis[p->mfcr2_dnis_index] = 0;
+	/*
+	ast_log(LOG_DEBUG, "Got digit %c in zap, dnis so far: %s\n", digit, p->exten);
+	int ret;
+	ret = ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num);
+	ast_log(LOG_DEBUG, "ast_exists_extension(%s, %s, 1, %s) = %d\n", p->context, p->exten, p->cid_num, ret);
+	ret = ast_matchmore_extension(NULL, p->context, p->exten, 1, p->cid_num);
+	ast_log(LOG_DEBUG, "ast_matchmore_extension(%s, %s, 1, %s) = %d\n", p->context, p->exten, p->cid_num, ret);
+	*/
+	/* if the DNIS is a match and cannot match more, stop requesting DNIS */
+	if ((p->mfcr2_dnis_matched || 
+	    (ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num) && (p->mfcr2_dnis_matched = 1))) &&
+	    !ast_matchmore_extension(NULL, p->context, p->exten, 1, p->cid_num)) {
+		return 0;
+	}
+	/* otherwise keep going */
+	return 1;
+}
+
+static void zt_r2_on_ani_digit_received(openr2_chan_t *r2chan, char digit)
+{
+	struct zt_pvt *p = openr2_chan_get_client_data(r2chan);
+	p->cid_num[p->mfcr2_ani_index] = digit;
+	p->cid_name[p->mfcr2_ani_index] = digit;
+	p->mfcr2_ani_index++;
+	p->cid_num[p->mfcr2_ani_index] = 0;
+	p->cid_name[p->mfcr2_ani_index] = 0;
+}
+
 static openr2_event_interface_t zt_r2_event_iface = {
-	zt_r2_on_call_init,
-	zt_r2_on_call_offered,
-	zt_r2_on_call_accepted,
-	zt_r2_on_call_answered,
-	zt_r2_on_call_disconnected,
-	zt_r2_on_call_end,
-	zt_r2_on_call_read,
-	zt_r2_on_hardware_alarm,
-	zt_r2_on_os_error,
-	zt_r2_on_protocol_error,
-	zt_r2_on_line_blocked,
-	zt_r2_on_line_idle,
-	zt_r2_on_context_logging
+	.on_call_init = zt_r2_on_call_init,
+	.on_call_offered = zt_r2_on_call_offered,
+	.on_call_accepted = zt_r2_on_call_accepted,
+	.on_call_answered = zt_r2_on_call_answered,
+	.on_call_disconnect = zt_r2_on_call_disconnect,
+	.on_call_end = zt_r2_on_call_end,
+	.on_call_read = zt_r2_on_call_read,
+	.on_hardware_alarm = zt_r2_on_hardware_alarm,
+	.on_os_error = zt_r2_on_os_error,
+	.on_protocol_error = zt_r2_on_protocol_error,
+	.on_line_blocked = zt_r2_on_line_blocked,
+	.on_line_idle = zt_r2_on_line_idle,
+	.on_context_log = zt_r2_on_context_log,
+	.on_dnis_digit_received = zt_r2_on_dnis_digit_received,
+	.on_ani_digit_received = zt_r2_on_ani_digit_received,
+	/* so far we do nothing with billing pulses */
+	.on_billing_pulse_received = NULL
 };
 
 static inline int16_t zt_r2_alaw_to_linear(uint8_t sample)
@@ -7532,6 +7593,8 @@
 					tmp->mfcr2_category = mfcr2_cur_category;
 					tmp->mfcr2 = zap_r2;
 					tmp->mfcr2call = 0;
+					tmp->mfcr2_ani_index = 0;
+					tmp->mfcr2_dnis_index = 0;
 					tmp->mfcr2_allow_collect_calls = mfcr2_cur_allow_collect_calls;
 					tmp->mfcr2_forced_release = mfcr2_cur_forced_release;
 					zap_r2->monitored_count++;
@@ -11497,8 +11560,14 @@
 				mfcr2_cur_call_files = ast_true(v->value);
 			} else if (!strcasecmp(v->name, "mfcr2_max_ani")) {
 				mfcr2_cur_max_ani = atoi(v->value);
+				if (mfcr2_cur_max_ani >= AST_MAX_EXTENSION) {
+					mfcr2_cur_max_ani = AST_MAX_EXTENSION - 1;
+				}
 			} else if (!strcasecmp(v->name, "mfcr2_max_dnis")) {
 				mfcr2_cur_max_dnis = atoi(v->value);
+				if (mfcr2_cur_max_dnis >= AST_MAX_EXTENSION) {
+					mfcr2_cur_max_dnis = AST_MAX_EXTENSION - 1;
+				}
 			} else if (!strcasecmp(v->name, "mfcr2_category")) {
 				mfcr2_cur_category = openr2_proto_get_category(v->value);
 				if (OR2_CALLING_PARTY_CATEGORY_UNKNOWN == mfcr2_cur_category) {




More information about the asterisk-commits mailing list