MODAPP-221

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@12262 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2009-02-24 18:36:45 +00:00
parent be15ed423f
commit 3dd6e878e7
3 changed files with 65 additions and 60 deletions

View File

@ -582,7 +582,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_new(switch_ivr_digit_str
\param stream a pointer to the stream object \param stream a pointer to the stream object
\return NULL if no match found or consumer data that was associated with a given digit string when matched \return NULL if no match found or consumer data that was associated with a given digit string when matched
*/ */
SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_destroy(switch_ivr_digit_stream_t *stream); SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_destroy(switch_ivr_digit_stream_t **stream);
/*! /*!
\brief Set a digit string to action mapping \brief Set a digit string to action mapping

View File

@ -33,7 +33,7 @@
* *
*/ */
#include <switch.h> #include <switch.h>
//#define INTENSE_DEBUG
SWITCH_MODULE_LOAD_FUNCTION(mod_conference_load); SWITCH_MODULE_LOAD_FUNCTION(mod_conference_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_conference_shutdown); SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_conference_shutdown);
SWITCH_MODULE_DEFINITION(mod_conference, mod_conference_load, mod_conference_shutdown, NULL); SWITCH_MODULE_DEFINITION(mod_conference, mod_conference_load, mod_conference_shutdown, NULL);
@ -1961,9 +1961,9 @@ static void conference_loop_output(conference_member_t *member)
#ifdef INTENSE_DEBUG #ifdef INTENSE_DEBUG
switch_log_printf(SWITCH_CHANNEL_LOG, switch_log_printf(SWITCH_CHANNEL_LOG,
SWITCH_LOG_INFO, SWITCH_LOG_INFO,
"executing caller control '%s' param '%s' on call '%u, %s, %s, %s'\n", "executing caller control '%s' param '%s' on call '%u, %s\n",
caller_action->fndesc->key, caller_action->fndesc->key,
param ? param : "none", member->id, switch_channel_get_name(channel), profile->caller_id_name, profile->caller_id_number); param ? param : "none", member->id, switch_channel_get_name(channel));
#endif #endif
caller_action->fndesc->handler(member, caller_action); caller_action->fndesc->handler(member, caller_action);
@ -2110,7 +2110,7 @@ static void conference_loop_output(conference_member_t *member)
} /* Rinse ... Repeat */ } /* Rinse ... Repeat */
if (member->digit_stream != NULL) { if (member->digit_stream != NULL) {
switch_ivr_digit_stream_destroy(member->digit_stream); switch_ivr_digit_stream_destroy(&member->digit_stream);
} }
switch_clear_flag_locked(member, MFLAG_RUNNING); switch_clear_flag_locked(member, MFLAG_RUNNING);

View File

