fix iax and add regex dialplan
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@381 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
b243f79024
commit
54664b3dab
|
@ -66,7 +66,7 @@ void gettimeofday(struct timeval *tv, void /*struct timezone*/ *tz);
|
|||
#include "jitterbuf.h"
|
||||
#endif
|
||||
|
||||
typedef long time_in_ms_t;
|
||||
typedef int64_t time_in_ms_t;
|
||||
|
||||
#include "iax-client.h"
|
||||
#include "md5.h"
|
||||
|
|
|
@ -17,3 +17,4 @@ endpoints/mod_woomera
|
|||
event_handlers/mod_xmpp_event
|
||||
formats/mod_sndfile
|
||||
timers/mod_softtimer
|
||||
dialplans/mod_pcre
|
||||
|
|
|
@ -74,6 +74,8 @@ struct switch_config {
|
|||
char buf[1024];
|
||||
/*! current line number in file */
|
||||
int lineno;
|
||||
/*! current category number in file */
|
||||
int catno;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
|
|
@ -33,26 +33,33 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <pcre.h>
|
||||
|
||||
static const char modname[] = "mod_pcre";
|
||||
|
||||
#define cleanre() if (re) {\
|
||||
pcre_free(re);\
|
||||
re = NULL;\
|
||||
}
|
||||
|
||||
switch_caller_extension *dialplan_hunt(switch_core_session *session)
|
||||
{
|
||||
switch_caller_profile *caller_profile;
|
||||
switch_caller_extension *extension = NULL;
|
||||
switch_channel *channel;
|
||||
char *cf = "extensions.conf";
|
||||
char *cf = "regextensions.conf";
|
||||
switch_config cfg;
|
||||
char *var, *val;
|
||||
char app[1024];
|
||||
char app[1024] = "";
|
||||
int catno = -1;
|
||||
char *regex = NULL;
|
||||
char *exten_name = NULL;
|
||||
pcre *re = NULL;
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
caller_profile = switch_channel_get_caller_profile(channel);
|
||||
//switch_channel_set_variable(channel, "pleasework", "yay");
|
||||
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hello %s You Dialed %s!\n", caller_profile->caller_id_name, caller_profile->destination_number);
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Processing %s->%s!\n", caller_profile->caller_id_name, caller_profile->destination_number);
|
||||
|
||||
if (!switch_config_open_file(&cfg, cf)) {
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "open of %s failed\n", cf);
|
||||
|
@ -61,12 +68,80 @@ switch_caller_extension *dialplan_hunt(switch_core_session *session)
|
|||
}
|
||||
|
||||
while (switch_config_next_pair(&cfg, &var, &val)) {
|
||||
if (!strcasecmp(cfg.category, "extensions")) {
|
||||
if (!strcmp(var, caller_profile->destination_number) && val) {
|
||||
if (cfg.catno != catno) { /* new category */
|
||||
regex = NULL;
|
||||
catno = cfg.catno;
|
||||
exten_name = cfg.category;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!strcasecmp(var, "regex")) {
|
||||
const char *error = NULL;
|
||||
int erroffset = 0;
|
||||
|
||||
cleanre();
|
||||
re = pcre_compile(
|
||||
val, /* the pattern */
|
||||
0, /* default options */
|
||||
&error, /* for error message */
|
||||
&erroffset, /* for error offset */
|
||||
NULL); /* use default character tables */
|
||||
if (error) {
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "ERROR: %d %s\n", erroffset, error);
|
||||
cleanre();
|
||||
return NULL;
|
||||
}
|
||||
} else if (!strcasecmp(var, "match")) {
|
||||
int rc;
|
||||
int ovector[30];
|
||||
|
||||
rc = pcre_exec(
|
||||
re, /* result of pcre_compile() */
|
||||
NULL, /* we didn't study the pattern */
|
||||
caller_profile->destination_number, /* the subject string */
|
||||
strlen(caller_profile->destination_number), /* the length of the subject string */
|
||||
0, /* start at offset 0 in the subject */
|
||||
0, /* default options */
|
||||
ovector, /* vector of integers for substring information */
|
||||
sizeof(ovector) / sizeof(ovector[0])); /* number of elements (NOT size in bytes) */
|
||||
|
||||
|
||||
if (rc > 0) {
|
||||
char newval[1024] = "";
|
||||
char index[10] = "";
|
||||
char replace[128] = "";
|
||||
int x, y=0, z=0, num = 0;
|
||||
char *data;
|
||||
|
||||
|
||||
for (x = 0; x < sizeof(newval) && x < strlen(val);) {
|
||||
if (val[x] == '$') {
|
||||
x++;
|
||||
|
||||
while(val[x] > 47 && val[x] < 58) {
|
||||
index[z++] = val[x];
|
||||
x++;
|
||||
}
|
||||
index[z++] = '\0';
|
||||
z = 0;
|
||||
num = atoi(index);
|
||||
|
||||
if (pcre_copy_substring(caller_profile->destination_number, ovector, rc, num, replace, sizeof(replace)) > 0) {
|
||||
int r;
|
||||
for(r = 0; r < strlen(replace); r++) {
|
||||
newval[y++] = replace[r];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
newval[y++] = val[x];
|
||||
x++;
|
||||
}
|
||||
}
|
||||
newval[y++] = '\0';
|
||||
|
||||
memset(app, 0, sizeof(app));
|
||||
strncpy(app, val, sizeof(app));
|
||||
switch_copy_string(app, newval, sizeof(app));
|
||||
|
||||
if ((data = strchr(app, ' '))) {
|
||||
*data = '\0';
|
||||
|
@ -75,16 +150,20 @@ switch_caller_extension *dialplan_hunt(switch_core_session *session)
|
|||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "invalid extension on line %d\n", cfg.lineno);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (!extension) {
|
||||
if (!(extension = switch_caller_extension_new(session, caller_profile->destination_number, caller_profile->destination_number))) {
|
||||
if (!(extension = switch_caller_extension_new(session, exten_name, caller_profile->destination_number))) {
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "memory error!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch_caller_extension_add_application(session, extension, app, data);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
switch_config_close_file(&cfg);
|
||||
|
@ -95,12 +174,13 @@ switch_caller_extension *dialplan_hunt(switch_core_session *session)
|
|||
switch_channel_hangup(channel);
|
||||
}
|
||||
|
||||
cleanre();
|
||||
return extension;
|
||||
}
|
||||
|
||||
|
||||
static const switch_dialplan_interface dialplan_interface = {
|
||||
/*.interface_name =*/ "demo",
|
||||
/*.interface_name =*/ "pcre",
|
||||
/*.hunt_function = */ dialplan_hunt
|
||||
/*.next = NULL */
|
||||
};
|
||||
|
|
|
@ -88,7 +88,7 @@ struct private_object {
|
|||
unsigned int codecs;
|
||||
unsigned short samprate;
|
||||
switch_mutex_t *mutex;
|
||||
switch_thread_cond_t *cond;
|
||||
//switch_thread_cond_t *cond;
|
||||
};
|
||||
|
||||
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan)
|
||||
|
@ -434,8 +434,8 @@ static switch_status channel_on_init(switch_core_session *session)
|
|||
switch_set_flag(tech_pvt, TFLAG_IO);
|
||||
|
||||
switch_mutex_init(&tech_pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
|
||||
switch_thread_cond_create(&tech_pvt->cond, switch_core_session_get_pool(session));
|
||||
switch_mutex_lock(tech_pvt->mutex);
|
||||
//switch_thread_cond_create(&tech_pvt->cond, switch_core_session_get_pool(session));
|
||||
//switch_mutex_lock(tech_pvt->mutex);
|
||||
|
||||
/* Move Channel's State Machine to RING */
|
||||
switch_channel_set_state(channel, CS_RING);
|
||||
|
@ -489,7 +489,8 @@ static switch_status channel_on_hangup(switch_core_session *session)
|
|||
assert(tech_pvt != NULL);
|
||||
|
||||
switch_clear_flag(tech_pvt, TFLAG_IO);
|
||||
switch_thread_cond_signal(tech_pvt->cond);
|
||||
switch_clear_flag(tech_pvt, TFLAG_VOICE);
|
||||
//switch_thread_cond_signal(tech_pvt->cond);
|
||||
|
||||
if (tech_pvt->read_codec.implementation) {
|
||||
switch_core_codec_destroy(&tech_pvt->read_codec);
|
||||
|
@ -526,7 +527,7 @@ static switch_status channel_kill_channel(switch_core_session *session, int sig)
|
|||
switch_clear_flag(tech_pvt, TFLAG_IO);
|
||||
switch_clear_flag(tech_pvt, TFLAG_VOICE);
|
||||
switch_channel_hangup(channel);
|
||||
switch_thread_cond_signal(tech_pvt->cond);
|
||||
//switch_thread_cond_signal(tech_pvt->cond);
|
||||
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s CHANNEL KILL\n", switch_channel_get_name(channel));
|
||||
|
||||
|
@ -663,25 +664,26 @@ static switch_status channel_read_frame(switch_core_session *session, switch_fra
|
|||
tech_pvt = switch_core_session_get_private(session);
|
||||
assert(tech_pvt != NULL);
|
||||
|
||||
for(;;) {
|
||||
if (switch_test_flag(tech_pvt, TFLAG_IO)) {
|
||||
switch_thread_cond_wait(tech_pvt->cond, tech_pvt->mutex);
|
||||
if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (switch_test_flag(tech_pvt, TFLAG_IO)) {
|
||||
switch_clear_flag(tech_pvt, TFLAG_VOICE);
|
||||
if(!tech_pvt->read_frame.datalen) {
|
||||
continue;
|
||||
}
|
||||
|
||||
*frame = &tech_pvt->read_frame;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
while (switch_test_flag(tech_pvt, TFLAG_IO)) {
|
||||
//switch_thread_cond_wait(tech_pvt->cond, tech_pvt->mutex);
|
||||
if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
if (switch_test_flag(tech_pvt, TFLAG_IO) && switch_test_flag(tech_pvt, TFLAG_VOICE)) {
|
||||
switch_clear_flag(tech_pvt, TFLAG_VOICE);
|
||||
if(!tech_pvt->read_frame.datalen) {
|
||||
continue;
|
||||
}
|
||||
|
||||
*frame = &tech_pvt->read_frame;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
switch_yield(1000);
|
||||
}
|
||||
|
||||
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -999,7 +1001,7 @@ SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void)
|
|||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Hangup %s\n", switch_channel_get_name(channel));
|
||||
switch_set_flag(tech_pvt, TFLAG_HANGUP);
|
||||
switch_channel_hangup(channel);
|
||||
switch_thread_cond_signal(tech_pvt->cond);
|
||||
//switch_thread_cond_signal(tech_pvt->cond);
|
||||
iaxevent->session = NULL;
|
||||
} else {
|
||||
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "No Session? %s\n", switch_test_flag(tech_pvt, TFLAG_VOICE) ? "yes" : "no");
|
||||
|
@ -1012,13 +1014,16 @@ SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void)
|
|||
break;
|
||||
case IAX_EVENT_VOICE:
|
||||
if (tech_pvt && (tech_pvt->read_frame.datalen = iaxevent->datalen)) {
|
||||
int bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame;
|
||||
int frames = (int)(tech_pvt->read_frame.datalen / bytes);
|
||||
tech_pvt->read_frame.samples = frames * tech_pvt->read_codec.implementation->samples_per_frame;
|
||||
memcpy(tech_pvt->read_frame.data, iaxevent->data, iaxevent->datalen);
|
||||
/* wake up the i/o thread*/
|
||||
switch_set_flag(tech_pvt, TFLAG_VOICE);
|
||||
switch_thread_cond_signal(tech_pvt->cond);
|
||||
switch_channel *channel;
|
||||
if ((channel = switch_core_session_get_channel(tech_pvt->session)) && switch_channel_get_state(channel) <= CS_HANGUP) {
|
||||
int bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame;
|
||||
int frames = (int)(tech_pvt->read_frame.datalen / bytes);
|
||||
tech_pvt->read_frame.samples = frames * tech_pvt->read_codec.implementation->samples_per_frame;
|
||||
memcpy(tech_pvt->read_frame.data, iaxevent->data, iaxevent->datalen);
|
||||
/* wake up the i/o thread*/
|
||||
switch_set_flag(tech_pvt, TFLAG_VOICE);
|
||||
//switch_thread_cond_signal(tech_pvt->cond);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IAX_EVENT_TRANSFER:
|
||||
|
|
|
@ -97,6 +97,7 @@ SWITCH_DECLARE(int) switch_config_next_pair(switch_config *cfg, char **var, char
|
|||
*end = '\0';
|
||||
(*var)++;
|
||||
switch_copy_string(cfg->category, *var, sizeof(cfg->category));
|
||||
cfg->catno++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue