2006-03-31 19:38:09 +00:00
/*
* FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
* Copyright ( C ) 2005 / 2006 , Anthony Minessale II < anthmct @ yahoo . com >
*
* 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
* Anthony Minessale II < anthmct @ yahoo . com >
* Portions created by the Initial Developer are Copyright ( C )
* the Initial Developer . All Rights Reserved .
*
* Contributor ( s ) :
*
* Anthony Minessale II < anthmct @ yahoo . com >
*
*
* mod_dingaling . c - - Jingle Endpoint Module
*
*/
# include <switch.h>
# include <libdingaling.h>
2007-04-04 17:32:56 +00:00
# ifdef SWITCH_HAVE_ODBC
# include <switch_odbc.h>
# endif
2006-03-31 19:38:09 +00:00
2006-04-13 23:19:33 +00:00
# define DL_CAND_WAIT 10000000
2006-04-15 05:56:23 +00:00
# define DL_CAND_INITIAL_WAIT 2000000
2006-05-01 18:55:04 +00:00
# define DL_EVENT_LOGIN_SUCCESS "dingaling::login_success"
# define DL_EVENT_LOGIN_FAILURE "dingaling::login_failure"
2006-06-22 21:57:40 +00:00
# define DL_EVENT_CONNECTED "dingaling::connected"
2006-10-20 22:11:26 +00:00
# define MDL_CHAT_PROTO "jingle"
2006-05-01 18:55:04 +00:00
2006-03-31 19:38:09 +00:00
static const char modname [ ] = " mod_dingaling " ;
2006-04-29 01:00:52 +00:00
static switch_memory_pool_t * module_pool = NULL ;
2006-03-31 19:38:09 +00:00
2006-10-18 22:57:35 +00:00
static char sub_sql [ ] =
2007-04-04 17:32:56 +00:00
" CREATE TABLE jabber_subscriptions ( \n "
" sub_from VARCHAR(255), \n "
" sub_to VARCHAR(255), \n "
" show_pres VARCHAR(255), \n "
" status VARCHAR(255) \n "
2007-03-30 00:15:25 +00:00
" ); \n " ;
2006-10-18 22:57:35 +00:00
2006-03-31 19:38:09 +00:00
typedef enum {
TFLAG_IO = ( 1 < < 0 ) ,
TFLAG_INBOUND = ( 1 < < 1 ) ,
TFLAG_OUTBOUND = ( 1 < < 2 ) ,
TFLAG_READING = ( 1 < < 3 ) ,
TFLAG_WRITING = ( 1 < < 4 ) ,
TFLAG_BYE = ( 1 < < 5 ) ,
TFLAG_VOICE = ( 1 < < 6 ) ,
TFLAG_RTP_READY = ( 1 < < 7 ) ,
TFLAG_CODEC_READY = ( 1 < < 8 ) ,
2006-04-15 22:30:25 +00:00
TFLAG_TRANSPORT = ( 1 < < 9 ) ,
TFLAG_ANSWER = ( 1 < < 10 ) ,
2007-03-29 22:31:56 +00:00
TFLAG_VAD_IN = ( 1 < < 11 ) ,
TFLAG_VAD_OUT = ( 1 < < 12 ) ,
TFLAG_VAD = ( 1 < < 13 ) ,
TFLAG_DO_CAND = ( 1 < < 14 ) ,
2006-04-27 15:59:58 +00:00
TFLAG_DO_DESC = ( 1 < < 15 ) ,
2006-05-02 16:43:13 +00:00
TFLAG_LANADDR = ( 1 < < 16 ) ,
2006-05-04 01:08:03 +00:00
TFLAG_AUTO = ( 1 < < 17 ) ,
2006-05-24 16:10:05 +00:00
TFLAG_DTMF = ( 1 < < 18 ) ,
2007-03-29 22:31:56 +00:00
TFLAG_TIMER = ( 1 < < 19 ) ,
TFLAG_TERM = ( 1 < < 20 ) ,
2006-08-18 21:02:40 +00:00
TFLAG_TRANSPORT_ACCEPT = ( 1 < < 21 ) ,
2006-10-10 00:11:41 +00:00
TFLAG_READY = ( 1 < < 22 ) ,
2006-03-31 19:38:09 +00:00
} TFLAGS ;
typedef enum {
GFLAG_MY_CODEC_PREFS = ( 1 < < 0 )
} GFLAGS ;
static struct {
int debug ;
char * dialplan ;
char * codec_string ;
char * codec_order [ SWITCH_MAX_CODECS ] ;
int codec_order_last ;
char * codec_rates_string ;
char * codec_rates [ SWITCH_MAX_CODECS ] ;
int codec_rates_last ;
unsigned int flags ;
unsigned int init ;
2006-04-29 01:00:52 +00:00
switch_hash_t * profile_hash ;
2006-03-31 19:38:09 +00:00
int running ;
int handles ;
2007-03-29 22:31:56 +00:00
char guess_ip [ 80 ] ;
2006-03-31 19:38:09 +00:00
} globals ;
struct mdl_profile {
2007-03-29 22:31:56 +00:00
char * name ;
char * login ;
char * password ;
char * message ;
2006-10-12 14:06:09 +00:00
char * auto_reply ;
2007-03-29 22:31:56 +00:00
char * dialplan ;
char * ip ;
char * extip ;
char * lanaddr ;
2006-08-11 00:24:38 +00:00
char * server ;
2007-03-29 22:31:56 +00:00
char * exten ;
char * context ;
2006-09-12 22:23:45 +00:00
char * timer_name ;
2006-10-18 22:57:35 +00:00
char * dbname ;
2007-04-04 17:32:56 +00:00
# ifdef SWITCH_HAVE_ODBC
char * odbc_dsn ;
char * odbc_user ;
char * odbc_pass ;
switch_odbc_handle_t * master_odbc ;
# endif
2006-10-18 22:57:35 +00:00
switch_mutex_t * mutex ;
2007-03-29 22:31:56 +00:00
ldl_handle_t * handle ;
uint32_t flags ;
uint32_t user_flags ;
2006-03-31 19:38:09 +00:00
} ;
2007-04-04 17:32:56 +00:00
typedef struct mdl_profile mdl_profile_t ;
2006-03-31 19:38:09 +00:00
struct private_object {
unsigned int flags ;
2006-04-29 06:05:03 +00:00
switch_codec_t read_codec ;
switch_codec_t write_codec ;
switch_frame_t read_frame ;
2007-04-04 17:32:56 +00:00
mdl_profile_t * profile ;
2006-04-29 06:05:03 +00:00
switch_core_session_t * session ;
switch_caller_profile_t * caller_profile ;
2006-03-31 19:38:09 +00:00
unsigned short samprate ;
switch_mutex_t * mutex ;
2006-07-10 22:08:02 +00:00
const switch_codec_implementation_t * codecs [ SWITCH_MAX_CODECS ] ;
2006-03-31 19:38:09 +00:00
unsigned int num_codecs ;
int codec_index ;
2006-04-29 01:00:52 +00:00
switch_rtp_t * rtp_session ;
2006-03-31 19:38:09 +00:00
ldl_session_t * dlsession ;
char * remote_ip ;
2006-04-05 20:17:22 +00:00
switch_port_t local_port ;
switch_port_t remote_port ;
2006-04-06 23:31:01 +00:00
char local_user [ 17 ] ;
2006-04-15 22:30:25 +00:00
char local_pass [ 17 ] ;
2006-03-31 19:38:09 +00:00
char * remote_user ;
2006-10-24 18:23:23 +00:00
char * us ;
char * them ;
2006-03-31 19:38:09 +00:00
unsigned int cand_id ;
unsigned int desc_id ;
unsigned int dc ;
2007-03-06 01:19:41 +00:00
uint32_t timestamp_send ;
2006-03-31 19:38:09 +00:00
int32_t timestamp_recv ;
2006-04-13 16:19:49 +00:00
uint32_t last_read ;
2006-03-31 19:38:09 +00:00
char * codec_name ;
2006-04-18 16:50:34 +00:00
switch_payload_t codec_num ;
2006-08-18 01:28:50 +00:00
switch_payload_t r_codec_num ;
2006-08-18 16:36:26 +00:00
uint32_t codec_rate ;
2006-04-15 22:30:25 +00:00
switch_time_t next_desc ;
2006-04-15 16:02:31 +00:00
switch_time_t next_cand ;
2006-04-13 17:15:51 +00:00
char * stun_ip ;
2006-05-03 23:45:07 +00:00
char * recip ;
2006-05-04 14:37:11 +00:00
char * dnis ;
2006-04-14 05:53:59 +00:00
uint16_t stun_port ;
2006-06-23 16:59:47 +00:00
switch_mutex_t * flag_mutex ;
2006-03-31 19:38:09 +00:00
} ;
struct rfc2833_digit {
char digit ;
int duration ;
} ;
2007-02-14 19:22:42 +00:00
SWITCH_DECLARE_GLOBAL_STRING_FUNC ( set_global_dialplan , globals . dialplan )
2007-03-29 22:31:56 +00:00
SWITCH_DECLARE_GLOBAL_STRING_FUNC ( set_global_codec_string , globals . codec_string )
SWITCH_DECLARE_GLOBAL_STRING_FUNC ( set_global_codec_rates_string , globals . codec_rates_string )
static switch_status_t dl_login ( char * arg , switch_core_session_t * session , switch_stream_handle_t * stream ) ;
2007-03-30 00:13:31 +00:00
static switch_status_t dl_logout ( char * profile_name , switch_core_session_t * session , switch_stream_handle_t * stream ) ;
2007-03-29 22:31:56 +00:00
static switch_status_t channel_on_init ( switch_core_session_t * session ) ;
static switch_status_t channel_on_hangup ( switch_core_session_t * session ) ;
static switch_status_t channel_on_ring ( switch_core_session_t * session ) ;
static switch_status_t channel_on_loopback ( switch_core_session_t * session ) ;
static switch_status_t channel_on_transmit ( switch_core_session_t * session ) ;
static switch_call_cause_t channel_outgoing_channel ( switch_core_session_t * session ,
switch_caller_profile_t * outbound_profile ,
2007-03-30 00:15:25 +00:00
switch_core_session_t * * new_session , switch_memory_pool_t * * pool ) ;
2007-03-30 00:13:31 +00:00
static switch_status_t channel_read_frame ( switch_core_session_t * session , switch_frame_t * * frame , int timeout , switch_io_flag_t flags , int stream_id ) ;
static switch_status_t channel_write_frame ( switch_core_session_t * session , switch_frame_t * frame , int timeout , switch_io_flag_t flags , int stream_id ) ;
2007-03-29 22:31:56 +00:00
static switch_status_t channel_kill_channel ( switch_core_session_t * session , int sig ) ;
static ldl_status handle_signalling ( ldl_handle_t * handle , ldl_session_t * dlsession , ldl_signal_t dl_signal ,
char * to , char * from , char * subject , char * msg ) ;
static ldl_status handle_response ( ldl_handle_t * handle , char * id ) ;
static switch_status_t load_config ( void ) ;
static int sin_callback ( void * pArg , int argc , char * * argv , char * * columnNames ) ;
2006-05-02 16:43:13 +00:00
2006-12-16 03:00:56 +00:00
# define is_special(s) (s && (strstr(s, "ext+") || strstr(s, "user+")))
2006-10-24 18:23:23 +00:00
2007-03-29 22:31:56 +00:00
static char * translate_rpid ( char * in , char * ext )
2006-10-20 06:17:00 +00:00
{
char * r = NULL ;
if ( in & & ( strstr ( in , " null " ) | | strstr ( in , " NULL " ) ) ) {
in = NULL ;
}
if ( ! in ) {
in = ext ;
}
if ( ! in ) {
return NULL ;
}
2007-03-29 22:31:56 +00:00
2006-10-20 06:17:00 +00:00
if ( ! strcasecmp ( in , " busy " ) ) {
r = " dnd " ;
}
if ( ! strcasecmp ( in , " unavailable " ) ) {
r = " dnd " ;
}
2006-10-20 22:11:26 +00:00
if ( ! strcasecmp ( in , " idle " ) ) {
r = " away " ;
}
2006-10-20 06:17:00 +00:00
if ( ext & & ! strcasecmp ( ext , " idle " ) ) {
r = " away " ;
} else if ( ext & & ! strcasecmp ( ext , " away " ) ) {
r = " away " ;
}
2007-03-29 22:31:56 +00:00
2006-10-20 06:17:00 +00:00
return r ;
}
2006-08-18 16:36:26 +00:00
2007-04-04 17:32:56 +00:00
static void mdl_execute_sql ( mdl_profile_t * profile , char * sql , switch_mutex_t * mutex )
{
switch_core_db_t * db ;
if ( mutex ) {
switch_mutex_lock ( mutex ) ;
}
# ifdef SWITCH_HAVE_ODBC
if ( profile - > odbc_dsn ) {
SQLHSTMT stmt ;
if ( switch_odbc_handle_exec ( profile - > master_odbc , sql , & stmt ) ! = SWITCH_ODBC_SUCCESS ) {
char * err_str ;
err_str = switch_odbc_handle_get_error ( profile - > master_odbc , stmt ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " ERR: [%s] \n [%s] \n " , sql , switch_str_nil ( err_str ) ) ;
switch_safe_free ( err_str ) ;
}
SQLFreeHandle ( SQL_HANDLE_STMT , stmt ) ;
} else {
# endif
if ( ! ( db = switch_core_db_open_file ( profile - > dbname ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error Opening DB %s \n " , profile - > dbname ) ;
goto end ;
}
switch_core_db_persistant_execute ( db , sql , 25 ) ;
switch_core_db_close ( db ) ;
# ifdef SWITCH_HAVE_ODBC
}
# endif
end :
if ( mutex ) {
switch_mutex_unlock ( mutex ) ;
}
}
static switch_bool_t mdl_execute_sql_callback ( mdl_profile_t * profile ,
switch_mutex_t * mutex ,
char * sql ,
switch_core_db_callback_func_t callback ,
void * pdata )
{
switch_bool_t ret = SWITCH_FALSE ;
switch_core_db_t * db ;
char * errmsg = NULL ;
if ( mutex ) {
switch_mutex_lock ( mutex ) ;
}
# ifdef SWITCH_HAVE_ODBC
if ( profile - > odbc_dsn ) {
switch_odbc_handle_callback_exec ( profile - > master_odbc , sql , callback , pdata ) ;
} else {
# endif
if ( ! ( db = switch_core_db_open_file ( profile - > dbname ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error Opening DB %s \n " , profile - > dbname ) ;
goto end ;
}
switch_core_db_exec ( db , sql , callback , pdata , & errmsg ) ;
if ( errmsg ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " SQL ERR: [%s] %s \n " , sql , errmsg ) ;
free ( errmsg ) ;
}
if ( db ) {
switch_core_db_close ( db ) ;
}
# ifdef SWITCH_HAVE_ODBC
}
# endif
end :
if ( mutex ) {
switch_mutex_unlock ( mutex ) ;
}
return ret ;
}
2006-10-18 22:57:35 +00:00
static int sub_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
2007-04-04 17:32:56 +00:00
mdl_profile_t * profile = ( mdl_profile_t * ) pArg ;
2006-10-18 22:57:35 +00:00
char * sub_from = argv [ 0 ] ;
char * sub_to = argv [ 1 ] ;
char * type = argv [ 2 ] ;
2006-10-20 06:17:00 +00:00
char * rpid = argv [ 3 ] ;
char * status = argv [ 4 ] ;
2006-10-20 22:11:26 +00:00
//char *proto = argv[5];
2007-03-29 22:31:56 +00:00
2006-10-18 22:57:35 +00:00
if ( switch_strlen_zero ( type ) ) {
type = NULL ;
} else if ( ! strcasecmp ( type , " unavailable " ) ) {
2006-10-20 06:17:00 +00:00
status = NULL ;
2006-10-18 22:57:35 +00:00
}
2006-10-20 06:17:00 +00:00
rpid = translate_rpid ( rpid , status ) ;
2006-10-20 22:11:26 +00:00
2006-11-16 15:50:17 +00:00
//ldl_handle_send_presence(profile->handle, sub_to, sub_from, "probe", rpid, status);
2006-10-20 06:17:00 +00:00
ldl_handle_send_presence ( profile - > handle , sub_to , sub_from , type , rpid , status ) ;
2006-10-18 22:57:35 +00:00
2006-10-20 22:11:26 +00:00
2006-10-18 22:57:35 +00:00
return 0 ;
}
static int rost_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
2007-04-04 17:32:56 +00:00
mdl_profile_t * profile = ( mdl_profile_t * ) pArg ;
2006-10-18 22:57:35 +00:00
char * sub_from = argv [ 0 ] ;
char * sub_to = argv [ 1 ] ;
char * show = argv [ 2 ] ;
2006-10-20 06:17:00 +00:00
char * status = argv [ 3 ] ;
2006-10-18 22:57:35 +00:00
2006-10-20 06:17:00 +00:00
if ( ! strcasecmp ( status , " n/a " ) ) {
if ( ! strcasecmp ( show , " dnd " ) ) {
status = " Busy " ;
} else if ( ! strcasecmp ( show , " away " ) ) {
status = " Idle " ;
}
}
2006-10-18 22:57:35 +00:00
2006-10-20 06:17:00 +00:00
ldl_handle_send_presence ( profile - > handle , sub_to , sub_from , NULL , show , status ) ;
2006-10-18 22:57:35 +00:00
return 0 ;
}
static void pres_event_handler ( switch_event_t * event )
{
2007-04-04 17:32:56 +00:00
mdl_profile_t * profile = NULL ;
2006-10-18 22:57:35 +00:00
switch_hash_index_t * hi ;
2007-03-29 22:31:56 +00:00
void * val ;
2006-10-20 22:11:26 +00:00
char * proto = switch_event_get_header ( event , " proto " ) ;
2006-10-18 22:57:35 +00:00
char * from = switch_event_get_header ( event , " from " ) ;
2007-03-29 22:31:56 +00:00
char * status = switch_event_get_header ( event , " status " ) ;
2006-10-20 06:17:00 +00:00
char * rpid = switch_event_get_header ( event , " rpid " ) ;
char * type = switch_event_get_header ( event , " event_subtype " ) ;
2006-10-18 22:57:35 +00:00
char * sql ;
2007-04-04 17:32:56 +00:00
2006-10-18 22:57:35 +00:00
2006-10-20 22:11:26 +00:00
if ( ! proto ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error Missing 'proto' header \n " ) ;
return ;
}
if ( ! from ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error Missing 'from' header \n " ) ;
return ;
}
2006-10-18 22:57:35 +00:00
if ( status & & ! strcasecmp ( status , " n/a " ) ) {
2006-10-20 06:17:00 +00:00
status = NULL ;
2006-10-18 22:57:35 +00:00
}
2007-03-29 22:31:56 +00:00
switch ( event - > event_id ) {
case SWITCH_EVENT_PRESENCE_PROBE :
if ( proto ) {
char * sql ;
char * to = switch_event_get_header ( event , " to " ) ;
char * f_host = NULL ;
if ( to ) {
if ( ( f_host = strchr ( to , ' @ ' ) ) ) {
f_host + + ;
}
}
if ( f_host & & ( profile = switch_core_hash_find ( globals . profile_hash , f_host ) ) ) {
2007-04-04 17:32:56 +00:00
if ( to & & ( sql = switch_mprintf ( " select * from jabber_subscriptions where sub_to='%q' " , to ) ) ) {
mdl_execute_sql_callback ( profile , profile - > mutex , sql , sin_callback , profile ) ;
2007-03-29 22:31:56 +00:00
switch_safe_free ( sql ) ;
}
}
}
return ;
2006-10-18 22:57:35 +00:00
case SWITCH_EVENT_PRESENCE_IN :
if ( ! status ) {
status = " Available " ;
}
break ;
case SWITCH_EVENT_PRESENCE_OUT :
type = " unavailable " ;
break ;
default :
break ;
}
2007-03-29 22:31:56 +00:00
2006-10-18 22:57:35 +00:00
2006-10-20 22:11:26 +00:00
if ( ! type ) {
type = " " ;
}
if ( ! rpid ) {
rpid = " " ;
2006-10-18 22:57:35 +00:00
}
2006-10-20 22:11:26 +00:00
if ( ! status ) {
status = " Away " ;
}
2007-03-29 22:31:56 +00:00
2007-04-04 17:32:56 +00:00
sql = switch_mprintf ( " select sub_from, sub_to,'%q','%q','%q','%q' from jabber_subscriptions where sub_to like '%%%q' " , type , rpid , status , proto , from ) ;
2007-03-29 22:31:56 +00:00
2007-03-30 00:13:31 +00:00
for ( hi = switch_hash_first ( switch_hash_pool_get ( globals . profile_hash ) , globals . profile_hash ) ; hi ; hi = switch_hash_next ( hi ) ) {
2007-03-29 22:31:56 +00:00
switch_hash_this ( hi , NULL , NULL , & val ) ;
2007-04-04 17:32:56 +00:00
profile = ( mdl_profile_t * ) val ;
2006-10-18 22:57:35 +00:00
2007-03-29 22:31:56 +00:00
if ( ! ( profile - > user_flags & LDL_FLAG_COMPONENT ) ) {
2006-10-18 22:57:35 +00:00
continue ;
2007-03-29 22:31:56 +00:00
}
2006-10-18 22:57:35 +00:00
if ( sql ) {
2007-04-04 17:32:56 +00:00
switch_bool_t worked = mdl_execute_sql_callback ( profile , profile - > mutex , sql , sub_callback , profile ) ;
if ( ! worked ) {
2006-10-18 22:57:35 +00:00
continue ;
}
}
2007-03-29 22:31:56 +00:00
2006-10-18 22:57:35 +00:00
}
switch_safe_free ( sql ) ;
}
2006-10-20 22:11:26 +00:00
static switch_status_t chat_send ( char * proto , char * from , char * to , char * subject , char * body , char * hint )
2006-10-18 22:57:35 +00:00
{
2006-12-27 18:42:32 +00:00
char * user , * host , * f_user = NULL , * ffrom = NULL , * f_host = NULL , * f_resource = NULL ;
2007-04-04 17:32:56 +00:00
mdl_profile_t * profile = NULL ;
2006-10-18 22:57:35 +00:00
2006-10-20 22:11:26 +00:00
assert ( proto ! = NULL ) ;
2006-10-18 22:57:35 +00:00
if ( from & & ( f_user = strdup ( from ) ) ) {
if ( ( f_host = strchr ( f_user , ' @ ' ) ) ) {
* f_host + + = ' \0 ' ;
2007-03-29 22:31:56 +00:00
if ( ( f_resource = strchr ( f_host , ' / ' ) ) ) {
* f_resource + + = ' \0 ' ;
}
2006-10-18 22:57:35 +00:00
}
}
if ( to & & ( user = strdup ( to ) ) ) {
if ( ( host = strchr ( user , ' @ ' ) ) ) {
* host + + = ' \0 ' ;
}
if ( f_host & & ( profile = switch_core_hash_find ( globals . profile_hash , f_host ) ) ) {
2007-03-29 22:31:56 +00:00
2006-10-20 22:11:26 +00:00
if ( ! strcmp ( proto , MDL_CHAT_PROTO ) ) {
from = hint ;
} else {
char * p ;
ffrom = switch_mprintf ( " %s+%s " , proto , from ) ;
from = ffrom ;
if ( ( p = strchr ( from , ' / ' ) ) ) {
* p = ' \0 ' ;
}
}
2006-10-18 22:57:35 +00:00
ldl_handle_send_msg ( profile - > handle , from , to , NULL , body ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invalid Profile %s \n " , f_host ? f_host : " NULL " ) ;
2006-10-19 07:13:34 +00:00
return SWITCH_STATUS_FALSE ;
2006-10-18 22:57:35 +00:00
}
2006-10-20 22:11:26 +00:00
switch_safe_free ( user ) ;
switch_safe_free ( f_user ) ;
2006-10-18 22:57:35 +00:00
}
2006-10-19 07:13:34 +00:00
return SWITCH_STATUS_SUCCESS ;
2006-10-18 22:57:35 +00:00
}
static void roster_event_handler ( switch_event_t * event )
{
2007-03-29 22:31:56 +00:00
char * status = switch_event_get_header ( event , " status " ) ;
char * from = switch_event_get_header ( event , " from " ) ;
2006-10-18 22:57:35 +00:00
char * event_type = switch_event_get_header ( event , " event_type " ) ;
2007-04-04 17:32:56 +00:00
mdl_profile_t * profile = NULL ;
2006-10-18 22:57:35 +00:00
switch_hash_index_t * hi ;
2007-03-29 22:31:56 +00:00
void * val ;
2006-10-18 22:57:35 +00:00
char * sql ;
2007-04-04 17:32:56 +00:00
2006-10-18 22:57:35 +00:00
if ( status & & ! strcasecmp ( status , " n/a " ) ) {
2006-10-20 06:17:00 +00:00
status = NULL ;
2006-10-18 22:57:35 +00:00
}
if ( switch_strlen_zero ( event_type ) ) {
2007-03-29 22:31:56 +00:00
event_type = " presence " ;
2006-10-18 22:57:35 +00:00
}
2006-10-20 06:17:00 +00:00
if ( from ) {
2007-04-04 17:32:56 +00:00
sql = switch_mprintf ( " select *,'%q' from jabber_subscriptions where sub_from='%q' " , status ? status : " " , from ) ;
2006-10-20 06:17:00 +00:00
} else {
2007-04-04 17:32:56 +00:00
sql = switch_mprintf ( " select *,'%q' from jabber_subscriptions " , status ? status : " " ) ;
2006-10-20 06:17:00 +00:00
}
2006-10-18 22:57:35 +00:00
2007-03-30 00:13:31 +00:00
for ( hi = switch_hash_first ( switch_hash_pool_get ( globals . profile_hash ) , globals . profile_hash ) ; hi ; hi = switch_hash_next ( hi ) ) {
2007-03-29 22:31:56 +00:00
switch_hash_this ( hi , NULL , NULL , & val ) ;
2007-04-04 17:32:56 +00:00
profile = ( mdl_profile_t * ) val ;
2006-10-18 22:57:35 +00:00
2007-03-29 22:31:56 +00:00
if ( ! ( profile - > user_flags & LDL_FLAG_COMPONENT ) ) {
2006-10-18 22:57:35 +00:00
continue ;
2007-03-29 22:31:56 +00:00
}
2006-10-18 22:57:35 +00:00
if ( sql ) {
2007-04-04 17:32:56 +00:00
switch_bool_t worked = mdl_execute_sql_callback ( profile , profile - > mutex , sql , rost_callback , profile ) ;
if ( ! worked ) {
2006-10-18 22:57:35 +00:00
continue ;
}
}
2007-03-29 22:31:56 +00:00
2006-10-18 22:57:35 +00:00
}
switch_safe_free ( sql ) ;
}
2006-10-20 06:44:58 +00:00
static int so_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
2007-04-04 17:32:56 +00:00
mdl_profile_t * profile = ( mdl_profile_t * ) pArg ;
2006-10-20 06:44:58 +00:00
char * sub_from = argv [ 0 ] ;
char * sub_to = argv [ 1 ] ;
ldl_handle_send_presence ( profile - > handle , sub_to , sub_from , " unavailable " , " dnd " , " Bub-Bye " ) ;
2007-03-29 22:31:56 +00:00
2006-10-20 06:44:58 +00:00
return 0 ;
}
2006-10-22 04:37:19 +00:00
static int sin_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
2007-04-04 17:32:56 +00:00
mdl_profile_t * profile = ( mdl_profile_t * ) pArg ;
2006-10-22 04:37:19 +00:00
switch_event_t * event ;
//char *sub_from = argv[0];
char * sub_to = argv [ 1 ] ;
2007-03-29 22:31:56 +00:00
2006-10-24 18:23:23 +00:00
if ( is_special ( sub_to ) ) {
2006-10-22 04:37:19 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_PRESENCE_IN ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " proto " , MDL_CHAT_PROTO ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " login " , " %s " , profile - > login ) ;
2007-03-29 22:31:56 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " from " , " %s " , sub_to ) ;
2006-10-22 04:37:19 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " rpid " , " available " ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " status " , " Online " ) ;
switch_event_fire ( & event ) ;
}
}
return 0 ;
}
2006-10-20 06:44:58 +00:00
static void sign_off ( void )
{
2007-04-04 17:32:56 +00:00
mdl_profile_t * profile = NULL ;
2006-10-20 06:44:58 +00:00
switch_hash_index_t * hi ;
2007-03-29 22:31:56 +00:00
void * val ;
2006-10-20 06:44:58 +00:00
char * sql ;
2007-04-04 17:32:56 +00:00
sql = switch_mprintf ( " select * from jabber_subscriptions " ) ;
2006-10-20 06:44:58 +00:00
2007-03-29 22:31:56 +00:00
2007-03-30 00:13:31 +00:00
for ( hi = switch_hash_first ( switch_hash_pool_get ( globals . profile_hash ) , globals . profile_hash ) ; hi ; hi = switch_hash_next ( hi ) ) {
2007-03-29 22:31:56 +00:00
switch_hash_this ( hi , NULL , NULL , & val ) ;
2007-04-04 17:32:56 +00:00
profile = ( mdl_profile_t * ) val ;
2006-10-20 06:44:58 +00:00
2007-03-29 22:31:56 +00:00
if ( ! ( profile - > user_flags & LDL_FLAG_COMPONENT ) ) {
2006-10-20 06:44:58 +00:00
continue ;
2007-03-29 22:31:56 +00:00
}
2006-10-20 06:44:58 +00:00
if ( sql ) {
2007-04-04 17:32:56 +00:00
switch_bool_t worked = mdl_execute_sql_callback ( profile , profile - > mutex , sql , so_callback , profile ) ;
if ( ! worked ) {
2006-10-20 06:44:58 +00:00
continue ;
}
}
2007-03-29 22:31:56 +00:00
2006-10-20 06:44:58 +00:00
}
2007-03-29 22:31:56 +00:00
2006-10-20 06:44:58 +00:00
switch_yield ( 1000000 ) ;
switch_safe_free ( sql ) ;
}
2007-04-04 17:32:56 +00:00
static void sign_on ( mdl_profile_t * profile )
2006-10-22 04:37:19 +00:00
{
char * sql ;
2007-04-04 17:32:56 +00:00
if ( ( sql = switch_mprintf ( " select * from jabber_subscriptions where sub_to like 'ext+%%' or sub_to like 'user+%%' or sub_to like 'conf+%%' " ) ) ) {
mdl_execute_sql_callback ( profile , profile - > mutex , sql , sin_callback , profile ) ;
2006-10-22 04:37:19 +00:00
switch_safe_free ( sql ) ;
}
}
2006-09-22 15:22:31 +00:00
static void terminate_session ( switch_core_session_t * * session , int line , switch_call_cause_t cause )
2006-08-18 16:36:26 +00:00
{
if ( * session ) {
switch_channel_t * channel = switch_core_session_get_channel ( * session ) ;
switch_channel_state_t state = switch_channel_get_state ( channel ) ;
struct private_object * tech_pvt = NULL ;
2007-03-29 22:31:56 +00:00
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Terminate called from line %d state=%s \n " , line , switch_channel_state_name ( state ) ) ;
2007-03-29 22:31:56 +00:00
2006-08-18 16:36:26 +00:00
tech_pvt = switch_core_session_get_private ( * session ) ;
2006-10-10 00:11:41 +00:00
if ( ! tech_pvt | | ! switch_test_flag ( tech_pvt , TFLAG_READY ) ) {
2006-08-18 16:36:26 +00:00
switch_core_session_destroy ( session ) ;
2006-10-10 00:11:41 +00:00
return ;
}
2006-09-22 15:22:31 +00:00
2006-10-10 00:11:41 +00:00
if ( switch_test_flag ( tech_pvt , TFLAG_TERM ) ) {
2007-03-29 22:31:56 +00:00
/*once is enough */
2006-10-10 00:11:41 +00:00
return ;
}
2006-09-22 15:22:31 +00:00
if ( state < CS_HANGUP ) {
switch_channel_hangup ( channel , cause ) ;
}
2007-03-29 22:31:56 +00:00
2006-10-25 17:00:23 +00:00
switch_mutex_lock ( tech_pvt - > flag_mutex ) ;
switch_set_flag ( tech_pvt , TFLAG_TERM ) ;
switch_set_flag ( tech_pvt , TFLAG_BYE ) ;
switch_clear_flag ( tech_pvt , TFLAG_IO ) ;
switch_mutex_unlock ( tech_pvt - > flag_mutex ) ;
2006-09-22 15:22:31 +00:00
* session = NULL ;
2006-08-18 16:36:26 +00:00
}
2006-09-22 15:22:31 +00:00
2006-08-18 16:36:26 +00:00
}
2006-05-02 16:43:13 +00:00
static void dl_logger ( char * file , const char * func , int line , int level , char * fmt , . . . )
2006-04-14 02:05:29 +00:00
{
2006-04-14 03:04:53 +00:00
va_list ap ;
2006-04-14 03:12:55 +00:00
char data [ 1024 ] ;
2006-04-14 03:04:53 +00:00
2006-04-14 03:12:55 +00:00
va_start ( ap , fmt ) ;
2007-03-29 22:31:56 +00:00
2006-04-14 03:12:55 +00:00
vsnprintf ( data , sizeof ( data ) , fmt , ap ) ;
2007-02-14 03:45:10 +00:00
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , file , func , line , SWITCH_LOG_DEBUG , " %s " , data ) ;
2006-04-14 03:04:53 +00:00
va_end ( ap ) ;
2006-04-14 02:05:29 +00:00
}
2006-03-31 19:38:09 +00:00
2006-08-18 16:36:26 +00:00
static int get_codecs ( struct private_object * tech_pvt )
2006-03-31 19:38:09 +00:00
{
assert ( tech_pvt ! = NULL ) ;
assert ( tech_pvt - > session ! = NULL ) ;
2006-08-18 16:36:26 +00:00
if ( ! tech_pvt - > num_codecs ) {
if ( globals . codec_string ) {
if ( ( tech_pvt - > num_codecs = switch_loadable_module_get_codecs_sorted ( tech_pvt - > codecs ,
2007-03-30 00:13:31 +00:00
SWITCH_MAX_CODECS , globals . codec_order , globals . codec_order_last ) ) < = 0 ) {
2006-08-18 16:36:26 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " NO codecs? \n " ) ;
return 0 ;
}
} else if ( ( ( tech_pvt - > num_codecs =
2007-03-30 00:13:31 +00:00
switch_loadable_module_get_codecs ( switch_core_session_get_pool ( tech_pvt - > session ) , tech_pvt - > codecs , SWITCH_MAX_CODECS ) ) ) < = 0 ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " NO codecs? \n " ) ;
2006-08-18 16:36:26 +00:00
return 0 ;
2006-03-31 19:38:09 +00:00
}
}
2006-08-18 16:36:26 +00:00
return tech_pvt - > num_codecs ;
2006-03-31 19:38:09 +00:00
}
2007-03-30 00:13:31 +00:00
static void * SWITCH_THREAD_FUNC handle_thread_run ( switch_thread_t * thread , void * obj )
2006-03-31 19:38:09 +00:00
{
ldl_handle_t * handle = obj ;
2007-04-04 17:32:56 +00:00
mdl_profile_t * profile = NULL ;
2006-10-20 06:17:00 +00:00
2006-10-20 22:11:26 +00:00
2006-03-31 19:38:09 +00:00
profile = ldl_handle_get_private ( handle ) ;
globals . handles + + ;
2006-05-02 16:43:13 +00:00
switch_set_flag ( profile , TFLAG_IO ) ;
2006-03-31 19:38:09 +00:00
ldl_handle_run ( handle ) ;
2006-05-02 16:43:13 +00:00
switch_clear_flag ( profile , TFLAG_IO ) ;
2006-03-31 19:38:09 +00:00
globals . handles - - ;
ldl_handle_destroy ( & handle ) ;
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Handle %s [%s] Destroyed \n " , profile - > name , profile - > login ) ;
2007-03-29 22:31:56 +00:00
2006-03-31 19:38:09 +00:00
return NULL ;
}
2007-03-29 22:31:56 +00:00
static void handle_thread_launch ( ldl_handle_t * handle )
2006-03-31 19:38:09 +00:00
{
2006-04-29 01:00:52 +00:00
switch_thread_t * thread ;
2006-03-31 19:38:09 +00:00
switch_threadattr_t * thd_attr = NULL ;
2007-03-29 22:31:56 +00:00
2006-03-31 19:38:09 +00:00
switch_threadattr_create ( & thd_attr , module_pool ) ;
switch_threadattr_detach_set ( thd_attr , 1 ) ;
2006-04-26 17:18:33 +00:00
switch_threadattr_stacksize_set ( thd_attr , SWITCH_THREAD_STACKSIZE ) ;
2006-03-31 19:38:09 +00:00
switch_thread_create ( & thread , thd_attr , handle_thread_run , handle , module_pool ) ;
}
2006-04-15 22:30:25 +00:00
static int activate_rtp ( struct private_object * tech_pvt )
2006-03-31 19:38:09 +00:00
{
2006-04-29 06:05:03 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( tech_pvt - > session ) ;
2006-04-15 22:30:25 +00:00
const char * err ;
2006-09-07 15:08:40 +00:00
int ms = 0 ;
2006-05-24 16:10:05 +00:00
switch_rtp_flag_t flags ;
2006-03-31 19:38:09 +00:00
2006-08-28 23:05:26 +00:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
2006-08-18 01:28:50 +00:00
return 1 ;
2006-04-15 22:30:25 +00:00
}
2006-03-31 19:38:09 +00:00
2007-03-29 22:31:56 +00:00
if ( ! ( tech_pvt - > remote_ip & & tech_pvt - > remote_port ) ) {
2007-02-08 21:08:45 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " No valid candidates received! \n " ) ;
2007-03-29 22:31:56 +00:00
return 0 ;
}
2006-12-19 20:24:07 +00:00
2006-04-15 22:30:25 +00:00
if ( switch_core_codec_init ( & tech_pvt - > read_codec ,
2006-08-18 16:36:26 +00:00
tech_pvt - > codec_name ,
2006-10-09 02:24:43 +00:00
NULL ,
2006-08-18 16:36:26 +00:00
tech_pvt - > codec_rate ,
ms ,
1 ,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE ,
NULL , switch_core_session_get_pool ( tech_pvt - > session ) ) ! = SWITCH_STATUS_SUCCESS ) {
2006-04-15 22:30:25 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Can't load codec? \n " ) ;
2006-04-22 03:05:25 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2006-08-18 01:28:50 +00:00
return 0 ;
2006-04-15 22:30:25 +00:00
}
tech_pvt - > read_frame . rate = tech_pvt - > read_codec . implementation - > samples_per_second ;
tech_pvt - > read_frame . codec = & tech_pvt - > read_codec ;
2006-03-31 19:38:09 +00:00
2007-03-29 22:31:56 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Set Read Codec to %s@%d \n " ,
tech_pvt - > codec_name , ( int ) tech_pvt - > read_codec . implementation - > samples_per_second ) ;
2006-04-15 22:30:25 +00:00
if ( switch_core_codec_init ( & tech_pvt - > write_codec ,
2006-08-18 16:36:26 +00:00
tech_pvt - > codec_name ,
2006-10-09 02:24:43 +00:00
NULL ,
2006-08-18 16:36:26 +00:00
tech_pvt - > codec_rate ,
ms ,
1 ,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE ,
NULL , switch_core_session_get_pool ( tech_pvt - > session ) ) ! = SWITCH_STATUS_SUCCESS ) {
2006-04-15 22:30:25 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Can't load codec? \n " ) ;
2006-04-22 03:05:25 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2006-08-18 01:28:50 +00:00
return 0 ;
2006-04-15 22:30:25 +00:00
}
2007-03-29 22:31:56 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Set Write Codec to %s@%d \n " ,
tech_pvt - > codec_name , ( int ) tech_pvt - > write_codec . implementation - > samples_per_second ) ;
2006-04-15 22:30:25 +00:00
switch_core_session_set_read_codec ( tech_pvt - > session , & tech_pvt - > read_codec ) ;
switch_core_session_set_write_codec ( tech_pvt - > session , & tech_pvt - > write_codec ) ;
2006-04-15 05:56:23 +00:00
2007-03-29 22:31:56 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " SETUP RTP %s:%d -> %s:%d \n " , tech_pvt - > profile - > ip ,
tech_pvt - > local_port , tech_pvt - > remote_ip , tech_pvt - > remote_port ) ;
2006-05-24 16:10:05 +00:00
flags = SWITCH_RTP_FLAG_GOOGLEHACK | SWITCH_RTP_FLAG_AUTOADJ ;
2006-08-18 01:28:50 +00:00
//flags = SWITCH_RTP_FLAG_AUTOADJ;
2006-05-24 16:10:05 +00:00
if ( switch_test_flag ( tech_pvt - > profile , TFLAG_TIMER ) ) {
2007-03-29 22:31:56 +00:00
flags | = SWITCH_RTP_FLAG_USE_TIMER ;
2006-05-24 16:10:05 +00:00
}
2006-04-15 22:30:25 +00:00
2007-03-07 18:34:22 +00:00
flags | = SWITCH_RTP_FLAG_AUTO_CNG ;
2006-04-15 22:30:25 +00:00
if ( ! ( tech_pvt - > rtp_session = switch_rtp_new ( tech_pvt - > profile - > ip ,
2006-07-18 18:34:42 +00:00
tech_pvt - > local_port ,
tech_pvt - > remote_ip ,
tech_pvt - > remote_port ,
tech_pvt - > codec_num ,
2007-03-29 22:31:56 +00:00
tech_pvt - > read_codec . implementation - > encoded_bytes_per_frame ,
2006-07-18 18:34:42 +00:00
tech_pvt - > read_codec . implementation - > microseconds_per_frame ,
2007-03-30 00:13:31 +00:00
flags , NULL , tech_pvt - > profile - > timer_name , & err , switch_core_session_get_pool ( tech_pvt - > session ) ) ) ) {
2006-04-15 22:30:25 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " RTP ERROR %s \n " , err ) ;
2006-04-22 03:05:25 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2006-08-18 01:28:50 +00:00
return 0 ;
2006-04-21 22:31:08 +00:00
} else {
uint8_t vad_in = switch_test_flag ( tech_pvt , TFLAG_VAD_IN ) ? 1 : 0 ;
uint8_t vad_out = switch_test_flag ( tech_pvt , TFLAG_VAD_OUT ) ? 1 : 0 ;
uint8_t inb = switch_test_flag ( tech_pvt , TFLAG_OUTBOUND ) ? 0 : 1 ;
switch_rtp_activate_ice ( tech_pvt - > rtp_session , tech_pvt - > remote_user , tech_pvt - > local_user ) ;
if ( ( vad_in & & inb ) | | ( vad_out & & ! inb ) ) {
2007-03-30 00:13:31 +00:00
switch_rtp_enable_vad ( tech_pvt - > rtp_session , tech_pvt - > session , & tech_pvt - > read_codec , SWITCH_VAD_FLAG_TALKING ) ;
2006-06-23 16:59:47 +00:00
switch_set_flag_locked ( tech_pvt , TFLAG_VAD ) ;
2006-04-21 22:31:08 +00:00
}
2007-03-17 01:52:05 +00:00
switch_rtp_set_cng_pt ( tech_pvt - > rtp_session , 13 ) ;
switch_rtp_set_telephony_event ( tech_pvt - > rtp_session , 101 ) ;
2006-04-13 17:15:51 +00:00
}
2006-03-31 19:38:09 +00:00
2006-08-18 01:28:50 +00:00
return 1 ;
2006-04-15 22:30:25 +00:00
}
2006-03-31 19:38:09 +00:00
2006-04-15 22:30:25 +00:00
static int do_candidates ( struct private_object * tech_pvt , int force )
{
2006-04-29 06:05:03 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( tech_pvt - > session ) ;
2006-04-15 22:30:25 +00:00
assert ( channel ! = NULL ) ;
2006-04-15 16:02:31 +00:00
2006-04-22 01:49:27 +00:00
if ( switch_test_flag ( tech_pvt , TFLAG_DO_CAND ) ) {
2006-08-18 16:36:26 +00:00
return 1 ;
2006-04-22 01:49:27 +00:00
}
2006-04-15 22:30:25 +00:00
tech_pvt - > next_cand + = DL_CAND_WAIT ;
2006-04-22 01:21:53 +00:00
if ( switch_test_flag ( tech_pvt , TFLAG_BYE ) ) {
2006-08-18 16:36:26 +00:00
return 0 ;
2006-04-22 01:21:53 +00:00
}
2006-06-23 16:59:47 +00:00
switch_set_flag_locked ( tech_pvt , TFLAG_DO_CAND ) ;
2006-04-15 16:02:31 +00:00
2006-04-15 22:30:25 +00:00
if ( force | | ! switch_test_flag ( tech_pvt , TFLAG_RTP_READY ) ) {
2006-04-27 15:59:58 +00:00
ldl_candidate_t cand [ 1 ] ;
char * advip = tech_pvt - > profile - > extip ? tech_pvt - > profile - > extip : tech_pvt - > profile - > ip ;
char * err ;
memset ( cand , 0 , sizeof ( cand ) ) ;
switch_stun_random_string ( tech_pvt - > local_user , 16 , NULL ) ;
switch_stun_random_string ( tech_pvt - > local_pass , 16 , NULL ) ;
2006-04-05 22:46:50 +00:00
2006-04-27 15:59:58 +00:00
if ( switch_test_flag ( tech_pvt , TFLAG_LANADDR ) ) {
advip = tech_pvt - > profile - > ip ;
}
2006-03-31 19:38:09 +00:00
2006-04-05 22:46:50 +00:00
2006-04-27 15:59:58 +00:00
cand [ 0 ] . port = tech_pvt - > local_port ;
cand [ 0 ] . address = advip ;
2007-03-29 22:31:56 +00:00
2006-04-27 15:59:58 +00:00
if ( ! strncasecmp ( advip , " stun: " , 5 ) ) {
char * stun_ip = advip + 5 ;
2007-03-29 22:31:56 +00:00
2006-04-27 15:59:58 +00:00
if ( tech_pvt - > stun_ip ) {
cand [ 0 ] . address = tech_pvt - > stun_ip ;
cand [ 0 ] . port = tech_pvt - > stun_port ;
} else {
if ( ! stun_ip ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Stun Failed! NO STUN SERVER! \n " ) ;
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2006-08-18 16:36:26 +00:00
return 0 ;
2006-04-05 22:46:50 +00:00
}
2006-04-27 15:59:58 +00:00
cand [ 0 ] . address = tech_pvt - > profile - > ip ;
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Stun Lookup Local %s:%d \n " , cand [ 0 ] . address , cand [ 0 ] . port ) ;
2007-03-29 22:31:56 +00:00
if ( switch_stun_lookup
( & cand [ 0 ] . address , & cand [ 0 ] . port , stun_ip , SWITCH_STUN_DEFAULT_PORT , & err ,
switch_core_session_get_pool ( tech_pvt - > session ) ) ! = SWITCH_STATUS_SUCCESS ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Stun Failed! %s:%d [%s] \n " , stun_ip , SWITCH_STUN_DEFAULT_PORT , err ) ;
2006-04-27 15:59:58 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2006-08-18 16:36:26 +00:00
return 0 ;
2006-04-27 15:59:58 +00:00
}
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Stun Success %s:%d \n " , cand [ 0 ] . address , cand [ 0 ] . port ) ;
2006-03-31 19:38:09 +00:00
}
2006-04-27 15:59:58 +00:00
cand [ 0 ] . type = " stun " ;
tech_pvt - > stun_ip = switch_core_session_strdup ( tech_pvt - > session , cand [ 0 ] . address ) ;
tech_pvt - > stun_port = cand [ 0 ] . port ;
} else {
cand [ 0 ] . type = " local " ;
}
cand [ 0 ] . name = " rtp " ;
cand [ 0 ] . username = tech_pvt - > local_user ;
cand [ 0 ] . password = tech_pvt - > local_pass ;
cand [ 0 ] . pref = 1 ;
cand [ 0 ] . protocol = " udp " ;
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Send Candidate %s:%d [%s] \n " , cand [ 0 ] . address , cand [ 0 ] . port , cand [ 0 ] . username ) ;
2006-04-27 15:59:58 +00:00
tech_pvt - > cand_id = ldl_session_candidates ( tech_pvt - > dlsession , cand , 1 ) ;
2006-11-16 15:50:17 +00:00
switch_set_flag_locked ( tech_pvt , TFLAG_TRANSPORT ) ;
2006-06-23 16:59:47 +00:00
switch_set_flag_locked ( tech_pvt , TFLAG_RTP_READY ) ;
2006-04-27 15:59:58 +00:00
}
2006-06-23 16:59:47 +00:00
switch_clear_flag_locked ( tech_pvt , TFLAG_DO_CAND ) ;
2006-08-18 16:36:26 +00:00
return 1 ;
2006-04-15 22:30:25 +00:00
}
2006-04-19 20:38:02 +00:00
static char * lame ( char * in )
{
if ( ! strncasecmp ( in , " ilbc " , 4 ) ) {
return " iLBC " ;
} else {
return in ;
}
}
2006-04-15 22:30:25 +00:00
static int do_describe ( struct private_object * tech_pvt , int force )
{
ldl_payload_t payloads [ 5 ] ;
2006-08-30 22:03:52 +00:00
if ( ! tech_pvt - > session ) {
return 0 ;
}
2006-04-15 22:30:25 +00:00
2006-04-22 01:49:27 +00:00
if ( switch_test_flag ( tech_pvt , TFLAG_DO_DESC ) ) {
2006-08-18 16:36:26 +00:00
return 1 ;
2006-04-22 01:49:27 +00:00
}
2006-04-15 22:30:25 +00:00
tech_pvt - > next_desc + = DL_CAND_WAIT ;
2006-04-22 01:21:53 +00:00
if ( switch_test_flag ( tech_pvt , TFLAG_BYE ) ) {
2006-08-18 16:36:26 +00:00
return 0 ;
2006-04-22 01:21:53 +00:00
}
2006-04-15 22:30:25 +00:00
memset ( payloads , 0 , sizeof ( payloads ) ) ;
2006-06-23 16:59:47 +00:00
switch_set_flag_locked ( tech_pvt , TFLAG_DO_CAND ) ;
2006-08-18 16:36:26 +00:00
if ( ! get_codecs ( tech_pvt ) ) {
2006-09-22 15:22:31 +00:00
terminate_session ( & tech_pvt - > session , __LINE__ , SWITCH_CAUSE_INCOMPATIBLE_DESTINATION ) ;
2006-08-18 16:36:26 +00:00
switch_set_flag_locked ( tech_pvt , TFLAG_BYE ) ;
switch_clear_flag_locked ( tech_pvt , TFLAG_IO ) ;
return 0 ;
2006-03-31 19:38:09 +00:00
}
2006-08-18 16:36:26 +00:00
2006-04-15 22:30:25 +00:00
if ( force | | ! switch_test_flag ( tech_pvt , TFLAG_CODEC_READY ) ) {
if ( tech_pvt - > codec_index < 0 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Don't have my codec yet here's one \n " ) ;
2006-07-10 22:08:02 +00:00
tech_pvt - > codec_name = lame ( tech_pvt - > codecs [ 0 ] - > iananame ) ;
tech_pvt - > codec_num = tech_pvt - > codecs [ 0 ] - > ianacode ;
2006-08-18 16:36:26 +00:00
tech_pvt - > codec_rate = tech_pvt - > codecs [ 0 ] - > samples_per_second ;
2006-08-18 01:28:50 +00:00
tech_pvt - > r_codec_num = tech_pvt - > codecs [ 0 ] - > ianacode ;
2006-04-15 22:30:25 +00:00
tech_pvt - > codec_index = 0 ;
2007-03-29 22:31:56 +00:00
2006-07-10 22:08:02 +00:00
payloads [ 0 ] . name = lame ( tech_pvt - > codecs [ 0 ] - > iananame ) ;
payloads [ 0 ] . id = tech_pvt - > codecs [ 0 ] - > ianacode ;
2006-08-18 01:28:50 +00:00
payloads [ 0 ] . rate = tech_pvt - > codecs [ 0 ] - > samples_per_second ;
payloads [ 0 ] . bps = tech_pvt - > codecs [ 0 ] - > bits_per_second ;
2007-03-29 22:31:56 +00:00
2006-04-15 22:30:25 +00:00
} else {
2006-07-10 22:08:02 +00:00
payloads [ 0 ] . name = lame ( tech_pvt - > codecs [ tech_pvt - > codec_index ] - > iananame ) ;
payloads [ 0 ] . id = tech_pvt - > codecs [ tech_pvt - > codec_index ] - > ianacode ;
2006-08-23 21:08:28 +00:00
payloads [ 0 ] . rate = tech_pvt - > codecs [ tech_pvt - > codec_index ] - > samples_per_second ;
payloads [ 0 ] . bps = tech_pvt - > codecs [ tech_pvt - > codec_index ] - > bits_per_second ;
2006-04-15 22:30:25 +00:00
}
2006-03-31 19:38:09 +00:00
2007-03-29 22:31:56 +00:00
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Send Describe [%s@%d] \n " , payloads [ 0 ] . name , payloads [ 0 ] . rate ) ;
2007-03-29 22:31:56 +00:00
tech_pvt - > desc_id =
ldl_session_describe ( tech_pvt - > dlsession , payloads , 1 ,
2007-03-30 00:13:31 +00:00
switch_test_flag ( tech_pvt , TFLAG_OUTBOUND ) ? LDL_DESCRIPTION_INITIATE : LDL_DESCRIPTION_ACCEPT ) ;
2006-06-23 16:59:47 +00:00
switch_set_flag_locked ( tech_pvt , TFLAG_CODEC_READY ) ;
2007-03-29 22:31:56 +00:00
}
2006-06-23 16:59:47 +00:00
switch_clear_flag_locked ( tech_pvt , TFLAG_DO_CAND ) ;
2006-08-18 16:36:26 +00:00
return 1 ;
2006-04-15 22:30:25 +00:00
}
2006-03-31 19:38:09 +00:00
2006-10-10 00:11:41 +00:00
static switch_status_t negotiate_media ( switch_core_session_t * session )
2006-04-15 22:30:25 +00:00
{
2006-10-10 00:11:41 +00:00
switch_status_t ret = SWITCH_STATUS_FALSE ;
2006-04-29 06:05:03 +00:00
switch_channel_t * channel ;
2006-04-15 22:30:25 +00:00
struct private_object * tech_pvt = NULL ;
switch_time_t started ;
switch_time_t now ;
unsigned int elapsed ;
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
2006-06-23 16:59:47 +00:00
switch_set_flag_locked ( tech_pvt , TFLAG_IO ) ;
2006-04-15 22:30:25 +00:00
started = switch_time_now ( ) ;
2007-02-13 15:47:15 +00:00
/* jingle has no ringing indication so we will just pretend that we got one */
switch_core_session_queue_indication ( session , SWITCH_MESSAGE_INDICATE_RINGING ) ;
switch_channel_mark_ring_ready ( channel ) ;
2007-03-29 22:31:56 +00:00
2006-04-15 22:30:25 +00:00
if ( switch_test_flag ( tech_pvt , TFLAG_OUTBOUND ) ) {
2006-11-16 15:50:17 +00:00
tech_pvt - > next_cand = switch_time_now ( ) + DL_CAND_WAIT ;
2006-04-15 22:30:25 +00:00
tech_pvt - > next_desc = switch_time_now ( ) ;
} else {
tech_pvt - > next_cand = switch_time_now ( ) + DL_CAND_WAIT ;
tech_pvt - > next_desc = switch_time_now ( ) + DL_CAND_WAIT ;
2006-03-31 19:38:09 +00:00
}
2007-03-29 22:31:56 +00:00
while ( ! ( switch_test_flag ( tech_pvt , TFLAG_CODEC_READY ) & &
switch_test_flag ( tech_pvt , TFLAG_RTP_READY ) & &
2007-03-30 00:15:25 +00:00
switch_test_flag ( tech_pvt , TFLAG_ANSWER ) & & switch_test_flag ( tech_pvt , TFLAG_TRANSPORT_ACCEPT )
& & switch_test_flag ( tech_pvt , TFLAG_TRANSPORT ) ) ) {
2006-04-15 22:30:25 +00:00
now = switch_time_now ( ) ;
2007-03-29 22:31:56 +00:00
elapsed = ( unsigned int ) ( ( now - started ) / 1000 ) ;
2006-04-15 22:30:25 +00:00
if ( switch_channel_get_state ( channel ) > = CS_HANGUP | | switch_test_flag ( tech_pvt , TFLAG_BYE ) ) {
2006-08-18 01:28:50 +00:00
goto out ;
2006-04-15 22:30:25 +00:00
}
2007-03-29 22:31:56 +00:00
2006-04-15 22:30:25 +00:00
if ( now > = tech_pvt - > next_desc ) {
2006-08-18 16:36:26 +00:00
if ( ! do_describe ( tech_pvt , 0 ) ) {
goto out ;
2006-04-15 22:30:25 +00:00
}
}
2007-03-29 22:31:56 +00:00
2006-04-15 22:30:25 +00:00
if ( tech_pvt - > next_cand & & now > = tech_pvt - > next_cand ) {
2006-08-18 16:36:26 +00:00
if ( ! do_candidates ( tech_pvt , 0 ) ) {
goto out ;
2006-04-15 22:30:25 +00:00
}
}
if ( elapsed > 60000 ) {
2007-03-29 22:31:56 +00:00
terminate_session ( & tech_pvt - > session , __LINE__ , SWITCH_CAUSE_NORMAL_CLEARING ) ;
2006-06-23 16:59:47 +00:00
switch_set_flag_locked ( tech_pvt , TFLAG_BYE ) ;
switch_clear_flag_locked ( tech_pvt , TFLAG_IO ) ;
2006-09-22 15:22:31 +00:00
goto done ;
2006-04-15 22:30:25 +00:00
}
2007-03-29 22:31:56 +00:00
if ( switch_test_flag ( tech_pvt , TFLAG_BYE ) | | ! switch_test_flag ( tech_pvt , TFLAG_IO ) ) {
2006-09-22 15:22:31 +00:00
goto done ;
2006-04-12 20:48:47 +00:00
}
2006-04-15 22:30:25 +00:00
switch_yield ( 1000 ) ;
2006-04-12 20:48:47 +00:00
}
2007-03-29 22:31:56 +00:00
2006-04-15 22:30:25 +00:00
if ( switch_channel_get_state ( channel ) > = CS_HANGUP | | switch_test_flag ( tech_pvt , TFLAG_BYE ) ) {
2006-08-18 01:28:50 +00:00
goto out ;
2007-03-29 22:31:56 +00:00
}
2006-04-12 20:48:47 +00:00
2006-08-18 01:28:50 +00:00
if ( ! activate_rtp ( tech_pvt ) ) {
goto out ;
}
2007-03-29 22:31:56 +00:00
2006-03-31 19:38:09 +00:00
if ( switch_test_flag ( tech_pvt , TFLAG_OUTBOUND ) ) {
2006-08-18 16:36:26 +00:00
if ( ! do_candidates ( tech_pvt , 0 ) ) {
goto out ;
}
2006-03-31 19:38:09 +00:00
switch_channel_answer ( channel ) ;
2007-03-29 22:31:56 +00:00
}
2006-10-10 00:11:41 +00:00
ret = SWITCH_STATUS_SUCCESS ;
2006-09-22 15:22:31 +00:00
goto done ;
2007-03-29 22:31:56 +00:00
out :
terminate_session ( & session , __LINE__ , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
done :
2006-03-31 19:38:09 +00:00
2006-10-10 00:11:41 +00:00
return ret ;
2006-03-31 19:38:09 +00:00
}
/*
2006-04-27 15:59:58 +00:00
State methods they get called when the state changes to the specific state
returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next
so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it .
2006-03-31 19:38:09 +00:00
*/
2006-04-29 23:43:28 +00:00
static switch_status_t channel_on_init ( switch_core_session_t * session )
2006-03-31 19:38:09 +00:00
{
2006-04-29 06:05:03 +00:00
switch_channel_t * channel ;
2006-03-31 19:38:09 +00:00
struct private_object * tech_pvt = NULL ;
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
2006-04-06 19:50:53 +00:00
tech_pvt - > read_frame . buflen = SWITCH_RTP_MAX_BUF_LEN ;
2006-10-10 00:11:41 +00:00
switch_set_flag ( tech_pvt , TFLAG_READY ) ;
if ( negotiate_media ( session ) = = SWITCH_STATUS_SUCCESS ) {
/* Move Channel's State Machine to RING */
switch_channel_set_state ( channel , CS_RING ) ;
}
2006-03-31 19:38:09 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 23:43:28 +00:00
static switch_status_t channel_on_ring ( switch_core_session_t * session )
2006-03-31 19:38:09 +00:00
{
2006-04-29 06:05:03 +00:00
switch_channel_t * channel = NULL ;
2006-03-31 19:38:09 +00:00
struct private_object * tech_pvt = NULL ;
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
2007-03-29 22:31:56 +00:00
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " %s CHANNEL RING \n " , switch_channel_get_name ( channel ) ) ;
2006-03-31 19:38:09 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 23:43:28 +00:00
static switch_status_t channel_on_execute ( switch_core_session_t * session )
2006-03-31 19:38:09 +00:00
{
2006-04-29 06:05:03 +00:00
switch_channel_t * channel = NULL ;
2006-03-31 19:38:09 +00:00
struct private_object * tech_pvt = NULL ;
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " %s CHANNEL EXECUTE \n " , switch_channel_get_name ( channel ) ) ;
2006-03-31 19:38:09 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 23:43:28 +00:00
static switch_status_t channel_on_hangup ( switch_core_session_t * session )
2006-03-31 19:38:09 +00:00
{
2006-04-29 06:05:03 +00:00
switch_channel_t * channel = NULL ;
2006-03-31 19:38:09 +00:00
struct private_object * tech_pvt = NULL ;
2007-03-29 22:31:56 +00:00
2006-03-31 19:38:09 +00:00
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
2006-06-23 16:59:47 +00:00
switch_clear_flag_locked ( tech_pvt , TFLAG_IO ) ;
switch_clear_flag_locked ( tech_pvt , TFLAG_VOICE ) ;
switch_set_flag_locked ( tech_pvt , TFLAG_BYE ) ;
2006-10-24 18:23:23 +00:00
/* Dunno why, but if googletalk calls us for the first time, as soon as the call ends
2007-03-29 22:31:56 +00:00
they think we are offline for no reason so we send this presence packet to stop it from happening
We should find out why . . . . .
*/
if ( ( tech_pvt - > profile - > user_flags & LDL_FLAG_COMPONENT ) & & is_special ( tech_pvt - > them ) ) {
ldl_handle_send_presence ( tech_pvt - > profile - > handle , tech_pvt - > them , tech_pvt - > us , NULL , NULL , " Click To Call " ) ;
2006-10-24 18:23:23 +00:00
}
2006-03-31 19:38:09 +00:00
if ( tech_pvt - > dlsession ) {
2006-08-18 18:44:11 +00:00
if ( ! switch_test_flag ( tech_pvt , TFLAG_TERM ) ) {
ldl_session_terminate ( tech_pvt - > dlsession ) ;
switch_set_flag_locked ( tech_pvt , TFLAG_TERM ) ;
}
2006-03-31 19:38:09 +00:00
ldl_session_destroy ( & tech_pvt - > dlsession ) ;
}
2006-08-28 23:05:26 +00:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
2006-04-03 21:00:13 +00:00
switch_rtp_destroy ( & tech_pvt - > rtp_session ) ;
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " NUKE RTP \n " ) ;
2006-03-31 19:38:09 +00:00
tech_pvt - > rtp_session = NULL ;
}
if ( tech_pvt - > read_codec . implementation ) {
switch_core_codec_destroy ( & tech_pvt - > read_codec ) ;
}
if ( tech_pvt - > write_codec . implementation ) {
switch_core_codec_destroy ( & tech_pvt - > write_codec ) ;
}
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " %s CHANNEL HANGUP \n " , switch_channel_get_name ( channel ) ) ;
2006-03-31 19:38:09 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 23:43:28 +00:00
static switch_status_t channel_kill_channel ( switch_core_session_t * session , int sig )
2006-03-31 19:38:09 +00:00
{
2006-04-29 06:05:03 +00:00
switch_channel_t * channel = NULL ;
2006-03-31 19:38:09 +00:00
struct private_object * tech_pvt = NULL ;
2007-03-29 22:31:56 +00:00
if ( ! ( channel = switch_core_session_get_channel ( session ) ) ) {
return SWITCH_STATUS_SUCCESS ;
}
if ( ! ( tech_pvt = switch_core_session_get_private ( session ) ) ) {
return SWITCH_STATUS_SUCCESS ;
}
switch ( sig ) {
case SWITCH_SIG_KILL :
switch_clear_flag_locked ( tech_pvt , TFLAG_IO ) ;
switch_clear_flag_locked ( tech_pvt , TFLAG_VOICE ) ;
switch_set_flag_locked ( tech_pvt , TFLAG_BYE ) ;
if ( tech_pvt - > dlsession ) {
if ( ! switch_test_flag ( tech_pvt , TFLAG_TERM ) ) {
ldl_session_terminate ( tech_pvt - > dlsession ) ;
switch_set_flag_locked ( tech_pvt , TFLAG_TERM ) ;
}
ldl_session_destroy ( & tech_pvt - > dlsession ) ;
}
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
switch_rtp_kill_socket ( tech_pvt - > rtp_session ) ;
}
break ;
2006-12-21 16:46:11 +00:00
case SWITCH_SIG_BREAK :
2007-03-29 22:31:56 +00:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
2007-02-23 18:04:52 +00:00
switch_rtp_set_flag ( tech_pvt - > rtp_session , SWITCH_RTP_FLAG_BREAK ) ;
}
2006-12-21 16:46:11 +00:00
break ;
2007-03-29 22:31:56 +00:00
}
2006-08-18 16:36:26 +00:00
2007-03-29 22:31:56 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " %s CHANNEL KILL \n " , switch_channel_get_name ( channel ) ) ;
2006-08-18 16:36:26 +00:00
2006-03-31 19:38:09 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 23:43:28 +00:00
static switch_status_t channel_on_loopback ( switch_core_session_t * session )
2006-03-31 19:38:09 +00:00
{
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " CHANNEL LOOPBACK \n " ) ;
2006-03-31 19:38:09 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 23:43:28 +00:00
static switch_status_t channel_on_transmit ( switch_core_session_t * session )
2006-03-31 19:38:09 +00:00
{
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " CHANNEL TRANSMIT \n " ) ;
2006-03-31 19:38:09 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 23:43:28 +00:00
static switch_status_t channel_waitfor_read ( switch_core_session_t * session , int ms , int stream_id )
2006-03-31 19:38:09 +00:00
{
struct private_object * tech_pvt = NULL ;
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 23:43:28 +00:00
static switch_status_t channel_waitfor_write ( switch_core_session_t * session , int ms , int stream_id )
2006-03-31 19:38:09 +00:00
{
struct private_object * tech_pvt = NULL ;
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 23:43:28 +00:00
static switch_status_t channel_send_dtmf ( switch_core_session_t * session , char * dtmf )
2006-03-31 19:38:09 +00:00
{
struct private_object * tech_pvt = NULL ;
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
2006-05-03 23:45:07 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " DTMF [%s] \n " , dtmf ) ;
2006-03-31 19:38:09 +00:00
2007-03-30 00:13:31 +00:00
return switch_rtp_queue_rfc2833 ( tech_pvt - > rtp_session , dtmf , 100 * ( tech_pvt - > read_codec . implementation - > samples_per_second / 1000 ) ) ;
2006-05-04 17:51:53 +00:00
2006-03-31 19:38:09 +00:00
}
2007-03-30 00:13:31 +00:00
static switch_status_t channel_read_frame ( switch_core_session_t * session , switch_frame_t * * frame , int timeout , switch_io_flag_t flags , int stream_id )
2006-03-31 19:38:09 +00:00
{
struct private_object * tech_pvt = NULL ;
2006-04-09 00:10:13 +00:00
uint32_t bytes = 0 ;
switch_size_t samples = 0 , frames = 0 , ms = 0 ;
2006-04-29 06:05:03 +00:00
switch_channel_t * channel = NULL ;
2006-04-18 16:50:34 +00:00
switch_payload_t payload = 0 ;
2006-04-29 23:43:28 +00:00
switch_status_t status ;
2006-03-31 19:38:09 +00:00
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
2006-04-13 00:47:16 +00:00
if ( ! tech_pvt - > rtp_session ) {
return SWITCH_STATUS_FALSE ;
}
2006-03-31 19:38:09 +00:00
2006-10-25 17:00:23 +00:00
if ( switch_test_flag ( tech_pvt , TFLAG_BYE ) ) {
//terminate_session(&session, __LINE__, SWITCH_CAUSE_NORMAL_CLEARING);
return SWITCH_STATUS_FALSE ;
}
2006-03-31 19:38:09 +00:00
tech_pvt - > read_frame . datalen = 0 ;
2006-06-23 16:59:47 +00:00
switch_set_flag_locked ( tech_pvt , TFLAG_READING ) ;
2006-03-31 19:38:09 +00:00
bytes = tech_pvt - > read_codec . implementation - > encoded_bytes_per_frame ;
samples = tech_pvt - > read_codec . implementation - > samples_per_frame ;
ms = tech_pvt - > read_codec . implementation - > microseconds_per_frame ;
tech_pvt - > read_frame . datalen = 0 ;
2007-03-29 22:31:56 +00:00
while ( ! switch_test_flag ( tech_pvt , TFLAG_BYE ) & & switch_test_flag ( tech_pvt , TFLAG_IO )
& & tech_pvt - > read_frame . datalen = = 0 ) {
2006-04-06 19:50:53 +00:00
tech_pvt - > read_frame . flags = 0 ;
2006-04-18 16:40:18 +00:00
status = switch_rtp_zerocopy_read_frame ( tech_pvt - > rtp_session , & tech_pvt - > read_frame ) ;
2007-03-29 22:31:56 +00:00
2006-04-18 16:40:18 +00:00
if ( status ! = SWITCH_STATUS_SUCCESS & & status ! = SWITCH_STATUS_BREAK ) {
2006-04-10 18:28:46 +00:00
return SWITCH_STATUS_FALSE ;
2006-04-18 16:40:18 +00:00
}
payload = tech_pvt - > read_frame . payload ;
2006-03-31 19:38:09 +00:00
2006-05-05 16:03:15 +00:00
if ( switch_rtp_has_dtmf ( tech_pvt - > rtp_session ) ) {
char dtmf [ 128 ] ;
switch_rtp_dequeue_dtmf ( tech_pvt - > rtp_session , dtmf , sizeof ( dtmf ) ) ;
switch_channel_queue_dtmf ( channel , dtmf ) ;
2006-06-23 16:59:47 +00:00
switch_set_flag_locked ( tech_pvt , TFLAG_DTMF ) ;
2006-05-05 16:03:15 +00:00
}
2006-05-04 01:08:03 +00:00
if ( switch_test_flag ( tech_pvt , TFLAG_DTMF ) ) {
2006-06-23 16:59:47 +00:00
switch_clear_flag_locked ( tech_pvt , TFLAG_DTMF ) ;
2006-05-04 01:08:03 +00:00
return SWITCH_STATUS_BREAK ;
}
2006-05-03 23:45:07 +00:00
2006-04-13 16:19:49 +00:00
if ( switch_test_flag ( & tech_pvt - > read_frame , SFF_CNG ) ) {
2007-03-30 00:13:31 +00:00
tech_pvt - > read_frame . datalen = tech_pvt - > last_read ? tech_pvt - > last_read : tech_pvt - > read_codec . implementation - > encoded_bytes_per_frame ;
2006-04-13 16:19:49 +00:00
}
2006-04-13 23:19:33 +00:00
2006-03-31 19:38:09 +00:00
if ( tech_pvt - > read_frame . datalen > 0 ) {
2007-03-29 22:31:56 +00:00
if ( ! switch_test_flag ( ( & tech_pvt - > read_frame ) , SFF_CNG ) ) {
if ( tech_pvt - > read_codec . implementation - > encoded_bytes_per_frame & & bytes ) {
bytes = tech_pvt - > read_codec . implementation - > encoded_bytes_per_frame ;
frames = ( tech_pvt - > read_frame . datalen / bytes ) ;
} else {
frames = 1 ;
}
samples = frames * tech_pvt - > read_codec . implementation - > samples_per_frame ;
ms = frames * tech_pvt - > read_codec . implementation - > microseconds_per_frame ;
tech_pvt - > timestamp_recv + = ( int32_t ) samples ;
tech_pvt - > read_frame . samples = ( int ) samples ;
tech_pvt - > last_read = tech_pvt - > read_frame . datalen ;
}
2006-03-31 19:38:09 +00:00
break ;
}
switch_yield ( 1000 ) ;
}
2006-06-23 16:59:47 +00:00
switch_clear_flag_locked ( tech_pvt , TFLAG_READING ) ;
2006-03-31 19:38:09 +00:00
* frame = & tech_pvt - > read_frame ;
return SWITCH_STATUS_SUCCESS ;
}
2007-03-30 00:13:31 +00:00
static switch_status_t channel_write_frame ( switch_core_session_t * session , switch_frame_t * frame , int timeout , switch_io_flag_t flags , int stream_id )
2006-03-31 19:38:09 +00:00
{
struct private_object * tech_pvt ;
2006-04-29 06:05:03 +00:00
switch_channel_t * channel = NULL ;
2006-04-29 23:43:28 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2006-03-31 19:38:09 +00:00
int bytes = 0 , samples = 0 , frames = 0 ;
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
2006-04-13 00:47:16 +00:00
if ( ! tech_pvt - > rtp_session ) {
return SWITCH_STATUS_FALSE ;
}
2006-03-31 19:38:09 +00:00
if ( ! switch_test_flag ( tech_pvt , TFLAG_RTP_READY ) ) {
return SWITCH_STATUS_SUCCESS ;
}
if ( switch_test_flag ( tech_pvt , TFLAG_BYE ) ) {
return SWITCH_STATUS_FALSE ;
}
2006-06-23 16:59:47 +00:00
switch_set_flag_locked ( tech_pvt , TFLAG_WRITING ) ;
2006-03-31 19:38:09 +00:00
2006-07-18 18:34:42 +00:00
if ( tech_pvt - > read_codec . implementation - > encoded_bytes_per_frame ) {
bytes = tech_pvt - > read_codec . implementation - > encoded_bytes_per_frame ;
frames = ( ( int ) frame - > datalen / bytes ) ;
} else {
frames = 1 ;
}
2006-03-31 19:38:09 +00:00
samples = frames * tech_pvt - > read_codec . implementation - > samples_per_frame ;
2007-03-05 20:53:54 +00:00
tech_pvt - > timestamp_send + = samples ;
2007-03-07 18:34:22 +00:00
if ( switch_rtp_write_frame ( tech_pvt - > rtp_session , frame , 0 ) < 0 ) {
2007-03-29 22:31:56 +00:00
terminate_session ( & session , __LINE__ , SWITCH_CAUSE_NORMAL_CLEARING ) ;
2006-04-15 06:06:46 +00:00
return SWITCH_STATUS_FALSE ;
}
2007-03-05 20:53:54 +00:00
2006-03-31 19:38:09 +00:00
2006-06-23 16:59:47 +00:00
switch_clear_flag_locked ( tech_pvt , TFLAG_WRITING ) ;
2006-10-10 00:11:41 +00:00
2006-03-31 19:38:09 +00:00
return status ;
}
2006-04-29 23:43:28 +00:00
static switch_status_t channel_answer_channel ( switch_core_session_t * session )
2006-03-31 19:38:09 +00:00
{
struct private_object * tech_pvt ;
2006-04-29 06:05:03 +00:00
switch_channel_t * channel = NULL ;
2006-03-31 19:38:09 +00:00
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
return SWITCH_STATUS_SUCCESS ;
}
2006-04-17 18:25:43 +00:00
2006-04-29 23:43:28 +00:00
static switch_status_t channel_receive_message ( switch_core_session_t * session , switch_core_session_message_t * msg )
2006-04-17 18:25:43 +00:00
{
2006-04-29 06:05:03 +00:00
switch_channel_t * channel ;
2006-04-17 18:25:43 +00:00
struct private_object * tech_pvt ;
2007-03-29 22:31:56 +00:00
2006-04-17 18:25:43 +00:00
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
2007-03-29 22:31:56 +00:00
2006-04-17 18:25:43 +00:00
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
switch ( msg - > message_id ) {
case SWITCH_MESSAGE_INDICATE_BRIDGE :
2007-03-29 22:31:56 +00:00
if ( tech_pvt - > rtp_session & & switch_test_flag ( tech_pvt - > profile , TFLAG_TIMER ) ) {
2006-04-27 15:59:58 +00:00
switch_rtp_clear_flag ( tech_pvt - > rtp_session , SWITCH_RTP_FLAG_USE_TIMER ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " De-activate timed RTP! \n " ) ;
//switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_TIMER_RECLOCK);
}
break ;
2006-04-17 18:25:43 +00:00
case SWITCH_MESSAGE_INDICATE_UNBRIDGE :
2006-05-24 16:10:05 +00:00
if ( tech_pvt - > rtp_session & & switch_test_flag ( tech_pvt - > profile , TFLAG_TIMER ) ) {
2006-04-27 15:59:58 +00:00
switch_rtp_set_flag ( tech_pvt - > rtp_session , SWITCH_RTP_FLAG_USE_TIMER ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Re-activate timed RTP! \n " ) ;
//switch_rtp_clear_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_TIMER_RECLOCK);
}
break ;
2006-04-17 18:25:43 +00:00
default :
break ;
}
return SWITCH_STATUS_SUCCESS ;
}
2006-08-18 01:28:50 +00:00
static switch_status_t channel_receive_event ( switch_core_session_t * session , switch_event_t * event )
{
switch_channel_t * channel ;
2007-03-29 22:31:56 +00:00
struct private_object * tech_pvt ;
2006-08-18 01:28:50 +00:00
char * subject , * body ;
2007-03-29 22:31:56 +00:00
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
2006-08-18 01:28:50 +00:00
2007-03-29 22:31:56 +00:00
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
2006-08-18 01:28:50 +00:00
if ( ! ( body = switch_event_get_body ( event ) ) ) {
body = " " ;
}
if ( ! ( subject = switch_event_get_header ( event , " subject " ) ) ) {
subject = " None " ;
}
ldl_session_send_msg ( tech_pvt - > dlsession , subject , body ) ;
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 06:05:03 +00:00
static const switch_state_handler_table_t channel_event_handlers = {
2006-03-31 19:38:09 +00:00
/*.on_init */ channel_on_init ,
/*.on_ring */ channel_on_ring ,
/*.on_execute */ channel_on_execute ,
/*.on_hangup */ channel_on_hangup ,
/*.on_loopback */ channel_on_loopback ,
/*.on_transmit */ channel_on_transmit
} ;
2006-04-29 23:43:28 +00:00
static const switch_io_routines_t channel_io_routines = {
2006-03-31 19:38:09 +00:00
/*.outgoing_channel */ channel_outgoing_channel ,
/*.answer_channel */ channel_answer_channel ,
/*.read_frame */ channel_read_frame ,
/*.write_frame */ channel_write_frame ,
/*.kill_channel */ channel_kill_channel ,
/*.waitfor_read */ channel_waitfor_read ,
/*.waitfor_write */ channel_waitfor_write ,
2006-04-17 18:25:43 +00:00
/*.send_dtmf */ channel_send_dtmf ,
2007-03-29 22:31:56 +00:00
/*.receive_message */ channel_receive_message ,
/*.receive_event */ channel_receive_event
2006-03-31 19:38:09 +00:00
} ;
2006-04-29 23:43:28 +00:00
static const switch_endpoint_interface_t channel_endpoint_interface = {
2006-03-31 19:38:09 +00:00
/*.interface_name */ " dingaling " ,
/*.io_routines */ & channel_io_routines ,
/*.event_handlers */ & channel_event_handlers ,
/*.private */ NULL ,
/*.next */ NULL
} ;
2006-05-02 16:43:13 +00:00
static switch_api_interface_t logout_api_interface = {
/*.interface_name */ " dl_logout " ,
/*.desc */ " DingaLing Logout " ,
/*.function */ dl_logout ,
2006-10-08 07:11:42 +00:00
/*.syntax */ " dl_logout <profile_name> " ,
2006-05-02 16:43:13 +00:00
/*.next */ NULL
} ;
static switch_api_interface_t login_api_interface = {
/*.interface_name */ " dl_login " ,
/*.desc */ " DingaLing Login " ,
/*.function */ dl_login ,
2006-10-08 07:11:42 +00:00
/*.syntax */ " dl_login <profile_name> " ,
2006-05-02 16:43:13 +00:00
/*.next */ & logout_api_interface
} ;
2006-10-19 07:13:34 +00:00
static const switch_chat_interface_t channel_chat_interface = {
2006-10-20 22:11:26 +00:00
/*.name */ MDL_CHAT_PROTO ,
2006-10-19 07:13:34 +00:00
/*.chat_send */ chat_send ,
} ;
2006-05-02 16:43:13 +00:00
2006-04-29 23:43:28 +00:00
static const switch_loadable_module_interface_t channel_module_interface = {
2006-03-31 19:38:09 +00:00
/*.module_name */ modname ,
/*.endpoint_interface */ & channel_endpoint_interface ,
/*.timer_interface */ NULL ,
/*.dialplan_interface */ NULL ,
/*.codec_interface */ NULL ,
2006-05-02 16:43:13 +00:00
/*.application_interface */ NULL ,
2006-10-19 07:13:34 +00:00
/*.api_interface */ & login_api_interface ,
/*.file_interface */ NULL ,
2007-03-29 22:31:56 +00:00
/*.speech_interface */ NULL ,
/*.directory_interface */ NULL ,
/*.chat_interface */ & channel_chat_interface
2006-03-31 19:38:09 +00:00
} ;
/* Make sure when you have 2 sessions in the same scope that you pass the appropriate one to the routines
2006-04-27 15:59:58 +00:00
that allocate memory or you will have 1 channel with memory allocated from another channel ' s pool !
2006-03-31 19:38:09 +00:00
*/
2007-03-29 22:31:56 +00:00
static switch_call_cause_t channel_outgoing_channel ( switch_core_session_t * session ,
switch_caller_profile_t * outbound_profile ,
2007-03-30 00:15:25 +00:00
switch_core_session_t * * new_session , switch_memory_pool_t * * pool )
2006-03-31 19:38:09 +00:00
{
if ( ( * new_session = switch_core_session_request ( & channel_endpoint_interface , pool ) ) ! = 0 ) {
struct private_object * tech_pvt ;
2006-04-29 06:05:03 +00:00
switch_channel_t * channel ;
switch_caller_profile_t * caller_profile = NULL ;
2007-04-04 17:32:56 +00:00
mdl_profile_t * mdl_profile = NULL ;
2006-03-31 19:38:09 +00:00
ldl_session_t * dlsession = NULL ;
char * profile_name ;
char * callto ;
char idbuf [ 1024 ] ;
char * full_id ;
char sess_id [ 11 ] = " " ;
2006-05-04 14:37:11 +00:00
char * dnis = NULL ;
char workspace [ 1024 ] = " " ;
2007-02-14 17:22:34 +00:00
char * p , * u , ubuf [ 512 ] = " " , * user = NULL ;
2007-02-14 19:47:16 +00:00
char * cid_msg = NULL , * f_cid_msg = NULL ;
2006-11-15 00:40:45 +00:00
2006-03-31 19:38:09 +00:00
switch_copy_string ( workspace , outbound_profile - > destination_number , sizeof ( workspace ) ) ;
profile_name = workspace ;
2007-02-01 05:23:29 +00:00
2006-03-31 19:38:09 +00:00
if ( ( callto = strchr ( profile_name , ' / ' ) ) ) {
* callto + + = ' \0 ' ;
} else {
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Invalid URL! \n " ) ;
2007-03-29 22:31:56 +00:00
terminate_session ( new_session , __LINE__ , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2007-02-09 20:03:07 +00:00
return SWITCH_CAUSE_INVALID_NUMBER_FORMAT ;
2006-03-31 19:38:09 +00:00
}
2006-11-15 00:40:45 +00:00
2006-05-04 15:39:14 +00:00
if ( ( dnis = strchr ( callto , ' : ' ) ) ) {
2006-05-04 14:37:11 +00:00
* dnis + + = ' \0 ' ;
}
2006-03-31 19:38:09 +00:00
2007-03-29 22:31:56 +00:00
for ( p = callto ; p & & * p ; p + + ) {
* p = ( char ) tolower ( * p ) ;
}
2006-11-21 19:01:54 +00:00
if ( ( p = strchr ( profile_name , ' @ ' ) ) ) {
* p + + = ' \0 ' ;
u = profile_name ;
profile_name = p ;
snprintf ( ubuf , sizeof ( ubuf ) , " %s@%s/talk " , u , profile_name ) ;
user = ubuf ;
}
2006-11-21 15:43:55 +00:00
2006-03-31 19:38:09 +00:00
if ( ( mdl_profile = switch_core_hash_find ( globals . profile_hash , profile_name ) ) ) {
2006-11-21 19:01:54 +00:00
if ( ! ( mdl_profile - > user_flags & LDL_FLAG_COMPONENT ) ) {
2006-11-15 20:21:29 +00:00
user = ldl_handle_get_login ( mdl_profile - > handle ) ;
2006-11-21 19:01:54 +00:00
} else {
if ( ! user ) {
if ( strchr ( outbound_profile - > caller_id_number , ' @ ' ) ) {
snprintf ( ubuf , sizeof ( ubuf ) , " %s/talk " , outbound_profile - > caller_id_number ) ;
user = ubuf ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Invalid User! \n " ) ;
2007-03-29 22:31:56 +00:00
terminate_session ( new_session , __LINE__ , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2006-11-21 19:01:54 +00:00
}
}
2006-11-14 17:41:35 +00:00
}
2006-03-31 19:38:09 +00:00
if ( ! ldl_handle_ready ( mdl_profile - > handle ) ) {
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Doh! we are not logged in yet! \n " ) ;
2007-03-29 22:31:56 +00:00
terminate_session ( new_session , __LINE__ , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2007-02-09 20:03:07 +00:00
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
2006-03-31 19:38:09 +00:00
}
2006-10-18 22:57:35 +00:00
if ( ! ( full_id = ldl_handle_probe ( mdl_profile - > handle , callto , user , idbuf , sizeof ( idbuf ) ) ) ) {
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Unknown Recipient! \n " ) ;
2007-03-29 22:31:56 +00:00
terminate_session ( new_session , __LINE__ , SWITCH_CAUSE_NO_USER_RESPONSE ) ;
2007-02-09 20:03:07 +00:00
return SWITCH_CAUSE_NO_USER_RESPONSE ;
2006-03-31 19:38:09 +00:00
}
} else {
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Unknown Profile! \n " ) ;
2007-03-29 22:31:56 +00:00
terminate_session ( new_session , __LINE__ , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2007-02-09 20:03:07 +00:00
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
2006-03-31 19:38:09 +00:00
}
2007-03-29 22:31:56 +00:00
2006-03-31 19:38:09 +00:00
switch_core_session_add_stream ( * new_session , NULL ) ;
2007-03-30 00:13:31 +00:00
if ( ( tech_pvt = ( struct private_object * ) switch_core_session_alloc ( * new_session , sizeof ( struct private_object ) ) ) ! = 0 ) {
2006-03-31 19:38:09 +00:00
memset ( tech_pvt , 0 , sizeof ( * tech_pvt ) ) ;
2006-06-23 16:59:47 +00:00
switch_mutex_init ( & tech_pvt - > flag_mutex , SWITCH_MUTEX_NESTED , switch_core_session_get_pool ( * new_session ) ) ;
2006-04-21 22:31:08 +00:00
tech_pvt - > flags | = globals . flags ;
tech_pvt - > flags | = mdl_profile - > flags ;
2006-03-31 19:38:09 +00:00
channel = switch_core_session_get_channel ( * new_session ) ;
switch_core_session_set_private ( * new_session , tech_pvt ) ;
tech_pvt - > session = * new_session ;
tech_pvt - > codec_index = - 1 ;
2006-04-05 20:17:22 +00:00
tech_pvt - > local_port = switch_rtp_request_port ( ) ;
2006-05-03 23:45:07 +00:00
tech_pvt - > recip = switch_core_session_strdup ( * new_session , full_id ) ;
2006-05-04 14:37:11 +00:00
tech_pvt - > dnis = switch_core_session_strdup ( * new_session , dnis ) ;
2006-03-31 19:38:09 +00:00
} else {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Hey where is my memory pool? \n " ) ;
2007-03-29 22:31:56 +00:00
terminate_session ( new_session , __LINE__ , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2007-02-09 20:03:07 +00:00
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
2006-03-31 19:38:09 +00:00
}
if ( outbound_profile ) {
char name [ 128 ] ;
2007-03-29 22:31:56 +00:00
2006-10-22 04:37:19 +00:00
snprintf ( name , sizeof ( name ) , " DingaLing/%s " , outbound_profile - > destination_number ) ;
2006-03-31 19:38:09 +00:00
switch_channel_set_name ( channel , name ) ;
caller_profile = switch_caller_profile_clone ( * new_session , outbound_profile ) ;
switch_channel_set_caller_profile ( channel , caller_profile ) ;
tech_pvt - > caller_profile = caller_profile ;
} else {
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Doh! no caller profile \n " ) ;
2007-03-29 22:31:56 +00:00
terminate_session ( new_session , __LINE__ , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2007-02-09 20:03:07 +00:00
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
2006-03-31 19:38:09 +00:00
}
switch_channel_set_flag ( channel , CF_OUTBOUND ) ;
2006-06-23 16:59:47 +00:00
switch_set_flag_locked ( tech_pvt , TFLAG_OUTBOUND ) ;
2007-01-29 22:22:29 +00:00
2006-04-04 16:07:40 +00:00
switch_stun_random_string ( sess_id , 10 , " 0123456789 " ) ;
2007-01-29 22:22:29 +00:00
tech_pvt - > us = switch_core_session_strdup ( * new_session , user ) ;
tech_pvt - > them = switch_core_session_strdup ( * new_session , full_id ) ;
2006-11-16 16:10:39 +00:00
ldl_session_create ( & dlsession , mdl_profile - > handle , sess_id , full_id , user , LDL_FLAG_OUTBOUND ) ;
2007-03-29 22:31:56 +00:00
2007-02-14 19:47:16 +00:00
if ( session ) {
switch_channel_t * calling_channel = switch_core_session_get_channel ( session ) ;
cid_msg = switch_channel_get_variable ( calling_channel , " dl_cid_msg " ) ;
}
if ( ! cid_msg ) {
2007-03-30 00:13:31 +00:00
f_cid_msg = switch_mprintf ( " Incoming Call From %s %s \n " , outbound_profile - > caller_id_name , outbound_profile - > caller_id_number ) ;
2007-02-14 19:47:16 +00:00
cid_msg = f_cid_msg ;
}
if ( cid_msg ) {
2007-02-15 17:48:14 +00:00
char * them ;
2007-02-15 16:53:44 +00:00
them = strdup ( tech_pvt - > them ) ;
2007-02-15 17:48:14 +00:00
if ( them ) {
2007-02-15 16:53:44 +00:00
char * p ;
if ( ( p = strchr ( them , ' / ' ) ) ) {
* p = ' \0 ' ;
}
2007-02-15 17:48:14 +00:00
ldl_handle_send_msg ( mdl_profile - > handle , tech_pvt - > us , them , " " , cid_msg ) ;
2007-02-15 16:53:44 +00:00
}
switch_safe_free ( them ) ;
2007-02-14 15:32:02 +00:00
}
2007-02-14 19:47:16 +00:00
switch_safe_free ( f_cid_msg ) ;
2006-03-31 19:38:09 +00:00
tech_pvt - > profile = mdl_profile ;
ldl_session_set_private ( dlsession , * new_session ) ;
2007-02-01 05:23:29 +00:00
ldl_session_set_value ( dlsession , " dnis " , dnis ) ;
ldl_session_set_value ( dlsession , " caller_id_name " , outbound_profile - > caller_id_name ) ;
ldl_session_set_value ( dlsession , " caller_id_number " , outbound_profile - > caller_id_number ) ;
2006-03-31 19:38:09 +00:00
tech_pvt - > dlsession = dlsession ;
2006-08-18 16:36:26 +00:00
if ( ! get_codecs ( tech_pvt ) ) {
2007-03-29 22:31:56 +00:00
terminate_session ( new_session , __LINE__ , SWITCH_CAUSE_BEARERCAPABILITY_NOTAVAIL ) ;
return SWITCH_CAUSE_BEARERCAPABILITY_NOTAVAIL ;
2006-08-18 16:36:26 +00:00
}
2006-10-10 00:11:41 +00:00
switch_channel_set_state ( channel , CS_INIT ) ;
2007-02-09 20:03:07 +00:00
return SWITCH_CAUSE_SUCCESS ;
2006-03-31 19:38:09 +00:00
}
2007-02-09 20:03:07 +00:00
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
2006-03-31 19:38:09 +00:00
}
2007-03-30 00:13:31 +00:00
SWITCH_MOD_DECLARE ( switch_status_t ) switch_module_load ( const switch_loadable_module_interface_t * * module_interface , char * filename )
2006-03-31 19:38:09 +00:00
{
if ( switch_core_new_memory_pool ( & module_pool ) ! = SWITCH_STATUS_SUCCESS ) {
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " OH OH no pool \n " ) ;
2006-03-31 19:38:09 +00:00
return SWITCH_STATUS_TERM ;
}
load_config ( ) ;
2006-05-01 18:55:04 +00:00
if ( switch_event_reserve_subclass ( DL_EVENT_LOGIN_SUCCESS ) ! = SWITCH_STATUS_SUCCESS ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't register subclass %s! " , DL_EVENT_LOGIN_SUCCESS ) ;
2006-05-01 18:55:04 +00:00
return SWITCH_STATUS_GENERR ;
}
if ( switch_event_reserve_subclass ( DL_EVENT_LOGIN_FAILURE ) ! = SWITCH_STATUS_SUCCESS ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't register subclass %s! " , DL_EVENT_LOGIN_FAILURE ) ;
2006-05-01 18:55:04 +00:00
return SWITCH_STATUS_GENERR ;
}
2006-06-22 21:57:40 +00:00
if ( switch_event_reserve_subclass ( DL_EVENT_CONNECTED ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't register subclass %s! " , DL_EVENT_CONNECTED ) ;
return SWITCH_STATUS_GENERR ;
}
2007-03-29 22:31:56 +00:00
2007-03-30 00:13:31 +00:00
if ( switch_event_bind ( ( char * ) modname , SWITCH_EVENT_PRESENCE_IN , SWITCH_EVENT_SUBCLASS_ANY , pres_event_handler , NULL ) ! = SWITCH_STATUS_SUCCESS ) {
2006-10-18 22:57:35 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't bind! \n " ) ;
return SWITCH_STATUS_GENERR ;
}
2007-03-30 00:13:31 +00:00
if ( switch_event_bind ( ( char * ) modname , SWITCH_EVENT_PRESENCE_PROBE , SWITCH_EVENT_SUBCLASS_ANY , pres_event_handler , NULL ) ! = SWITCH_STATUS_SUCCESS ) {
2006-12-19 17:48:50 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't bind! \n " ) ;
return SWITCH_STATUS_GENERR ;
}
2007-03-30 00:13:31 +00:00
if ( switch_event_bind ( ( char * ) modname , SWITCH_EVENT_PRESENCE_OUT , SWITCH_EVENT_SUBCLASS_ANY , pres_event_handler , NULL ) ! = SWITCH_STATUS_SUCCESS ) {
2006-10-18 22:57:35 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't bind! \n " ) ;
return SWITCH_STATUS_GENERR ;
}
2007-03-29 22:31:56 +00:00
if ( switch_event_bind ( ( char * ) modname , SWITCH_EVENT_ROSTER , SWITCH_EVENT_SUBCLASS_ANY , roster_event_handler , NULL )
! = SWITCH_STATUS_SUCCESS ) {
2006-10-18 22:57:35 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't bind! \n " ) ;
return SWITCH_STATUS_GENERR ;
}
2006-03-31 19:38:09 +00:00
/* connect my internal structure to the blank pointer passed to me */
2006-04-30 18:24:24 +00:00
* module_interface = & channel_module_interface ;
2006-03-31 19:38:09 +00:00
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS ;
}
2007-03-29 22:31:56 +00:00
static ldl_status handle_loop ( ldl_handle_t * handle )
2006-03-31 19:38:09 +00:00
{
if ( ! globals . running ) {
return LDL_STATUS_FALSE ;
}
return LDL_STATUS_SUCCESS ;
}
2006-05-02 16:43:13 +00:00
2007-04-04 17:32:56 +00:00
static switch_status_t init_profile ( mdl_profile_t * profile , uint8_t login )
2006-03-31 19:38:09 +00:00
{
2007-03-30 00:13:31 +00:00
if ( profile & & profile - > login & & profile - > password & & profile - > dialplan & & profile - > message & & profile - > ip & & profile - > name & & profile - > exten ) {
2006-03-31 19:38:09 +00:00
ldl_handle_t * handle ;
2006-09-14 00:15:03 +00:00
if ( switch_test_flag ( profile , TFLAG_TIMER ) & & ! profile - > timer_name ) {
2007-03-29 22:31:56 +00:00
profile - > timer_name = switch_core_strdup ( module_pool , " soft " ) ;
2006-09-14 00:15:03 +00:00
}
2006-05-02 16:43:13 +00:00
if ( login ) {
if ( ldl_handle_init ( & handle ,
profile - > login ,
profile - > password ,
2006-08-11 00:24:38 +00:00
profile - > server ,
2007-03-30 00:13:31 +00:00
profile - > user_flags , profile - > message , handle_loop , handle_signalling , handle_response , profile ) = = LDL_STATUS_SUCCESS ) {
2006-05-02 16:43:13 +00:00
profile - > handle = handle ;
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Started Thread for %s@%s \n " , profile - > login , profile - > dialplan ) ;
2006-05-02 16:43:13 +00:00
switch_core_hash_insert ( globals . profile_hash , profile - > name , profile ) ;
handle_thread_launch ( handle ) ;
}
} else {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Created Profile for %s@%s \n " , profile - > login , profile - > dialplan ) ;
2006-03-31 19:38:09 +00:00
switch_core_hash_insert ( globals . profile_hash , profile - > name , profile ) ;
2006-05-02 16:43:13 +00:00
}
2006-03-31 19:38:09 +00:00
} else {
2007-03-29 22:31:56 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG ,
2006-05-02 16:43:13 +00:00
" Invalid Profile \n "
" login[%s] \n "
" pass[%s] \n "
" dialplan[%s] \n "
" message[%s] \n "
" rtp-ip[%s] \n "
" name[%s] \n "
2007-03-30 00:15:25 +00:00
" exten[%s] \n " , profile - > login , profile - > password , profile - > dialplan , profile - > message , profile - > ip , profile - > name ,
profile - > exten ) ;
2006-05-02 16:43:13 +00:00
return SWITCH_STATUS_FALSE ;
2006-03-31 19:38:09 +00:00
}
2006-05-02 16:43:13 +00:00
return SWITCH_STATUS_SUCCESS ;
2006-03-31 19:38:09 +00:00
}
2006-04-29 23:43:28 +00:00
SWITCH_MOD_DECLARE ( switch_status_t ) switch_module_shutdown ( void )
2006-03-31 19:38:09 +00:00
{
2006-10-20 06:44:58 +00:00
sign_off ( ) ;
2006-03-31 19:38:09 +00:00
if ( globals . running ) {
int x = 0 ;
globals . running = 0 ;
while ( globals . handles > 0 ) {
switch_yield ( 100000 ) ;
x + + ;
2007-03-29 22:31:56 +00:00
if ( x > 10 ) {
2006-03-31 19:38:09 +00:00
break ;
}
}
2006-05-10 03:23:05 +00:00
if ( globals . init ) {
ldl_global_destroy ( ) ;
}
2006-03-31 19:38:09 +00:00
}
return SWITCH_STATUS_SUCCESS ;
}
2007-04-04 17:32:56 +00:00
static void set_profile_val ( mdl_profile_t * profile , char * var , char * val )
2006-05-02 16:43:13 +00:00
{
2007-03-29 22:31:56 +00:00
2006-05-02 16:43:13 +00:00
if ( ! strcasecmp ( var , " login " ) ) {
profile - > login = switch_core_strdup ( module_pool , val ) ;
} else if ( ! strcasecmp ( var , " password " ) ) {
profile - > password = switch_core_strdup ( module_pool , val ) ;
2007-04-04 17:32:56 +00:00
} else if ( ! strcasecmp ( var , " odbc-dsn " ) ) {
# ifdef SWITCH_HAVE_ODBC
profile - > odbc_dsn = switch_core_strdup ( module_pool , val ) ;
if ( ( profile - > odbc_user = strchr ( profile - > odbc_dsn , ' : ' ) ) ) {
* profile - > odbc_user + + = ' \0 ' ;
}
if ( ( profile - > odbc_pass = strchr ( profile - > odbc_user , ' : ' ) ) ) {
* profile - > odbc_pass + + = ' \0 ' ;
}
# else
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " ODBC IS NOT AVAILABLE! \n " ) ;
# endif
2006-05-24 16:10:05 +00:00
} else if ( ! strcasecmp ( var , " use-rtp-timer " ) & & switch_true ( val ) ) {
2007-03-29 22:31:56 +00:00
switch_set_flag ( profile , TFLAG_TIMER ) ;
2006-05-02 16:43:13 +00:00
} else if ( ! strcasecmp ( var , " dialplan " ) ) {
profile - > dialplan = switch_core_strdup ( module_pool , val ) ;
2006-10-12 14:06:09 +00:00
} else if ( ! strcasecmp ( var , " auto-reply " ) ) {
profile - > auto_reply = switch_core_strdup ( module_pool , val ) ;
2006-05-02 16:43:13 +00:00
} else if ( ! strcasecmp ( var , " name " ) ) {
profile - > name = switch_core_strdup ( module_pool , val ) ;
} else if ( ! strcasecmp ( var , " message " ) ) {
profile - > message = switch_core_strdup ( module_pool , val ) ;
} else if ( ! strcasecmp ( var , " rtp-ip " ) ) {
2007-01-19 19:11:44 +00:00
profile - > ip = switch_core_strdup ( module_pool , strcasecmp ( val , " auto " ) ? val : globals . guess_ip ) ;
2006-05-02 16:43:13 +00:00
} else if ( ! strcasecmp ( var , " ext-rtp-ip " ) ) {
2007-01-19 19:11:44 +00:00
profile - > extip = switch_core_strdup ( module_pool , strcasecmp ( val , " auto " ) ? val : globals . guess_ip ) ;
2006-08-11 00:24:38 +00:00
} else if ( ! strcasecmp ( var , " server " ) ) {
profile - > server = switch_core_strdup ( module_pool , val ) ;
2006-09-12 22:23:45 +00:00
} else if ( ! strcasecmp ( var , " rtp-timer-name " ) ) {
profile - > timer_name = switch_core_strdup ( module_pool , val ) ;
2006-05-02 16:43:13 +00:00
} else if ( ! strcasecmp ( var , " lanaddr " ) ) {
profile - > lanaddr = switch_core_strdup ( module_pool , val ) ;
2006-08-11 00:24:38 +00:00
} else if ( ! strcasecmp ( var , " tls " ) ) {
if ( switch_true ( val ) ) {
profile - > user_flags | = LDL_FLAG_TLS ;
}
} else if ( ! strcasecmp ( var , " sasl " ) ) {
if ( ! strcasecmp ( val , " plain " ) ) {
profile - > user_flags | = LDL_FLAG_SASL_PLAIN ;
} else if ( ! strcasecmp ( val , " md5 " ) ) {
profile - > user_flags | = LDL_FLAG_SASL_MD5 ;
}
2006-05-02 16:43:13 +00:00
} else if ( ! strcasecmp ( var , " exten " ) ) {
profile - > exten = switch_core_strdup ( module_pool , val ) ;
} else if ( ! strcasecmp ( var , " context " ) ) {
profile - > context = switch_core_strdup ( module_pool , val ) ;
} else if ( ! strcasecmp ( var , " auto-login " ) ) {
if ( switch_true ( val ) ) {
switch_set_flag ( profile , TFLAG_AUTO ) ;
}
} else if ( ! strcasecmp ( var , " vad " ) ) {
if ( ! strcasecmp ( val , " in " ) ) {
switch_set_flag ( profile , TFLAG_VAD_IN ) ;
} else if ( ! strcasecmp ( val , " out " ) ) {
switch_set_flag ( profile , TFLAG_VAD_OUT ) ;
} else if ( ! strcasecmp ( val , " both " ) ) {
switch_set_flag ( profile , TFLAG_VAD_IN ) ;
switch_set_flag ( profile , TFLAG_VAD_OUT ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invald option %s for VAD \n " , val ) ;
}
}
}
2006-07-26 20:12:49 +00:00
static switch_status_t dl_logout ( char * profile_name , switch_core_session_t * session , switch_stream_handle_t * stream )
2006-05-02 16:43:13 +00:00
{
2007-04-04 17:32:56 +00:00
mdl_profile_t * profile ;
2006-06-07 14:53:13 +00:00
2006-07-26 20:12:49 +00:00
if ( session ) {
return SWITCH_STATUS_FALSE ;
}
2006-06-07 14:53:13 +00:00
if ( ! profile_name ) {
2006-10-08 07:11:42 +00:00
stream - > write_function ( stream , " USAGE: %s \n " , logout_api_interface . syntax ) ;
2006-06-07 14:53:13 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-05-02 16:43:13 +00:00
if ( ( profile = switch_core_hash_find ( globals . profile_hash , profile_name ) ) ) {
ldl_handle_stop ( profile - > handle ) ;
2006-05-10 15:47:54 +00:00
stream - > write_function ( stream , " OK \n " ) ;
2006-05-02 16:43:13 +00:00
} else {
2006-05-10 15:47:54 +00:00
stream - > write_function ( stream , " NO SUCH PROFILE %s \n " , profile_name ) ;
2006-05-02 16:43:13 +00:00
}
return SWITCH_STATUS_SUCCESS ;
}
2006-07-26 20:12:49 +00:00
static switch_status_t dl_login ( char * arg , switch_core_session_t * session , switch_stream_handle_t * stream )
2006-05-02 16:43:13 +00:00
{
2007-03-29 22:31:56 +00:00
char * argv [ 10 ] = { 0 } ;
2006-05-02 16:43:13 +00:00
int argc = 0 ;
char * var , * val , * myarg ;
2007-04-04 17:32:56 +00:00
mdl_profile_t * profile = NULL ;
2006-05-02 16:43:13 +00:00
int x ;
2006-07-26 20:12:49 +00:00
if ( session ) {
return SWITCH_STATUS_FALSE ;
}
2007-03-29 22:31:56 +00:00
if ( switch_strlen_zero ( arg ) ) {
stream - > write_function ( stream , " USAGE: %s \n " , login_api_interface . syntax ) ;
return SWITCH_STATUS_SUCCESS ;
}
2007-01-04 22:08:41 +00:00
2006-05-02 16:43:13 +00:00
myarg = strdup ( arg ) ;
argc = switch_separate_string ( myarg , ' ; ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
2006-10-08 07:11:42 +00:00
if ( switch_strlen_zero ( arg ) | | argc ! = 1 ) {
stream - > write_function ( stream , " USAGE: %s \n " , login_api_interface . syntax ) ;
return SWITCH_STATUS_SUCCESS ;
}
2006-05-02 16:43:13 +00:00
if ( ! strncasecmp ( argv [ 0 ] , " profile= " , 8 ) ) {
char * profile_name = argv [ 0 ] + 8 ;
profile = switch_core_hash_find ( globals . profile_hash , profile_name ) ;
if ( profile ) {
if ( switch_test_flag ( profile , TFLAG_IO ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Profile already exists. " ) ;
2006-05-10 15:47:54 +00:00
stream - > write_function ( stream , " Profile already exists \n " ) ;
2006-05-02 16:43:13 +00:00
return SWITCH_STATUS_SUCCESS ;
}
}
} else {
profile = switch_core_alloc ( module_pool , sizeof ( * profile ) ) ;
2007-03-29 22:31:56 +00:00
for ( x = 0 ; x < argc ; x + + ) {
2006-05-02 16:43:13 +00:00
var = argv [ x ] ;
if ( ( val = strchr ( var , ' = ' ) ) ) {
* val + + = ' \0 ' ;
set_profile_val ( profile , var , val ) ;
}
}
}
2007-03-29 22:31:56 +00:00
2006-10-20 06:17:00 +00:00
2006-05-02 16:43:13 +00:00
if ( profile & & init_profile ( profile , 1 ) = = SWITCH_STATUS_SUCCESS ) {
2006-05-10 15:47:54 +00:00
stream - > write_function ( stream , " OK \n " ) ;
2006-05-02 16:43:13 +00:00
} else {
2006-05-10 15:47:54 +00:00
stream - > write_function ( stream , " FAIL \n " ) ;
2006-05-02 16:43:13 +00:00
}
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 23:43:28 +00:00
static switch_status_t load_config ( void )
2006-03-31 19:38:09 +00:00
{
char * cf = " dingaling.conf " ;
2007-04-04 17:32:56 +00:00
mdl_profile_t * profile = NULL ;
2006-05-10 03:23:05 +00:00
switch_xml_t cfg , xml , settings , param , xmlint ;
2006-03-31 19:38:09 +00:00
memset ( & globals , 0 , sizeof ( globals ) ) ;
globals . running = 1 ;
2006-05-02 16:43:13 +00:00
2007-03-29 22:31:56 +00:00
switch_find_local_ip ( globals . guess_ip , sizeof ( globals . guess_ip ) , AF_INET ) ;
switch_core_hash_init ( & globals . profile_hash , module_pool ) ;
2006-05-10 03:23:05 +00:00
2006-05-10 15:47:54 +00:00
if ( ! ( xml = switch_xml_open_cfg ( cf , & cfg , NULL ) ) ) {
2006-05-10 03:23:05 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " open of %s failed \n " , cf ) ;
2006-03-31 19:38:09 +00:00
return SWITCH_STATUS_TERM ;
}
2006-05-10 03:23:05 +00:00
if ( ( settings = switch_xml_child ( cfg , " settings " ) ) ) {
for ( param = switch_xml_child ( settings , " param " ) ; param ; param = param - > next ) {
2006-05-17 00:58:21 +00:00
char * var = ( char * ) switch_xml_attr_soft ( param , " name " ) ;
char * val = ( char * ) switch_xml_attr_soft ( param , " value " ) ;
2006-05-10 03:23:05 +00:00
2006-05-02 16:43:13 +00:00
if ( ! strcasecmp ( var , " debug " ) ) {
2006-03-31 19:38:09 +00:00
globals . debug = atoi ( val ) ;
2006-05-16 17:08:21 +00:00
} else if ( ! strcasecmp ( var , " codec-prefs " ) ) {
2006-03-31 19:38:09 +00:00
set_global_codec_string ( val ) ;
2007-03-30 00:13:31 +00:00
globals . codec_order_last = switch_separate_string ( globals . codec_string , ' , ' , globals . codec_order , SWITCH_MAX_CODECS ) ;
2006-05-16 17:08:21 +00:00
} else if ( ! strcasecmp ( var , " codec-rates " ) ) {
2006-03-31 19:38:09 +00:00
set_global_codec_rates_string ( val ) ;
2007-03-30 00:13:31 +00:00
globals . codec_rates_last = switch_separate_string ( globals . codec_rates_string , ' , ' , globals . codec_rates , SWITCH_MAX_CODECS ) ;
2006-03-31 19:38:09 +00:00
}
2006-05-10 03:23:05 +00:00
}
}
2007-03-29 22:31:56 +00:00
2006-10-20 06:17:00 +00:00
if ( ! ( xmlint = switch_xml_child ( cfg , " profile " ) ) ) {
if ( ( xmlint = switch_xml_child ( cfg , " interface " ) ) ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " !!!!!!! DEPRICATION WARNING 'interface' is now 'profile' !!!!!!! \n " ) ;
2006-10-20 06:17:00 +00:00
}
}
for ( ; xmlint ; xmlint = xmlint - > next ) {
char * type = ( char * ) switch_xml_attr_soft ( xmlint , " type " ) ;
2006-05-10 03:23:05 +00:00
for ( param = switch_xml_child ( xmlint , " param " ) ; param ; param = param - > next ) {
2006-05-17 00:58:21 +00:00
char * var = ( char * ) switch_xml_attr_soft ( param , " name " ) ;
char * val = ( char * ) switch_xml_attr_soft ( param , " value " ) ;
2006-05-02 16:43:13 +00:00
2006-03-31 19:38:09 +00:00
if ( ! globals . init ) {
ldl_global_init ( globals . debug ) ;
2006-04-14 02:05:29 +00:00
ldl_global_set_logger ( dl_logger ) ;
2006-03-31 19:38:09 +00:00
globals . init = 1 ;
}
2007-03-29 22:31:56 +00:00
if ( ! profile ) {
2006-03-31 19:38:09 +00:00
profile = switch_core_alloc ( module_pool , sizeof ( * profile ) ) ;
}
2006-05-02 16:43:13 +00:00
set_profile_val ( profile , var , val ) ;
2006-03-31 19:38:09 +00:00
}
2006-05-10 03:23:05 +00:00
2006-10-20 06:17:00 +00:00
if ( type & & ! strcasecmp ( type , " component " ) ) {
char dbname [ 256 ] ;
switch_core_db_t * db ;
if ( ! profile - > login & & profile - > name ) {
profile - > login = switch_core_strdup ( module_pool , profile - > name ) ;
}
switch_set_flag ( profile , TFLAG_AUTO ) ;
profile - > message = " " ;
profile - > user_flags | = LDL_FLAG_COMPONENT ;
switch_mutex_init ( & profile - > mutex , SWITCH_MUTEX_NESTED , module_pool ) ;
snprintf ( dbname , sizeof ( dbname ) , " dingaling_%s " , profile - > name ) ;
profile - > dbname = switch_core_strdup ( module_pool , dbname ) ;
2007-04-04 17:32:56 +00:00
# ifdef SWITCH_HAVE_ODBC
if ( profile - > odbc_dsn ) {
if ( ! ( profile - > master_odbc = switch_odbc_handle_new ( profile - > odbc_dsn , profile - > odbc_user , profile - > odbc_pass ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Cannot Open ODBC Database! \n " ) ;
continue ;
}
if ( switch_odbc_handle_connect ( profile - > master_odbc ) ! = SWITCH_ODBC_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Cannot Open ODBC Database! \n " ) ;
continue ;
}
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Connected ODBC DSN: %s \n " , profile - > odbc_dsn ) ;
switch_odbc_handle_exec ( profile - > master_odbc , sub_sql , NULL ) ;
//mdl_execute_sql(profile, sub_sql, NULL);
2006-10-20 06:17:00 +00:00
} else {
2007-04-04 17:32:56 +00:00
# endif
if ( ( db = switch_core_db_open_file ( profile - > dbname ) ) ) {
switch_core_db_test_reactive ( db , " select * from jabber_subscriptions " , sub_sql ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Cannot Open SQL Database! \n " ) ;
continue ;
}
switch_core_db_close ( db ) ;
# ifdef SWITCH_HAVE_ODBC
2006-10-20 06:17:00 +00:00
}
2007-04-04 17:32:56 +00:00
# endif
2006-10-20 06:17:00 +00:00
}
2006-05-10 03:23:05 +00:00
if ( profile ) {
init_profile ( profile , switch_test_flag ( profile , TFLAG_AUTO ) ? 1 : 0 ) ;
profile = NULL ;
}
2006-03-31 19:38:09 +00:00
}
if ( profile ) {
2006-05-02 16:43:13 +00:00
init_profile ( profile , switch_test_flag ( profile , TFLAG_AUTO ) ? 1 : 0 ) ;
2006-03-31 19:38:09 +00:00
profile = NULL ;
}
if ( ! globals . dialplan ) {
set_global_dialplan ( " default " ) ;
}
2006-05-02 16:43:13 +00:00
if ( ! globals . init ) {
ldl_global_init ( globals . debug ) ;
ldl_global_set_logger ( dl_logger ) ;
globals . init = 1 ;
}
2006-05-10 03:23:05 +00:00
switch_xml_free ( xml ) ;
2006-03-31 19:38:09 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2007-03-29 22:31:56 +00:00
static void do_vcard ( ldl_handle_t * handle , char * to , char * from , char * id )
2006-10-22 04:37:19 +00:00
{
char * params = NULL , * real_to , * to_user , * xmlstr = NULL , * to_host = NULL ;
2006-10-22 15:46:23 +00:00
switch_xml_t domain , xml = NULL , user , vcard ;
2006-10-22 04:37:19 +00:00
if ( ! strncasecmp ( to , " user+ " , 5 ) ) {
real_to = to + 5 ;
} else {
real_to = to ;
}
if ( ( to_user = strdup ( real_to ) ) ) {
if ( ( to_host = strchr ( to_user , ' @ ' ) ) ) {
* to_host + + = ' \0 ' ;
}
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Memory Error! \n " ) ;
goto end ;
}
2007-03-29 22:31:56 +00:00
2006-10-22 04:37:19 +00:00
if ( ! to_host ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Missing Host! \n " ) ;
goto end ;
}
2007-03-29 22:31:56 +00:00
if ( ! ( params = switch_mprintf ( " to=%s@%s&from=%s&object=vcard " , to_user , to_host , from ) ) ) {
2006-10-22 04:37:19 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Memory Error! \n " ) ;
goto end ;
}
2007-03-29 22:31:56 +00:00
2006-10-22 04:37:19 +00:00
if ( switch_xml_locate ( " directory " , " domain " , " name " , to_host , & xml , & domain , params ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " can't find domain for [%s@%s] \n " , to_user , to_host ) ;
goto end ;
}
if ( ! ( user = switch_xml_find_child ( domain , " user " , " id " , to_user ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " can't find user [%s@%s] \n " , to_user , to_host ) ;
goto end ;
}
if ( ! ( vcard = switch_xml_child ( user , " vcard " ) ) ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " can't find <vcard> tag for user [%s@%s] \n " , to_user , to_host ) ;
2006-10-22 04:37:19 +00:00
goto end ;
}
switch_xml_set_attr ( vcard , " xmlns " , " vcard-tmp " ) ;
if ( ( xmlstr = switch_xml_toxml ( vcard ) ) ) {
ldl_handle_send_vcard ( handle , to , from , id , xmlstr ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Memory Error! \n " ) ;
}
2007-03-29 22:31:56 +00:00
end :
if ( xml )
switch_xml_free ( xml ) ;
2006-10-22 04:37:19 +00:00
switch_safe_free ( to_user ) ;
switch_safe_free ( params ) ;
switch_safe_free ( xmlstr ) ;
}
2007-03-30 00:15:25 +00:00
static ldl_status handle_signalling ( ldl_handle_t * handle , ldl_session_t * dlsession , ldl_signal_t dl_signal , char * to , char * from , char * subject ,
char * msg )
2006-03-31 19:38:09 +00:00
{
2007-04-04 17:32:56 +00:00
mdl_profile_t * profile = NULL ;
2006-04-29 06:05:03 +00:00
switch_core_session_t * session = NULL ;
switch_channel_t * channel = NULL ;
2007-03-29 22:31:56 +00:00
struct private_object * tech_pvt = NULL ;
2006-05-01 18:55:04 +00:00
switch_event_t * event ;
2006-09-22 15:22:31 +00:00
ldl_status status = LDL_STATUS_SUCCESS ;
2006-10-18 22:57:35 +00:00
char * sql ;
2006-03-31 19:38:09 +00:00
assert ( handle ! = NULL ) ;
if ( ! ( profile = ldl_handle_get_private ( handle ) ) ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " ERROR NO PROFILE! \n " ) ;
2006-09-22 15:22:31 +00:00
status = LDL_STATUS_FALSE ;
goto done ;
2006-03-31 19:38:09 +00:00
}
2006-05-01 18:55:04 +00:00
if ( ! dlsession ) {
2006-10-20 22:26:06 +00:00
if ( profile - > user_flags & LDL_FLAG_COMPONENT ) {
2007-03-29 22:31:56 +00:00
switch ( dl_signal ) {
2006-10-22 04:37:19 +00:00
case LDL_SIGNAL_VCARD :
do_vcard ( handle , to , from , subject ) ;
break ;
2006-10-20 22:26:06 +00:00
case LDL_SIGNAL_UNSUBSCRIBE :
2006-10-18 22:57:35 +00:00
2007-04-04 17:32:56 +00:00
if ( ( sql = switch_mprintf ( " delete from jabber_subscriptions where sub_from='%q' and sub_to='%q'; " , from , to ) ) ) {
mdl_execute_sql ( profile , sql , profile - > mutex ) ;
2006-10-18 22:57:35 +00:00
switch_core_db_free ( sql ) ;
}
2006-10-20 22:26:06 +00:00
break ;
2006-10-18 22:57:35 +00:00
2006-10-20 22:26:06 +00:00
case LDL_SIGNAL_SUBSCRIBE :
2007-03-30 16:41:12 +00:00
if ( profile - > user_flags & LDL_FLAG_COMPONENT & & ldl_jid_domcmp ( from , to ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Attempt to add presence from/to our own domain [%s][%s] \n " , from , to ) ;
} else {
2007-04-04 17:32:56 +00:00
switch_mutex_lock ( profile - > mutex ) ;
if ( ( sql = switch_mprintf ( " delete from jabber_subscriptions where sub_from='%q' and sub_to='%q' " , from , to ) ) ) {
mdl_execute_sql ( profile , sql , NULL ) ;
2007-03-30 16:41:12 +00:00
switch_core_db_free ( sql ) ;
}
2007-04-04 17:32:56 +00:00
if ( ( sql = switch_mprintf ( " insert into jabber_subscriptions values('%q','%q','%q','%q'); \n " ,
switch_str_nil ( from ) ,
switch_str_nil ( to ) ,
switch_str_nil ( msg ) ,
switch_str_nil ( subject ) ) ) ) {
mdl_execute_sql ( profile , sql , NULL ) ;
switch_core_db_free ( sql ) ;
}
switch_mutex_unlock ( profile - > mutex ) ;
2007-03-30 16:41:12 +00:00
if ( is_special ( to ) ) {
ldl_handle_send_presence ( profile - > handle , to , from , NULL , NULL , " Click To Call " ) ;
}
2006-11-16 15:50:17 +00:00
#if 0
2007-03-30 16:41:12 +00:00
if ( is_special ( to ) ) {
if ( switch_event_create ( & event , SWITCH_EVENT_PRESENCE_IN ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " proto " , MDL_CHAT_PROTO ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " login " , " %s " , profile - > login ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " from " , " %s " , to ) ;
//switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "unknown");
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " status " , " Click To Call " ) ;
switch_event_fire ( & event ) ;
}
2006-10-22 04:37:19 +00:00
}
2006-11-16 15:50:17 +00:00
# endif
2007-03-30 16:41:12 +00:00
}
2006-10-20 22:26:06 +00:00
break ;
case LDL_SIGNAL_ROSTER :
if ( switch_event_create ( & event , SWITCH_EVENT_ROSTER ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " proto " , MDL_CHAT_PROTO ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " from " , " %s " , from ) ;
switch_event_fire ( & event ) ;
}
break ;
2006-12-12 17:44:59 +00:00
case LDL_SIGNAL_PRESENCE_PROBE :
if ( is_special ( to ) ) {
2007-03-29 22:31:56 +00:00
ldl_handle_send_presence ( profile - > handle , to , from , NULL , NULL , " Click To Call " ) ;
} else {
2006-12-16 03:00:56 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_PRESENCE_PROBE ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " proto " , MDL_CHAT_PROTO ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " login " , " %s " , profile - > login ) ;
2007-03-29 22:31:56 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " from " , " %s " , from ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " to " , " %s " , to ) ;
2006-12-16 03:00:56 +00:00
switch_event_fire ( & event ) ;
}
2007-03-29 22:31:56 +00:00
}
break ;
2006-10-20 22:26:06 +00:00
case LDL_SIGNAL_PRESENCE_IN :
2007-03-29 22:31:56 +00:00
2007-04-04 17:32:56 +00:00
if ( ( sql = switch_mprintf ( " update jabber_subscriptions set show_pres='%q', status='%q' where sub_from='%q' " ,
switch_str_nil ( msg ) , switch_str_nil ( subject ) , switch_str_nil ( from ) ) ) ) {
mdl_execute_sql ( profile , sql , profile - > mutex ) ;
2006-10-20 22:26:06 +00:00
switch_core_db_free ( sql ) ;
}
2007-03-29 22:31:56 +00:00
2006-10-20 22:26:06 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_PRESENCE_IN ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " proto " , MDL_CHAT_PROTO ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " login " , " %s " , profile - > login ) ;
2007-03-29 22:31:56 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " from " , " %s " , from ) ;
2006-10-20 22:26:06 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " rpid " , " %s " , msg ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " status " , " %s " , subject ) ;
switch_event_fire ( & event ) ;
}
2006-10-18 22:57:35 +00:00
2007-03-29 22:31:56 +00:00
2006-11-16 15:50:17 +00:00
if ( is_special ( to ) ) {
2006-12-12 17:44:59 +00:00
ldl_handle_send_presence ( profile - > handle , to , from , NULL , NULL , " Click To Call " ) ;
2006-11-16 15:50:17 +00:00
}
#if 0
2006-10-24 18:23:23 +00:00
if ( is_special ( to ) ) {
2006-10-22 04:37:19 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_PRESENCE_IN ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " proto " , MDL_CHAT_PROTO ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " login " , " %s " , profile - > login ) ;
2007-03-29 22:31:56 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " from " , " %s " , to ) ;
2006-12-12 17:44:59 +00:00
//switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "unknown");
2006-10-22 04:37:19 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " status " , " Click To Call " ) ;
switch_event_fire ( & event ) ;
}
}
2006-11-16 15:50:17 +00:00
# endif
2006-12-19 17:29:33 +00:00
break ;
2006-12-12 17:44:59 +00:00
2006-10-20 22:26:06 +00:00
case LDL_SIGNAL_PRESENCE_OUT :
2007-03-29 22:31:56 +00:00
2007-04-04 17:32:56 +00:00
if ( ( sql = switch_mprintf ( " update jabber_subscriptions set show_pres='%q', status='%q' where sub_from='%q' " ,
switch_str_nil ( msg ) , switch_str_nil ( subject ) , switch_str_nil ( from ) ) ) ) {
mdl_execute_sql ( profile , sql , profile - > mutex ) ;
2006-10-20 22:26:06 +00:00
switch_core_db_free ( sql ) ;
}
if ( switch_event_create ( & event , SWITCH_EVENT_PRESENCE_OUT ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " proto " , MDL_CHAT_PROTO ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " login " , " %s " , profile - > login ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " from " , " %s " , from ) ;
switch_event_fire ( & event ) ;
}
break ;
default :
break ;
2006-10-20 06:17:00 +00:00
}
2007-03-29 22:31:56 +00:00
}
switch ( dl_signal ) {
case LDL_SIGNAL_MSG : {
switch_chat_interface_t * ci ;
char * proto = MDL_CHAT_PROTO ;
char * pproto = NULL , * ffrom = NULL ;
char * hint ;
2006-10-12 14:06:09 +00:00
2007-03-29 22:31:56 +00:00
if ( profile - > auto_reply ) {
ldl_handle_send_msg ( handle ,
2007-03-30 00:15:25 +00:00
( profile - > user_flags & LDL_FLAG_COMPONENT ) ? to : ldl_handle_get_login ( profile - > handle ) , from , " " ,
profile - > auto_reply ) ;
2006-10-19 07:13:34 +00:00
}
2006-10-23 17:34:03 +00:00
2007-03-29 22:31:56 +00:00
if ( strchr ( to , ' + ' ) ) {
pproto = strdup ( to ) ;
if ( ( to = strchr ( pproto , ' + ' ) ) ) {
* to + + = ' \0 ' ;
}
proto = pproto ;
}
2006-10-23 17:34:03 +00:00
2007-03-29 22:31:56 +00:00
hint = from ;
if ( strchr ( from , ' / ' ) & & ( ffrom = strdup ( from ) ) ) {
char * p ;
if ( ( p = strchr ( ffrom , ' / ' ) ) ) {
* p = ' \0 ' ;
}
from = ffrom ;
2006-10-20 22:11:26 +00:00
}
2007-03-29 22:31:56 +00:00
if ( ( ci = switch_loadable_module_get_chat_interface ( proto ) ) ) {
ci - > chat_send ( MDL_CHAT_PROTO , from , to , subject , msg , hint ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invalid Chat Interface [%s]! \n " , proto ) ;
}
2006-10-19 07:13:34 +00:00
2007-03-29 22:31:56 +00:00
switch_safe_free ( pproto ) ;
switch_safe_free ( ffrom ) ;
}
2006-05-01 18:55:04 +00:00
break ;
case LDL_SIGNAL_LOGIN_SUCCESS :
2007-03-30 00:13:31 +00:00
if ( switch_event_create_subclass ( & event , SWITCH_EVENT_CUSTOM , DL_EVENT_LOGIN_SUCCESS ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " login " , " %s " , ldl_handle_get_login ( profile - > handle ) ) ;
2006-05-01 18:55:04 +00:00
switch_event_fire ( & event ) ;
}
2006-10-22 04:37:19 +00:00
if ( profile - > user_flags & LDL_FLAG_COMPONENT ) {
sign_on ( profile ) ;
}
2006-05-01 18:55:04 +00:00
break ;
case LDL_SIGNAL_LOGIN_FAILURE :
2007-03-30 00:13:31 +00:00
if ( switch_event_create_subclass ( & event , SWITCH_EVENT_CUSTOM , DL_EVENT_LOGIN_FAILURE ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " login " , " %s " , ldl_handle_get_login ( profile - > handle ) ) ;
2006-05-01 18:55:04 +00:00
switch_event_fire ( & event ) ;
}
break ;
2006-06-22 21:57:40 +00:00
case LDL_SIGNAL_CONNECTED :
if ( switch_event_create_subclass ( & event , SWITCH_EVENT_CUSTOM , DL_EVENT_CONNECTED ) = = SWITCH_STATUS_SUCCESS ) {
2007-03-30 00:13:31 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " login " , " %s " , ldl_handle_get_login ( profile - > handle ) ) ;
2006-06-22 21:57:40 +00:00
switch_event_fire ( & event ) ;
}
break ;
2006-05-01 18:55:04 +00:00
default :
break ;
2007-03-29 22:31:56 +00:00
2006-05-01 18:55:04 +00:00
}
2006-09-22 15:22:31 +00:00
status = LDL_STATUS_SUCCESS ;
goto done ;
2006-05-01 18:55:04 +00:00
}
2007-03-29 22:31:56 +00:00
2006-05-01 18:55:04 +00:00
2006-03-31 19:38:09 +00:00
if ( ( session = ldl_session_get_private ( dlsession ) ) ) {
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
2007-03-29 22:31:56 +00:00
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " using Existing session for %s \n " , ldl_session_get_id ( dlsession ) ) ;
2006-03-31 19:38:09 +00:00
if ( switch_channel_get_state ( channel ) > = CS_HANGUP ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Call %s is already over \n " , switch_channel_get_name ( channel ) ) ;
2006-09-22 15:22:31 +00:00
status = LDL_STATUS_FALSE ;
goto done ;
2006-03-31 19:38:09 +00:00
}
} else {
2006-12-19 17:29:33 +00:00
if ( dl_signal ! = LDL_SIGNAL_INITIATE ) {
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Session is already dead \n " ) ;
2006-09-22 15:22:31 +00:00
status = LDL_STATUS_FALSE ;
goto done ;
2006-03-31 19:38:09 +00:00
}
if ( ( session = switch_core_session_request ( & channel_endpoint_interface , NULL ) ) ! = 0 ) {
switch_core_session_add_stream ( session , NULL ) ;
2007-03-29 22:31:56 +00:00
2007-03-30 00:13:31 +00:00
if ( ( tech_pvt = ( struct private_object * ) switch_core_session_alloc ( session , sizeof ( struct private_object ) ) ) ! = 0 ) {
2006-03-31 19:38:09 +00:00
memset ( tech_pvt , 0 , sizeof ( * tech_pvt ) ) ;
2006-06-23 16:59:47 +00:00
switch_mutex_init ( & tech_pvt - > flag_mutex , SWITCH_MUTEX_NESTED , switch_core_session_get_pool ( session ) ) ;
2006-04-21 22:31:08 +00:00
tech_pvt - > flags | = globals . flags ;
tech_pvt - > flags | = profile - > flags ;
2006-03-31 19:38:09 +00:00
channel = switch_core_session_get_channel ( session ) ;
switch_core_session_set_private ( session , tech_pvt ) ;
tech_pvt - > session = session ;
tech_pvt - > codec_index = - 1 ;
tech_pvt - > profile = profile ;
2006-04-05 20:17:22 +00:00
tech_pvt - > local_port = switch_rtp_request_port ( ) ;
2006-06-23 16:59:47 +00:00
switch_set_flag_locked ( tech_pvt , TFLAG_ANSWER ) ;
2006-05-03 23:45:07 +00:00
tech_pvt - > recip = switch_core_session_strdup ( session , from ) ;
2006-08-18 21:02:40 +00:00
switch_set_flag_locked ( tech_pvt , TFLAG_TRANSPORT_ACCEPT ) ;
2006-03-31 19:38:09 +00:00
} else {
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Hey where is my memory pool? \n " ) ;
2007-03-29 22:31:56 +00:00
terminate_session ( & session , __LINE__ , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2006-09-22 15:22:31 +00:00
status = LDL_STATUS_FALSE ;
goto done ;
2006-03-31 19:38:09 +00:00
}
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Creating a session for %s \n " , ldl_session_get_id ( dlsession ) ) ;
2006-03-31 19:38:09 +00:00
ldl_session_set_private ( dlsession , session ) ;
tech_pvt - > dlsession = dlsession ;
2006-11-16 15:50:17 +00:00
switch_channel_set_name ( channel , " DingaLing/new " ) ;
2006-10-10 00:11:41 +00:00
switch_channel_set_state ( channel , CS_INIT ) ;
switch_core_session_thread_launch ( session ) ;
2006-09-22 15:22:31 +00:00
} else {
status = LDL_STATUS_FALSE ;
goto done ;
2006-03-31 19:38:09 +00:00
}
2006-09-22 15:22:31 +00:00
2006-03-31 19:38:09 +00:00
}
2006-05-03 23:59:54 +00:00
2007-03-29 22:31:56 +00:00
switch ( dl_signal ) {
2006-03-31 19:38:09 +00:00
case LDL_SIGNAL_MSG :
2007-03-29 22:31:56 +00:00
if ( msg ) {
2006-03-31 19:38:09 +00:00
if ( * msg = = ' + ' ) {
switch_channel_queue_dtmf ( channel , msg + 1 ) ;
2006-06-23 16:59:47 +00:00
switch_set_flag_locked ( tech_pvt , TFLAG_DTMF ) ;
2006-08-28 23:05:26 +00:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
2006-08-18 01:28:50 +00:00
switch_rtp_set_flag ( tech_pvt - > rtp_session , SWITCH_RTP_FLAG_BREAK ) ;
}
2006-03-31 19:38:09 +00:00
}
2006-10-20 22:11:26 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " SESSION MSG [%s] \n " , msg ) ;
2006-03-31 19:38:09 +00:00
}
2006-10-12 00:59:09 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_MESSAGE ) = = SWITCH_STATUS_SUCCESS ) {
2006-10-23 17:34:03 +00:00
char * hint = NULL , * p , * freeme = NULL ;
2007-03-29 22:31:56 +00:00
hint = from ;
2006-10-20 22:11:26 +00:00
if ( strchr ( from , ' / ' ) ) {
freeme = strdup ( from ) ;
p = strchr ( freeme , ' / ' ) ;
* p = ' \0 ' ;
2007-03-29 22:31:56 +00:00
from = freeme ;
2006-10-20 22:11:26 +00:00
}
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " proto " , MDL_CHAT_PROTO ) ;
2006-11-15 20:21:29 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " login " , " %s " , ldl_handle_get_login ( profile - > handle ) ) ;
2006-10-23 17:34:03 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " hint " , " %s " , hint ) ;
2006-10-15 04:44:33 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " from " , " %s " , from ) ;
2006-10-20 22:11:26 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " to " , " %s " , to ) ;
2006-10-15 04:44:33 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " subject " , " %s " , subject ) ;
2006-10-12 00:59:09 +00:00
if ( msg ) {
2007-02-14 03:45:10 +00:00
switch_event_add_body ( event , " %s " , msg ) ;
2006-10-12 00:59:09 +00:00
}
2006-07-12 18:39:19 +00:00
if ( switch_core_session_queue_event ( tech_pvt - > session , & event ) ! = SWITCH_STATUS_SUCCESS ) {
2006-07-17 14:12:07 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " delivery-failure " , " true " ) ;
2006-07-12 18:39:19 +00:00
switch_event_fire ( & event ) ;
}
2006-07-17 14:12:07 +00:00
2006-10-20 22:11:26 +00:00
switch_safe_free ( freeme ) ;
2006-05-01 18:55:04 +00:00
}
break ;
2006-08-18 21:02:40 +00:00
case LDL_SIGNAL_TRANSPORT_ACCEPT :
switch_set_flag_locked ( tech_pvt , TFLAG_TRANSPORT_ACCEPT ) ;
2006-03-31 19:38:09 +00:00
break ;
case LDL_SIGNAL_INITIATE :
2006-12-19 17:29:33 +00:00
if ( dl_signal ) {
2006-03-31 19:38:09 +00:00
ldl_payload_t * payloads ;
unsigned int len = 0 ;
2006-05-12 22:01:31 +00:00
int match = 0 ;
2006-03-31 19:38:09 +00:00
2006-04-15 22:30:25 +00:00
if ( switch_test_flag ( tech_pvt , TFLAG_OUTBOUND ) ) {
if ( ! strcasecmp ( msg , " accept " ) ) {
2006-06-23 16:59:47 +00:00
switch_set_flag_locked ( tech_pvt , TFLAG_ANSWER ) ;
2006-08-18 16:36:26 +00:00
if ( ! do_candidates ( tech_pvt , 0 ) ) {
2007-03-29 22:31:56 +00:00
terminate_session ( & session , __LINE__ , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2006-09-22 15:22:31 +00:00
status = LDL_STATUS_FALSE ;
goto done ;
2006-08-18 16:36:26 +00:00
}
2006-04-15 22:30:25 +00:00
}
}
2006-04-15 05:16:24 +00:00
2006-03-31 19:38:09 +00:00
if ( tech_pvt - > codec_index > - 1 ) {
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Already decided on a codec \n " ) ;
2006-03-31 19:38:09 +00:00
break ;
}
2006-08-18 16:36:26 +00:00
if ( ! get_codecs ( tech_pvt ) ) {
2007-03-29 22:31:56 +00:00
terminate_session ( & session , __LINE__ , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2006-09-22 15:22:31 +00:00
status = LDL_STATUS_FALSE ;
goto done ;
2006-03-31 19:38:09 +00:00
}
2007-03-29 22:31:56 +00:00
2006-03-31 19:38:09 +00:00
if ( ldl_session_get_payloads ( dlsession , & payloads , & len ) = = LDL_STATUS_SUCCESS ) {
2007-03-29 22:31:56 +00:00
unsigned int x , y ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " %u payloads \n " , len ) ;
for ( x = 0 ; x < len ; x + + ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Available Payload %s %u \n " , payloads [ x ] . name , payloads [ x ] . id ) ;
2007-03-29 22:31:56 +00:00
for ( y = 0 ; y < tech_pvt - > num_codecs ; y + + ) {
2006-07-10 22:08:02 +00:00
char * name = tech_pvt - > codecs [ y ] - > iananame ;
2006-04-19 21:40:15 +00:00
if ( ! strncasecmp ( name , " ilbc " , 4 ) ) {
name = " ilbc " ;
}
2007-03-29 22:31:56 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " compare %s %d/%d to %s %d/%d \n " ,
payloads [ x ] . name , payloads [ x ] . id , payloads [ x ] . rate ,
name , tech_pvt - > codecs [ y ] - > ianacode , tech_pvt - > codecs [ y ] - > samples_per_second ) ;
2006-10-09 02:24:43 +00:00
if ( tech_pvt - > codecs [ y ] - > ianacode > 95 ) {
2006-04-19 21:40:15 +00:00
match = strcasecmp ( name , payloads [ x ] . name ) ? 0 : 1 ;
2006-04-19 21:28:28 +00:00
} else {
2006-07-10 22:08:02 +00:00
match = ( payloads [ x ] . id = = tech_pvt - > codecs [ y ] - > ianacode ) ? 1 : 0 ;
2006-04-19 21:28:28 +00:00
}
2007-03-29 22:31:56 +00:00
2006-08-18 01:28:50 +00:00
if ( match & & payloads [ x ] . rate = = tech_pvt - > codecs [ y ] - > samples_per_second ) {
2006-03-31 19:38:09 +00:00
tech_pvt - > codec_index = y ;
2007-03-30 00:15:25 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Choosing Payload index %u %s %u \n " , y , payloads [ x ] . name ,
payloads [ x ] . id ) ;
2006-07-10 22:08:02 +00:00
tech_pvt - > codec_name = tech_pvt - > codecs [ y ] - > iananame ;
tech_pvt - > codec_num = tech_pvt - > codecs [ y ] - > ianacode ;
2007-03-29 22:31:56 +00:00
tech_pvt - > r_codec_num = ( switch_payload_t ) ( payloads [ x ] . id ) ;
2006-08-18 16:36:26 +00:00
tech_pvt - > codec_rate = payloads [ x ] . rate ;
2006-04-15 22:30:25 +00:00
if ( ! switch_test_flag ( tech_pvt , TFLAG_OUTBOUND ) ) {
2006-08-18 16:36:26 +00:00
if ( ! do_describe ( tech_pvt , 0 ) ) {
2007-03-29 22:31:56 +00:00
terminate_session ( & session , __LINE__ , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2006-09-22 15:22:31 +00:00
status = LDL_STATUS_FALSE ;
goto done ;
2006-08-18 16:36:26 +00:00
}
2006-04-15 22:30:25 +00:00
}
2006-09-22 15:22:31 +00:00
status = LDL_STATUS_SUCCESS ;
goto done ;
2006-03-31 19:38:09 +00:00
}
}
}
2006-05-12 22:01:31 +00:00
if ( ! match & & ! switch_test_flag ( tech_pvt , TFLAG_OUTBOUND ) ) {
2006-08-18 16:36:26 +00:00
if ( ! do_describe ( tech_pvt , 0 ) ) {
2007-03-29 22:31:56 +00:00
terminate_session ( & session , __LINE__ , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2006-09-22 15:22:31 +00:00
status = LDL_STATUS_FALSE ;
goto done ;
2006-08-18 16:36:26 +00:00
}
2006-05-12 22:01:31 +00:00
}
2006-03-31 19:38:09 +00:00
}
}
2007-03-29 22:31:56 +00:00
2006-03-31 19:38:09 +00:00
break ;
case LDL_SIGNAL_CANDIDATES :
2006-12-19 17:29:33 +00:00
if ( dl_signal ) {
2006-03-31 19:38:09 +00:00
ldl_candidate_t * candidates ;
unsigned int len = 0 ;
2006-11-16 15:50:17 +00:00
unsigned int x ;
2006-03-31 19:38:09 +00:00
2006-11-16 15:50:17 +00:00
if ( ldl_session_get_candidates ( dlsession , & candidates , & len ) ! = LDL_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Candidate Error! \n " ) ;
switch_set_flag ( tech_pvt , TFLAG_BYE ) ;
switch_clear_flag ( tech_pvt , TFLAG_IO ) ;
status = LDL_STATUS_FALSE ;
goto done ;
}
2006-03-31 19:38:09 +00:00
2007-03-29 22:31:56 +00:00
2006-11-16 15:50:17 +00:00
if ( tech_pvt - > remote_ip ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Already picked an IP [%s] \n " , tech_pvt - > remote_ip ) ;
2006-11-16 15:50:17 +00:00
break ;
}
2006-03-31 19:38:09 +00:00
2006-11-16 15:50:17 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " %u candidates \n " , len ) ;
2007-03-29 22:31:56 +00:00
for ( x = 0 ; x < len ; x + + ) {
2006-11-16 15:50:17 +00:00
uint8_t lanaddr = 0 ;
2006-04-27 21:25:47 +00:00
2006-11-16 15:50:17 +00:00
if ( profile - > lanaddr ) {
lanaddr = strncasecmp ( candidates [ x ] . address , profile - > lanaddr , strlen ( profile - > lanaddr ) ) ? 0 : 1 ;
2007-03-29 22:31:56 +00:00
}
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " candidates %s:%d \n " , candidates [ x ] . address , candidates [ x ] . port ) ;
2007-03-29 22:31:56 +00:00
if ( ! strcasecmp ( candidates [ x ] . protocol , " udp " ) & & ( ! strcasecmp ( candidates [ x ] . type , " local " ) | | ! strcasecmp ( candidates [ x ] . type , " stun " ) ) & & ( ( profile - > lanaddr & & lanaddr ) | | ( strncasecmp ( candidates [ x ] . address , " 10. " , 3 ) & & strncasecmp ( candidates [ x ] . address , " 192.168. " , 8 ) & & strncasecmp ( candidates [ x ] . address , " 127. " , 4 ) & & strncasecmp ( candidates [ x ] . address , " 255. " , 4 ) & & strncasecmp ( candidates [ x ] . address , " 0. " , 2 ) & & strncasecmp ( candidates [ x ] . address , " 1. " , 2 ) & & strncasecmp ( candidates [ x ] . address , " 2. " , 2 ) & & strncasecmp ( candidates [ x ] . address , " 172.16. " , 7 ) & & strncasecmp ( candidates [ x ] . address , " 172.17. " , 7 ) & & strncasecmp ( candidates [ x ] . address , " 172.18. " , 7 ) & & strncasecmp ( candidates [ x ] . address , " 172.19. " , 7 ) & & strncasecmp ( candidates [ x ] . address , " 172.2 " , 5 ) & & strncasecmp ( candidates [ x ] . address , " 172.30. " , 7 ) & & strncasecmp ( candidates [ x ] . address , " 172.31. " , 7 ) & & strncasecmp ( candidates [ x ] . address , " 192.0.2. " , 8 ) & & // 192.0.0.0 - 192.0.127.255 is marked as reserved, should we filter all of them?
strncasecmp
( candidates
[ x ] .
address ,
" 169.254. " ,
8 )
) ) ) {
2006-11-16 15:50:17 +00:00
ldl_payload_t payloads [ 5 ] ;
char * exten ;
char * context ;
char * cid_name ;
char * cid_num ;
char * tmp , * t , * them = NULL ;
memset ( payloads , 0 , sizeof ( payloads ) ) ;
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Acceptable Candidate %s:%d \n " , candidates [ x ] . address , candidates [ x ] . port ) ;
2006-11-16 15:50:17 +00:00
if ( ! switch_test_flag ( tech_pvt , TFLAG_OUTBOUND ) ) {
switch_set_flag_locked ( tech_pvt , TFLAG_TRANSPORT_ACCEPT ) ;
ldl_session_accept_candidate ( dlsession , & candidates [ x ] ) ;
}
if ( ! ( exten = ldl_session_get_value ( dlsession , " dnis " ) ) ) {
exten = profile - > exten ;
/* if it's _auto_ set the extension to match the username portion of the called address */
if ( ! strcmp ( exten , " _auto_ " ) ) {
if ( ( t = ldl_session_get_callee ( dlsession ) ) ) {
if ( ( them = strdup ( t ) ) ) {
char * a , * b , * p ;
if ( ( p = strchr ( them , ' / ' ) ) ) {
* p = ' \0 ' ;
}
2006-05-04 15:37:06 +00:00
2006-11-16 15:50:17 +00:00
if ( ( a = strchr ( them , ' + ' ) ) & & ( b = strrchr ( them , ' + ' ) ) & & a ! = b ) {
* b + + = ' \0 ' ;
switch_channel_set_variable ( channel , " dl_user " , them ) ;
switch_channel_set_variable ( channel , " dl_host " , b ) ;
2006-10-18 22:57:35 +00:00
}
2006-11-16 15:50:17 +00:00
exten = them ;
2006-10-18 22:57:35 +00:00
}
}
2006-05-04 15:37:06 +00:00
}
2006-11-16 15:50:17 +00:00
}
2007-03-29 22:31:56 +00:00
2006-11-16 15:50:17 +00:00
if ( ! ( context = ldl_session_get_value ( dlsession , " context " ) ) ) {
context = profile - > context ;
}
2006-05-04 15:37:06 +00:00
2006-11-16 15:50:17 +00:00
if ( ! ( cid_name = ldl_session_get_value ( dlsession , " caller_id_name " ) ) ) {
cid_name = tech_pvt - > recip ;
}
2006-05-04 15:37:06 +00:00
2006-11-16 15:50:17 +00:00
if ( ! ( cid_num = ldl_session_get_value ( dlsession , " caller_id_number " ) ) ) {
cid_num = tech_pvt - > recip ;
}
2006-10-22 04:37:19 +00:00
2006-11-16 15:50:17 +00:00
/* context of "_auto_" means set it to the domain */
if ( profile - > context & & ! strcmp ( profile - > context , " _auto_ " ) ) {
context = profile - > name ;
}
2007-03-29 22:31:56 +00:00
2006-11-16 15:50:17 +00:00
tech_pvt - > them = switch_core_session_strdup ( session , ldl_session_get_callee ( dlsession ) ) ;
tech_pvt - > us = switch_core_session_strdup ( session , ldl_session_get_caller ( dlsession ) ) ;
2006-10-29 15:36:23 +00:00
2006-11-16 15:50:17 +00:00
if ( ( tmp = strdup ( tech_pvt - > us ) ) ) {
char * p , * q ;
2006-10-29 15:36:23 +00:00
2006-11-16 15:50:17 +00:00
if ( ( p = strchr ( tmp , ' @ ' ) ) ) {
* p + + = ' \0 ' ;
if ( ( q = strchr ( p , ' / ' ) ) ) {
* q = ' \0 ' ;
2006-10-29 15:36:23 +00:00
}
2006-11-16 15:50:17 +00:00
switch_channel_set_variable ( channel , " dl_from_user " , tmp ) ;
switch_channel_set_variable ( channel , " dl_from_host " , p ) ;
2006-10-29 15:36:23 +00:00
}
2006-11-16 15:50:17 +00:00
switch_safe_free ( tmp ) ;
}
2007-03-29 22:31:56 +00:00
2006-11-16 15:50:17 +00:00
if ( ! tech_pvt - > caller_profile ) {
2007-03-29 22:31:56 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG ,
2007-03-30 00:13:31 +00:00
" Creating an identity for %s %s <%s> %s \n " , ldl_session_get_id ( dlsession ) , cid_name , cid_num , exten ) ;
2007-03-29 22:31:56 +00:00
2006-11-16 15:50:17 +00:00
if ( ( tech_pvt - > caller_profile = switch_caller_profile_new ( switch_core_session_get_pool ( session ) ,
ldl_handle_get_login ( profile - > handle ) ,
profile - > dialplan ,
cid_name ,
cid_num ,
ldl_session_get_ip ( dlsession ) ,
2007-03-29 22:31:56 +00:00
ldl_session_get_value ( dlsession ,
" ani " ) ,
ldl_session_get_value ( dlsession ,
" aniii " ) ,
ldl_session_get_value ( dlsession ,
2007-03-30 00:15:25 +00:00
" rdnis " ) , ( char * ) modname , context ,
exten ) ) ! = 0 ) {
2006-11-16 15:50:17 +00:00
char name [ 128 ] ;
snprintf ( name , sizeof ( name ) , " DingaLing/%s " , tech_pvt - > caller_profile - > destination_number ) ;
switch_channel_set_name ( channel , name ) ;
switch_channel_set_caller_profile ( channel , tech_pvt - > caller_profile ) ;
2006-05-04 15:37:06 +00:00
}
2006-11-16 15:50:17 +00:00
}
2006-05-04 15:37:06 +00:00
2006-11-16 15:50:17 +00:00
switch_safe_free ( them ) ;
2007-03-29 22:31:56 +00:00
2006-11-16 15:50:17 +00:00
if ( lanaddr ) {
switch_set_flag_locked ( tech_pvt , TFLAG_LANADDR ) ;
}
2006-04-27 15:59:58 +00:00
2006-11-16 15:50:17 +00:00
if ( ! get_codecs ( tech_pvt ) ) {
2007-03-29 22:31:56 +00:00
terminate_session ( & session , __LINE__ , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2006-11-16 15:50:17 +00:00
status = LDL_STATUS_FALSE ;
goto done ;
}
2006-08-18 16:36:26 +00:00
2007-03-29 22:31:56 +00:00
2006-11-16 15:50:17 +00:00
tech_pvt - > remote_ip = switch_core_session_strdup ( session , candidates [ x ] . address ) ;
ldl_session_set_ip ( dlsession , tech_pvt - > remote_ip ) ;
tech_pvt - > remote_port = candidates [ x ] . port ;
tech_pvt - > remote_user = switch_core_session_strdup ( session , candidates [ x ] . username ) ;
2006-08-18 01:28:50 +00:00
2007-03-29 22:31:56 +00:00
2006-11-16 15:50:17 +00:00
if ( ! switch_test_flag ( tech_pvt , TFLAG_OUTBOUND ) ) {
if ( ! do_candidates ( tech_pvt , 0 ) ) {
2007-03-29 22:31:56 +00:00
terminate_session ( & session , __LINE__ , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2006-11-16 15:50:17 +00:00
status = LDL_STATUS_FALSE ;
goto done ;
2006-04-15 22:30:25 +00:00
}
2006-03-31 19:38:09 +00:00
}
2007-03-29 22:31:56 +00:00
2006-11-16 15:50:17 +00:00
status = LDL_STATUS_SUCCESS ;
goto done ;
2006-03-31 19:38:09 +00:00
}
}
}
break ;
2007-01-29 22:22:29 +00:00
case LDL_SIGNAL_REJECT :
2007-03-29 22:31:56 +00:00
if ( channel ) {
2007-01-29 22:22:29 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " reject %s \n " , switch_channel_get_name ( channel ) ) ;
2007-03-29 22:31:56 +00:00
terminate_session ( & session , __LINE__ , SWITCH_CAUSE_CALL_REJECTED ) ;
2007-01-29 22:22:29 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " End Call (Rejected) \n " ) ;
goto done ;
}
2007-03-29 22:31:56 +00:00
break ;
2006-03-31 19:38:09 +00:00
case LDL_SIGNAL_ERROR :
case LDL_SIGNAL_TERMINATE :
if ( channel ) {
2007-03-09 23:51:52 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " hungup %s \n " , switch_channel_get_name ( channel ) ) ;
2007-03-29 22:31:56 +00:00
terminate_session ( & session , __LINE__ , SWITCH_CAUSE_NORMAL_CLEARING ) ;
2006-09-22 15:22:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " End Call \n " ) ;
goto done ;
2006-03-31 19:38:09 +00:00
}
break ;
2006-05-01 18:55:04 +00:00
default :
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " ERROR \n " ) ;
break ;
2006-03-31 19:38:09 +00:00
}
2007-03-29 22:31:56 +00:00
done :
2006-09-22 15:22:31 +00:00
return status ;
2006-03-31 19:38:09 +00:00
}
2007-03-29 22:31:56 +00:00
static ldl_status handle_response ( ldl_handle_t * handle , char * id )
2006-03-31 19:38:09 +00:00
{
return LDL_STATUS_SUCCESS ;
}
2006-11-27 22:30:48 +00:00
/* For Emacs:
* Local Variables :
* mode : c
2007-02-09 02:36:03 +00:00
* indent - tabs - mode : t
2006-11-27 22:30:48 +00:00
* tab - width : 4
* c - basic - offset : 4
* End :
* For VIM :
* vim : set softtabstop = 4 shiftwidth = 4 tabstop = 4 expandtab :
*/