@ -1388,6 +1388,7 @@ struct switch_ivr_digit_stream_parser {
switch_memory_pool_t *pool; switch_memory_pool_t *pool;
switch_hash_t *hash; switch_hash_t *hash;
switch_size_t maxlen; switch_size_t maxlen;
switch_size_t buflen;
switch_size_t minlen; switch_size_t minlen;
char terminator; char terminator;
unsigned int digit_timeout_ms; unsigned int digit_timeout_ms;
@ -1461,24 +1462,25 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_new(switch_ivr_digit_str
switch_status_t status = SWITCH_STATUS_FALSE; switch_status_t status = SWITCH_STATUS_FALSE;
/* if we have a parser object memory pool and a stream object pointer that is null */ /* if we have a parser object memory pool and a stream object pointer that is null */
if (parser != NULL && parser->pool && stream != NULL && *stream == NULL) { if (parser && stream && *stream == NULL) {
*stream = (switch_ivr_digit_stream_t *) switch_core_alloc(parser->pool, sizeof(switch_ivr_digit_stream_t)); *stream = (switch_ivr_digit_stream_t *) malloc(sizeof(**stream));
if (*stream != NULL) { switch_assert(*stream);
memset(*stream, 0, sizeof(switch_ivr_digit_stream_t)); memset(*stream, 0, sizeof(**stream));
status = SWITCH_STATUS_SUCCESS; switch_zmalloc((*stream)->digits, parser->buflen + 1);
} status = SWITCH_STATUS_SUCCESS;
} }
return status; return status;
} }
SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_destroy(switch_ivr_digit_stream_t *stream) SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_destroy(switch_ivr_digit_stream_t **stream)
{ {
switch_status_t status = SWITCH_STATUS_FALSE; switch_status_t status = SWITCH_STATUS_FALSE;
if (stream && stream->digits != NULL) { if (*stream) {
free(stream->digits); switch_safe_free((*stream)->digits);
stream->digits = NULL; free(*stream);
*stream = NULL;
status = SWITCH_STATUS_SUCCESS; status = SWITCH_STATUS_SUCCESS;
} }
@ -1499,6 +1501,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_parser_set_event(switch_
* figure out when a digit set is completed, therefore we * figure out when a digit set is completed, therefore we
* keep track of the min and max digit lengths * keep track of the min and max digit lengths
*/ */
if (len > parser->buflen) {
parser->buflen = len;
}
if (parser->terminator == '\0') { if (parser->terminator == '\0') {
if (len > parser->maxlen) { if (len > parser->maxlen) {
parser->maxlen = len; parser->maxlen = len;
@ -1541,65 +1548,63 @@ SWITCH_DECLARE(void *) switch_ivr_digit_stream_parser_feed(switch_ivr_digit_stre
{ {
void *result = NULL; void *result = NULL;
if (parser != NULL && stream != NULL) { switch_assert(parser);
switch_size_t len = (stream->digits != NULL ? strlen(stream->digits) : 0); switch_assert(stream);
switch_assert(stream->digits);
/* handle new digit arrivals */ switch_size_t len = strlen(stream->digits);
if (digit != '\0') {
/* if it's not a terminator digit, add it to the collected digits */ /* handle new digit arrivals */
if (digit != parser->terminator) { if (digit) {
/* if collected digits length >= the max length of the keys /* if it's not a terminator digit, add it to the collected digits */
* in the hash table, then left shift the digit string if (digit != parser->terminator) {
*/ /* if collected digits length >= the max length of the keys
if (len > 0 && parser->maxlen != 0 && len >= parser->maxlen) { * in the hash table, then left shift the digit string
char *src = stream->digits + 1;
char *dst = stream->digits;
while (*src) {
*(dst++) = *(src++);
}
*dst = digit;
} else {
char *tmp = realloc(stream->digits, len + 2);
switch_assert(tmp);
stream->digits = tmp;
*(stream->digits + (len++)) = digit;
*(stream->digits + len) = '\0';
stream->last_digit_time = switch_micro_time_now() / 1000;
}
}
}
/* don't allow collected digit string testing if there are varying sized keys until timeout */
if (parser->maxlen - parser->minlen > 0 && (switch_micro_time_now() / 1000) - stream->last_digit_time < parser->digit_timeout_ms) {
len = 0;
}
/* if we have digits to test */
if (len) {
result = switch_core_hash_find(parser->hash, stream->digits);
/* if we matched the digit string, or this digit is the terminator
* reset the collected digits for next digit string
*/ */
if (result != NULL || parser->terminator == digit) { if (len > 0 && parser->maxlen != 0 && len >= parser->maxlen) {
free(stream->digits); char *src = stream->digits + 1;
stream->digits = NULL; char *dst = stream->digits;
while (*src) {
*(dst++) = *(src++);
}
*dst = digit;
} else {
*(stream->digits + (len++)) = digit;
*(stream->digits + len) = '\0';
stream->last_digit_time = switch_micro_time_now() / 1000;
} }
} }
} }
/* don't allow collected digit string testing if there are varying sized keys until timeout */
if (parser->maxlen - parser->minlen > 0 && (switch_micro_time_now() / 1000) - stream->last_digit_time < parser->digit_timeout_ms) {
len = 0;
}
/* if we have digits to test */
if (len) {
result = switch_core_hash_find(parser->hash, stream->digits);
/* if we matched the digit string, or this digit is the terminator
* reset the collected digits for next digit string
*/
if (result != NULL || parser->terminator == digit) {
*stream->digits = '\0';
}
}
return result; return result;
} }
SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_reset(switch_ivr_digit_stream_t *stream) SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_reset(switch_ivr_digit_stream_t *stream)
{ {
switch_status_t status = SWITCH_STATUS_FALSE; switch_status_t status = SWITCH_STATUS_FALSE;
switch_assert(stream);
switch_assert(stream->digits);
if (stream != NULL && stream->digits != NULL) { *stream->digits = '\0';
free(stream->digits); stream->last_digit_time = 0;
stream->digits = NULL; status = SWITCH_STATUS_SUCCESS;
stream->last_digit_time = 0;
status = SWITCH_STATUS_SUCCESS;
}
return status; return status;
} }