[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