git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@1433 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2006-05-11 21:11:20 +00:00
parent 64c80bd894
commit 174ad6edc8
3 changed files with 279 additions and 22 deletions

View File

@ -758,10 +758,28 @@ SWITCH_DECLARE(switch_codec_t *) switch_core_session_get_write_codec(switch_core
/*!
\brief Open a core db (SQLite) file
\param filename the path to the db file to open
\return
\return the db handle
*/
SWITCH_DECLARE(switch_core_db_t *) switch_core_db_open_file(char *filename);
/*!
\brief Execute a sql stmt until it is accepted
\param db the db handle
\param sql the sql to execute
\param retries the number of retries to use
\return SWITCH_STATUS_SUCCESS if successful
*/
SWITCH_DECLARE(switch_status_t) switch_core_db_persistant_execute(switch_core_db_t *db, char *sql, uint32_t retries);
/*!
\brief perform a test query then perform a reactive query if the first one fails
\param db the db handle
\param test_sql the test sql
\param reactive_sql the reactive sql
*/
SWITCH_DECLARE(void) switch_core_db_test_reactive(switch_core_db_t *db, char *test_sql, char *reactive_sql);
#define SWITCH_CORE_DB "core"
/*!
\brief Open the default system database

View File

@ -77,6 +77,13 @@ typedef enum {
#define PACKET_LEN 160
#define DEFAULT_BYTES_PER_FRAME 160
struct reg_element {
char *key;
char *url;
switch_time_t expires;
int tid;
};
static struct {
int debug;
int bytes_per_frame;
@ -94,6 +101,8 @@ static struct {
int codec_ms;
int dtmf_duration;
unsigned int flags;
switch_mutex_t *reg_mutex;
switch_core_db_t *db;
} globals;
struct private_object {
@ -125,6 +134,14 @@ struct private_object {
static char create_interfaces_sql[] =
"CREATE TABLE sip_registrations (\n"
" key VARCHAR(255),\n"
" url VARCHAR(255),\n"
" expires INTEGER(8)"
");\n";
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan)
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_extrtpip, globals.extrtpip)
@ -886,6 +903,51 @@ static const switch_loadable_module_interface_t exosip_module_interface = {
/*.application_interface */ NULL
};
struct callback_t {
char *val;
switch_size_t len;
int matches;
};
static int find_callback(void *pArg, int argc, char **argv, char **columnNames){
struct callback_t *cbt = (struct callback_t *) pArg;
switch_copy_string(cbt->val, argv[0], cbt->len);
cbt->matches++;
return 0;
}
static char *find_reg_url(switch_core_db_t *db, char *key, char *val, switch_size_t len)
{
char *errmsg;
switch_core_db_t *udb = NULL;
struct callback_t cbt = {0};
if (db) {
udb = db;
} else {
udb = switch_core_db_handle();
}
cbt.val = val;
cbt.len = len;
snprintf(val, len, "select url from sip_registrations where key='%s'", key);
switch_core_db_exec(udb, val, find_callback, &cbt, &errmsg);
if (errmsg) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR [%s][%s]\n", val, errmsg);
switch_core_db_free(errmsg);
errmsg = NULL;
}
if (!db) {
switch_core_db_close(udb);
}
return cbt.matches ? val : NULL;
}
static switch_status_t exosip_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t *pool)
{
@ -910,7 +972,8 @@ static switch_status_t exosip_outgoing_channel(switch_core_session_t *session, s
if (outbound_profile) {
char name[128];
switch_caller_profile_t *caller_profile = NULL;
char tmp[1024];
char *url;
if (*outbound_profile->destination_number == '!') {
char *p;
@ -933,6 +996,13 @@ static switch_status_t exosip_outgoing_channel(switch_core_session_t *session, s
caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
switch_mutex_lock(globals.reg_mutex);
if (!strchr(caller_profile->destination_number, '@') && (url = find_reg_url(NULL, caller_profile->destination_number, tmp, sizeof(tmp)))) {
caller_profile->rdnis = switch_core_session_strdup(*new_session, caller_profile->destination_number);
caller_profile->destination_number = switch_core_session_strdup(*new_session, url);
}
switch_mutex_unlock(globals.reg_mutex);
switch_channel_set_caller_profile(channel, caller_profile);
tech_pvt->caller_profile = caller_profile;
} else {
@ -953,20 +1023,31 @@ static switch_status_t exosip_outgoing_channel(switch_core_session_t *session, s
SWITCH_MOD_DECLARE(switch_status_t) switch_module_shutdown(void)
{
if (globals.running) {
globals.running = -1;
while (globals.running) {
switch_yield(100000);
}
}
switch_core_db_close(globals.db);
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename)
{
/* NOTE: **interface is **_interface because the common lib redefines interface to struct in some situations */
if ((globals.db = switch_core_db_handle())) {
switch_core_db_test_reactive(globals.db, "select * from sip_registrations", create_interfaces_sql);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open SQL Database!\n");
return SWITCH_STATUS_TERM;
}
if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
return SWITCH_STATUS_TERM;
@ -974,6 +1055,8 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_mod
switch_core_hash_init(&globals.call_hash, module_pool);
switch_core_hash_init(&globals.srtp_hash, module_pool);
switch_mutex_init(&globals.reg_mutex, SWITCH_MUTEX_NESTED, module_pool);
/* connect my internal structure to the blank pointer passed to me */
*module_interface = &exosip_module_interface;
@ -1365,6 +1448,86 @@ static switch_status_t parse_sdp_media(sdp_media_t * media, char **dname, char *
return status;
}
static char *get_header_value(eXosip_event_t *je, char *name)
{
osip_header_t *hp = NULL;
osip_message_header_get_byname (je->request, name, 0, &hp);
return hp ? hp->hvalue : NULL;
}
static void handle_message_new(eXosip_event_t *je)
{
if (MSG_IS_REGISTER(je->request)) {
int x = 0;
osip_contact_t *contact;
osip_uri_t *contact_uri = NULL;
char *lame = NULL;
char *url;
char *expires = NULL;
osip_message_t *tmp = NULL;
char sql[1024] = "";
int exptime;
for(;;) {
if (osip_message_get_contact(je->request, x++, &contact) < 0) {
break;
}
if (lame) {
free(lame);
lame = NULL;
}
osip_contact_to_str((const osip_contact_t *) contact, &lame);
contact_uri = osip_contact_get_url(contact);
if ((url = strchr(lame, ':'))) {
char *p;
url++;
if ((p = strchr(url, '>'))) {
*p = '\0';
}
expires = get_header_value(je, "expires");
exptime = time(NULL) + atoi(expires) + 20;
if (!find_reg_url(globals.db, je->request->from->url->username, sql, sizeof(sql))) {
snprintf(sql, sizeof(sql), "insert into sip_registrations values ('%s','%s',%d)",
je->request->from->url->username,
url, exptime);
} else {
snprintf(sql, sizeof(sql), "update sip_registrations set url='%s', expires=%d where key = '%s'",
url,
exptime,
je->request->from->url->username);
}
printf("TEST [%s]\n", sql);
switch_mutex_lock(globals.reg_mutex);
switch_core_db_persistant_execute(globals.db, sql, 25);
switch_mutex_unlock(globals.reg_mutex);
eXosip_lock();
if (eXosip_message_build_answer(je->tid, 200, &tmp) < 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "build_answer failed\n");
eXosip_unlock();
continue;
}
eXosip_message_send_answer(je->tid, 200, tmp);
eXosip_unlock();
}
}
} else {
/* Unimplemented */
}
}
static void handle_answer(eXosip_event_t * event)
{
osip_message_t *ack = NULL;
@ -1482,9 +1645,69 @@ static void handle_answer(eXosip_event_t * event)
}
}
static const char *event_names[] = {
"EXOSIP_REGISTRATION_NEW",
"EXOSIP_REGISTRATION_SUCCESS",
"EXOSIP_REGISTRATION_FAILURE",
"EXOSIP_REGISTRATION_REFRESHED",
"EXOSIP_REGISTRATION_TERMINATED",
"EXOSIP_CALL_INVITE",
"EXOSIP_CALL_REINVITE",
"EXOSIP_CALL_NOANSWER",
"EXOSIP_CALL_PROCEEDING",
"EXOSIP_CALL_RINGING",
"EXOSIP_CALL_ANSWERED",
"EXOSIP_CALL_REDIRECTED",
"EXOSIP_CALL_REQUESTFAILURE",
"EXOSIP_CALL_SERVERFAILURE",
"EXOSIP_CALL_GLOBALFAILURE",
"EXOSIP_CALL_ACK",
"EXOSIP_CALL_CANCELLED",
"EXOSIP_CALL_TIMEOUT",
"EXOSIP_CALL_MESSAGE_NEW",
"EXOSIP_CALL_MESSAGE_PROCEEDING",
"EXOSIP_CALL_MESSAGE_ANSWERED",
"EXOSIP_CALL_MESSAGE_REDIRECTED",
"EXOSIP_CALL_MESSAGE_REQUESTFAILURE",
"EXOSIP_CALL_MESSAGE_SERVERFAILURE",
"EXOSIP_CALL_MESSAGE_GLOBALFAILURE",
"EXOSIP_CALL_CLOSED",
"EXOSIP_CALL_RELEASED",
"EXOSIP_MESSAGE_NEW",
"EXOSIP_MESSAGE_PROCEEDING",
"EXOSIP_MESSAGE_ANSWERED",
"EXOSIP_MESSAGE_REDIRECTED",
"EXOSIP_MESSAGE_REQUESTFAILURE",
"EXOSIP_MESSAGE_SERVERFAILURE",
"EXOSIP_MESSAGE_GLOBALFAILURE",
"EXOSIP_SUBSCRIPTION_UPDATE",
"EXOSIP_SUBSCRIPTION_CLOSED",
"EXOSIP_SUBSCRIPTION_NOANSWER",
"EXOSIP_SUBSCRIPTION_PROCEEDING",
"EXOSIP_SUBSCRIPTION_ANSWERED",
"EXOSIP_SUBSCRIPTION_REDIRECTED",
"EXOSIP_SUBSCRIPTION_REQUESTFAILURE",
"EXOSIP_SUBSCRIPTION_SERVERFAILURE",
"EXOSIP_SUBSCRIPTION_GLOBALFAILURE",
"EXOSIP_SUBSCRIPTION_NOTIFY",
"EXOSIP_SUBSCRIPTION_RELEASED",
"EXOSIP_IN_SUBSCRIPTION_NEW",
"EXOSIP_IN_SUBSCRIPTION_RELEASED",
"EXOSIP_NOTIFICATION_NOANSWER",
"EXOSIP_NOTIFICATION_PROCEEDING",
"EXOSIP_NOTIFICATION_ANSWERED",
"EXOSIP_NOTIFICATION_REDIRECTED",
"EXOSIP_NOTIFICATION_REQUESTFAILURE",
"EXOSIP_NOTIFICATION_SERVERFAILURE",
"EXOSIP_NOTIFICATION_GLOBALFAILURE",
"EXOSIP_EVENT_COUNT"
};
static void log_event(eXosip_event_t * je)
{
char buf[100];
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "EVENT [%s]\n", event_names[je->type]);
buf[0] = '\0';
if (je->type == EXOSIP_CALL_NOANSWER) {
@ -1696,10 +1919,24 @@ static int config_exosip(int reload)
}
static void check_expire(time_t now)
{
char sql[1024];
switch_mutex_lock(globals.reg_mutex);
snprintf(sql, sizeof(sql), "delete from sip_registrations where expires > 0 and expires < %ld", now);
switch_core_db_persistant_execute(globals.db, sql, 1);
switch_mutex_unlock(globals.reg_mutex);
}
SWITCH_MOD_DECLARE(switch_status_t) switch_module_runtime(void)
{
eXosip_event_t *event = NULL;
switch_event_t *s_event;
time_t now = 0, next = 0;
int interval = 60;
config_exosip(0);
@ -1722,10 +1959,15 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_runtime(void)
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "port", "%d", globals.port);
switch_event_fire(&s_event);
}
globals.running = 1;
while (globals.running > 0) {
if ((event = eXosip_event_wait(0, 100)) == 0) {
now = time(NULL);
if (now >= next) {
check_expire(now);
next = now + interval;
}
switch_yield(1000);
continue;
}
@ -1737,16 +1979,19 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_runtime(void)
log_event(event);
switch (event->type) {
case EXOSIP_MESSAGE_NEW:
handle_message_new(event);
break;
case EXOSIP_CALL_INVITE:
if (exosip_create_call(event) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "invite failure\n");
destroy_call_by_event(event);
}
break;
case EXOSIP_CALL_REINVITE:
/* See what the reinvite is about - on hold or whatever */
//handle_reinvite(event);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Got a reinvite.\n");
break;
case EXOSIP_CALL_MESSAGE_NEW:
if (event->request != NULL && MSG_IS_REFER(event->request)) {
@ -1757,7 +2002,6 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_runtime(void)
/* If audio is not flowing and this has SDP - fire it up! */
break;
case EXOSIP_CALL_ANSWERED:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "The call was answered.\n");
handle_answer(event);
break;
case EXOSIP_CALL_PROCEEDING:
@ -1767,7 +2011,6 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_runtime(void)
//handle_ringing(event);
break;
case EXOSIP_CALL_REDIRECTED:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call was redirect\n");
break;
case EXOSIP_CALL_CLOSED:
destroy_call_by_event(event);
@ -1776,24 +2019,19 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_runtime(void)
destroy_call_by_event(event);
break;
case EXOSIP_CALL_NOANSWER:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "The call was not answered.\n");
destroy_call_by_event(event);
break;
case EXOSIP_CALL_REQUESTFAILURE:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Request failure\n");
destroy_call_by_event(event);
break;
case EXOSIP_CALL_SERVERFAILURE:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Server failure\n");
destroy_call_by_event(event);
break;
case EXOSIP_CALL_GLOBALFAILURE:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Global failure\n");
destroy_call_by_event(event);
break;
/* Registration related stuff */
case EXOSIP_REGISTRATION_NEW:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Received registration attempt\n");
break;
default:
/* Unknown event... casually absorb it for now */

View File

@ -135,8 +135,9 @@ SWITCH_DECLARE(switch_core_db_t *) switch_core_db_open_file(char *filename)
return db;
}
#if 0
static void check_table_exists(switch_core_db_t *db, char *test_sql, char *create_sql) {
SWITCH_DECLARE(void) switch_core_db_test_reactive(switch_core_db_t *db, char *test_sql, char *reactive_sql)
{
char *errmsg;
if(db) {
@ -155,13 +156,13 @@ static void check_table_exists(switch_core_db_t *db, char *test_sql, char *creat
errmsg = NULL;
switch_core_db_exec(
db,
create_sql,
reactive_sql,
NULL,
NULL,
&errmsg
);
if (errmsg) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SQL ERR [%s]\n[%s]\n", errmsg, create_sql);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SQL ERR [%s]\n[%s]\n", errmsg, reactive_sql);
switch_core_db_free(errmsg);
errmsg = NULL;
}
@ -170,7 +171,7 @@ static void check_table_exists(switch_core_db_t *db, char *test_sql, char *creat
}
}
#endif
SWITCH_DECLARE(switch_status_t) switch_core_set_console(char *console)
@ -2499,7 +2500,7 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_by_name(char
return switch_core_session_request(endpoint_interface, pool);
}
static switch_status_t switch_core_sql_persistant_execute(switch_core_db_t *db, char *sql, uint32_t retries)
SWITCH_DECLARE(switch_status_t) switch_core_db_persistant_execute(switch_core_db_t *db, char *sql, uint32_t retries)
{
char *errmsg;
switch_status_t status = SWITCH_STATUS_FALSE;
@ -2513,7 +2514,7 @@ static switch_status_t switch_core_sql_persistant_execute(switch_core_db_t *db,
&errmsg
);
if (errmsg) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR [%s]\n", errmsg);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR\n[%s]\n[%s]\n", sql,errmsg);
switch_core_db_free(errmsg);
switch_yield(100000);
retries--;
@ -2547,7 +2548,7 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread,
work++;
if (itterations == 0) {
char *isql = "begin transaction CORE1;";
if (switch_core_sql_persistant_execute(runtime.event_db, isql, 25) != SWITCH_STATUS_SUCCESS) {
if (switch_core_db_persistant_execute(runtime.event_db, isql, 25) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL exec error! [%s]\n", isql);
} else {
trans = 1;
@ -2556,7 +2557,7 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread,
itterations++;
if (switch_core_sql_persistant_execute(runtime.event_db, sql, 25) != SWITCH_STATUS_SUCCESS) {
if (switch_core_db_persistant_execute(runtime.event_db, sql, 25) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL exec error! [%s]\n", sql);
}
free(sql);
@ -2573,7 +2574,7 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread,
if (trans && (itterations == target || diff >= freq)) {
char *sql = "end transaction CORE1";
work++;
if (switch_core_sql_persistant_execute(runtime.event_db, sql, 25) != SWITCH_STATUS_SUCCESS) {
if (switch_core_db_persistant_execute(runtime.event_db, sql, 25) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL exec error! [%s]\n", sql);
}
last_commit = switch_time_now();