2008-12-23 21:49:17 +00:00
/*
* FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
2009-02-13 23:37:37 +00:00
* Copyright ( C ) 2005 - 2009 , Anthony Minessale II < anthm @ freeswitch . org >
2008-12-23 21:49:17 +00:00
*
* Version : MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 ( the " License " ) ; you may not use this file except in compliance with
* the License . You may obtain a copy of the License at
* http : //www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an " AS IS " basis ,
* WITHOUT WARRANTY OF ANY KIND , either express or implied . See the License
* for the specific language governing rights and limitations under the
* License .
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
*
* The Initial Developer of the Original Code is
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2008-12-23 21:49:17 +00:00
*
* The Initial Developer of this module is
* Ken Rice < krice at rmktek dot com >
*
* Portions created by the Initial Developer are Copyright ( C )
* the Initial Developer . All Rights Reserved .
*
* Contributor ( s ) :
* Ken Rice < krice at rmktek dot com >
*
* mod_easyroute . c - - EasyRoute
* Take Incoming DIDs and Lookup where to send them as well as retrieve
* the number of channels they are allowed you use
*
2009-01-03 21:39:12 +00:00
* Big Thanks to CP and Joseph Watson ( Powercode Systems , LLC ) for funding this work .
2008-12-23 21:49:17 +00:00
*
*/
# include <switch.h>
typedef struct easyroute_results {
char limit [ 16 ] ;
2009-01-13 23:38:12 +00:00
char dialstring [ 256 ] ;
char group [ 16 ] ;
2008-12-23 21:49:17 +00:00
char acctcode [ 17 ] ;
2009-01-13 23:38:12 +00:00
char translated [ 17 ] ;
2008-12-23 21:49:17 +00:00
} easyroute_results_t ;
typedef struct route_callback {
char gateway [ 129 ] ;
char group [ 129 ] ;
char techprofile [ 129 ] ;
char limit [ 129 ] ;
char acctcode [ 129 ] ;
char translated [ 17 ] ;
} route_callback_t ;
static struct {
char * db_username ;
char * db_password ;
char * db_dsn ;
char * default_techprofile ;
char * default_gateway ;
switch_mutex_t * mutex ;
2009-01-02 04:31:34 +00:00
char * custom_query ;
2008-12-23 21:49:17 +00:00
switch_odbc_handle_t * master_odbc ;
} globals ;
SWITCH_MODULE_LOAD_FUNCTION ( mod_easyroute_load ) ;
SWITCH_MODULE_SHUTDOWN_FUNCTION ( mod_easyroute_shutdown ) ;
SWITCH_MODULE_DEFINITION ( mod_easyroute , mod_easyroute_load , mod_easyroute_shutdown , NULL ) ;
SWITCH_DECLARE_GLOBAL_STRING_FUNC ( set_global_db_username , globals . db_username ) ;
SWITCH_DECLARE_GLOBAL_STRING_FUNC ( set_global_db_password , globals . db_password ) ;
SWITCH_DECLARE_GLOBAL_STRING_FUNC ( set_global_db_dsn , globals . db_dsn ) ;
SWITCH_DECLARE_GLOBAL_STRING_FUNC ( set_global_default_techprofile , globals . default_techprofile ) ;
SWITCH_DECLARE_GLOBAL_STRING_FUNC ( set_global_default_gateway , globals . default_gateway ) ;
2009-01-02 04:31:34 +00:00
SWITCH_DECLARE_GLOBAL_STRING_FUNC ( set_global_custom_query , globals . custom_query ) ;
2008-12-23 21:49:17 +00:00
static int route_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
route_callback_t * cbt = ( route_callback_t * ) pArg ;
switch_copy_string ( cbt - > gateway , argv [ 0 ] , 128 ) ;
switch_copy_string ( cbt - > group , argv [ 1 ] , 128 ) ;
switch_copy_string ( cbt - > limit , argv [ 2 ] , 128 ) ;
switch_copy_string ( cbt - > techprofile , argv [ 3 ] , 128 ) ;
switch_copy_string ( cbt - > acctcode , argv [ 4 ] , 128 ) ;
switch_copy_string ( cbt - > translated , argv [ 5 ] , 16 ) ;
return 0 ;
}
static switch_status_t load_config ( void )
{
char * cf = " easyroute.conf " ;
switch_xml_t cfg , xml = NULL , param , settings ;
switch_status_t status = SWITCH_STATUS_SUCCESS ;
if ( ! ( xml = switch_xml_open_cfg ( cf , & cfg , NULL ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " open of %s failed \n " , cf ) ;
status = SWITCH_STATUS_FALSE ;
goto done ;
}
if ( ( settings = switch_xml_child ( cfg , " settings " ) ) ) {
for ( param = switch_xml_child ( settings , " param " ) ; param ; param = param - > next ) {
char * var = ( char * ) switch_xml_attr_soft ( param , " name " ) ;
char * val = ( char * ) switch_xml_attr_soft ( param , " value " ) ;
2009-01-02 04:31:34 +00:00
if ( ! strcasecmp ( var , " db-username " ) ) {
2008-12-23 21:49:17 +00:00
set_global_db_username ( val ) ;
2009-01-02 04:31:34 +00:00
} else if ( ! strcasecmp ( var , " db-password " ) ) {
2008-12-23 21:49:17 +00:00
set_global_db_password ( val ) ;
2009-01-02 04:31:34 +00:00
} else if ( ! strcasecmp ( var , " db-dsn " ) ) {
2008-12-23 21:49:17 +00:00
set_global_db_dsn ( val ) ;
} else if ( ! strcasecmp ( var , " default-techprofile " ) ) {
set_global_default_techprofile ( val ) ;
} else if ( ! strcasecmp ( var , " default-gateway " ) ) {
set_global_default_gateway ( val ) ;
2009-01-02 04:31:34 +00:00
} else if ( ! strcasecmp ( var , " custom-query " ) ) {
set_global_custom_query ( val ) ;
2008-12-23 21:49:17 +00:00
}
}
}
2009-12-30 00:44:27 +00:00
done :
2009-10-23 16:03:42 +00:00
if ( zstr ( globals . db_username ) ) {
2008-12-23 21:49:17 +00:00
set_global_db_username ( " root " ) ;
}
2009-10-23 16:03:42 +00:00
if ( zstr ( globals . db_password ) ) {
2008-12-31 17:00:12 +00:00
set_global_db_password ( " password " ) ;
2008-12-23 21:49:17 +00:00
}
2009-10-23 16:03:42 +00:00
if ( zstr ( globals . db_dsn ) ) {
2008-12-23 21:49:17 +00:00
set_global_db_dsn ( " easyroute " ) ;
}
2009-06-24 16:02:43 +00:00
if ( switch_odbc_available ( ) & & globals . db_dsn ) {
2008-12-23 21:49:17 +00:00
if ( ! ( globals . master_odbc = switch_odbc_handle_new ( globals . db_dsn , globals . db_username , globals . db_password ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Cannot Open ODBC Database! \n " ) ;
status = SWITCH_STATUS_FALSE ;
goto reallydone ;
} else {
2009-01-21 07:49:25 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Opened ODBC Database! \n " ) ;
2008-12-23 21:49:17 +00:00
}
if ( switch_odbc_handle_connect ( globals . master_odbc ) ! = SWITCH_ODBC_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Cannot Open ODBC Database! \n " ) ;
status = SWITCH_STATUS_FALSE ;
goto reallydone ;
} else {
2009-01-21 07:49:25 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Opened ODBC Database! \n " ) ;
2008-12-23 21:49:17 +00:00
}
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Connected ODBC DSN: %s \n " , globals . db_dsn ) ;
2009-01-21 07:49:25 +00:00
if ( ! globals . custom_query ) {
2010-01-13 01:40:11 +00:00
if ( switch_odbc_handle_exec ( globals . master_odbc , " select count(*) from numbers " , NULL , NULL ) ! = SWITCH_STATUS_SUCCESS ) {
2009-01-21 07:49:25 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Cannot find SQL Database! (Where \' s the numbers table \ ? \ ?) \n " ) ;
}
2010-01-13 01:40:11 +00:00
if ( switch_odbc_handle_exec ( globals . master_odbc , " select count(*) from gateways " , NULL , NULL ) ! = SWITCH_STATUS_SUCCESS ) {
2009-01-21 07:49:25 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Cannot find SQL Database! (Where \' s the gateways table \ ? \ ?) \n " ) ;
}
2008-12-23 21:49:17 +00:00
}
2009-06-24 16:02:43 +00:00
} else if ( globals . db_dsn ) {
2008-12-23 21:49:17 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Cannot Open ODBC Connection (did you enable it?!) \n " ) ;
}
2009-12-30 00:44:27 +00:00
reallydone :
2008-12-23 21:49:17 +00:00
if ( xml ) {
switch_xml_free ( xml ) ;
}
if ( ! globals . default_techprofile ) {
set_global_default_techprofile ( " sofia/default " ) ;
}
if ( ! globals . default_gateway ) {
set_global_default_gateway ( " 192.168.1.1 " ) ;
}
return status ;
}
2009-01-21 07:49:25 +00:00
static char SQL_LOOKUP [ ] = " SELECT gateways.gateway_ip, gateways.group, gateways.limit, gateways.techprofile, numbers.acctcode, numbers.translated from gateways, numbers where numbers.number = '%q' and numbers.gateway_id = gateways.gateway_id limit 1; " ;
2008-12-23 21:49:17 +00:00
2009-12-30 00:44:27 +00:00
static switch_status_t route_lookup ( char * dn , easyroute_results_t * results , int noat , char * separator )
2008-12-23 21:49:17 +00:00
{
switch_status_t sstatus = SWITCH_STATUS_SUCCESS ;
2009-01-21 07:49:25 +00:00
char * sql = NULL ;
2008-12-23 21:49:17 +00:00
route_callback_t pdata ;
2009-06-24 16:02:43 +00:00
if ( ! switch_odbc_available ( ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT ,
" mod_easyroute requires core ODBC support. Please refer to the documentation on how to enable this \n " ) ;
return sstatus ;
}
2008-12-23 21:49:17 +00:00
memset ( & pdata , 0 , sizeof ( pdata ) ) ;
2009-01-02 04:31:34 +00:00
if ( ! globals . custom_query ) {
2009-01-21 07:49:25 +00:00
sql = switch_mprintf ( SQL_LOOKUP , dn ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Doing static Query \n [%s] \n " , sql ) ;
2009-01-02 04:31:34 +00:00
} else {
2009-01-21 07:49:25 +00:00
sql = switch_mprintf ( globals . custom_query , dn ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Doing custom Query \n [%s] \n " , sql ) ;
2009-01-02 04:31:34 +00:00
}
2008-12-23 21:49:17 +00:00
if ( globals . mutex ) {
switch_mutex_lock ( globals . mutex ) ;
}
/* Do the Query */
2009-11-17 01:31:12 +00:00
if ( switch_odbc_handle_callback_exec ( globals . master_odbc , sql , route_callback , & pdata , NULL ) = = SWITCH_ODBC_SUCCESS ) {
2008-12-23 21:49:17 +00:00
char tmp_profile [ 129 ] ;
2009-01-02 04:31:34 +00:00
char tmp_gateway [ 129 ] ;
2008-12-23 21:49:17 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( pdata . limit ) ) {
2008-12-23 21:49:17 +00:00
switch_set_string ( results - > limit , " 9999 " ) ;
} else {
switch_set_string ( results - > limit , pdata . limit ) ;
}
2009-10-23 16:03:42 +00:00
if ( zstr ( pdata . techprofile ) ) {
2008-12-23 21:49:17 +00:00
switch_set_string ( tmp_profile , globals . default_techprofile ) ;
} else {
switch_set_string ( tmp_profile , pdata . techprofile ) ;
}
2009-10-23 16:03:42 +00:00
if ( zstr ( pdata . gateway ) ) {
2008-12-23 21:49:17 +00:00
switch_set_string ( tmp_gateway , globals . default_gateway ) ;
} else {
switch_set_string ( tmp_gateway , pdata . gateway ) ;
}
2009-10-23 16:03:42 +00:00
if ( zstr ( pdata . translated ) ) {
2008-12-23 21:49:17 +00:00
switch_set_string ( results - > translated , dn ) ;
} else {
switch_set_string ( results - > translated , pdata . translated ) ;
}
2009-01-20 06:18:19 +00:00
if ( noat ) {
switch_snprintf ( results - > dialstring , 256 , " %s/%s%s " , tmp_profile , results - > translated , tmp_gateway ) ;
2009-12-30 00:44:27 +00:00
} else if ( separator ) {
switch_snprintf ( results - > dialstring , 256 , " %s/%s%s%s " , tmp_profile , results - > translated , separator , tmp_gateway ) ;
2009-01-20 06:18:19 +00:00
} else {
switch_snprintf ( results - > dialstring , 256 , " %s/%s@%s " , tmp_profile , results - > translated , tmp_gateway ) ;
}
2009-01-02 04:31:34 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " THE ROUTE [%s] \n " , results - > dialstring ) ;
2008-12-23 21:49:17 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( pdata . group ) ) {
2008-12-23 21:49:17 +00:00
switch_set_string ( results - > group , " " ) ;
} else {
switch_set_string ( results - > group , pdata . group ) ;
}
2009-10-23 16:03:42 +00:00
if ( zstr ( pdata . acctcode ) ) {
2008-12-23 21:49:17 +00:00
switch_set_string ( results - > acctcode , " " ) ;
} else {
switch_set_string ( results - > acctcode , pdata . acctcode ) ;
}
} else {
2009-01-13 23:38:12 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " DB Error Setting Default Route! \n " ) ;
2008-12-23 21:49:17 +00:00
switch_set_string ( results - > limit , " 9999 " ) ;
2009-01-20 06:18:19 +00:00
if ( noat ) {
switch_snprintf ( results - > dialstring , 256 , " %s/%s%s " , globals . default_techprofile , dn , globals . default_gateway ) ;
2009-12-30 00:44:27 +00:00
} else if ( separator ) {
switch_snprintf ( results - > dialstring , 256 , " %s/%s%s%s " , globals . default_techprofile , dn , separator , globals . default_gateway ) ;
2009-01-20 06:18:19 +00:00
} else {
switch_snprintf ( results - > dialstring , 256 , " %s/%s@%s " , globals . default_techprofile , dn , globals . default_gateway ) ;
}
2008-12-23 21:49:17 +00:00
switch_set_string ( results - > group , " " ) ;
switch_set_string ( results - > acctcode , " " ) ;
}
2009-01-20 06:18:19 +00:00
2009-02-19 00:52:06 +00:00
switch_safe_free ( sql ) ;
2008-12-23 21:49:17 +00:00
if ( globals . mutex ) {
switch_mutex_unlock ( globals . mutex ) ;
}
return sstatus ;
}
SWITCH_STANDARD_APP ( easyroute_app_function )
{
int argc = 0 ;
char * argv [ 4 ] = { 0 } ;
char * mydata = NULL ;
char * destnum = NULL ;
2009-01-20 06:18:19 +00:00
int noat = 0 ;
2009-12-30 00:44:27 +00:00
char * separator = NULL ;
2009-01-20 06:18:19 +00:00
2008-12-23 21:49:17 +00:00
easyroute_results_t results ;
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
if ( ! channel ) {
return ;
}
if ( ! ( mydata = switch_core_session_strdup ( session , data ) ) ) {
return ;
}
if ( ( argc = switch_separate_string ( mydata , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) ) {
destnum = argv [ 0 ] ;
2009-01-20 06:18:19 +00:00
if ( argc = = 2 ) {
if ( ! strcasecmp ( argv [ 1 ] , " noat " ) ) {
noat = 1 ;
2009-12-30 00:44:27 +00:00
} else if ( ! strcasecmp ( argv [ 1 ] , " separator " ) ) {
if ( argc = = 3 ) {
switch_set_string ( separator , argv [ 2 ] ) ;
2009-01-20 06:18:19 +00:00
}
}
}
2009-12-30 00:44:27 +00:00
route_lookup ( destnum , & results , noat , separator ) ;
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_INFO , " EASY ROUTE DEST: [%s] \n " , results . dialstring ) ;
2009-05-14 02:57:21 +00:00
switch_channel_set_variable ( channel , " easy_destnum " , destnum ) ;
2008-12-23 21:49:17 +00:00
switch_channel_set_variable ( channel , " easy_dialstring " , results . dialstring ) ;
switch_channel_set_variable ( channel , " easy_group " , results . group ) ;
switch_channel_set_variable ( channel , " easy_limit " , results . limit ) ;
switch_channel_set_variable ( channel , " easy_acctcode " , results . acctcode ) ;
}
}
SWITCH_STANDARD_API ( easyroute_function )
{
int argc = 0 ;
char * argv [ 4 ] = { 0 } ;
char * mydata = NULL ;
char * destnum = NULL ;
2009-12-30 00:44:27 +00:00
char * separator = NULL ;
2009-01-20 06:18:19 +00:00
int noat = 0 ;
2008-12-23 21:49:17 +00:00
easyroute_results_t results ;
2009-05-27 02:16:22 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2008-12-23 21:49:17 +00:00
if ( session ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " This function cannot be called from the dialplan. \n " ) ;
2009-05-27 02:16:22 +00:00
status = SWITCH_STATUS_FALSE ;
goto done ;
2008-12-23 21:49:17 +00:00
}
2009-01-20 06:18:19 +00:00
2009-06-24 16:02:43 +00:00
if ( ! switch_odbc_available ( ) ) {
stream - > write_function ( stream , " mod_easyroute requires you enable core odbc support \n " ) ;
status = SWITCH_STATUS_SUCCESS ;
goto done ;
}
2008-12-23 21:49:17 +00:00
if ( ! cmd | | ! ( mydata = strdup ( cmd ) ) ) {
stream - > write_function ( stream , " Usage: easyroute <number> \n " ) ;
2009-05-27 02:16:22 +00:00
status = SWITCH_STATUS_SUCCESS ;
goto done ;
2008-12-23 21:49:17 +00:00
}
if ( ( argc = switch_separate_string ( mydata , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) ) {
destnum = argv [ 0 ] ;
2009-01-20 06:18:19 +00:00
if ( argc < 1 | | argc > 3 ) {
2009-01-13 23:38:12 +00:00
stream - > write_function ( stream , " Invalid Input! \n " ) ;
2009-05-27 02:16:22 +00:00
status = SWITCH_STATUS_SUCCESS ;
goto done ;
2009-01-13 23:38:12 +00:00
}
2009-01-20 06:18:19 +00:00
if ( argc = = 2 ) {
if ( ! strcasecmp ( argv [ 1 ] , " noat " ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Entering noat. \n " ) ;
2009-01-20 06:18:19 +00:00
noat = 1 ;
2009-12-30 00:44:27 +00:00
} else if ( ! strcasecmp ( argv [ 1 ] , " separator " ) ) {
if ( argc = = 3 ) {
switch_set_string ( separator , argv [ 2 ] ) ;
2009-01-20 06:18:19 +00:00
}
}
}
2008-12-23 21:49:17 +00:00
2009-12-30 00:44:27 +00:00
if ( ! route_lookup ( destnum , & results , noat , separator ) = = SWITCH_STATUS_SUCCESS ) {
2008-12-23 21:49:17 +00:00
stream - > write_function ( stream , " No Match! \n " ) ;
2009-05-27 02:16:22 +00:00
status = SWITCH_STATUS_SUCCESS ;
goto done ;
2008-12-23 21:49:17 +00:00
}
2009-01-13 23:38:12 +00:00
if ( argc ! = 2 ) {
stream - > write_function ( stream , " Number \t Limit \t Group \t AcctCode \t Dialstring \n " ) ;
stream - > write_function ( stream , " %-10s \t %-10s \t %-10s \t %-10s \t %s \n " , destnum , results . limit , results . group , results . acctcode , results . dialstring ) ;
} else {
if ( ! strncasecmp ( argv [ 1 ] , " dialstring " , 10 ) ) {
stream - > write_function ( stream , " %s " , results . dialstring ) ;
} else if ( ! strncasecmp ( argv [ 1 ] , " translated " , 10 ) ) {
stream - > write_function ( stream , " %s " , results . translated ) ;
} else if ( ! strncasecmp ( argv [ 1 ] , " limit " , 5 ) ) {
stream - > write_function ( stream , " %s " , results . limit ) ;
} else if ( ! strncasecmp ( argv [ 1 ] , " group " , 5 ) ) {
stream - > write_function ( stream , " %s " , results . group ) ;
} else if ( ! strncasecmp ( argv [ 1 ] , " acctcode " , 8 ) ) {
stream - > write_function ( stream , " %s " , results . acctcode ) ;
} else {
stream - > write_function ( stream , " Invalid Input! \n " ) ;
2009-05-27 02:16:22 +00:00
status = SWITCH_STATUS_SUCCESS ;
goto done ;
2009-01-13 23:38:12 +00:00
}
}
2008-12-23 21:49:17 +00:00
} else {
stream - > write_function ( stream , " Invalid Input! \n " ) ;
}
2009-05-27 02:16:22 +00:00
done :
switch_safe_free ( mydata ) ;
return status ;
2008-12-23 21:49:17 +00:00
}
SWITCH_MODULE_LOAD_FUNCTION ( mod_easyroute_load )
{
switch_api_interface_t * api_interface ;
switch_application_interface_t * app_interface ;
memset ( & globals , 0 , sizeof ( globals ) ) ;
load_config ( ) ;
/* connect my internal structure to the blank pointer passed to me */
* module_interface = switch_loadable_module_create_module_interface ( pool , modname ) ;
SWITCH_ADD_API ( api_interface , " easyroute " , " EasyRoute " , easyroute_function , " " ) ;
2009-09-18 22:55:33 +00:00
SWITCH_ADD_APP ( app_interface , " easyroute " , " Perform an easyroute lookup " , " Perform an easyroute lookup " , easyroute_app_function , " <number> " , SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC ) ;
2008-12-23 21:49:17 +00:00
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS ;
}
SWITCH_MODULE_SHUTDOWN_FUNCTION ( mod_easyroute_shutdown )
{
2009-01-13 23:38:12 +00:00
switch_odbc_handle_disconnect ( globals . master_odbc ) ;
2009-02-23 19:17:24 +00:00
switch_safe_free ( globals . db_username ) ;
switch_safe_free ( globals . db_password ) ;
switch_safe_free ( globals . db_dsn ) ;
switch_safe_free ( globals . default_techprofile ) ;
switch_safe_free ( globals . default_gateway ) ;
switch_safe_free ( globals . custom_query ) ;
2008-12-23 21:49:17 +00:00
return SWITCH_STATUS_UNLOAD ;
}
/* For Emacs:
* Local Variables :
* mode : c
* indent - tabs - mode : t
* tab - width : 4
* c - basic - offset : 4
* End :
* For VIM :
2009-09-14 22:03:37 +00:00
* vim : set softtabstop = 4 shiftwidth = 4 tabstop = 4 :
2008-12-23 21:49:17 +00:00
*/