2005-11-19 20:07:43 +00:00
/*
* FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
2009-02-13 23:37:37 +00:00
* Copyright ( C ) 2005 - 2009 , Anthony Minessale II < anthm @ freeswitch . org >
2005-11-19 20:07:43 +00:00
*
* Version : MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 ( the " License " ) ; you may not use this file except in compliance with
* the License . You may obtain a copy of the License at
* http : //www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an " AS IS " basis ,
* WITHOUT WARRANTY OF ANY KIND , either express or implied . See the License
* for the specific language governing rights and limitations under the
* License .
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
*
* The Initial Developer of the Original Code is
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2005-11-19 20:07:43 +00:00
* Portions created by the Initial Developer are Copyright ( C )
* the Initial Developer . All Rights Reserved .
*
* Contributor ( s ) :
*
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2006-09-18 05:08:55 +00:00
* Michael Jerris < mike @ jerris . com >
2005-11-19 20:07:43 +00:00
*
*
* switch_channel . c - - Media Channel Interface
*
*/
2008-01-27 17:36:53 +00:00
2006-04-29 01:00:52 +00:00
# include <switch.h>
2006-04-29 06:05:03 +00:00
# include <switch_channel.h>
2005-11-19 20:07:43 +00:00
2006-04-22 18:12:17 +00:00
struct switch_cause_table {
const char * name ;
switch_call_cause_t cause ;
} ;
static struct switch_cause_table CAUSE_CHART [ ] = {
2008-07-03 22:51:09 +00:00
{ " NONE " , SWITCH_CAUSE_NONE } ,
2008-07-23 14:19:53 +00:00
{ " UNALLOCATED_NUMBER " , SWITCH_CAUSE_UNALLOCATED_NUMBER } ,
2007-03-29 22:31:56 +00:00
{ " NO_ROUTE_TRANSIT_NET " , SWITCH_CAUSE_NO_ROUTE_TRANSIT_NET } ,
{ " NO_ROUTE_DESTINATION " , SWITCH_CAUSE_NO_ROUTE_DESTINATION } ,
{ " CHANNEL_UNACCEPTABLE " , SWITCH_CAUSE_CHANNEL_UNACCEPTABLE } ,
{ " CALL_AWARDED_DELIVERED " , SWITCH_CAUSE_CALL_AWARDED_DELIVERED } ,
{ " NORMAL_CLEARING " , SWITCH_CAUSE_NORMAL_CLEARING } ,
{ " USER_BUSY " , SWITCH_CAUSE_USER_BUSY } ,
{ " NO_USER_RESPONSE " , SWITCH_CAUSE_NO_USER_RESPONSE } ,
{ " NO_ANSWER " , SWITCH_CAUSE_NO_ANSWER } ,
{ " SUBSCRIBER_ABSENT " , SWITCH_CAUSE_SUBSCRIBER_ABSENT } ,
{ " CALL_REJECTED " , SWITCH_CAUSE_CALL_REJECTED } ,
{ " NUMBER_CHANGED " , SWITCH_CAUSE_NUMBER_CHANGED } ,
{ " REDIRECTION_TO_NEW_DESTINATION " , SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION } ,
{ " EXCHANGE_ROUTING_ERROR " , SWITCH_CAUSE_EXCHANGE_ROUTING_ERROR } ,
{ " DESTINATION_OUT_OF_ORDER " , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER } ,
{ " INVALID_NUMBER_FORMAT " , SWITCH_CAUSE_INVALID_NUMBER_FORMAT } ,
{ " FACILITY_REJECTED " , SWITCH_CAUSE_FACILITY_REJECTED } ,
{ " RESPONSE_TO_STATUS_ENQUIRY " , SWITCH_CAUSE_RESPONSE_TO_STATUS_ENQUIRY } ,
{ " NORMAL_UNSPECIFIED " , SWITCH_CAUSE_NORMAL_UNSPECIFIED } ,
{ " NORMAL_CIRCUIT_CONGESTION " , SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION } ,
{ " NETWORK_OUT_OF_ORDER " , SWITCH_CAUSE_NETWORK_OUT_OF_ORDER } ,
{ " NORMAL_TEMPORARY_FAILURE " , SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE } ,
{ " SWITCH_CONGESTION " , SWITCH_CAUSE_SWITCH_CONGESTION } ,
{ " ACCESS_INFO_DISCARDED " , SWITCH_CAUSE_ACCESS_INFO_DISCARDED } ,
{ " REQUESTED_CHAN_UNAVAIL " , SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL } ,
{ " PRE_EMPTED " , SWITCH_CAUSE_PRE_EMPTED } ,
{ " FACILITY_NOT_SUBSCRIBED " , SWITCH_CAUSE_FACILITY_NOT_SUBSCRIBED } ,
{ " OUTGOING_CALL_BARRED " , SWITCH_CAUSE_OUTGOING_CALL_BARRED } ,
{ " INCOMING_CALL_BARRED " , SWITCH_CAUSE_INCOMING_CALL_BARRED } ,
{ " BEARERCAPABILITY_NOTAUTH " , SWITCH_CAUSE_BEARERCAPABILITY_NOTAUTH } ,
{ " BEARERCAPABILITY_NOTAVAIL " , SWITCH_CAUSE_BEARERCAPABILITY_NOTAVAIL } ,
{ " SERVICE_UNAVAILABLE " , SWITCH_CAUSE_SERVICE_UNAVAILABLE } ,
{ " CHAN_NOT_IMPLEMENTED " , SWITCH_CAUSE_CHAN_NOT_IMPLEMENTED } ,
{ " FACILITY_NOT_IMPLEMENTED " , SWITCH_CAUSE_FACILITY_NOT_IMPLEMENTED } ,
{ " SERVICE_NOT_IMPLEMENTED " , SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED } ,
{ " INVALID_CALL_REFERENCE " , SWITCH_CAUSE_INVALID_CALL_REFERENCE } ,
{ " INCOMPATIBLE_DESTINATION " , SWITCH_CAUSE_INCOMPATIBLE_DESTINATION } ,
{ " INVALID_MSG_UNSPECIFIED " , SWITCH_CAUSE_INVALID_MSG_UNSPECIFIED } ,
{ " MANDATORY_IE_MISSING " , SWITCH_CAUSE_MANDATORY_IE_MISSING } ,
{ " MESSAGE_TYPE_NONEXIST " , SWITCH_CAUSE_MESSAGE_TYPE_NONEXIST } ,
{ " WRONG_MESSAGE " , SWITCH_CAUSE_WRONG_MESSAGE } ,
{ " IE_NONEXIST " , SWITCH_CAUSE_IE_NONEXIST } ,
{ " INVALID_IE_CONTENTS " , SWITCH_CAUSE_INVALID_IE_CONTENTS } ,
{ " WRONG_CALL_STATE " , SWITCH_CAUSE_WRONG_CALL_STATE } ,
{ " RECOVERY_ON_TIMER_EXPIRE " , SWITCH_CAUSE_RECOVERY_ON_TIMER_EXPIRE } ,
{ " MANDATORY_IE_LENGTH_ERROR " , SWITCH_CAUSE_MANDATORY_IE_LENGTH_ERROR } ,
{ " PROTOCOL_ERROR " , SWITCH_CAUSE_PROTOCOL_ERROR } ,
{ " INTERWORKING " , SWITCH_CAUSE_INTERWORKING } ,
2008-07-03 22:51:09 +00:00
{ " SUCCESS " , SWITCH_CAUSE_SUCCESS } ,
2007-03-29 22:31:56 +00:00
{ " ORIGINATOR_CANCEL " , SWITCH_CAUSE_ORIGINATOR_CANCEL } ,
{ " CRASH " , SWITCH_CAUSE_CRASH } ,
{ " SYSTEM_SHUTDOWN " , SWITCH_CAUSE_SYSTEM_SHUTDOWN } ,
{ " LOSE_RACE " , SWITCH_CAUSE_LOSE_RACE } ,
{ " MANAGER_REQUEST " , SWITCH_CAUSE_MANAGER_REQUEST } ,
{ " BLIND_TRANSFER " , SWITCH_CAUSE_BLIND_TRANSFER } ,
{ " ATTENDED_TRANSFER " , SWITCH_CAUSE_ATTENDED_TRANSFER } ,
{ " ALLOTTED_TIMEOUT " , SWITCH_CAUSE_ALLOTTED_TIMEOUT } ,
2007-06-08 22:28:32 +00:00
{ " USER_CHALLENGE " , SWITCH_CAUSE_USER_CHALLENGE } ,
2007-10-31 13:08:45 +00:00
{ " MEDIA_TIMEOUT " , SWITCH_CAUSE_MEDIA_TIMEOUT } ,
2007-12-08 00:14:21 +00:00
{ " PICKED_OFF " , SWITCH_CAUSE_PICKED_OFF } ,
2008-08-11 16:12:55 +00:00
{ " USER_NOT_REGISTERED " , SWITCH_CAUSE_USER_NOT_REGISTERED } ,
2008-10-09 00:38:59 +00:00
{ " PROGRESS_TIMEOUT " , SWITCH_CAUSE_PROGRESS_TIMEOUT } ,
2007-03-29 22:31:56 +00:00
{ NULL , 0 }
2006-04-22 18:12:17 +00:00
} ;
2005-11-19 20:07:43 +00:00
struct switch_channel {
char * name ;
2009-02-23 16:31:59 +00:00
switch_call_direction_t direction ;
2007-12-22 00:32:20 +00:00
switch_queue_t * dtmf_queue ;
2009-02-23 16:31:59 +00:00
switch_queue_t * dtmf_log_queue ;
2005-12-06 21:25:56 +00:00
switch_mutex_t * dtmf_mutex ;
2006-06-22 23:56:09 +00:00
switch_mutex_t * flag_mutex ;
2009-02-20 18:31:08 +00:00
switch_mutex_t * state_mutex ;
2006-04-28 19:46:57 +00:00
switch_mutex_t * profile_mutex ;
2006-04-29 06:05:03 +00:00
switch_core_session_t * session ;
2006-04-29 23:43:28 +00:00
switch_channel_state_t state ;
2007-12-08 00:14:21 +00:00
switch_channel_state_t running_state ;
2009-08-26 17:42:36 +00:00
uint32_t flags [ CF_FLAG_MAX ] ;
2009-10-14 19:26:10 +00:00
uint32_t caps [ CC_FLAG_MAX ] ;
2008-12-11 15:20:24 +00:00
uint8_t state_flags [ CF_FLAG_MAX ] ;
2008-12-04 04:46:10 +00:00
uint32_t private_flags ;
2009-01-22 14:01:15 +00:00
uint32_t app_flags ;
2006-04-29 06:05:03 +00:00
switch_caller_profile_t * caller_profile ;
const switch_state_handler_table_t * state_handlers [ SWITCH_MAX_STATE_HANDLERS ] ;
2006-02-07 20:47:15 +00:00
int state_handler_index ;
2007-09-29 01:06:08 +00:00
switch_event_t * variables ;
2006-09-07 03:58:01 +00:00
switch_hash_t * private_hash ;
2006-04-21 23:16:26 +00:00
switch_call_cause_t hangup_cause ;
2007-04-28 21:48:03 +00:00
int vi ;
2007-12-15 00:39:53 +00:00
int event_count ;
2008-02-26 23:29:58 +00:00
int profile_index ;
2005-11-19 20:07:43 +00:00
} ;
2007-05-12 14:48:14 +00:00
SWITCH_DECLARE ( const char * ) switch_channel_cause2str ( switch_call_cause_t cause )
2006-04-22 18:12:17 +00:00
{
uint8_t x ;
2007-05-12 14:48:14 +00:00
const char * str = " UNKNOWN " ;
2006-04-22 18:12:17 +00:00
2008-05-27 04:30:03 +00:00
for ( x = 0 ; x < ( sizeof ( CAUSE_CHART ) / sizeof ( struct switch_cause_table ) ) - 1 ; x + + ) {
2006-04-22 18:12:17 +00:00
if ( CAUSE_CHART [ x ] . cause = = cause ) {
2007-05-12 14:48:14 +00:00
str = CAUSE_CHART [ x ] . name ;
2008-05-21 20:00:00 +00:00
break ;
2006-04-22 18:12:17 +00:00
}
}
return str ;
}
2007-05-12 14:48:14 +00:00
SWITCH_DECLARE ( switch_call_cause_t ) switch_channel_str2cause ( const char * str )
2006-04-22 18:12:17 +00:00
{
uint8_t x ;
2008-07-03 22:51:09 +00:00
switch_call_cause_t cause = SWITCH_CAUSE_NONE ;
2006-04-22 18:12:17 +00:00
2007-07-03 21:05:41 +00:00
if ( * str > 47 & & * str < 58 ) {
cause = atoi ( str ) ;
} else {
2008-05-21 20:00:00 +00:00
for ( x = 0 ; x < ( sizeof ( CAUSE_CHART ) / sizeof ( struct switch_cause_table ) ) - 1 & & CAUSE_CHART [ x ] . name ; x + + ) {
2007-07-03 21:05:41 +00:00
if ( ! strcasecmp ( CAUSE_CHART [ x ] . name , str ) ) {
cause = CAUSE_CHART [ x ] . cause ;
2008-05-21 20:00:00 +00:00
break ;
2007-07-03 21:05:41 +00:00
}
2006-04-22 18:12:17 +00:00
}
}
return cause ;
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( switch_call_cause_t ) switch_channel_get_cause ( switch_channel_t * channel )
2006-04-22 18:12:17 +00:00
{
return channel - > hangup_cause ;
}
2008-11-27 04:02:57 +00:00
SWITCH_DECLARE ( void ) switch_channel_audio_sync ( switch_channel_t * channel )
{
if ( switch_channel_media_ready ( channel ) ) {
2009-10-12 22:23:55 +00:00
switch_core_session_message_t msg = { 0 } ;
2008-11-27 04:02:57 +00:00
msg . message_id = SWITCH_MESSAGE_INDICATE_AUDIO_SYNC ;
msg . from = channel - > name ;
switch_core_session_receive_message ( channel - > session , & msg ) ;
}
}
2008-09-24 21:19:29 +00:00
SWITCH_DECLARE ( switch_call_cause_t ) switch_channel_cause_q850 ( switch_call_cause_t cause )
{
if ( cause < = SWITCH_CAUSE_INTERWORKING ) {
return cause ;
} else {
return SWITCH_CAUSE_NORMAL_CLEARING ;
}
}
SWITCH_DECLARE ( switch_call_cause_t ) switch_channel_get_cause_q850 ( switch_channel_t * channel )
{
return switch_channel_cause_q850 ( channel - > hangup_cause ) ;
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( switch_channel_timetable_t * ) switch_channel_get_timetable ( switch_channel_t * channel )
2006-02-24 22:22:43 +00:00
{
2007-03-29 22:31:56 +00:00
switch_channel_timetable_t * times = NULL ;
2006-12-01 15:26:37 +00:00
2007-03-29 22:31:56 +00:00
if ( channel - > caller_profile ) {
switch_mutex_lock ( channel - > profile_mutex ) ;
times = channel - > caller_profile - > times ;
switch_mutex_unlock ( channel - > profile_mutex ) ;
}
2006-12-01 15:26:37 +00:00
return times ;
2006-02-24 22:22:43 +00:00
}
2005-11-19 20:07:43 +00:00
2009-04-21 17:47:22 +00:00
SWITCH_DECLARE ( switch_call_direction_t ) switch_channel_direction ( switch_channel_t * channel )
{
return channel - > direction ;
}
2009-02-23 16:31:59 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_channel_alloc ( switch_channel_t * * channel , switch_call_direction_t direction , switch_memory_pool_t * pool )
2005-11-19 20:07:43 +00:00
{
2007-12-11 19:23:57 +00:00
switch_assert ( pool ! = NULL ) ;
2005-11-19 20:07:43 +00:00
2006-04-29 06:05:03 +00:00
if ( ( ( * channel ) = switch_core_alloc ( pool , sizeof ( switch_channel_t ) ) ) = = 0 ) {
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_MEMERR ;
}
2008-01-28 07:26:10 +00:00
2009-03-24 23:44:03 +00:00
switch_event_create_plain ( & ( * channel ) - > variables , SWITCH_EVENT_CHANNEL_DATA ) ;
2008-01-28 07:26:10 +00:00
2006-09-07 03:58:01 +00:00
switch_core_hash_init ( & ( * channel ) - > private_hash , pool ) ;
2009-02-23 16:31:59 +00:00
switch_queue_create ( & ( * channel ) - > dtmf_queue , SWITCH_DTMF_LOG_LEN , pool ) ;
switch_queue_create ( & ( * channel ) - > dtmf_log_queue , SWITCH_DTMF_LOG_LEN , pool ) ;
2006-09-08 18:57:24 +00:00
2005-12-06 21:25:56 +00:00
switch_mutex_init ( & ( * channel ) - > dtmf_mutex , SWITCH_MUTEX_NESTED , pool ) ;
2006-06-22 23:56:09 +00:00
switch_mutex_init ( & ( * channel ) - > flag_mutex , SWITCH_MUTEX_NESTED , pool ) ;
2009-02-20 18:31:08 +00:00
switch_mutex_init ( & ( * channel ) - > state_mutex , SWITCH_MUTEX_NESTED , pool ) ;
2006-04-28 19:46:57 +00:00
switch_mutex_init ( & ( * channel ) - > profile_mutex , SWITCH_MUTEX_NESTED , pool ) ;
2008-07-03 22:51:09 +00:00
( * channel ) - > hangup_cause = SWITCH_CAUSE_NONE ;
2008-02-26 23:29:58 +00:00
( * channel ) - > name = " " ;
2009-02-23 16:31:59 +00:00
( * channel ) - > direction = direction ;
2005-12-22 01:57:32 +00:00
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( switch_size_t ) switch_channel_has_dtmf ( switch_channel_t * channel )
2005-11-19 20:07:43 +00:00
{
2006-03-30 23:02:50 +00:00
switch_size_t has ;
2005-11-19 20:07:43 +00:00
2005-12-06 21:25:56 +00:00
switch_mutex_lock ( channel - > dtmf_mutex ) ;
2007-12-22 00:32:20 +00:00
has = switch_queue_size ( channel - > dtmf_queue ) ;
2005-12-06 21:25:56 +00:00
switch_mutex_unlock ( channel - > dtmf_mutex ) ;
return has ;
2005-11-19 20:07:43 +00:00
}
2007-12-22 00:32:20 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_channel_queue_dtmf ( switch_channel_t * channel , const switch_dtmf_t * dtmf )
2005-11-19 20:07:43 +00:00
{
2006-04-29 23:43:28 +00:00
switch_status_t status ;
2007-12-22 00:32:20 +00:00
void * pop ;
2008-02-21 21:38:49 +00:00
switch_dtmf_t new_dtmf ;
2008-05-27 04:30:03 +00:00
2008-02-21 21:38:49 +00:00
switch_assert ( dtmf ) ;
2005-12-21 22:25:22 +00:00
2008-05-27 04:30:03 +00:00
switch_mutex_lock ( channel - > dtmf_mutex ) ;
2008-02-21 21:38:49 +00:00
new_dtmf = * dtmf ;
2008-05-27 04:30:03 +00:00
2007-06-12 21:00:26 +00:00
if ( ( status = switch_core_session_recv_dtmf ( channel - > session , dtmf ) ! = SWITCH_STATUS_SUCCESS ) ) {
goto done ;
}
2006-03-30 23:02:50 +00:00
2008-02-21 21:38:49 +00:00
if ( is_dtmf ( new_dtmf . digit ) ) {
2007-12-22 00:32:20 +00:00
switch_dtmf_t * dt ;
int x = 0 ;
2008-04-18 17:03:34 +00:00
if ( new_dtmf . duration > switch_core_max_dtmf_duration ( 0 ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( channel ) , SWITCH_LOG_WARNING , " %s EXCESSIVE DTMF DIGIT [%c] LEN [%d] \n " ,
2008-02-21 21:38:49 +00:00
switch_channel_get_name ( channel ) , new_dtmf . digit , new_dtmf . duration ) ;
2008-04-18 17:03:34 +00:00
new_dtmf . duration = switch_core_max_dtmf_duration ( 0 ) ;
2009-09-16 21:24:22 +00:00
} else if ( new_dtmf . duration < switch_core_min_dtmf_duration ( 0 ) ) {
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( channel ) , SWITCH_LOG_WARNING , " %s SHORT DTMF DIGIT [%c] LEN [%d] \n " ,
switch_channel_get_name ( channel ) , new_dtmf . digit , new_dtmf . duration ) ;
new_dtmf . duration = switch_core_min_dtmf_duration ( 0 ) ;
2008-02-21 21:38:49 +00:00
} else if ( ! new_dtmf . duration ) {
2008-04-18 17:03:34 +00:00
new_dtmf . duration = switch_core_default_dtmf_duration ( 0 ) ;
2008-02-21 21:38:49 +00:00
}
2008-05-27 04:30:03 +00:00
2007-12-22 00:32:20 +00:00
switch_zmalloc ( dt , sizeof ( * dt ) ) ;
2008-02-21 21:38:49 +00:00
* dt = new_dtmf ;
2007-12-22 00:32:20 +00:00
while ( switch_queue_trypush ( channel - > dtmf_queue , dt ) ! = SWITCH_STATUS_SUCCESS ) {
2009-02-27 19:29:52 +00:00
if ( switch_queue_trypop ( channel - > dtmf_queue , & pop ) = = SWITCH_STATUS_SUCCESS ) {
free ( pop ) ;
}
2007-12-22 00:32:20 +00:00
if ( + + x > 100 ) {
status = SWITCH_STATUS_FALSE ;
free ( dt ) ;
2008-01-28 07:26:10 +00:00
goto done ;
2007-12-22 00:32:20 +00:00
}
2006-05-04 00:07:20 +00:00
}
}
2008-01-28 07:26:10 +00:00
2007-12-22 00:32:20 +00:00
status = SWITCH_STATUS_SUCCESS ;
2007-06-12 21:00:26 +00:00
2008-05-27 04:30:03 +00:00
done :
2007-06-12 21:00:26 +00:00
2005-12-06 21:25:56 +00:00
switch_mutex_unlock ( channel - > dtmf_mutex ) ;
return status ;
2005-11-19 20:07:43 +00:00
}
2008-01-12 20:30:48 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_channel_queue_dtmf_string ( switch_channel_t * channel , const char * dtmf_string )
{
char * p ;
2008-05-27 04:30:03 +00:00
switch_dtmf_t dtmf = { 0 , switch_core_default_dtmf_duration ( 0 ) } ;
2008-01-12 20:30:48 +00:00
int sent = 0 , dur ;
char * string ;
int i , argc ;
char * argv [ 256 ] ;
2009-10-23 16:03:42 +00:00
if ( zstr ( dtmf_string ) ) {
2008-01-12 20:30:48 +00:00
return SWITCH_STATUS_FALSE ;
}
string = switch_core_session_strdup ( channel - > session , dtmf_string ) ;
argc = switch_separate_string ( string , ' + ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
2008-01-28 07:26:10 +00:00
2008-05-27 04:30:03 +00:00
for ( i = 0 ; i < argc ; i + + ) {
2008-04-18 17:03:34 +00:00
dtmf . duration = switch_core_default_dtmf_duration ( 0 ) ;
dur = switch_core_default_dtmf_duration ( 0 ) / 8 ;
2008-01-12 20:30:48 +00:00
if ( ( p = strchr ( argv [ i ] , ' @ ' ) ) ) {
* p + + = ' \0 ' ;
if ( ( dur = atoi ( p ) ) > 50 ) {
dtmf . duration = dur * 8 ;
}
}
2008-04-18 17:03:34 +00:00
if ( dtmf . duration > switch_core_max_dtmf_duration ( 0 ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( channel ) , SWITCH_LOG_WARNING , " EXCESSIVE DTMF DIGIT LEN %c %d \n " , dtmf . digit , dtmf . duration ) ;
2008-04-18 17:03:34 +00:00
dtmf . duration = switch_core_max_dtmf_duration ( 0 ) ;
2009-09-16 21:24:22 +00:00
} else if ( dtmf . duration < switch_core_min_dtmf_duration ( 0 ) ) {
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( channel ) , SWITCH_LOG_WARNING , " SHORT DTMF DIGIT LEN %c %d \n " , dtmf . digit , dtmf . duration ) ;
dtmf . duration = switch_core_min_dtmf_duration ( 0 ) ;
2008-02-21 21:38:49 +00:00
} else if ( ! dtmf . duration ) {
2008-04-18 17:03:34 +00:00
dtmf . duration = switch_core_default_dtmf_duration ( 0 ) ;
2008-02-21 21:38:49 +00:00
}
2008-01-12 20:30:48 +00:00
for ( p = argv [ i ] ; p & & * p ; p + + ) {
if ( is_dtmf ( * p ) ) {
dtmf . digit = * p ;
if ( switch_channel_queue_dtmf ( channel , & dtmf ) = = SWITCH_STATUS_SUCCESS ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( channel ) , SWITCH_LOG_DEBUG , " %s Queue dtmf \n digit=%c ms=%u samples=%u \n " ,
2008-05-27 04:30:03 +00:00
switch_channel_get_name ( channel ) , dtmf . digit , dur , dtmf . duration ) ;
2008-01-12 20:30:48 +00:00
sent + + ;
}
}
}
2008-01-28 07:26:10 +00:00
2008-01-12 20:30:48 +00:00
}
return sent ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE ;
}
2007-12-22 00:32:20 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_channel_dequeue_dtmf ( switch_channel_t * channel , switch_dtmf_t * dtmf )
2005-11-19 20:07:43 +00:00
{
2006-04-29 01:00:52 +00:00
switch_event_t * event ;
2007-12-22 00:32:20 +00:00
void * pop ;
switch_dtmf_t * dt ;
switch_status_t status = SWITCH_STATUS_FALSE ;
2005-11-19 20:07:43 +00:00
2005-12-06 21:25:56 +00:00
switch_mutex_lock ( channel - > dtmf_mutex ) ;
2007-12-22 00:32:20 +00:00
if ( switch_queue_trypop ( channel - > dtmf_queue , & pop ) = = SWITCH_STATUS_SUCCESS ) {
dt = ( switch_dtmf_t * ) pop ;
* dtmf = * dt ;
2009-02-23 16:31:59 +00:00
if ( switch_queue_trypush ( channel - > dtmf_log_queue , dt ) ! = SWITCH_STATUS_SUCCESS ) {
free ( dt ) ;
}
dt = NULL ;
2008-02-21 21:38:49 +00:00
2008-04-18 17:03:34 +00:00
if ( dtmf - > duration > switch_core_max_dtmf_duration ( 0 ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( channel ) , SWITCH_LOG_WARNING , " %s EXCESSIVE DTMF DIGIT [%c] LEN [%d] \n " ,
2008-02-21 21:38:49 +00:00
switch_channel_get_name ( channel ) , dtmf - > digit , dtmf - > duration ) ;
2008-04-18 17:03:34 +00:00
dtmf - > duration = switch_core_max_dtmf_duration ( 0 ) ;
2009-09-16 21:24:22 +00:00
} else if ( dtmf - > duration < switch_core_min_dtmf_duration ( 0 ) ) {
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( channel ) , SWITCH_LOG_WARNING , " %s SHORT DTMF DIGIT [%c] LEN [%d] \n " ,
switch_channel_get_name ( channel ) , dtmf - > digit , dtmf - > duration ) ;
dtmf - > duration = switch_core_min_dtmf_duration ( 0 ) ;
2008-02-21 21:38:49 +00:00
} else if ( ! dtmf - > duration ) {
2008-04-18 17:03:34 +00:00
dtmf - > duration = switch_core_default_dtmf_duration ( 0 ) ;
2008-02-21 21:38:49 +00:00
}
2007-12-22 00:32:20 +00:00
status = SWITCH_STATUS_SUCCESS ;
2005-11-19 20:07:43 +00:00
}
2005-12-06 21:25:56 +00:00
switch_mutex_unlock ( channel - > dtmf_mutex ) ;
2008-01-28 07:26:10 +00:00
2007-12-22 00:32:20 +00:00
if ( status = = SWITCH_STATUS_SUCCESS & & switch_event_create ( & event , SWITCH_EVENT_DTMF ) = = SWITCH_STATUS_SUCCESS ) {
2005-12-21 22:25:22 +00:00
switch_channel_event_set_data ( channel , event ) ;
2007-12-22 00:32:20 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " DTMF-Digit " , " %c " , dtmf - > digit ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " DTMF-Duration " , " %u " , dtmf - > duration ) ;
2009-02-21 23:19:58 +00:00
if ( switch_channel_test_flag ( channel , CF_DIVERT_EVENTS ) ) {
switch_core_session_queue_event ( channel - > session , & event ) ;
} else {
switch_event_fire ( & event ) ;
}
2005-12-21 22:25:22 +00:00
}
2005-12-06 21:25:56 +00:00
2007-12-22 00:32:20 +00:00
return status ;
}
SWITCH_DECLARE ( switch_size_t ) switch_channel_dequeue_dtmf_string ( switch_channel_t * channel , char * dtmf_str , switch_size_t len )
{
switch_size_t x = 0 ;
2008-05-27 04:30:03 +00:00
switch_dtmf_t dtmf = { 0 } ;
2007-12-22 00:32:20 +00:00
memset ( dtmf_str , 0 , len ) ;
2008-05-27 04:30:03 +00:00
while ( x < len - 1 & & switch_channel_dequeue_dtmf ( channel , & dtmf ) = = SWITCH_STATUS_SUCCESS ) {
2007-12-22 00:32:20 +00:00
dtmf_str [ x + + ] = dtmf . digit ;
}
return x ;
2005-11-19 20:07:43 +00:00
}
2007-12-22 00:32:20 +00:00
SWITCH_DECLARE ( void ) switch_channel_flush_dtmf ( switch_channel_t * channel )
{
void * pop ;
2009-02-21 22:50:35 +00:00
2007-12-22 00:32:20 +00:00
switch_mutex_lock ( channel - > dtmf_mutex ) ;
2008-05-27 04:30:03 +00:00
while ( switch_queue_trypop ( channel - > dtmf_queue , & pop ) = = SWITCH_STATUS_SUCCESS ) {
2009-02-23 16:31:59 +00:00
switch_dtmf_t * dt = ( switch_dtmf_t * ) pop ;
if ( channel - > state > = CS_HANGUP | | switch_queue_trypush ( channel - > dtmf_log_queue , dt ) ! = SWITCH_STATUS_SUCCESS ) {
free ( dt ) ;
}
2007-12-22 00:32:20 +00:00
}
switch_mutex_unlock ( channel - > dtmf_mutex ) ;
}
2006-09-08 18:57:24 +00:00
SWITCH_DECLARE ( void ) switch_channel_uninit ( switch_channel_t * channel )
{
2009-02-23 16:31:59 +00:00
void * pop ;
2007-12-22 02:15:50 +00:00
switch_channel_flush_dtmf ( channel ) ;
2009-02-23 16:31:59 +00:00
while ( switch_queue_trypop ( channel - > dtmf_log_queue , & pop ) = = SWITCH_STATUS_SUCCESS ) {
switch_safe_free ( pop ) ;
}
2007-09-29 01:06:08 +00:00
switch_core_hash_destroy ( & channel - > private_hash ) ;
2008-10-30 22:40:39 +00:00
switch_mutex_lock ( channel - > profile_mutex ) ;
2007-09-29 01:06:08 +00:00
switch_event_destroy ( & channel - > variables ) ;
2008-10-30 22:40:39 +00:00
switch_mutex_unlock ( channel - > profile_mutex ) ;
2006-09-08 18:57:24 +00:00
}
2007-03-30 00:15:25 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_channel_init ( switch_channel_t * channel , switch_core_session_t * session , switch_channel_state_t state ,
2008-12-11 15:20:24 +00:00
switch_channel_flag_t flag )
2005-11-19 20:07:43 +00:00
{
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2005-11-19 20:07:43 +00:00
channel - > state = state ;
2008-12-11 15:20:24 +00:00
switch_channel_set_flag ( channel , flag ) ;
2005-11-19 20:07:43 +00:00
channel - > session = session ;
2007-12-19 23:24:55 +00:00
channel - > running_state = CS_NONE ;
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2008-08-25 16:30:28 +00:00
SWITCH_DECLARE ( void ) switch_channel_presence ( switch_channel_t * channel , const char * rpid , const char * status , const char * id )
2006-10-21 04:58:15 +00:00
{
switch_event_t * event ;
switch_event_types_t type = SWITCH_EVENT_PRESENCE_IN ;
if ( ! status ) {
type = SWITCH_EVENT_PRESENCE_OUT ;
}
2008-08-25 16:30:28 +00:00
if ( ! id ) {
id = switch_channel_get_variable ( channel , " presence_id " ) ;
}
2006-10-21 04:58:15 +00:00
if ( ! id ) {
return ;
}
if ( switch_event_create ( & event , type ) = = SWITCH_STATUS_SUCCESS ) {
2007-12-15 00:39:53 +00:00
switch_channel_event_set_data ( channel , event ) ;
2008-08-16 02:17:09 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " proto " , __FILE__ ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " login " , __FILE__ ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " from " , id ) ;
2006-10-21 04:58:15 +00:00
if ( type = = SWITCH_EVENT_PRESENCE_IN ) {
if ( ! rpid ) {
rpid = " unknown " ;
}
2008-08-16 02:17:09 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " rpid " , rpid ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " status " , status ) ;
2006-10-21 04:58:15 +00:00
}
2008-08-16 02:17:09 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " event_type " , " presence " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " alt_event_type " , " dialog " ) ;
2007-12-15 00:39:53 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " event_count " , " %d " , channel - > event_count + + ) ;
2006-10-21 04:58:15 +00:00
switch_event_fire ( & event ) ;
}
}
2007-11-01 11:28:26 +00:00
SWITCH_DECLARE ( const char * ) switch_channel_get_variable ( switch_channel_t * channel , const char * varname )
2005-11-19 20:07:43 +00:00
{
2009-03-21 16:47:57 +00:00
const char * v = NULL , * r = NULL ;
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2006-10-20 06:55:30 +00:00
2007-04-28 21:48:03 +00:00
switch_mutex_lock ( channel - > profile_mutex ) ;
2009-03-17 13:25:02 +00:00
if ( ! channel - > variables | | ! ( v = switch_event_get_header ( channel - > variables , varname ) ) ) {
2009-06-05 01:16:02 +00:00
switch_caller_profile_t * cp = switch_channel_get_caller_profile ( channel ) ;
2008-01-28 07:26:10 +00:00
2007-12-06 19:51:55 +00:00
if ( cp ) {
if ( ! strncmp ( varname , " aleg_ " , 5 ) ) {
cp = cp - > originator_caller_profile ;
varname + = 5 ;
} else if ( ! strncmp ( varname , " bleg_ " , 5 ) ) {
cp = cp - > originatee_caller_profile ;
varname + = 5 ;
2006-11-09 05:39:04 +00:00
}
}
2007-12-06 19:51:55 +00:00
if ( ! cp | | ! ( v = switch_caller_get_field_by_name ( cp , varname ) ) ) {
v = switch_core_get_variable ( varname ) ;
}
2006-10-20 06:55:30 +00:00
}
2009-03-20 01:50:50 +00:00
2009-03-21 16:47:57 +00:00
if ( v ) r = switch_core_session_strdup ( channel - > session , v ) ;
2009-03-20 01:50:50 +00:00
2007-04-28 21:48:03 +00:00
switch_mutex_unlock ( channel - > profile_mutex ) ;
2007-03-29 22:31:56 +00:00
2009-03-21 16:47:57 +00:00
return r ;
2005-11-19 20:07:43 +00:00
}
2008-02-07 22:42:27 +00:00
SWITCH_DECLARE ( const char * ) switch_channel_get_variable_partner ( switch_channel_t * channel , const char * varname )
{
const char * uuid ;
2009-03-21 16:47:57 +00:00
const char * val = NULL , * r = NULL ;
2008-02-07 22:42:27 +00:00
switch_assert ( channel ! = NULL ) ;
2008-10-29 20:22:34 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( varname ) ) {
2008-02-07 22:42:27 +00:00
if ( ( uuid = switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) ) ) {
switch_core_session_t * session ;
if ( ( session = switch_core_session_locate ( uuid ) ) ) {
switch_channel_t * tchannel = switch_core_session_get_channel ( session ) ;
val = switch_channel_get_variable ( tchannel , varname ) ;
switch_core_session_rwunlock ( session ) ;
}
}
}
2009-03-21 16:47:57 +00:00
if ( val ) r = switch_core_session_strdup ( channel - > session , val ) ;
2009-03-20 01:50:50 +00:00
2009-03-21 16:47:57 +00:00
return r ;
2008-02-07 22:42:27 +00:00
}
2007-04-28 21:48:03 +00:00
SWITCH_DECLARE ( void ) switch_channel_variable_last ( switch_channel_t * channel )
{
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2007-10-09 15:29:18 +00:00
if ( ! channel - > vi ) {
return ;
2007-04-28 21:48:03 +00:00
}
2007-10-09 15:29:18 +00:00
channel - > vi = 0 ;
switch_mutex_unlock ( channel - > profile_mutex ) ;
2008-01-28 07:26:10 +00:00
2007-04-28 21:48:03 +00:00
}
2007-09-29 01:06:08 +00:00
SWITCH_DECLARE ( switch_event_header_t * ) switch_channel_variable_first ( switch_channel_t * channel )
2006-06-13 01:49:18 +00:00
{
2007-10-09 15:29:18 +00:00
switch_event_header_t * hi = NULL ;
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2007-10-09 15:29:18 +00:00
switch_mutex_lock ( channel - > profile_mutex ) ;
if ( ( hi = channel - > variables - > headers ) ) {
channel - > vi = 1 ;
} else {
switch_mutex_unlock ( channel - > profile_mutex ) ;
2007-04-28 21:48:03 +00:00
}
2007-10-09 15:29:18 +00:00
return hi ;
2006-06-13 01:49:18 +00:00
}
2007-05-12 14:48:14 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_channel_set_private ( switch_channel_t * channel , const char * key , const void * private_info )
2005-11-19 20:07:43 +00:00
{
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2007-09-29 01:06:08 +00:00
switch_core_hash_insert_locked ( channel - > private_hash , key , private_info , channel - > profile_mutex ) ;
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2007-05-12 14:48:14 +00:00
SWITCH_DECLARE ( void * ) switch_channel_get_private ( switch_channel_t * channel , const char * key )
2005-11-19 20:07:43 +00:00
{
2007-04-28 21:48:03 +00:00
void * val ;
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2007-10-09 15:29:18 +00:00
val = switch_core_hash_find_locked ( channel - > private_hash , key , channel - > profile_mutex ) ;
2007-04-28 21:48:03 +00:00
return val ;
2005-11-19 20:07:43 +00:00
}
2007-05-12 14:48:14 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_channel_set_name ( switch_channel_t * channel , const char * name )
2005-11-19 20:07:43 +00:00
{
2008-02-26 23:29:58 +00:00
const char * old = NULL ;
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( channel - > name ) ) {
2008-02-26 23:29:58 +00:00
old = channel - > name ;
}
2005-11-19 20:07:43 +00:00
channel - > name = NULL ;
if ( name ) {
2006-04-28 19:46:57 +00:00
char * uuid = switch_core_session_get_uuid ( channel - > session ) ;
2005-11-19 20:07:43 +00:00
channel - > name = switch_core_session_strdup ( channel - > session , name ) ;
2007-12-06 19:51:55 +00:00
switch_channel_set_variable ( channel , SWITCH_CHANNEL_NAME_VARIABLE , name ) ;
2008-02-26 23:29:58 +00:00
if ( old ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( channel ) , SWITCH_LOG_NOTICE , " Rename Channel %s->%s [%s] \n " , old , name , uuid ) ;
2008-02-26 23:29:58 +00:00
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( channel ) , SWITCH_LOG_NOTICE , " New Channel %s [%s] \n " , name , uuid ) ;
2008-02-26 23:29:58 +00:00
}
2005-11-19 20:07:43 +00:00
}
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( char * ) switch_channel_get_name ( switch_channel_t * channel )
2005-11-19 20:07:43 +00:00
{
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2009-10-23 16:03:42 +00:00
return ( ! zstr ( channel - > name ) ) ? channel - > name : " N/A " ;
2005-11-19 20:07:43 +00:00
}
2009-10-19 19:58:23 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_channel_set_profile_var ( switch_channel_t * channel , const char * name , const char * val )
{
char * v ;
switch_status_t status = SWITCH_STATUS_SUCCESS ;
switch_mutex_lock ( channel - > profile_mutex ) ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( val ) ) {
2009-10-19 19:58:23 +00:00
v = switch_core_strdup ( channel - > caller_profile - > pool , val ) ;
} else {
v = SWITCH_BLANK_STRING ;
}
if ( ! strcasecmp ( name , " dialplan " ) ) {
channel - > caller_profile - > dialplan = v ;
} else if ( ! strcasecmp ( name , " username " ) ) {
channel - > caller_profile - > username = v ;
} else if ( ! strcasecmp ( name , " caller_id_name " ) ) {
channel - > caller_profile - > caller_id_name = v ;
} else if ( ! strcasecmp ( name , " caller_id_number " ) ) {
channel - > caller_profile - > caller_id_number = v ;
} else if ( ! strcasecmp ( name , " callee_id_name " ) ) {
channel - > caller_profile - > callee_id_name = v ;
} else if ( ! strcasecmp ( name , " callee_id_number " ) ) {
channel - > caller_profile - > callee_id_number = v ;
} else if ( val & & ! strcasecmp ( name , " caller_ton " ) ) {
channel - > caller_profile - > caller_ton = ( uint8_t ) atoi ( v ) ;
} else if ( val & & ! strcasecmp ( name , " caller_numplan " ) ) {
channel - > caller_profile - > caller_numplan = ( uint8_t ) atoi ( v ) ;
} else if ( val & & ! strcasecmp ( name , " destination_number_ton " ) ) {
channel - > caller_profile - > destination_number_ton = ( uint8_t ) atoi ( v ) ;
} else if ( val & & ! strcasecmp ( name , " destination_number_numplan " ) ) {
channel - > caller_profile - > destination_number_numplan = ( uint8_t ) atoi ( v ) ;
} else if ( ! strcasecmp ( name , " ani " ) ) {
channel - > caller_profile - > ani = v ;
} else if ( ! strcasecmp ( name , " aniii " ) ) {
channel - > caller_profile - > aniii = v ;
} else if ( ! strcasecmp ( name , " network_addr " ) ) {
channel - > caller_profile - > network_addr = v ;
} else if ( ! strcasecmp ( name , " rdnis " ) ) {
channel - > caller_profile - > rdnis = v ;
} else if ( ! strcasecmp ( name , " destination_number " ) ) {
channel - > caller_profile - > destination_number = v ;
} else if ( ! strcasecmp ( name , " uuid " ) ) {
channel - > caller_profile - > uuid = v ;
} else if ( ! strcasecmp ( name , " source " ) ) {
channel - > caller_profile - > source = v ;
} else if ( ! strcasecmp ( name , " context " ) ) {
channel - > caller_profile - > context = v ;
} else if ( ! strcasecmp ( name , " chan_name " ) ) {
channel - > caller_profile - > chan_name = v ;
} else {
status = SWITCH_STATUS_FALSE ;
}
switch_mutex_unlock ( channel - > profile_mutex ) ;
return status ;
}
2009-01-21 21:34:31 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_channel_set_variable_var_check ( switch_channel_t * channel ,
const char * varname , const char * value , switch_bool_t var_check )
2005-11-19 20:07:43 +00:00
{
2009-03-25 20:07:40 +00:00
switch_status_t status = SWITCH_STATUS_FALSE ;
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2008-01-28 07:26:10 +00:00
2009-03-25 20:07:40 +00:00
switch_mutex_lock ( channel - > profile_mutex ) ;
2009-10-23 16:03:42 +00:00
if ( channel - > variables & & ! zstr ( varname ) ) {
2007-10-02 19:58:06 +00:00
switch_event_del_header ( channel - > variables , varname ) ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( value ) ) {
2009-01-21 21:34:31 +00:00
int ok = 1 ;
2009-01-22 03:42:22 +00:00
2009-01-21 21:34:31 +00:00
if ( var_check ) {
2009-01-22 03:42:22 +00:00
ok = ! switch_string_var_check_const ( value ) ;
2009-01-21 21:34:31 +00:00
}
if ( ok ) {
switch_event_add_header_string ( channel - > variables , SWITCH_STACK_BOTTOM , varname , value ) ;
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( channel ) , SWITCH_LOG_CRIT , " Invalid data (${%s} contains a variable) \n " , varname ) ;
2009-01-21 21:34:31 +00:00
}
2008-05-27 04:30:03 +00:00
}
2009-03-25 20:07:40 +00:00
status = SWITCH_STATUS_SUCCESS ;
2007-02-19 22:57:27 +00:00
}
2009-03-25 20:07:40 +00:00
switch_mutex_unlock ( channel - > profile_mutex ) ;
2007-02-19 22:57:27 +00:00
2009-03-25 20:07:40 +00:00
return status ;
2007-02-19 22:57:27 +00:00
}
2008-09-29 17:48:43 +00:00
switch_status_t switch_event_base_add_header ( switch_event_t * event , switch_stack_t stack , const char * header_name , char * data ) ;
SWITCH_DECLARE ( switch_status_t ) switch_channel_set_variable_printf ( switch_channel_t * channel , const char * varname , const char * fmt , . . . )
{
int ret = 0 ;
char * data ;
va_list ap ;
2009-03-25 20:07:40 +00:00
switch_status_t status = SWITCH_STATUS_FALSE ;
2008-09-29 17:48:43 +00:00
switch_assert ( channel ! = NULL ) ;
2009-03-25 20:07:40 +00:00
switch_mutex_lock ( channel - > profile_mutex ) ;
2009-10-23 16:03:42 +00:00
if ( channel - > variables & & ! zstr ( varname ) ) {
2008-09-29 17:48:43 +00:00
switch_event_del_header ( channel - > variables , varname ) ;
va_start ( ap , fmt ) ;
ret = switch_vasprintf ( & data , fmt , ap ) ;
va_end ( ap ) ;
if ( ret = = - 1 ) {
switch_mutex_unlock ( channel - > profile_mutex ) ;
return SWITCH_STATUS_MEMERR ;
}
switch_event_base_add_header ( channel - > variables , SWITCH_STACK_BOTTOM , varname , data ) ;
2009-03-25 20:07:40 +00:00
status = SWITCH_STATUS_SUCCESS ;
2008-09-29 17:48:43 +00:00
}
2009-03-25 20:07:40 +00:00
switch_mutex_unlock ( channel - > profile_mutex ) ;
2008-09-29 17:48:43 +00:00
2009-03-25 20:07:40 +00:00
return status ;
2008-09-29 17:48:43 +00:00
}
2007-12-20 21:42:00 +00:00
2009-01-21 21:34:31 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_channel_set_variable_partner_var_check ( switch_channel_t * channel ,
const char * varname , const char * value , switch_bool_t var_check )
2007-12-20 21:42:00 +00:00
{
const char * uuid ;
switch_assert ( channel ! = NULL ) ;
2008-01-28 07:26:10 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( varname ) ) {
2007-12-20 21:42:00 +00:00
if ( ( uuid = switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) ) ) {
switch_core_session_t * session ;
if ( ( session = switch_core_session_locate ( uuid ) ) ) {
switch_channel_t * tchannel = switch_core_session_get_channel ( session ) ;
2009-01-21 21:34:31 +00:00
switch_channel_set_variable_var_check ( tchannel , varname , value , var_check ) ;
2007-12-20 21:42:00 +00:00
switch_core_session_rwunlock ( session ) ;
}
return SWITCH_STATUS_SUCCESS ;
}
}
return SWITCH_STATUS_FALSE ;
}
2008-12-11 15:20:24 +00:00
SWITCH_DECLARE ( uint32_t ) switch_channel_test_flag ( switch_channel_t * channel , switch_channel_flag_t flag )
2005-11-19 20:07:43 +00:00
{
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2009-11-03 16:50:16 +00:00
return channel - > flags [ flag ] ;
2005-11-19 20:07:43 +00:00
}
2008-12-11 15:20:24 +00:00
SWITCH_DECLARE ( switch_bool_t ) switch_channel_set_flag_partner ( switch_channel_t * channel , switch_channel_flag_t flag )
2007-03-30 22:13:19 +00:00
{
2007-11-01 11:28:26 +00:00
const char * uuid ;
2007-03-30 22:13:19 +00:00
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2007-03-30 22:13:19 +00:00
2007-05-09 19:44:15 +00:00
if ( ( uuid = switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) ) ) {
2007-03-30 22:13:19 +00:00
switch_core_session_t * session ;
if ( ( session = switch_core_session_locate ( uuid ) ) ) {
2008-12-11 15:20:24 +00:00
switch_channel_set_flag ( switch_core_session_get_channel ( session ) , flag ) ;
2007-03-30 22:13:19 +00:00
switch_core_session_rwunlock ( session ) ;
return SWITCH_TRUE ;
}
}
return SWITCH_FALSE ;
}
2009-04-23 13:15:03 +00:00
SWITCH_DECLARE ( uint32_t ) switch_channel_test_flag_partner ( switch_channel_t * channel , switch_channel_flag_t flag )
{
const char * uuid ;
int r = 0 ;
switch_assert ( channel ! = NULL ) ;
if ( ( uuid = switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) ) ) {
switch_core_session_t * session ;
if ( ( session = switch_core_session_locate ( uuid ) ) ) {
r = switch_channel_test_flag ( switch_core_session_get_channel ( session ) , flag ) ;
switch_core_session_rwunlock ( session ) ;
}
}
return r ;
}
2008-12-11 15:20:24 +00:00
SWITCH_DECLARE ( switch_bool_t ) switch_channel_clear_flag_partner ( switch_channel_t * channel , switch_channel_flag_t flag )
2007-03-30 22:13:19 +00:00
{
2007-11-01 11:28:26 +00:00
const char * uuid ;
2007-03-30 22:13:19 +00:00
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2007-03-30 22:13:19 +00:00
2007-05-09 19:44:15 +00:00
if ( ( uuid = switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) ) ) {
2007-03-30 22:13:19 +00:00
switch_core_session_t * session ;
if ( ( session = switch_core_session_locate ( uuid ) ) ) {
2008-12-11 15:20:24 +00:00
switch_channel_clear_flag ( switch_core_session_get_channel ( session ) , flag ) ;
2007-03-30 22:13:19 +00:00
switch_core_session_rwunlock ( session ) ;
return SWITCH_TRUE ;
}
}
return SWITCH_FALSE ;
}
2007-12-08 00:14:21 +00:00
SWITCH_DECLARE ( void ) switch_channel_wait_for_state ( switch_channel_t * channel , switch_channel_t * other_channel , switch_channel_state_t want_state )
{
switch_channel_state_t state , mystate , ostate ;
ostate = switch_channel_get_state ( channel ) ;
2008-01-28 07:26:10 +00:00
2008-05-27 04:30:03 +00:00
for ( ; ; ) {
2007-12-08 00:14:21 +00:00
state = switch_channel_get_running_state ( other_channel ) ;
mystate = switch_channel_get_running_state ( channel ) ;
2008-01-28 07:26:10 +00:00
2009-04-27 17:45:04 +00:00
if ( mystate ! = ostate | | state > = CS_HANGUP | | state > = want_state ) {
2007-12-08 00:14:21 +00:00
break ;
}
2008-11-14 23:31:21 +00:00
switch_cond_next ( ) ;
2007-12-08 00:14:21 +00:00
}
}
2009-05-07 17:27:15 +00:00
SWITCH_DECLARE ( void ) switch_channel_wait_for_state_timeout ( switch_channel_t * other_channel , switch_channel_state_t want_state , uint32_t timeout )
{
switch_channel_state_t state ;
uint32_t count = 0 ;
for ( ; ; ) {
state = switch_channel_get_running_state ( other_channel ) ;
if ( state > = want_state ) {
break ;
}
switch_cond_next ( ) ;
if ( + + count > = timeout ) {
break ;
}
}
}
2008-09-09 16:31:53 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_channel_wait_for_flag ( switch_channel_t * channel ,
switch_channel_flag_t want_flag ,
switch_bool_t pres ,
uint32_t to ,
switch_channel_t * super_channel )
2008-01-05 20:44:54 +00:00
{
2009-05-12 14:54:34 +00:00
2008-01-05 20:44:54 +00:00
if ( to ) {
to + + ;
}
2008-05-27 04:30:03 +00:00
for ( ; ; ) {
2008-01-05 22:17:26 +00:00
if ( pres ) {
2008-12-11 15:20:24 +00:00
if ( switch_channel_test_flag ( channel , want_flag ) ) {
2008-01-05 22:17:26 +00:00
break ;
}
} else {
2008-12-11 15:20:24 +00:00
if ( ! switch_channel_test_flag ( channel , want_flag ) ) {
2008-01-05 22:17:26 +00:00
break ;
}
}
2008-11-14 23:31:21 +00:00
switch_cond_next ( ) ;
2008-09-09 16:31:53 +00:00
if ( super_channel & & ! switch_channel_ready ( super_channel ) ) {
return SWITCH_STATUS_FALSE ;
}
2009-03-04 04:19:33 +00:00
if ( switch_channel_down ( channel ) ) {
2008-09-09 16:31:53 +00:00
return SWITCH_STATUS_FALSE ;
}
2008-01-05 20:44:54 +00:00
if ( to & & ! - - to ) {
return SWITCH_STATUS_TIMEOUT ;
}
}
2008-01-28 07:26:10 +00:00
2008-01-05 20:44:54 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2009-10-14 19:26:10 +00:00
SWITCH_DECLARE ( void ) switch_channel_set_cap ( switch_channel_t * channel , switch_channel_cap_t cap )
{
switch_assert ( channel ) ;
switch_assert ( channel - > flag_mutex ) ;
switch_mutex_lock ( channel - > flag_mutex ) ;
channel - > caps [ cap ] = 1 ;
switch_mutex_unlock ( channel - > flag_mutex ) ;
}
SWITCH_DECLARE ( void ) switch_channel_clear_cap ( switch_channel_t * channel , switch_channel_cap_t cap )
{
switch_assert ( channel ! = NULL ) ;
switch_assert ( channel - > flag_mutex ) ;
switch_mutex_lock ( channel - > flag_mutex ) ;
channel - > caps [ cap ] = 0 ;
switch_mutex_unlock ( channel - > flag_mutex ) ;
}
SWITCH_DECLARE ( uint32_t ) switch_channel_test_cap ( switch_channel_t * channel , switch_channel_cap_t cap )
{
switch_assert ( channel ! = NULL ) ;
return channel - > caps [ cap ] ? 1 : 0 ;
}
2008-12-11 15:20:24 +00:00
SWITCH_DECLARE ( void ) switch_channel_set_flag ( switch_channel_t * channel , switch_channel_flag_t flag )
2005-11-19 20:07:43 +00:00
{
2008-12-11 15:20:24 +00:00
switch_assert ( channel ) ;
switch_assert ( channel - > flag_mutex ) ;
switch_mutex_lock ( channel - > flag_mutex ) ;
channel - > flags [ flag ] = 1 ;
switch_mutex_unlock ( channel - > flag_mutex ) ;
if ( flag = = CF_OUTBOUND ) {
2008-10-22 18:32:54 +00:00
switch_channel_set_variable ( channel , " is_outbound " , " true " ) ;
}
2005-11-19 20:07:43 +00:00
}
2009-08-26 17:42:36 +00:00
SWITCH_DECLARE ( void ) switch_channel_set_flag_recursive ( switch_channel_t * channel , switch_channel_flag_t flag )
{
switch_assert ( channel ) ;
switch_assert ( channel - > flag_mutex ) ;
switch_mutex_lock ( channel - > flag_mutex ) ;
channel - > flags [ flag ] + + ;
switch_mutex_unlock ( channel - > flag_mutex ) ;
if ( flag = = CF_OUTBOUND ) {
switch_channel_set_variable ( channel , " is_outbound " , " true " ) ;
}
}
2008-12-04 04:46:10 +00:00
SWITCH_DECLARE ( void ) switch_channel_set_private_flag ( switch_channel_t * channel , uint32_t flags )
{
switch_assert ( channel ! = NULL ) ;
switch_mutex_lock ( channel - > flag_mutex ) ;
channel - > private_flags | = flags ;
switch_mutex_unlock ( channel - > flag_mutex ) ;
}
SWITCH_DECLARE ( void ) switch_channel_clear_private_flag ( switch_channel_t * channel , uint32_t flags )
{
switch_assert ( channel ! = NULL ) ;
switch_mutex_lock ( channel - > flag_mutex ) ;
channel - > private_flags & = ~ flags ;
switch_mutex_unlock ( channel - > flag_mutex ) ;
}
SWITCH_DECLARE ( int ) switch_channel_test_private_flag ( switch_channel_t * channel , uint32_t flags )
{
switch_assert ( channel ! = NULL ) ;
return ( channel - > private_flags & flags ) ;
}
2009-01-22 14:01:15 +00:00
SWITCH_DECLARE ( void ) switch_channel_set_app_flag ( switch_channel_t * channel , uint32_t flags )
{
switch_assert ( channel ! = NULL ) ;
switch_mutex_lock ( channel - > flag_mutex ) ;
channel - > app_flags | = flags ;
switch_mutex_unlock ( channel - > flag_mutex ) ;
}
SWITCH_DECLARE ( void ) switch_channel_clear_app_flag ( switch_channel_t * channel , uint32_t flags )
{
switch_assert ( channel ! = NULL ) ;
switch_mutex_lock ( channel - > flag_mutex ) ;
if ( ! flags ) {
channel - > app_flags = 0 ;
} else {
channel - > app_flags & = ~ flags ;
}
switch_mutex_unlock ( channel - > flag_mutex ) ;
}
SWITCH_DECLARE ( int ) switch_channel_test_app_flag ( switch_channel_t * channel , uint32_t flags )
{
switch_assert ( channel ! = NULL ) ;
return ( channel - > app_flags & flags ) ;
}
2008-12-11 15:20:24 +00:00
SWITCH_DECLARE ( void ) switch_channel_set_state_flag ( switch_channel_t * channel , switch_channel_flag_t flag )
2006-09-19 02:18:24 +00:00
{
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2006-09-19 02:18:24 +00:00
switch_mutex_lock ( channel - > flag_mutex ) ;
2008-12-11 15:20:24 +00:00
channel - > state_flags [ 0 ] = 1 ;
channel - > state_flags [ flag ] = 1 ;
2006-09-19 02:18:24 +00:00
switch_mutex_unlock ( channel - > flag_mutex ) ;
}
2008-12-11 15:20:24 +00:00
SWITCH_DECLARE ( void ) switch_channel_clear_flag ( switch_channel_t * channel , switch_channel_flag_t flag )
2005-11-19 20:07:43 +00:00
{
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2008-12-11 15:20:24 +00:00
switch_assert ( channel - > flag_mutex ) ;
switch_mutex_lock ( channel - > flag_mutex ) ;
channel - > flags [ flag ] = 0 ;
switch_mutex_unlock ( channel - > flag_mutex ) ;
if ( flag = = CF_OUTBOUND ) {
2008-10-22 18:32:54 +00:00
switch_channel_set_variable ( channel , " is_outbound " , NULL ) ;
}
2005-11-19 20:07:43 +00:00
}
2009-08-26 17:42:36 +00:00
SWITCH_DECLARE ( void ) switch_channel_clear_flag_recursive ( switch_channel_t * channel , switch_channel_flag_t flag )
{
switch_assert ( channel ! = NULL ) ;
switch_assert ( channel - > flag_mutex ) ;
switch_mutex_lock ( channel - > flag_mutex ) ;
if ( channel - > flags [ flag ] ) {
channel - > flags [ flag ] - - ;
}
switch_mutex_unlock ( channel - > flag_mutex ) ;
if ( flag = = CF_OUTBOUND ) {
switch_channel_set_variable ( channel , " is_outbound " , NULL ) ;
}
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_channel_state_t ) switch_channel_get_state ( switch_channel_t * channel )
2005-11-19 20:07:43 +00:00
{
2006-09-16 00:43:58 +00:00
switch_channel_state_t state ;
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2006-09-16 00:43:58 +00:00
state = channel - > state ;
return state ;
2005-11-19 20:07:43 +00:00
}
2007-12-08 00:14:21 +00:00
SWITCH_DECLARE ( switch_channel_state_t ) switch_channel_get_running_state ( switch_channel_t * channel )
{
switch_channel_state_t state ;
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2007-12-08 00:14:21 +00:00
state = channel - > running_state ;
return state ;
}
2009-02-10 19:09:06 +00:00
SWITCH_DECLARE ( int ) switch_channel_test_ready ( switch_channel_t * channel , switch_bool_t media )
2006-03-01 22:55:28 +00:00
{
2009-02-10 19:09:06 +00:00
int ret = 0 ;
2007-03-30 22:13:19 +00:00
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2008-01-28 07:26:10 +00:00
2009-02-10 19:09:06 +00:00
if ( media ) {
ret = ( ( switch_channel_test_flag ( channel , CF_ANSWERED ) | |
switch_channel_test_flag ( channel , CF_EARLY_MEDIA ) ) & & ! switch_channel_test_flag ( channel , CF_PROXY_MODE ) & &
switch_core_session_get_read_codec ( channel - > session ) & & switch_core_session_get_write_codec ( channel - > session ) ) ;
if ( ! ret ) return ret ;
}
ret = 0 ;
2008-05-27 04:30:03 +00:00
if ( ! channel - > hangup_cause & & channel - > state > CS_ROUTING & & channel - > state < CS_HANGUP & & channel - > state ! = CS_RESET & &
2009-10-22 22:11:28 +00:00
! switch_channel_test_flag ( channel , CF_TRANSFER ) & & ! switch_channel_test_flag ( channel , CF_NOT_READY ) ) {
2008-05-27 04:30:03 +00:00
ret + + ;
2007-03-30 22:13:19 +00:00
}
return ret ;
2006-03-01 22:55:28 +00:00
}
2005-12-21 22:25:22 +00:00
static const char * state_names [ ] = {
" CS_NEW " ,
" CS_INIT " ,
2008-05-05 15:30:55 +00:00
" CS_ROUTING " ,
" CS_SOFT_EXECUTE " ,
2005-12-21 22:25:22 +00:00
" CS_EXECUTE " ,
2008-05-05 15:30:55 +00:00
" CS_EXCHANGE_MEDIA " ,
2007-12-13 22:17:20 +00:00
" CS_PARK " ,
2008-05-05 15:30:55 +00:00
" CS_CONSUME_MEDIA " ,
2006-10-31 21:38:06 +00:00
" CS_HIBERNATE " ,
2007-07-03 02:10:35 +00:00
" CS_RESET " ,
2005-12-21 22:25:22 +00:00
" CS_HANGUP " ,
2009-03-04 04:19:33 +00:00
" CS_REPORTING " ,
2009-04-10 17:43:18 +00:00
" CS_DESTROY " ,
2006-06-06 23:07:37 +00:00
NULL
2005-12-21 22:25:22 +00:00
} ;
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( const char * ) switch_channel_state_name ( switch_channel_state_t state )
2005-12-21 22:25:22 +00:00
{
return state_names [ state ] ;
}
2006-06-06 23:07:37 +00:00
2007-05-12 14:48:14 +00:00
SWITCH_DECLARE ( switch_channel_state_t ) switch_channel_name_state ( const char * name )
2006-06-06 23:07:37 +00:00
{
uint32_t x = 0 ;
2007-03-29 22:31:56 +00:00
for ( x = 0 ; state_names [ x ] ; x + + ) {
2006-06-06 23:07:37 +00:00
if ( ! strcasecmp ( state_names [ x ] , name ) ) {
return ( switch_channel_state_t ) x ;
}
}
2009-04-10 17:43:18 +00:00
return CS_DESTROY ;
2006-06-06 23:07:37 +00:00
}
2008-03-08 21:07:15 +00:00
SWITCH_DECLARE ( switch_channel_state_t ) switch_channel_perform_set_running_state ( switch_channel_t * channel , switch_channel_state_t state ,
2007-12-08 00:14:21 +00:00
const char * file , const char * func , int line )
{
2008-12-11 15:20:24 +00:00
int x ;
2009-02-20 18:31:08 +00:00
switch_mutex_lock ( channel - > state_mutex ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , file , func , line , switch_channel_get_uuid ( channel ) , SWITCH_LOG_DEBUG , " (%s) Running State Change %s \n " , channel - > name , state_names [ state ] ) ;
2008-03-08 21:07:15 +00:00
channel - > running_state = state ;
2007-12-08 00:14:21 +00:00
2008-12-11 15:20:24 +00:00
if ( channel - > state_flags [ 0 ] ) {
for ( x = 1 ; x < CF_FLAG_MAX ; x + + ) {
if ( channel - > state_flags [ x ] ) {
channel - > flags [ x ] = 1 ;
channel - > state_flags [ x ] = 0 ;
}
}
channel - > state_flags [ 0 ] = 0 ;
2007-12-19 23:24:55 +00:00
}
2008-01-28 07:26:10 +00:00
2008-12-11 15:20:24 +00:00
switch_channel_clear_flag ( channel , CF_TAGGED ) ;
2008-05-15 15:57:29 +00:00
2009-03-09 19:48:17 +00:00
if ( channel - > state > = CS_ROUTING & & channel - > state < = CS_HANGUP ) {
2009-03-17 13:25:02 +00:00
switch_channel_presence ( channel , " unknown " , ( const char * ) state_names [ state ] , NULL ) ;
2007-12-15 00:39:53 +00:00
}
2008-01-28 07:26:10 +00:00
2009-08-26 21:53:43 +00:00
if ( state < = CS_DESTROY ) {
2007-12-08 00:14:21 +00:00
switch_event_t * event ;
if ( switch_event_create ( & event , SWITCH_EVENT_CHANNEL_STATE ) = = SWITCH_STATUS_SUCCESS ) {
2008-05-05 15:30:55 +00:00
if ( state = = CS_ROUTING ) {
2007-12-08 00:14:21 +00:00
switch_channel_event_set_data ( channel , event ) ;
} else {
2009-03-17 13:25:02 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Channel-State " , switch_channel_state_name ( state ) ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " Channel-State-Number " , " %d " , state ) ;
2008-08-16 02:17:09 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Channel-Name " , channel - > name ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Unique-ID " , switch_core_session_get_uuid ( channel - > session ) ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Call-Direction " ,
2009-02-24 00:05:19 +00:00
channel - > direction = = SWITCH_CALL_DIRECTION_OUTBOUND ? " outbound " : " inbound " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Presence-Call-Direction " ,
channel - > direction = = SWITCH_CALL_DIRECTION_OUTBOUND ? " outbound " : " inbound " ) ;
2007-12-15 00:39:53 +00:00
if ( switch_channel_test_flag ( channel , CF_ANSWERED ) ) {
2008-08-16 02:17:09 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Answer-State " , " answered " ) ;
2007-12-15 00:39:53 +00:00
} else if ( switch_channel_test_flag ( channel , CF_EARLY_MEDIA ) ) {
2008-08-16 02:17:09 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Answer-State " , " early " ) ;
2007-12-15 00:39:53 +00:00
} else {
2008-08-16 02:17:09 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Answer-State " , " ringing " ) ;
2007-12-15 00:39:53 +00:00
}
2007-12-08 00:14:21 +00:00
}
switch_event_fire ( & event ) ;
}
}
2009-02-20 18:31:08 +00:00
switch_mutex_unlock ( channel - > state_mutex ) ;
2007-12-08 00:14:21 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_channel_state_t ) switch_channel_perform_set_state ( switch_channel_t * channel ,
2007-03-30 00:13:31 +00:00
const char * file , const char * func , int line , switch_channel_state_t state )
2005-11-19 20:07:43 +00:00
{
2006-04-29 23:43:28 +00:00
switch_channel_state_t last_state ;
2005-11-19 20:07:43 +00:00
int ok = 0 ;
2005-12-21 22:25:22 +00:00
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2009-04-10 17:43:18 +00:00
switch_assert ( state < = CS_DESTROY ) ;
2009-02-20 18:31:08 +00:00
switch_mutex_lock ( channel - > state_mutex ) ;
2006-09-16 00:43:58 +00:00
2005-11-19 20:07:43 +00:00
last_state = channel - > state ;
2009-04-10 17:43:18 +00:00
switch_assert ( last_state < = CS_DESTROY ) ;
2005-11-19 20:07:43 +00:00
if ( last_state = = state ) {
2006-09-16 00:43:58 +00:00
goto done ;
2005-11-19 20:07:43 +00:00
}
2006-02-13 17:37:10 +00:00
if ( last_state > = CS_HANGUP & & state < last_state ) {
2006-09-16 00:43:58 +00:00
goto done ;
2005-12-06 17:18:56 +00:00
}
2007-03-29 22:31:56 +00:00
2005-11-19 20:07:43 +00:00
/* STUB for more dev
2008-05-27 04:30:03 +00:00
case CS_INIT :
switch ( state ) {
case CS_NEW :
case CS_INIT :
case CS_EXCHANGE_MEDIA :
case CS_SOFT_EXECUTE :
case CS_ROUTING :
case CS_EXECUTE :
case CS_HANGUP :
2009-04-10 17:43:18 +00:00
case CS_DESTROY :
2008-05-27 04:30:03 +00:00
default :
break ;
}
break ;
*/
2006-01-20 15:05:05 +00:00
2008-05-27 04:30:03 +00:00
switch ( last_state ) {
2006-01-20 02:02:03 +00:00
case CS_NEW :
2008-05-27 04:30:03 +00:00
case CS_RESET :
switch ( state ) {
default :
ok + + ;
break ;
}
break ;
2006-01-20 02:02:03 +00:00
case CS_INIT :
2008-05-27 04:30:03 +00:00
switch ( state ) {
case CS_EXCHANGE_MEDIA :
case CS_SOFT_EXECUTE :
case CS_ROUTING :
case CS_EXECUTE :
case CS_PARK :
case CS_CONSUME_MEDIA :
case CS_HIBERNATE :
case CS_RESET :
ok + + ;
default :
break ;
}
break ;
2008-05-05 15:30:55 +00:00
case CS_EXCHANGE_MEDIA :
2008-05-27 04:30:03 +00:00
switch ( state ) {
case CS_SOFT_EXECUTE :
case CS_ROUTING :
case CS_EXECUTE :
case CS_PARK :
case CS_CONSUME_MEDIA :
case CS_HIBERNATE :
case CS_RESET :
ok + + ;
default :
break ;
}
break ;
2008-05-05 15:30:55 +00:00
case CS_SOFT_EXECUTE :
2008-05-27 04:30:03 +00:00
switch ( state ) {
case CS_EXCHANGE_MEDIA :
case CS_ROUTING :
case CS_EXECUTE :
case CS_PARK :
case CS_CONSUME_MEDIA :
case CS_HIBERNATE :
case CS_RESET :
ok + + ;
default :
break ;
}
break ;
case CS_PARK :
switch ( state ) {
case CS_EXCHANGE_MEDIA :
case CS_ROUTING :
case CS_EXECUTE :
case CS_SOFT_EXECUTE :
case CS_HIBERNATE :
case CS_RESET :
case CS_CONSUME_MEDIA :
ok + + ;
default :
break ;
}
break ;
case CS_CONSUME_MEDIA :
switch ( state ) {
case CS_EXCHANGE_MEDIA :
case CS_ROUTING :
case CS_EXECUTE :
case CS_SOFT_EXECUTE :
case CS_HIBERNATE :
case CS_RESET :
case CS_PARK :
ok + + ;
default :
break ;
}
break ;
case CS_HIBERNATE :
switch ( state ) {
case CS_EXCHANGE_MEDIA :
case CS_INIT :
case CS_ROUTING :
case CS_EXECUTE :
case CS_SOFT_EXECUTE :
case CS_PARK :
case CS_CONSUME_MEDIA :
case CS_RESET :
ok + + ;
default :
break ;
}
break ;
2008-05-05 15:30:55 +00:00
case CS_ROUTING :
2008-05-27 04:30:03 +00:00
switch ( state ) {
case CS_EXCHANGE_MEDIA :
case CS_EXECUTE :
case CS_SOFT_EXECUTE :
case CS_PARK :
case CS_CONSUME_MEDIA :
case CS_HIBERNATE :
case CS_RESET :
ok + + ;
default :
break ;
}
break ;
2005-11-19 20:07:43 +00:00
case CS_EXECUTE :
2008-05-27 04:30:03 +00:00
switch ( state ) {
case CS_EXCHANGE_MEDIA :
case CS_SOFT_EXECUTE :
case CS_ROUTING :
case CS_PARK :
case CS_CONSUME_MEDIA :
case CS_HIBERNATE :
case CS_RESET :
ok + + ;
default :
break ;
}
break ;
2005-11-19 20:07:43 +00:00
case CS_HANGUP :
2009-03-04 04:19:33 +00:00
switch ( state ) {
case CS_REPORTING :
2009-04-10 17:43:18 +00:00
case CS_DESTROY :
2009-03-04 04:19:33 +00:00
ok + + ;
default :
break ;
}
break ;
case CS_REPORTING :
2008-05-27 04:30:03 +00:00
switch ( state ) {
2009-04-10 17:43:18 +00:00
case CS_DESTROY :
2008-05-27 04:30:03 +00:00
ok + + ;
default :
break ;
}
break ;
2005-11-19 20:07:43 +00:00
default :
2008-05-27 04:30:03 +00:00
break ;
2005-11-19 20:07:43 +00:00
}
if ( ok ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , file , func , line , switch_channel_get_uuid ( channel ) , SWITCH_LOG_DEBUG , " (%s) State Change %s -> %s \n " ,
2008-05-27 04:30:03 +00:00
channel - > name , state_names [ last_state ] , state_names [ state ] ) ;
2009-03-20 01:50:50 +00:00
2005-11-19 20:07:43 +00:00
channel - > state = state ;
2006-04-22 18:12:17 +00:00
2007-01-26 20:39:45 +00:00
if ( state = = CS_HANGUP & & ! channel - > hangup_cause ) {
2006-04-22 18:12:17 +00:00
channel - > hangup_cause = SWITCH_CAUSE_NORMAL_CLEARING ;
}
2007-03-29 22:31:56 +00:00
2009-08-26 21:53:43 +00:00
if ( state < = CS_DESTROY ) {
2006-03-22 17:05:16 +00:00
switch_core_session_signal_state_change ( channel - > session ) ;
}
2005-11-19 20:07:43 +00:00
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , file , func , line , switch_channel_get_uuid ( channel ) , SWITCH_LOG_WARNING ,
2008-10-10 03:22:34 +00:00
" (%s) Invalid State Change %s -> %s \n " , channel - > name , state_names [ last_state ] , state_names [ state ] ) ;
2007-03-04 01:46:08 +00:00
/* we won't tolerate an invalid state change so we can make sure we are as robust as a nice cup of dark coffee! */
2008-03-08 21:07:15 +00:00
/* not cool lets crash this bad boy and figure out wtf is going on */
switch_assert ( channel - > state > = CS_HANGUP ) ;
2005-11-19 20:07:43 +00:00
}
2008-05-27 04:30:03 +00:00
done :
2007-03-29 22:31:56 +00:00
2009-02-20 18:31:08 +00:00
switch_mutex_unlock ( channel - > state_mutex ) ;
2005-11-19 20:07:43 +00:00
return channel - > state ;
}
2009-01-05 20:43:53 +00:00
SWITCH_DECLARE ( void ) switch_channel_event_set_basic_data ( switch_channel_t * channel , switch_event_t * event )
2005-12-21 22:25:22 +00:00
{
2006-12-01 15:26:37 +00:00
switch_caller_profile_t * caller_profile , * originator_caller_profile = NULL , * originatee_caller_profile = NULL ;
2009-03-20 01:50:50 +00:00
switch_codec_implementation_t impl = { 0 } ;
2006-04-04 21:26:21 +00:00
char state_num [ 25 ] ;
2009-01-05 20:43:53 +00:00
2007-06-24 04:06:05 +00:00
switch_mutex_lock ( channel - > profile_mutex ) ;
2006-12-01 15:26:37 +00:00
if ( ( caller_profile = switch_channel_get_caller_profile ( channel ) ) ) {
2007-03-29 22:31:56 +00:00
originator_caller_profile = caller_profile - > originator_caller_profile ;
originatee_caller_profile = caller_profile - > originatee_caller_profile ;
}
2006-01-03 01:17:59 +00:00
2008-08-16 02:17:09 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Channel-State " , switch_channel_state_name ( channel - > state ) ) ;
2007-12-12 21:53:32 +00:00
switch_snprintf ( state_num , sizeof ( state_num ) , " %d " , channel - > state ) ;
2008-08-16 02:17:09 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Channel-State-Number " , state_num ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Channel-Name " , switch_channel_get_name ( channel ) ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Unique-ID " , switch_core_session_get_uuid ( channel - > session ) ) ;
2009-02-24 00:05:19 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Call-Direction " ,
channel - > direction = = SWITCH_CALL_DIRECTION_OUTBOUND ? " outbound " : " inbound " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Presence-Call-Direction " ,
channel - > direction = = SWITCH_CALL_DIRECTION_OUTBOUND ? " outbound " : " inbound " ) ;
2007-03-29 22:31:56 +00:00
2007-12-15 00:39:53 +00:00
if ( switch_channel_test_flag ( channel , CF_ANSWERED ) ) {
2008-08-16 02:17:09 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Answer-State " , " answered " ) ;
2007-12-15 00:39:53 +00:00
} else if ( switch_channel_test_flag ( channel , CF_EARLY_MEDIA ) ) {
2008-08-16 02:17:09 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Answer-State " , " early " ) ;
2007-12-15 00:39:53 +00:00
} else {
2008-08-16 02:17:09 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Answer-State " , " ringing " ) ;
2007-12-15 00:39:53 +00:00
}
2009-03-20 01:50:50 +00:00
switch_core_session_get_read_impl ( channel - > session , & impl ) ;
if ( impl . iananame ) {
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Channel-Read-Codec-Name " , impl . iananame ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " Channel-Read-Codec-Rate " , " %u " , impl . actual_samples_per_second ) ;
2006-07-20 03:55:07 +00:00
}
2007-03-29 22:31:56 +00:00
2009-03-20 01:50:50 +00:00
switch_core_session_get_write_impl ( channel - > session , & impl ) ;
if ( impl . iananame ) {
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Channel-Write-Codec-Name " , impl . iananame ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " Channel-Write-Codec-Rate " , " %u " , impl . actual_samples_per_second ) ;
2006-07-20 03:55:07 +00:00
}
2009-01-05 20:43:53 +00:00
2008-10-08 14:22:55 +00:00
/* Index Caller's Profile */
if ( caller_profile ) {
switch_caller_profile_event_set_data ( caller_profile , " Caller " , event ) ;
}
if ( originator_caller_profile & & originatee_caller_profile ) {
/* Index Originator's Profile */
switch_caller_profile_event_set_data ( originator_caller_profile , " Originator " , event ) ;
/* Index Originatee's Profile */
switch_caller_profile_event_set_data ( originatee_caller_profile , " Originatee " , event ) ;
} else {
/* Index Originator's Profile */
if ( originator_caller_profile ) {
switch_caller_profile_event_set_data ( originator_caller_profile , " Other-Leg " , event ) ;
} else if ( originatee_caller_profile ) { /* Index Originatee's Profile */
switch_caller_profile_event_set_data ( originatee_caller_profile , " Other-Leg " , event ) ;
}
}
2009-01-05 20:51:45 +00:00
switch_mutex_unlock ( channel - > profile_mutex ) ;
2009-01-05 20:43:53 +00:00
}
2005-12-21 22:25:22 +00:00
2009-01-05 20:43:53 +00:00
SWITCH_DECLARE ( void ) switch_channel_event_set_extended_data ( switch_channel_t * channel , switch_event_t * event )
{
switch_event_header_t * hi ;
int x ;
2009-01-05 20:51:45 +00:00
switch_mutex_lock ( channel - > profile_mutex ) ;
2009-01-05 20:43:53 +00:00
2008-12-11 15:20:24 +00:00
if ( switch_channel_test_flag ( channel , CF_VERBOSE_EVENTS ) | |
2008-10-02 15:38:45 +00:00
event - > event_id = = SWITCH_EVENT_CHANNEL_ORIGINATE | |
2008-11-04 16:46:33 +00:00
event - > event_id = = SWITCH_EVENT_CHANNEL_UUID | |
2008-10-02 15:38:45 +00:00
event - > event_id = = SWITCH_EVENT_CHANNEL_ANSWER | |
2009-01-08 16:41:32 +00:00
event - > event_id = = SWITCH_EVENT_CHANNEL_PARK | |
event - > event_id = = SWITCH_EVENT_CHANNEL_UNPARK | |
2009-01-08 16:43:07 +00:00
event - > event_id = = SWITCH_EVENT_CHANNEL_BRIDGE | |
event - > event_id = = SWITCH_EVENT_CHANNEL_UNBRIDGE | |
2008-10-02 15:38:45 +00:00
event - > event_id = = SWITCH_EVENT_CHANNEL_PROGRESS | |
event - > event_id = = SWITCH_EVENT_CHANNEL_PROGRESS_MEDIA | |
2008-10-02 17:10:05 +00:00
event - > event_id = = SWITCH_EVENT_CHANNEL_HANGUP | |
2009-06-01 12:45:56 +00:00
event - > event_id = = SWITCH_EVENT_CHANNEL_HANGUP_COMPLETE | |
2008-10-02 17:10:05 +00:00
event - > event_id = = SWITCH_EVENT_REQUEST_PARAMS | |
2008-10-02 20:52:42 +00:00
event - > event_id = = SWITCH_EVENT_CHANNEL_DATA | |
2008-12-08 17:17:29 +00:00
event - > event_id = = SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE | |
2008-10-08 14:22:55 +00:00
event - > event_id = = SWITCH_EVENT_SESSION_HEARTBEAT | |
2009-04-21 14:57:43 +00:00
event - > event_id = = SWITCH_EVENT_API | |
2009-08-21 22:29:44 +00:00
event - > event_id = = SWITCH_EVENT_RECORD_START | |
event - > event_id = = SWITCH_EVENT_RECORD_STOP | |
2009-10-08 16:52:55 +00:00
event - > event_id = = SWITCH_EVENT_CALL_UPDATE | |
2008-10-02 20:52:42 +00:00
event - > event_id = = SWITCH_EVENT_CUSTOM
2008-10-02 15:38:45 +00:00
) {
x = 0 ;
/* Index Variables */
if ( channel - > variables ) {
for ( hi = channel - > variables - > headers ; hi ; hi = hi - > next ) {
char buf [ 1024 ] ;
char * vvar = NULL , * vval = NULL ;
vvar = ( char * ) hi - > name ;
vval = ( char * ) hi - > value ;
x + + ;
switch_assert ( vvar & & vval ) ;
switch_snprintf ( buf , sizeof ( buf ) , " variable_%s " , vvar ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , buf , vval ) ;
}
2008-03-11 03:45:16 +00:00
}
2005-12-21 22:25:22 +00:00
}
2008-10-02 15:38:45 +00:00
2007-06-24 04:06:05 +00:00
switch_mutex_unlock ( channel - > profile_mutex ) ;
2005-12-21 22:25:22 +00:00
}
2009-01-05 20:43:53 +00:00
SWITCH_DECLARE ( void ) switch_channel_event_set_data ( switch_channel_t * channel , switch_event_t * event )
{
2009-01-05 20:51:45 +00:00
switch_mutex_lock ( channel - > profile_mutex ) ;
2009-01-05 20:43:53 +00:00
switch_channel_event_set_basic_data ( channel , event ) ;
switch_channel_event_set_extended_data ( channel , event ) ;
2009-01-05 20:51:45 +00:00
switch_mutex_unlock ( channel - > profile_mutex ) ;
2009-01-05 20:43:53 +00:00
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( void ) switch_channel_set_caller_profile ( switch_channel_t * channel , switch_caller_profile_t * caller_profile )
2005-11-19 20:07:43 +00:00
{
2007-09-12 22:36:26 +00:00
char * uuid = NULL ;
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
switch_assert ( channel - > session ! = NULL ) ;
2006-04-28 19:46:57 +00:00
switch_mutex_lock ( channel - > profile_mutex ) ;
2007-12-11 19:23:57 +00:00
switch_assert ( caller_profile ! = NULL ) ;
2008-01-28 07:26:10 +00:00
2007-09-12 22:36:26 +00:00
uuid = switch_core_session_get_uuid ( channel - > session ) ;
2008-01-28 07:26:10 +00:00
2007-09-12 22:36:26 +00:00
if ( ! caller_profile - > uuid | | strcasecmp ( caller_profile - > uuid , uuid ) ) {
caller_profile - > uuid = switch_core_session_strdup ( channel - > session , uuid ) ;
2006-02-22 02:50:33 +00:00
}
2007-09-12 22:36:26 +00:00
if ( ! caller_profile - > chan_name | | strcasecmp ( caller_profile - > chan_name , channel - > name ) ) {
2006-02-22 02:50:33 +00:00
caller_profile - > chan_name = switch_core_session_strdup ( channel - > session , channel - > name ) ;
}
2006-05-10 03:23:05 +00:00
if ( ! caller_profile - > context ) {
2007-09-12 22:36:26 +00:00
caller_profile - > context = switch_core_session_strdup ( channel - > session , " default " ) ;
2006-05-10 03:23:05 +00:00
}
2006-04-04 21:26:21 +00:00
if ( ! channel - > caller_profile ) {
2006-04-29 01:00:52 +00:00
switch_event_t * event ;
2006-04-04 21:26:21 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_CHANNEL_CREATE ) = = SWITCH_STATUS_SUCCESS ) {
switch_channel_event_set_data ( channel , event ) ;
switch_event_fire ( & event ) ;
}
2007-03-29 22:31:56 +00:00
}
2007-03-30 00:13:31 +00:00
caller_profile - > times = ( switch_channel_timetable_t * ) switch_core_session_alloc ( channel - > session , sizeof ( * caller_profile - > times ) ) ;
2009-01-25 21:23:07 +00:00
caller_profile - > times - > profile_created = switch_micro_time_now ( ) ;
2006-12-01 15:26:37 +00:00
2007-03-29 22:31:56 +00:00
if ( channel - > caller_profile & & channel - > caller_profile - > times ) {
2007-12-20 17:27:11 +00:00
channel - > caller_profile - > times - > transferred = caller_profile - > times - > profile_created ;
2007-03-29 22:31:56 +00:00
caller_profile - > times - > answered = channel - > caller_profile - > times - > answered ;
2008-05-24 01:43:12 +00:00
caller_profile - > times - > progress = channel - > caller_profile - > times - > progress ;
caller_profile - > times - > progress_media = channel - > caller_profile - > times - > progress_media ;
2007-12-20 17:27:11 +00:00
caller_profile - > times - > created = channel - > caller_profile - > times - > created ;
caller_profile - > times - > hungup = channel - > caller_profile - > times - > hungup ;
2008-08-13 21:46:06 +00:00
if ( channel - > caller_profile - > caller_extension ) {
switch_caller_extension_clone ( & caller_profile - > caller_extension , channel - > caller_profile - > caller_extension , caller_profile - > pool ) ;
}
2007-12-20 18:04:07 +00:00
} else {
2009-01-25 21:23:07 +00:00
caller_profile - > times - > created = switch_micro_time_now ( ) ;
2007-03-29 22:31:56 +00:00
}
2006-04-04 21:26:21 +00:00
2006-04-28 19:46:57 +00:00
caller_profile - > next = channel - > caller_profile ;
2005-11-19 20:07:43 +00:00
channel - > caller_profile = caller_profile ;
2008-02-26 23:29:58 +00:00
caller_profile - > profile_index = switch_core_sprintf ( caller_profile - > pool , " %d " , + + channel - > profile_index ) ;
2008-05-27 04:30:03 +00:00
2006-04-28 19:46:57 +00:00
switch_mutex_unlock ( channel - > profile_mutex ) ;
2005-11-19 20:07:43 +00:00
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( switch_caller_profile_t * ) switch_channel_get_caller_profile ( switch_channel_t * channel )
2005-11-19 20:07:43 +00:00
{
2006-04-29 06:05:03 +00:00
switch_caller_profile_t * profile ;
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2006-04-28 19:46:57 +00:00
switch_mutex_lock ( channel - > profile_mutex ) ;
2009-06-05 01:46:09 +00:00
if ( ( profile = channel - > caller_profile ) & & profile - > hunt_caller_profile ) {
profile = profile - > hunt_caller_profile ;
}
2006-04-28 19:46:57 +00:00
switch_mutex_unlock ( channel - > profile_mutex ) ;
return profile ;
2005-11-19 20:07:43 +00:00
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( void ) switch_channel_set_originator_caller_profile ( switch_channel_t * channel , switch_caller_profile_t * caller_profile )
2005-11-19 20:07:43 +00:00
{
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2007-12-11 19:54:04 +00:00
switch_assert ( channel - > caller_profile ! = NULL ) ;
2007-09-29 01:06:08 +00:00
switch_mutex_lock ( channel - > profile_mutex ) ;
2008-10-22 18:32:54 +00:00
if ( ! caller_profile - > times ) {
caller_profile - > times = ( switch_channel_timetable_t * ) switch_core_alloc ( caller_profile - > pool , sizeof ( * caller_profile - > times ) ) ;
}
2007-03-29 22:31:56 +00:00
if ( channel - > caller_profile ) {
caller_profile - > next = channel - > caller_profile - > originator_caller_profile ;
channel - > caller_profile - > originator_caller_profile = caller_profile ;
}
2007-12-11 19:23:57 +00:00
switch_assert ( channel - > caller_profile - > originator_caller_profile - > next ! = channel - > caller_profile - > originator_caller_profile ) ;
2007-09-29 01:06:08 +00:00
switch_mutex_unlock ( channel - > profile_mutex ) ;
2005-11-19 20:07:43 +00:00
}
2009-06-05 01:05:11 +00:00
SWITCH_DECLARE ( void ) switch_channel_set_hunt_caller_profile ( switch_channel_t * channel , switch_caller_profile_t * caller_profile )
{
switch_assert ( channel ! = NULL ) ;
switch_assert ( channel - > caller_profile ! = NULL ) ;
switch_mutex_lock ( channel - > profile_mutex ) ;
channel - > caller_profile - > hunt_caller_profile = NULL ;
if ( channel - > caller_profile & & caller_profile ) {
channel - > caller_profile - > hunt_caller_profile = caller_profile ;
}
switch_mutex_unlock ( channel - > profile_mutex ) ;
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( void ) switch_channel_set_originatee_caller_profile ( switch_channel_t * channel , switch_caller_profile_t * caller_profile )
2005-12-26 19:09:59 +00:00
{
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2007-12-11 19:54:04 +00:00
switch_assert ( channel - > caller_profile ! = NULL ) ;
2007-09-29 01:06:08 +00:00
switch_mutex_lock ( channel - > profile_mutex ) ;
2007-03-29 22:31:56 +00:00
if ( channel - > caller_profile ) {
caller_profile - > next = channel - > caller_profile - > originatee_caller_profile ;
channel - > caller_profile - > originatee_caller_profile = caller_profile ;
}
2007-12-11 19:23:57 +00:00
switch_assert ( channel - > caller_profile - > originatee_caller_profile - > next ! = channel - > caller_profile - > originatee_caller_profile ) ;
2008-05-27 04:30:03 +00:00
switch_mutex_unlock ( channel - > profile_mutex ) ;
2005-12-26 19:09:59 +00:00
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( switch_caller_profile_t * ) switch_channel_get_originator_caller_profile ( switch_channel_t * channel )
2005-11-19 20:07:43 +00:00
{
2006-12-01 15:26:37 +00:00
switch_caller_profile_t * profile = NULL ;
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2006-04-28 19:46:57 +00:00
2007-09-29 01:06:08 +00:00
switch_mutex_lock ( channel - > profile_mutex ) ;
2007-03-29 22:31:56 +00:00
if ( channel - > caller_profile ) {
profile = channel - > caller_profile - > originator_caller_profile ;
}
2007-09-29 01:06:08 +00:00
switch_mutex_unlock ( channel - > profile_mutex ) ;
2008-01-28 07:26:10 +00:00
2006-04-28 19:46:57 +00:00
return profile ;
2005-11-19 20:07:43 +00:00
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( switch_caller_profile_t * ) switch_channel_get_originatee_caller_profile ( switch_channel_t * channel )
2005-12-26 19:09:59 +00:00
{
2006-12-01 15:26:37 +00:00
switch_caller_profile_t * profile = NULL ;
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2006-04-28 19:46:57 +00:00
2007-09-29 01:06:08 +00:00
switch_mutex_lock ( channel - > profile_mutex ) ;
2007-03-29 22:31:56 +00:00
if ( channel - > caller_profile ) {
profile = channel - > caller_profile - > originatee_caller_profile ;
}
2007-09-29 01:06:08 +00:00
switch_mutex_unlock ( channel - > profile_mutex ) ;
2008-01-28 07:26:10 +00:00
2006-04-28 19:46:57 +00:00
return profile ;
2005-12-26 19:09:59 +00:00
}
2006-12-01 15:26:37 +00:00
SWITCH_DECLARE ( char * ) switch_channel_get_uuid ( switch_channel_t * channel )
{
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
switch_assert ( channel - > session ! = NULL ) ;
2006-12-01 15:26:37 +00:00
return switch_core_session_get_uuid ( channel - > session ) ;
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( int ) switch_channel_add_state_handler ( switch_channel_t * channel , const switch_state_handler_table_t * state_handler )
2005-11-19 20:07:43 +00:00
{
2006-08-15 21:38:24 +00:00
int x , index ;
2006-02-07 22:58:56 +00:00
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2009-02-20 18:31:08 +00:00
switch_mutex_lock ( channel - > state_mutex ) ;
2006-08-15 21:38:24 +00:00
for ( x = 0 ; x < SWITCH_MAX_STATE_HANDLERS ; x + + ) {
if ( channel - > state_handlers [ x ] = = state_handler ) {
2006-10-04 23:11:11 +00:00
index = x ;
goto end ;
2006-08-15 21:38:24 +00:00
}
}
2006-02-07 22:58:56 +00:00
index = channel - > state_handler_index + + ;
2006-02-07 20:47:15 +00:00
if ( channel - > state_handler_index > = SWITCH_MAX_STATE_HANDLERS ) {
2006-10-04 23:11:11 +00:00
index = - 1 ;
goto end ;
2006-02-07 20:47:15 +00:00
}
2007-03-29 22:31:56 +00:00
2006-02-07 20:47:15 +00:00
channel - > state_handlers [ index ] = state_handler ;
2006-10-04 23:11:11 +00:00
2008-05-27 04:30:03 +00:00
end :
2009-02-20 18:31:08 +00:00
switch_mutex_unlock ( channel - > state_mutex ) ;
2006-02-07 20:47:15 +00:00
return index ;
2005-11-19 20:07:43 +00:00
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( const switch_state_handler_table_t * ) switch_channel_get_state_handler ( switch_channel_t * channel , int index )
2005-11-19 20:07:43 +00:00
{
2006-10-04 23:11:11 +00:00
const switch_state_handler_table_t * h = NULL ;
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2006-02-07 20:47:15 +00:00
2007-12-17 20:44:48 +00:00
if ( index > = SWITCH_MAX_STATE_HANDLERS | | index > channel - > state_handler_index ) {
2006-02-07 20:47:15 +00:00
return NULL ;
}
2009-02-20 18:31:08 +00:00
switch_mutex_lock ( channel - > state_mutex ) ;
2006-10-04 23:11:11 +00:00
h = channel - > state_handlers [ index ] ;
2009-02-20 18:31:08 +00:00
switch_mutex_unlock ( channel - > state_mutex ) ;
2006-10-04 23:11:11 +00:00
return h ;
2005-11-19 20:07:43 +00:00
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( void ) switch_channel_clear_state_handler ( switch_channel_t * channel , const switch_state_handler_table_t * state_handler )
2006-04-25 18:02:12 +00:00
{
2006-10-04 23:11:11 +00:00
int index , i = channel - > state_handler_index ;
2007-03-29 22:31:56 +00:00
const switch_state_handler_table_t * new_handlers [ SWITCH_MAX_STATE_HANDLERS ] = { 0 } ;
2006-04-25 18:02:12 +00:00
2008-05-15 21:08:42 +00:00
switch_assert ( channel ! = NULL ) ;
2006-10-04 23:11:11 +00:00
2009-02-20 18:31:08 +00:00
switch_mutex_lock ( channel - > state_mutex ) ;
2006-10-04 23:11:11 +00:00
channel - > state_handler_index = 0 ;
2006-04-25 18:02:12 +00:00
2006-08-17 00:53:09 +00:00
if ( state_handler ) {
2006-10-04 23:11:11 +00:00
for ( index = 0 ; index < i ; index + + ) {
2006-08-17 00:53:09 +00:00
if ( channel - > state_handlers [ index ] ! = state_handler ) {
2006-10-04 23:11:11 +00:00
new_handlers [ channel - > state_handler_index + + ] = channel - > state_handlers [ index ] ;
2006-08-17 00:53:09 +00:00
}
2006-04-25 18:02:12 +00:00
}
2009-11-04 21:07:18 +00:00
} else {
for ( index = 0 ; index < i ; index + + ) {
if ( switch_test_flag ( channel - > state_handlers [ index ] , SSH_FLAG_STICKY ) ) {
new_handlers [ channel - > state_handler_index + + ] = channel - > state_handlers [ index ] ;
}
}
2006-04-25 18:02:12 +00:00
}
2009-11-04 21:07:18 +00:00
2006-04-26 18:37:03 +00:00
for ( index = 0 ; index < SWITCH_MAX_STATE_HANDLERS ; index + + ) {
channel - > state_handlers [ index ] = NULL ;
}
2006-09-19 15:33:02 +00:00
2006-08-17 00:53:09 +00:00
if ( state_handler ) {
2006-10-04 23:11:11 +00:00
for ( index = 0 ; index < channel - > state_handler_index ; index + + ) {
channel - > state_handlers [ index ] = new_handlers [ index ] ;
2006-08-17 00:53:09 +00:00
}
2006-04-25 18:02:12 +00:00
}
2009-02-20 18:31:08 +00:00
switch_mutex_unlock ( channel - > state_mutex ) ;
2006-04-25 18:02:12 +00:00
}
2009-10-09 22:28:31 +00:00
SWITCH_DECLARE ( void ) switch_channel_restart ( switch_channel_t * channel )
{
switch_channel_set_state ( channel , CS_RESET ) ;
switch_channel_wait_for_state_timeout ( channel , CS_RESET , 5000 ) ;
switch_channel_set_state ( channel , CS_EXECUTE ) ;
}
/* XXX This is a somewhat simple operation. Were essentially taking the extension that one channel
was executing and generating a new extension for another channel that starts out where the
original one left off with an optional forward offset . Since all we are really doing is
copying a few basic pool - allocated structures from one channel to another there really is
not much to worry about here in terms of threading since we use read - write locks .
While the features are nice , they only really are needed in one specific crazy attended
transfer scenario where one channel was in the middle of calling a particular extension
when it was rudely cut off by a transfer key press . XXX */
2009-10-09 20:48:24 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_channel_caller_extension_masquerade ( switch_channel_t * orig_channel , switch_channel_t * new_channel , uint32_t offset )
{
switch_caller_profile_t * caller_profile ;
switch_caller_extension_t * extension = NULL , * orig_extension = NULL ;
switch_caller_application_t * ap ;
switch_status_t status = SWITCH_STATUS_FALSE ;
switch_event_header_t * hi = NULL ;
const char * no_copy = switch_channel_get_variable ( orig_channel , " attended_transfer_no_copy " ) ;
char * dup ;
int i , argc = 0 ;
char * argv [ 128 ] ;
if ( no_copy ) {
dup = switch_core_session_strdup ( new_channel - > session , no_copy ) ;
argc = switch_separate_string ( dup , ' , ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
}
switch_mutex_lock ( orig_channel - > profile_mutex ) ;
switch_mutex_lock ( new_channel - > profile_mutex ) ;
caller_profile = switch_caller_profile_clone ( new_channel - > session , new_channel - > caller_profile ) ;
switch_assert ( caller_profile ) ;
extension = switch_caller_extension_new ( new_channel - > session , caller_profile - > destination_number , caller_profile - > destination_number ) ;
orig_extension = switch_channel_get_caller_extension ( orig_channel ) ;
if ( extension & & orig_extension ) {
for ( ap = orig_extension - > current_application ; ap & & offset > 0 ; offset - - ) {
ap = ap - > next ;
}
for ( ; ap ; ap = ap - > next ) {
switch_caller_extension_add_application ( new_channel - > session , extension , ap - > application_name , ap - > application_data ) ;
}
caller_profile - > destination_number = switch_core_strdup ( caller_profile - > pool , orig_channel - > caller_profile - > destination_number ) ;
switch_channel_set_caller_profile ( new_channel , caller_profile ) ;
switch_channel_set_caller_extension ( new_channel , extension ) ;
for ( hi = orig_channel - > variables - > headers ; hi ; hi = hi - > next ) {
int ok = 1 ;
for ( i = 0 ; i < argc ; i + + ) {
if ( ! strcasecmp ( argv [ i ] , hi - > name ) ) {
ok = 0 ;
break ;
}
}
if ( ! ok ) continue ;
switch_channel_set_variable ( new_channel , hi - > name , hi - > value ) ;
}
status = SWITCH_STATUS_SUCCESS ;
}
switch_mutex_unlock ( new_channel - > profile_mutex ) ;
switch_mutex_unlock ( orig_channel - > profile_mutex ) ;
return status ;
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( void ) switch_channel_set_caller_extension ( switch_channel_t * channel , switch_caller_extension_t * caller_extension )
2005-11-19 20:07:43 +00:00
{
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2006-06-03 17:06:06 +00:00
switch_mutex_lock ( channel - > profile_mutex ) ;
2007-02-07 17:19:06 +00:00
caller_extension - > next = channel - > caller_profile - > caller_extension ;
channel - > caller_profile - > caller_extension = caller_extension ;
2006-06-03 17:06:06 +00:00
switch_mutex_unlock ( channel - > profile_mutex ) ;
2005-11-19 20:07:43 +00:00
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( switch_caller_extension_t * ) switch_channel_get_caller_extension ( switch_channel_t * channel )
2005-11-19 20:07:43 +00:00
{
2007-03-29 22:31:56 +00:00
switch_caller_extension_t * extension = NULL ;
2005-11-19 20:07:43 +00:00
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2007-02-07 17:19:06 +00:00
switch_mutex_lock ( channel - > profile_mutex ) ;
2007-03-28 12:30:20 +00:00
if ( channel - > caller_profile ) {
extension = channel - > caller_profile - > caller_extension ;
}
2007-03-29 22:31:56 +00:00
switch_mutex_unlock ( channel - > profile_mutex ) ;
return extension ;
2005-11-19 20:07:43 +00:00
}
2009-03-25 20:07:40 +00:00
SWITCH_DECLARE ( void ) switch_channel_set_hangup_time ( switch_channel_t * channel )
{
if ( channel - > caller_profile & & channel - > caller_profile - > times & & ! channel - > caller_profile - > times - > hungup ) {
switch_mutex_lock ( channel - > profile_mutex ) ;
channel - > caller_profile - > times - > hungup = switch_micro_time_now ( ) ;
switch_mutex_unlock ( channel - > profile_mutex ) ;
}
}
2007-03-29 22:31:56 +00:00
SWITCH_DECLARE ( switch_channel_state_t ) switch_channel_perform_hangup ( switch_channel_t * channel ,
2007-03-30 00:13:31 +00:00
const char * file , const char * func , int line , switch_call_cause_t hangup_cause )
2005-11-19 20:07:43 +00:00
{
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2009-03-04 04:19:33 +00:00
switch_channel_clear_flag ( channel , CF_BLOCK_STATE ) ;
2009-03-20 01:50:50 +00:00
2006-04-03 14:53:34 +00:00
if ( channel - > state < CS_HANGUP ) {
2009-10-07 04:30:19 +00:00
switch_channel_state_t last_state ;
2009-05-29 17:18:03 +00:00
switch_event_t * event ;
2008-01-28 07:26:10 +00:00
2009-03-20 01:50:50 +00:00
switch_mutex_lock ( channel - > state_mutex ) ;
2009-10-07 04:30:19 +00:00
last_state = channel - > state ;
2005-11-19 20:07:43 +00:00
channel - > state = CS_HANGUP ;
2009-03-20 01:50:50 +00:00
switch_mutex_unlock ( channel - > state_mutex ) ;
2006-04-22 03:05:25 +00:00
channel - > hangup_cause = hangup_cause ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , file , func , line , switch_channel_get_uuid ( channel ) , SWITCH_LOG_NOTICE , " Hangup %s [%s] [%s] \n " ,
2008-05-27 04:30:03 +00:00
channel - > name , state_names [ last_state ] , switch_channel_cause2str ( channel - > hangup_cause ) ) ;
2006-10-21 04:58:15 +00:00
2009-05-29 17:18:03 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_CHANNEL_HANGUP ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Hangup-Cause " , switch_channel_cause2str ( hangup_cause ) ) ;
switch_channel_event_set_data ( channel , event ) ;
switch_event_fire ( & event ) ;
}
2006-03-22 17:05:16 +00:00
switch_core_session_kill_channel ( channel - > session , SWITCH_SIG_KILL ) ;
2006-09-16 00:43:58 +00:00
switch_core_session_signal_state_change ( channel - > session ) ;
2009-09-14 20:10:58 +00:00
switch_core_session_hangup_state ( channel - > session ) ;
2005-11-19 20:07:43 +00:00
}
2006-09-16 00:43:58 +00:00
2005-11-19 20:07:43 +00:00
return channel - > state ;
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_channel_perform_mark_ring_ready ( switch_channel_t * channel , const char * file , const char * func , int line )
2007-02-13 02:32:10 +00:00
{
2008-06-05 20:45:03 +00:00
const char * var ;
char * app ;
2008-10-02 15:38:45 +00:00
switch_event_t * event ;
2008-06-05 20:45:03 +00:00
2007-02-13 02:32:10 +00:00
if ( ! switch_channel_test_flag ( channel , CF_RING_READY ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , file , func , line , switch_channel_get_uuid ( channel ) , SWITCH_LOG_NOTICE , " Ring-Ready %s! \n " , channel - > name ) ;
2007-02-13 02:32:10 +00:00
switch_channel_set_flag ( channel , CF_RING_READY ) ;
2008-05-24 02:03:16 +00:00
if ( channel - > caller_profile & & channel - > caller_profile - > times ) {
switch_mutex_lock ( channel - > profile_mutex ) ;
2009-01-25 21:23:07 +00:00
channel - > caller_profile - > times - > progress = switch_micro_time_now ( ) ;
2008-10-22 18:32:54 +00:00
if ( channel - > caller_profile - > originator_caller_profile ) {
switch_core_session_t * other_session ;
if ( ( other_session = switch_core_session_locate ( channel - > caller_profile - > originator_caller_profile - > uuid ) ) ) {
switch_channel_t * other_channel ;
other_channel = switch_core_session_get_channel ( other_session ) ;
if ( other_channel - > caller_profile ) {
other_channel - > caller_profile - > times - > progress = channel - > caller_profile - > times - > progress ;
}
switch_core_session_rwunlock ( other_session ) ;
}
channel - > caller_profile - > originator_caller_profile - > times - > progress = channel - > caller_profile - > times - > progress ;
}
2008-05-24 02:03:16 +00:00
switch_mutex_unlock ( channel - > profile_mutex ) ;
}
2008-06-05 20:45:03 +00:00
2008-10-02 15:38:45 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_CHANNEL_PROGRESS ) = = SWITCH_STATUS_SUCCESS ) {
switch_channel_event_set_data ( channel , event ) ;
switch_event_fire ( & event ) ;
}
2008-06-05 20:45:03 +00:00
var = switch_channel_get_variable ( channel , SWITCH_CHANNEL_EXECUTE_ON_RING_VARIABLE ) ;
if ( var ) {
char * arg = NULL ;
app = switch_core_session_strdup ( channel - > session , var ) ;
if ( ( arg = strchr ( app , ' ' ) ) ) {
* arg + + = ' \0 ' ;
}
switch_core_session_execute_application ( channel - > session , app , arg ) ;
}
2007-02-13 02:32:10 +00:00
return SWITCH_STATUS_SUCCESS ;
}
return SWITCH_STATUS_FALSE ;
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_channel_perform_mark_pre_answered ( switch_channel_t * channel , const char * file , const char * func , int line )
2007-02-09 01:34:01 +00:00
{
2007-03-29 22:31:56 +00:00
switch_event_t * event ;
2009-10-29 05:47:17 +00:00
const char * var = NULL ;
char * app ;
2007-02-09 01:34:01 +00:00
2007-03-29 22:31:56 +00:00
if ( ! switch_channel_test_flag ( channel , CF_EARLY_MEDIA ) ) {
2007-11-01 11:28:26 +00:00
const char * uuid ;
2007-03-29 22:31:56 +00:00
switch_core_session_t * other_session ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , file , func , line , switch_channel_get_uuid ( channel ) , SWITCH_LOG_NOTICE , " Pre-Answer %s! \n " , channel - > name ) ;
2007-03-29 22:31:56 +00:00
switch_channel_set_flag ( channel , CF_EARLY_MEDIA ) ;
2008-10-21 19:18:40 +00:00
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " EARLY MEDIA " ) ;
2008-10-02 15:38:45 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_CHANNEL_PROGRESS_MEDIA ) = = SWITCH_STATUS_SUCCESS ) {
2007-03-29 22:31:56 +00:00
switch_channel_event_set_data ( channel , event ) ;
switch_event_fire ( & event ) ;
}
2008-10-22 18:32:54 +00:00
2008-05-24 01:43:12 +00:00
if ( channel - > caller_profile & & channel - > caller_profile - > times ) {
switch_mutex_lock ( channel - > profile_mutex ) ;
2009-01-25 21:23:07 +00:00
channel - > caller_profile - > times - > progress_media = switch_micro_time_now ( ) ;
2008-10-22 18:32:54 +00:00
if ( channel - > caller_profile - > originator_caller_profile ) {
2008-10-23 01:39:04 +00:00
switch_core_session_t * osession ;
if ( ( osession = switch_core_session_locate ( channel - > caller_profile - > originator_caller_profile - > uuid ) ) ) {
2008-10-22 18:32:54 +00:00
switch_channel_t * other_channel ;
2008-10-23 01:39:04 +00:00
other_channel = switch_core_session_get_channel ( osession ) ;
2008-10-22 18:32:54 +00:00
if ( other_channel - > caller_profile ) {
other_channel - > caller_profile - > times - > progress_media = channel - > caller_profile - > times - > progress_media ;
}
2008-10-23 01:39:04 +00:00
switch_core_session_rwunlock ( osession ) ;
2008-10-22 18:32:54 +00:00
}
channel - > caller_profile - > originator_caller_profile - > times - > progress_media = channel - > caller_profile - > times - > progress_media ;
}
2008-05-24 01:43:12 +00:00
switch_mutex_unlock ( channel - > profile_mutex ) ;
}
2009-10-29 05:47:17 +00:00
if ( ( ( var = switch_channel_get_variable ( channel , SWITCH_CHANNEL_EXECUTE_ON_PRE_ANSWER_VARIABLE ) ) | |
( var = switch_channel_get_variable ( channel , SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE ) ) ) & & ! zstr ( var ) ) {
char * arg = NULL ;
app = switch_core_session_strdup ( channel - > session , var ) ;
if ( ( arg = strchr ( app , ' ' ) ) ) {
* arg + + = ' \0 ' ;
}
switch_core_session_execute_application ( channel - > session , app , arg ) ;
}
2007-03-29 22:31:56 +00:00
/* if we're the child of another channel and the other channel is in a blocking read they will never realize we have answered so send
2008-05-27 04:30:03 +00:00
a SWITCH_SIG_BREAK to interrupt any blocking reads on that channel
*/
2007-03-29 22:31:56 +00:00
if ( ( uuid = switch_channel_get_variable ( channel , SWITCH_ORIGINATOR_VARIABLE ) )
& & ( other_session = switch_core_session_locate ( uuid ) ) ) {
2008-05-27 04:30:03 +00:00
switch_core_session_kill_channel ( other_session , SWITCH_SIG_BREAK ) ;
switch_core_session_rwunlock ( other_session ) ;
2007-03-29 22:31:56 +00:00
}
return SWITCH_STATUS_SUCCESS ;
}
return SWITCH_STATUS_FALSE ;
2007-02-09 01:34:01 +00:00
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_channel_perform_pre_answer ( switch_channel_t * channel , const char * file , const char * func , int line )
2006-03-03 16:57:21 +00:00
{
2009-10-12 22:23:55 +00:00
switch_core_session_message_t msg = { 0 } ;
2009-01-20 18:36:02 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2007-03-29 22:31:56 +00:00
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2006-03-21 00:20:24 +00:00
2007-03-12 20:17:34 +00:00
if ( channel - > hangup_cause | | channel - > state > = CS_HANGUP ) {
2006-03-21 00:20:24 +00:00
return SWITCH_STATUS_FALSE ;
}
2006-07-10 19:51:19 +00:00
if ( switch_channel_test_flag ( channel , CF_ANSWERED ) ) {
return SWITCH_STATUS_SUCCESS ;
}
2006-10-08 15:51:10 +00:00
if ( switch_channel_test_flag ( channel , CF_EARLY_MEDIA ) ) {
return SWITCH_STATUS_SUCCESS ;
}
2009-01-20 18:36:02 +00:00
if ( ! switch_channel_test_flag ( channel , CF_OUTBOUND ) ) {
msg . message_id = SWITCH_MESSAGE_INDICATE_PROGRESS ;
msg . from = channel - > name ;
status = switch_core_session_perform_receive_message ( channel - > session , & msg , file , func , line ) ;
2009-01-19 16:25:49 +00:00
}
2006-03-03 17:49:22 +00:00
if ( status = = SWITCH_STATUS_SUCCESS ) {
2008-02-20 03:57:01 +00:00
switch_channel_perform_mark_pre_answered ( channel , file , func , line ) ;
} else {
switch_channel_hangup ( channel , SWITCH_CAUSE_INCOMPATIBLE_DESTINATION ) ;
2006-03-03 17:49:22 +00:00
}
2006-03-03 16:57:21 +00:00
return status ;
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_channel_perform_ring_ready ( switch_channel_t * channel , const char * file , const char * func , int line )
2006-10-25 04:28:49 +00:00
{
2009-10-12 22:23:55 +00:00
switch_core_session_message_t msg = { 0 } ;
2009-01-20 18:36:02 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2007-03-29 22:31:56 +00:00
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2006-10-25 04:28:49 +00:00
2007-03-12 20:17:34 +00:00
if ( channel - > hangup_cause | | channel - > state > = CS_HANGUP ) {
2006-10-25 04:28:49 +00:00
return SWITCH_STATUS_FALSE ;
}
if ( switch_channel_test_flag ( channel , CF_ANSWERED ) ) {
return SWITCH_STATUS_SUCCESS ;
}
if ( switch_channel_test_flag ( channel , CF_EARLY_MEDIA ) ) {
return SWITCH_STATUS_SUCCESS ;
}
2009-01-20 18:36:02 +00:00
if ( ! switch_channel_test_flag ( channel , CF_OUTBOUND ) ) {
msg . message_id = SWITCH_MESSAGE_INDICATE_RINGING ;
msg . from = channel - > name ;
status = switch_core_session_perform_receive_message ( channel - > session , & msg , file , func , line ) ;
2009-01-19 16:25:49 +00:00
}
2009-01-20 18:36:02 +00:00
2006-10-25 04:28:49 +00:00
if ( status = = SWITCH_STATUS_SUCCESS ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , file , func , line , switch_channel_get_uuid ( channel ) , SWITCH_LOG_NOTICE , " Ring Ready %s! \n " , channel - > name ) ;
2008-02-20 03:57:01 +00:00
} else {
switch_channel_hangup ( channel , SWITCH_CAUSE_INCOMPATIBLE_DESTINATION ) ;
2006-10-25 04:28:49 +00:00
}
return status ;
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_channel_perform_mark_answered ( switch_channel_t * channel , const char * file , const char * func , int line )
2006-12-05 23:08:14 +00:00
{
2007-03-29 22:31:56 +00:00
switch_event_t * event ;
2007-11-01 11:28:26 +00:00
const char * uuid ;
2007-03-29 22:31:56 +00:00
switch_core_session_t * other_session ;
2008-06-05 19:36:33 +00:00
const char * var ;
char * app ;
2006-12-05 23:08:14 +00:00
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2006-12-05 23:08:14 +00:00
2007-03-12 20:17:34 +00:00
if ( channel - > hangup_cause | | channel - > state > = CS_HANGUP ) {
2006-12-05 23:08:14 +00:00
return SWITCH_STATUS_FALSE ;
}
if ( switch_channel_test_flag ( channel , CF_ANSWERED ) ) {
return SWITCH_STATUS_SUCCESS ;
}
2007-03-29 22:31:56 +00:00
if ( channel - > caller_profile & & channel - > caller_profile - > times ) {
switch_mutex_lock ( channel - > profile_mutex ) ;
2009-01-25 21:23:07 +00:00
channel - > caller_profile - > times - > answered = switch_micro_time_now ( ) ;
2007-03-29 22:31:56 +00:00
switch_mutex_unlock ( channel - > profile_mutex ) ;
}
switch_channel_set_flag ( channel , CF_ANSWERED ) ;
if ( switch_event_create ( & event , SWITCH_EVENT_CHANNEL_ANSWER ) = = SWITCH_STATUS_SUCCESS ) {
switch_channel_event_set_data ( channel , event ) ;
switch_event_fire ( & event ) ;
}
/* if we're the child of another channel and the other channel is in a blocking read they will never realize we have answered so send
2008-05-27 04:30:03 +00:00
a SWITCH_SIG_BREAK to interrupt any blocking reads on that channel
*/
2007-03-29 22:31:56 +00:00
if ( ( uuid = switch_channel_get_variable ( channel , SWITCH_ORIGINATOR_VARIABLE ) )
& & ( other_session = switch_core_session_locate ( uuid ) ) ) {
2008-05-27 04:30:03 +00:00
switch_core_session_kill_channel ( other_session , SWITCH_SIG_BREAK ) ;
switch_core_session_rwunlock ( other_session ) ;
2007-03-29 22:31:56 +00:00
}
2008-10-07 21:03:37 +00:00
if ( ( var = switch_channel_get_variable ( channel , SWITCH_ENABLE_HEARTBEAT_EVENTS_VARIABLE ) ) ) {
uint32_t seconds = 60 ;
int tmp ;
if ( switch_is_number ( var ) ) {
tmp = atoi ( var ) ;
2008-10-07 21:42:31 +00:00
if ( tmp > 0 ) {
2008-10-07 21:03:37 +00:00
seconds = tmp ;
}
} else if ( ! switch_true ( var ) ) {
seconds = 0 ;
}
if ( seconds ) {
switch_core_session_enable_heartbeat ( channel - > session , seconds ) ;
}
}
2008-10-21 19:18:40 +00:00
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " ANSWER " ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , file , func , line , switch_channel_get_uuid ( channel ) , SWITCH_LOG_NOTICE , " Channel [%s] has been answered \n " , channel - > name ) ;
2009-10-29 05:47:17 +00:00
if ( ( ( var = switch_channel_get_variable ( channel , SWITCH_CHANNEL_EXECUTE_ON_ANSWER_VARIABLE ) ) | |
( ! switch_channel_test_flag ( channel , CF_EARLY_MEDIA ) & & ( var = switch_channel_get_variable ( channel , SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE ) ) ) )
& & ! zstr ( var ) ) {
2008-06-05 19:36:33 +00:00
char * arg = NULL ;
2007-03-29 22:31:56 +00:00
2008-06-05 19:36:33 +00:00
app = switch_core_session_strdup ( channel - > session , var ) ;
2009-05-20 13:02:41 +00:00
if ( ( arg = strchr ( app , ' : ' ) ) & & * ( arg + 1 ) = = ' : ' ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( channel ) , SWITCH_LOG_DEBUG , " %s execute on answer: %s (BROADCAST) \n " , channel - > name , app ) ;
2009-05-20 13:02:41 +00:00
switch_ivr_broadcast ( switch_core_session_get_uuid ( channel - > session ) , app , SMF_NONE ) ;
} else {
if ( ( arg = strchr ( app , ' ' ) ) ) {
* arg + + = ' \0 ' ;
}
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( channel ) , SWITCH_LOG_DEBUG , " %s execute on answer: %s(%s) \n " , channel - > name , app , switch_str_nil ( arg ) ) ;
2009-05-20 13:02:41 +00:00
switch_core_session_execute_application ( channel - > session , app , arg ) ;
2008-06-05 19:36:33 +00:00
}
}
2008-11-27 02:41:08 +00:00
2009-10-23 16:03:42 +00:00
if ( ( var = switch_channel_get_variable ( channel , SWITCH_CHANNEL_API_ON_ANSWER_VARIABLE ) ) & & ! zstr ( var ) ) {
2009-10-23 15:01:34 +00:00
switch_stream_handle_t stream = { 0 } ;
char * arg = NULL ;
app = switch_core_session_strdup ( channel - > session , var ) ;
if ( ( arg = strchr ( app , ' ' ) ) ) {
* arg + + = ' \0 ' ;
}
SWITCH_STANDARD_STREAM ( stream ) ;
switch_api_execute ( app , arg , NULL , & stream ) ;
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( channel ) , SWITCH_LOG_DEBUG , " %s api on answer: %s(%s) \n %s \n " ,
channel - > name , app , switch_str_nil ( arg ) , ( char * ) stream . data ) ;
free ( stream . data ) ;
}
2008-11-27 04:02:57 +00:00
switch_channel_audio_sync ( channel ) ;
2008-11-27 02:41:08 +00:00
2007-03-29 22:31:56 +00:00
return SWITCH_STATUS_SUCCESS ;
2006-12-05 23:08:14 +00:00
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_channel_perform_answer ( switch_channel_t * channel , const char * file , const char * func , int line )
2005-11-19 20:07:43 +00:00
{
2009-10-12 22:23:55 +00:00
switch_core_session_message_t msg = { 0 } ;
2009-01-20 18:36:02 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2007-04-16 16:53:30 +00:00
2007-12-11 19:23:57 +00:00
switch_assert ( channel ! = NULL ) ;
2005-11-19 20:07:43 +00:00
2007-03-12 20:17:34 +00:00
if ( channel - > hangup_cause | | channel - > state > = CS_HANGUP ) {
2006-03-21 00:20:24 +00:00
return SWITCH_STATUS_FALSE ;
2009-01-19 16:00:11 +00:00
}
2009-01-19 16:25:49 +00:00
if ( switch_channel_test_flag ( channel , CF_ANSWERED ) ) {
return SWITCH_STATUS_SUCCESS ;
2006-03-21 00:20:24 +00:00
}
2009-01-20 18:36:02 +00:00
if ( ! switch_channel_test_flag ( channel , CF_OUTBOUND ) ) {
msg . message_id = SWITCH_MESSAGE_INDICATE_ANSWER ;
msg . from = channel - > name ;
status = switch_core_session_perform_receive_message ( channel - > session , & msg , file , func , line ) ;
2006-06-06 23:49:02 +00:00
}
2007-04-16 16:53:30 +00:00
if ( status = = SWITCH_STATUS_SUCCESS ) {
2008-02-20 03:57:01 +00:00
switch_channel_perform_mark_answered ( channel , file , func , line ) ;
} else {
switch_channel_hangup ( channel , SWITCH_CAUSE_INCOMPATIBLE_DESTINATION ) ;
2005-11-19 20:07:43 +00:00
}
2008-02-20 03:57:01 +00:00
return status ;
2005-11-19 20:07:43 +00:00
}
2006-10-07 19:54:04 +00:00
2006-12-07 00:36:00 +00:00
# define resize(l) {\
2008-01-28 07:26:10 +00:00
char * dp ; \
olen + = ( len + l + block ) ; \
cpos = c - data ; \
if ( ( dp = realloc ( data , olen ) ) ) { \
data = dp ; \
c = data + cpos ; \
memset ( c , 0 , olen - cpos ) ; \
} } \
2006-12-07 00:36:00 +00:00
2007-12-05 20:23:50 +00:00
SWITCH_DECLARE ( char * ) switch_channel_expand_variables ( switch_channel_t * channel , const char * in )
2006-10-07 19:54:04 +00:00
{
2007-12-05 20:23:50 +00:00
char * p , * c = NULL ;
2008-08-11 15:37:50 +00:00
char * data , * indup , * endof_indup ;
Ringback (sponsored by Front Logic)
This addition lets you set artifical ringback on a channel
that is waiting for an originated call to be answered.
the syntax is
<action application="set" data="ringback=[data]"/>
where data is either the full path to an audio file
or a teletone generation script..
syntax of teletone scripts
LEGEND:
0-9,a-d,*,# (standard dtmf tones)
variables: c,r,d,v,>,<,+,w,l,L,%
c (channels) - Sets the number of channels.
r (rate) - Sets the sample rate.
d (duration) - Sets the default tone duration.
v (volume) - Sets the default volume.
> (decrease vol) - factor to decrease volume by per frame (0 for even decrease across duration).
< (increase vol) - factor to increase volume by per frame (0 for even increase across duration).
+ (step) - factor to step by used by < and >.
w (wait) - default silence after each tone.
l (loops) - number of times to repeat each tone in the script.
L (LOOPS) - number of times to repeat the the whole script.
% (manual tone) - a generic tone specified by a duration, a wait and a list of frequencies.
standard tones can have custom duration per use with the () modifier
7(1000, 500) to generate DTMF 7 for 1 second then pause .5 seconds
EXAMPLES
UK Ring Tone [400+450 hz on for 400ms off for 200ms then 400+450 hz on for 400ms off for 2200ms]
%(400,200,400,450);%(400,2200,400,450)
US Ring Tone [440+480 hz on for 2000ms off for 4000ms]
%(2000,4000,440,480)
ATT BONG [volume level 4000, even decay, step by 2, # key for 60ms with no wait, volume level 2000, 350+440hz {us dialtone} for 940ms
v=4000;>=0;+=2;#(60,0);v=2000;%(940,0,350,440)
SIT Tone 913.8 hz for 274 ms with no wait, 1370.6 hz for 274 ms with no wait, 1776.7 hz for 380ms with no wait
%(274,0,913.8);%(274,0,1370.6);%(380,0,1776.7)
ATTN TONE (phone's off the hook!) 1400+2060+2450+2600 hz for 100ms with 100ms wait
%(100,100,1400,2060,2450,2600)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3408 d0543943-73ff-0310-b7d9-9358b9ac24b2
2006-11-19 01:05:06 +00:00
size_t sp = 0 , len = 0 , olen = 0 , vtype = 0 , br = 0 , cpos , block = 128 ;
2008-06-06 13:43:41 +00:00
char * cloned_sub_val = NULL , * sub_val = NULL ;
2007-11-01 11:28:26 +00:00
char * func_val = NULL ;
2007-04-21 14:17:43 +00:00
int nv = 0 ;
2006-10-07 19:54:04 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( in ) ) {
2008-05-27 04:30:03 +00:00
return ( char * ) in ;
2008-03-11 23:49:06 +00:00
}
2009-04-14 15:24:30 +00:00
nv = switch_string_var_check_const ( in ) | | switch_string_has_escaped_data ( in ) ;
2008-01-28 07:26:10 +00:00
2007-10-23 01:29:37 +00:00
if ( ! nv ) {
2008-05-27 04:30:03 +00:00
return ( char * ) in ;
2006-10-07 19:54:04 +00:00
}
2008-05-27 04:30:03 +00:00
2007-10-23 01:29:37 +00:00
nv = 0 ;
olen = strlen ( in ) + 1 ;
2006-10-07 19:54:04 +00:00
indup = strdup ( in ) ;
2008-08-11 20:43:19 +00:00
endof_indup = end_of_p ( indup ) + 1 ;
2006-10-07 19:54:04 +00:00
if ( ( data = malloc ( olen ) ) ) {
memset ( data , 0 , olen ) ;
c = data ;
2008-08-11 15:37:50 +00:00
for ( p = indup ; p & & p < endof_indup & & * p ; p + + ) {
2006-10-07 19:54:04 +00:00
vtype = 0 ;
2008-01-28 07:26:10 +00:00
2007-04-21 14:17:43 +00:00
if ( * p = = ' \\ ' ) {
if ( * ( p + 1 ) = = ' $ ' ) {
nv = 1 ;
2009-05-21 20:10:24 +00:00
p + + ;
2007-04-21 14:23:12 +00:00
} else if ( * ( p + 1 ) = = ' \\ ' ) {
* c + + = * p + + ;
len + + ;
continue ;
2007-04-21 14:17:43 +00:00
}
}
if ( * p = = ' $ ' & & ! nv ) {
2008-05-27 04:30:03 +00:00
if ( * ( p + 1 ) ) {
if ( * ( p + 1 ) = = ' { ' ) {
2007-10-18 21:36:57 +00:00
vtype = 1 ;
} else {
nv = 1 ;
2007-10-17 18:26:08 +00:00
}
} else {
nv = 1 ;
2007-03-29 22:31:56 +00:00
}
2006-10-07 19:54:04 +00:00
}
2006-12-07 00:36:00 +00:00
2007-04-21 14:17:43 +00:00
if ( nv ) {
* c + + = * p ;
len + + ;
nv = 0 ;
continue ;
}
2006-10-07 19:54:04 +00:00
if ( vtype ) {
char * s = p , * e , * vname , * vval = NULL ;
2006-10-08 04:37:03 +00:00
size_t nlen ;
2006-12-07 00:36:00 +00:00
2006-10-07 19:54:04 +00:00
s + + ;
2006-12-07 00:36:00 +00:00
2006-11-20 02:01:21 +00:00
if ( vtype = = 1 & & * s = = ' { ' ) {
2006-10-07 19:54:04 +00:00
br = 1 ;
s + + ;
}
e = s ;
vname = s ;
while ( * e ) {
if ( br = = 1 & & * e = = ' } ' ) {
br = 0 ;
* e + + = ' \0 ' ;
break ;
}
2007-11-07 02:14:57 +00:00
if ( br > 0 ) {
if ( e ! = s & & * e = = ' { ' ) {
br + + ;
} else if ( br > 1 & & * e = = ' } ' ) {
br - - ;
}
}
2008-01-28 07:26:10 +00:00
2006-10-07 19:54:04 +00:00
e + + ;
}
2008-08-11 15:37:50 +00:00
p = e > endof_indup ? endof_indup : e ;
2008-01-28 07:26:10 +00:00
2007-10-18 21:36:57 +00:00
if ( ( vval = strchr ( vname , ' ( ' ) ) ) {
e = vval - 1 ;
* vval + + = ' \0 ' ;
2008-05-27 04:30:03 +00:00
while ( * e = = ' ' ) {
2007-10-18 21:36:57 +00:00
* e - - = ' \0 ' ;
}
2007-11-08 23:46:26 +00:00
e = vval ;
br = 1 ;
2008-05-27 04:30:03 +00:00
while ( e & & * e ) {
2007-11-08 23:46:26 +00:00
if ( * e = = ' ( ' ) {
br + + ;
} else if ( br > 1 & & * e = = ' ) ' ) {
br - - ;
} else if ( br = = 1 & & * e = = ' ) ' ) {
* e = ' \0 ' ;
break ;
}
e + + ;
2007-10-18 21:36:57 +00:00
}
2007-11-08 23:46:26 +00:00
2007-10-18 21:36:57 +00:00
vtype = 2 ;
}
2007-03-29 22:31:56 +00:00
2006-10-07 19:54:04 +00:00
if ( vtype = = 1 ) {
2007-11-07 18:28:33 +00:00
char * expanded = NULL ;
2007-11-09 19:25:46 +00:00
int offset = 0 ;
int ooffset = 0 ;
2007-12-17 22:52:32 +00:00
char * ptr ;
2007-11-09 19:25:46 +00:00
2008-05-27 04:30:03 +00:00
if ( ( expanded = switch_channel_expand_variables ( channel , ( char * ) vname ) ) = = vname ) {
2007-11-07 18:28:33 +00:00
expanded = NULL ;
} else {
vname = expanded ;
}
2007-12-17 22:52:32 +00:00
if ( ( ptr = strchr ( vname , ' : ' ) ) ) {
* ptr + + = ' \0 ' ;
offset = atoi ( ptr ) ;
if ( ( ptr = strchr ( ptr , ' : ' ) ) ) {
ptr + + ;
ooffset = atoi ( ptr ) ;
2007-11-09 19:25:46 +00:00
}
}
2008-01-28 07:26:10 +00:00
2008-06-06 13:43:41 +00:00
if ( ( sub_val = ( char * ) switch_channel_get_variable ( channel , vname ) ) ) {
2008-03-12 15:17:18 +00:00
if ( offset | | ooffset ) {
cloned_sub_val = strdup ( sub_val ) ;
switch_assert ( cloned_sub_val ) ;
sub_val = cloned_sub_val ;
}
2007-11-09 19:25:46 +00:00
2008-03-12 15:17:18 +00:00
if ( offset > = 0 ) {
2008-06-10 22:55:38 +00:00
if ( ( size_t ) offset > strlen ( sub_val ) ) {
2008-06-06 13:43:41 +00:00
* sub_val = ' \0 ' ;
} else {
sub_val + = offset ;
}
2008-05-27 04:30:03 +00:00
} else if ( ( size_t ) abs ( offset ) < = strlen ( sub_val ) ) {
2008-03-12 15:17:18 +00:00
sub_val = cloned_sub_val + ( strlen ( cloned_sub_val ) + offset ) ;
}
2007-11-09 19:25:46 +00:00
2008-05-27 04:30:03 +00:00
if ( ooffset > 0 & & ( size_t ) ooffset < strlen ( sub_val ) ) {
if ( ( ptr = ( char * ) sub_val + ooffset ) ) {
2008-03-12 15:17:18 +00:00
* ptr = ' \0 ' ;
}
2007-11-09 19:25:46 +00:00
}
}
2007-11-07 18:28:33 +00:00
switch_safe_free ( expanded ) ;
2006-10-07 19:54:04 +00:00
} else {
2007-03-29 22:31:56 +00:00
switch_stream_handle_t stream = { 0 } ;
2007-11-07 18:28:33 +00:00
char * expanded = NULL ;
2006-10-07 19:54:04 +00:00
SWITCH_STANDARD_STREAM ( stream ) ;
2007-03-29 22:31:56 +00:00
2006-10-07 19:54:04 +00:00
if ( stream . data ) {
2007-11-07 18:34:56 +00:00
char * expanded_vname = NULL ;
2007-11-08 23:46:26 +00:00
2008-05-27 04:30:03 +00:00
if ( ( expanded_vname = switch_channel_expand_variables ( channel , ( char * ) vname ) ) = = vname ) {
2007-11-07 18:34:56 +00:00
expanded_vname = NULL ;
} else {
vname = expanded_vname ;
}
2007-11-07 02:14:57 +00:00
2007-11-07 00:00:51 +00:00
if ( ( expanded = switch_channel_expand_variables ( channel , vval ) ) = = vval ) {
expanded = NULL ;
} else {
vval = expanded ;
}
2006-10-07 19:54:04 +00:00
if ( switch_api_execute ( vname , vval , channel - > session , & stream ) = = SWITCH_STATUS_SUCCESS ) {
func_val = stream . data ;
sub_val = func_val ;
2007-11-07 01:33:31 +00:00
} else {
free ( stream . data ) ;
2006-10-07 19:54:04 +00:00
}
2008-01-28 07:26:10 +00:00
2007-11-07 00:00:51 +00:00
switch_safe_free ( expanded ) ;
2007-11-07 18:34:56 +00:00
switch_safe_free ( expanded_vname ) ;
2008-01-28 07:26:10 +00:00
2006-10-07 19:54:04 +00:00
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( channel ) , SWITCH_LOG_CRIT , " Memory Error! \n " ) ;
2006-10-07 19:54:04 +00:00
free ( data ) ;
free ( indup ) ;
2008-05-27 04:30:03 +00:00
return ( char * ) in ;
2006-10-07 19:54:04 +00:00
}
}
2006-11-26 20:06:04 +00:00
if ( ( nlen = sub_val ? strlen ( sub_val ) : 0 ) ) {
if ( len + nlen > = olen ) {
2007-03-29 22:31:56 +00:00
resize ( nlen ) ;
2006-11-26 20:06:04 +00:00
}
Ringback (sponsored by Front Logic)
This addition lets you set artifical ringback on a channel
that is waiting for an originated call to be answered.
the syntax is
<action application="set" data="ringback=[data]"/>
where data is either the full path to an audio file
or a teletone generation script..
syntax of teletone scripts
LEGEND:
0-9,a-d,*,# (standard dtmf tones)
variables: c,r,d,v,>,<,+,w,l,L,%
c (channels) - Sets the number of channels.
r (rate) - Sets the sample rate.
d (duration) - Sets the default tone duration.
v (volume) - Sets the default volume.
> (decrease vol) - factor to decrease volume by per frame (0 for even decrease across duration).
< (increase vol) - factor to increase volume by per frame (0 for even increase across duration).
+ (step) - factor to step by used by < and >.
w (wait) - default silence after each tone.
l (loops) - number of times to repeat each tone in the script.
L (LOOPS) - number of times to repeat the the whole script.
% (manual tone) - a generic tone specified by a duration, a wait and a list of frequencies.
standard tones can have custom duration per use with the () modifier
7(1000, 500) to generate DTMF 7 for 1 second then pause .5 seconds
EXAMPLES
UK Ring Tone [400+450 hz on for 400ms off for 200ms then 400+450 hz on for 400ms off for 2200ms]
%(400,200,400,450);%(400,2200,400,450)
US Ring Tone [440+480 hz on for 2000ms off for 4000ms]
%(2000,4000,440,480)
ATT BONG [volume level 4000, even decay, step by 2, # key for 60ms with no wait, volume level 2000, 350+440hz {us dialtone} for 940ms
v=4000;>=0;+=2;#(60,0);v=2000;%(940,0,350,440)
SIT Tone 913.8 hz for 274 ms with no wait, 1370.6 hz for 274 ms with no wait, 1776.7 hz for 380ms with no wait
%(274,0,913.8);%(274,0,1370.6);%(380,0,1776.7)
ATTN TONE (phone's off the hook!) 1400+2060+2450+2600 hz for 100ms with 100ms wait
%(100,100,1400,2060,2450,2600)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3408 d0543943-73ff-0310-b7d9-9358b9ac24b2
2006-11-19 01:05:06 +00:00
len + = nlen ;
strcat ( c , sub_val ) ;
c + = nlen ;
2006-10-07 19:54:04 +00:00
}
2007-03-29 22:31:56 +00:00
Ringback (sponsored by Front Logic)
This addition lets you set artifical ringback on a channel
that is waiting for an originated call to be answered.
the syntax is
<action application="set" data="ringback=[data]"/>
where data is either the full path to an audio file
or a teletone generation script..
syntax of teletone scripts
LEGEND:
0-9,a-d,*,# (standard dtmf tones)
variables: c,r,d,v,>,<,+,w,l,L,%
c (channels) - Sets the number of channels.
r (rate) - Sets the sample rate.
d (duration) - Sets the default tone duration.
v (volume) - Sets the default volume.
> (decrease vol) - factor to decrease volume by per frame (0 for even decrease across duration).
< (increase vol) - factor to increase volume by per frame (0 for even increase across duration).
+ (step) - factor to step by used by < and >.
w (wait) - default silence after each tone.
l (loops) - number of times to repeat each tone in the script.
L (LOOPS) - number of times to repeat the the whole script.
% (manual tone) - a generic tone specified by a duration, a wait and a list of frequencies.
standard tones can have custom duration per use with the () modifier
7(1000, 500) to generate DTMF 7 for 1 second then pause .5 seconds
EXAMPLES
UK Ring Tone [400+450 hz on for 400ms off for 200ms then 400+450 hz on for 400ms off for 2200ms]
%(400,200,400,450);%(400,2200,400,450)
US Ring Tone [440+480 hz on for 2000ms off for 4000ms]
%(2000,4000,440,480)
ATT BONG [volume level 4000, even decay, step by 2, # key for 60ms with no wait, volume level 2000, 350+440hz {us dialtone} for 940ms
v=4000;>=0;+=2;#(60,0);v=2000;%(940,0,350,440)
SIT Tone 913.8 hz for 274 ms with no wait, 1370.6 hz for 274 ms with no wait, 1776.7 hz for 380ms with no wait
%(274,0,913.8);%(274,0,1370.6);%(380,0,1776.7)
ATTN TONE (phone's off the hook!) 1400+2060+2450+2600 hz for 100ms with 100ms wait
%(100,100,1400,2060,2450,2600)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3408 d0543943-73ff-0310-b7d9-9358b9ac24b2
2006-11-19 01:05:06 +00:00
switch_safe_free ( func_val ) ;
2007-11-09 19:25:46 +00:00
switch_safe_free ( cloned_sub_val ) ;
2007-03-29 22:31:56 +00:00
sub_val = NULL ;
vname = NULL ;
vtype = 0 ;
2007-11-09 19:25:46 +00:00
br = 0 ;
2007-03-29 22:31:56 +00:00
}
if ( len + 1 > = olen ) {
resize ( 1 ) ;
2006-10-07 19:54:04 +00:00
}
2006-12-07 00:36:00 +00:00
2006-10-07 19:54:04 +00:00
if ( sp ) {
* c + + = ' ' ;
sp = 0 ;
Ringback (sponsored by Front Logic)
This addition lets you set artifical ringback on a channel
that is waiting for an originated call to be answered.
the syntax is
<action application="set" data="ringback=[data]"/>
where data is either the full path to an audio file
or a teletone generation script..
syntax of teletone scripts
LEGEND:
0-9,a-d,*,# (standard dtmf tones)
variables: c,r,d,v,>,<,+,w,l,L,%
c (channels) - Sets the number of channels.
r (rate) - Sets the sample rate.
d (duration) - Sets the default tone duration.
v (volume) - Sets the default volume.
> (decrease vol) - factor to decrease volume by per frame (0 for even decrease across duration).
< (increase vol) - factor to increase volume by per frame (0 for even increase across duration).
+ (step) - factor to step by used by < and >.
w (wait) - default silence after each tone.
l (loops) - number of times to repeat each tone in the script.
L (LOOPS) - number of times to repeat the the whole script.
% (manual tone) - a generic tone specified by a duration, a wait and a list of frequencies.
standard tones can have custom duration per use with the () modifier
7(1000, 500) to generate DTMF 7 for 1 second then pause .5 seconds
EXAMPLES
UK Ring Tone [400+450 hz on for 400ms off for 200ms then 400+450 hz on for 400ms off for 2200ms]
%(400,200,400,450);%(400,2200,400,450)
US Ring Tone [440+480 hz on for 2000ms off for 4000ms]
%(2000,4000,440,480)
ATT BONG [volume level 4000, even decay, step by 2, # key for 60ms with no wait, volume level 2000, 350+440hz {us dialtone} for 940ms
v=4000;>=0;+=2;#(60,0);v=2000;%(940,0,350,440)
SIT Tone 913.8 hz for 274 ms with no wait, 1370.6 hz for 274 ms with no wait, 1776.7 hz for 380ms with no wait
%(274,0,913.8);%(274,0,1370.6);%(380,0,1776.7)
ATTN TONE (phone's off the hook!) 1400+2060+2450+2600 hz for 100ms with 100ms wait
%(100,100,1400,2060,2450,2600)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3408 d0543943-73ff-0310-b7d9-9358b9ac24b2
2006-11-19 01:05:06 +00:00
len + + ;
2006-10-07 19:54:04 +00:00
}
Ringback (sponsored by Front Logic)
This addition lets you set artifical ringback on a channel
that is waiting for an originated call to be answered.
the syntax is
<action application="set" data="ringback=[data]"/>
where data is either the full path to an audio file
or a teletone generation script..
syntax of teletone scripts
LEGEND:
0-9,a-d,*,# (standard dtmf tones)
variables: c,r,d,v,>,<,+,w,l,L,%
c (channels) - Sets the number of channels.
r (rate) - Sets the sample rate.
d (duration) - Sets the default tone duration.
v (volume) - Sets the default volume.
> (decrease vol) - factor to decrease volume by per frame (0 for even decrease across duration).
< (increase vol) - factor to increase volume by per frame (0 for even increase across duration).
+ (step) - factor to step by used by < and >.
w (wait) - default silence after each tone.
l (loops) - number of times to repeat each tone in the script.
L (LOOPS) - number of times to repeat the the whole script.
% (manual tone) - a generic tone specified by a duration, a wait and a list of frequencies.
standard tones can have custom duration per use with the () modifier
7(1000, 500) to generate DTMF 7 for 1 second then pause .5 seconds
EXAMPLES
UK Ring Tone [400+450 hz on for 400ms off for 200ms then 400+450 hz on for 400ms off for 2200ms]
%(400,200,400,450);%(400,2200,400,450)
US Ring Tone [440+480 hz on for 2000ms off for 4000ms]
%(2000,4000,440,480)
ATT BONG [volume level 4000, even decay, step by 2, # key for 60ms with no wait, volume level 2000, 350+440hz {us dialtone} for 940ms
v=4000;>=0;+=2;#(60,0);v=2000;%(940,0,350,440)
SIT Tone 913.8 hz for 274 ms with no wait, 1370.6 hz for 274 ms with no wait, 1776.7 hz for 380ms with no wait
%(274,0,913.8);%(274,0,1370.6);%(380,0,1776.7)
ATTN TONE (phone's off the hook!) 1400+2060+2450+2600 hz for 100ms with 100ms wait
%(100,100,1400,2060,2450,2600)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3408 d0543943-73ff-0310-b7d9-9358b9ac24b2
2006-11-19 01:05:06 +00:00
2006-12-06 17:19:07 +00:00
if ( * p = = ' $ ' ) {
Ringback (sponsored by Front Logic)
This addition lets you set artifical ringback on a channel
that is waiting for an originated call to be answered.
the syntax is
<action application="set" data="ringback=[data]"/>
where data is either the full path to an audio file
or a teletone generation script..
syntax of teletone scripts
LEGEND:
0-9,a-d,*,# (standard dtmf tones)
variables: c,r,d,v,>,<,+,w,l,L,%
c (channels) - Sets the number of channels.
r (rate) - Sets the sample rate.
d (duration) - Sets the default tone duration.
v (volume) - Sets the default volume.
> (decrease vol) - factor to decrease volume by per frame (0 for even decrease across duration).
< (increase vol) - factor to increase volume by per frame (0 for even increase across duration).
+ (step) - factor to step by used by < and >.
w (wait) - default silence after each tone.
l (loops) - number of times to repeat each tone in the script.
L (LOOPS) - number of times to repeat the the whole script.
% (manual tone) - a generic tone specified by a duration, a wait and a list of frequencies.
standard tones can have custom duration per use with the () modifier
7(1000, 500) to generate DTMF 7 for 1 second then pause .5 seconds
EXAMPLES
UK Ring Tone [400+450 hz on for 400ms off for 200ms then 400+450 hz on for 400ms off for 2200ms]
%(400,200,400,450);%(400,2200,400,450)
US Ring Tone [440+480 hz on for 2000ms off for 4000ms]
%(2000,4000,440,480)
ATT BONG [volume level 4000, even decay, step by 2, # key for 60ms with no wait, volume level 2000, 350+440hz {us dialtone} for 940ms
v=4000;>=0;+=2;#(60,0);v=2000;%(940,0,350,440)
SIT Tone 913.8 hz for 274 ms with no wait, 1370.6 hz for 274 ms with no wait, 1776.7 hz for 380ms with no wait
%(274,0,913.8);%(274,0,1370.6);%(380,0,1776.7)
ATTN TONE (phone's off the hook!) 1400+2060+2450+2600 hz for 100ms with 100ms wait
%(100,100,1400,2060,2450,2600)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3408 d0543943-73ff-0310-b7d9-9358b9ac24b2
2006-11-19 01:05:06 +00:00
p - - ;
} else {
* c + + = * p ;
len + + ;
2007-03-29 22:31:56 +00:00
}
2006-10-07 19:54:04 +00:00
}
}
free ( indup ) ;
2008-01-28 07:26:10 +00:00
2006-10-07 19:54:04 +00:00
return data ;
}
2006-11-27 22:30:48 +00:00
2007-11-17 00:26:28 +00:00
SWITCH_DECLARE ( char * ) switch_channel_build_param_string ( switch_channel_t * channel , switch_caller_profile_t * caller_profile , const char * prefix )
2007-11-16 19:11:16 +00:00
{
switch_stream_handle_t stream = { 0 } ;
switch_size_t encode_len = 1024 , new_len = 0 ;
char * encode_buf = NULL ;
2008-05-27 04:30:03 +00:00
const char * prof [ 12 ] = { 0 } , * prof_names [ 12 ] = {
0 } ;
2007-11-16 19:11:16 +00:00
char * e = NULL ;
switch_event_header_t * hi ;
uint32_t x = 0 ;
SWITCH_STANDARD_STREAM ( stream ) ;
2007-11-17 00:26:28 +00:00
if ( prefix ) {
stream . write_function ( & stream , " %s& " , prefix ) ;
}
2007-11-16 19:11:16 +00:00
encode_buf = malloc ( encode_len ) ;
2007-12-11 19:23:57 +00:00
switch_assert ( encode_buf ) ;
2007-11-16 19:11:16 +00:00
if ( ! caller_profile ) {
caller_profile = switch_channel_get_caller_profile ( channel ) ;
}
2007-12-11 19:23:57 +00:00
switch_assert ( caller_profile ! = NULL ) ;
2008-01-28 07:26:10 +00:00
2007-11-16 19:11:16 +00:00
prof [ 0 ] = caller_profile - > context ;
prof [ 1 ] = caller_profile - > destination_number ;
prof [ 2 ] = caller_profile - > caller_id_name ;
prof [ 3 ] = caller_profile - > caller_id_number ;
prof [ 4 ] = caller_profile - > network_addr ;
prof [ 5 ] = caller_profile - > ani ;
prof [ 6 ] = caller_profile - > aniii ;
prof [ 7 ] = caller_profile - > rdnis ;
prof [ 8 ] = caller_profile - > source ;
prof [ 9 ] = caller_profile - > chan_name ;
prof [ 10 ] = caller_profile - > uuid ;
2008-01-28 07:26:10 +00:00
2007-11-16 19:11:16 +00:00
prof_names [ 0 ] = " context " ;
prof_names [ 1 ] = " destination_number " ;
prof_names [ 2 ] = " caller_id_name " ;
prof_names [ 3 ] = " caller_id_number " ;
prof_names [ 4 ] = " network_addr " ;
prof_names [ 5 ] = " ani " ;
prof_names [ 6 ] = " aniii " ;
prof_names [ 7 ] = " rdnis " ;
prof_names [ 8 ] = " source " ;
prof_names [ 9 ] = " chan_name " ;
prof_names [ 10 ] = " uuid " ;
for ( x = 0 ; prof [ x ] ; x + + ) {
2009-10-23 16:03:42 +00:00
if ( zstr ( prof [ x ] ) ) {
2007-11-16 19:11:16 +00:00
continue ;
}
new_len = ( strlen ( prof [ x ] ) * 3 ) + 1 ;
if ( encode_len < new_len ) {
char * tmp ;
encode_len = new_len ;
if ( ! ( tmp = realloc ( encode_buf , encode_len ) ) ) {
abort ( ) ;
}
encode_buf = tmp ;
}
2008-05-21 21:31:17 +00:00
switch_url_encode ( prof [ x ] , encode_buf , encode_len ) ;
2007-11-16 19:11:16 +00:00
stream . write_function ( & stream , " %s=%s& " , prof_names [ x ] , encode_buf ) ;
}
if ( ( hi = switch_channel_variable_first ( channel ) ) ) {
for ( ; hi ; hi = hi - > next ) {
char * var = hi - > name ;
char * val = hi - > value ;
2008-01-28 07:26:10 +00:00
2007-11-16 19:11:16 +00:00
new_len = ( strlen ( ( char * ) var ) * 3 ) + 1 ;
if ( encode_len < new_len ) {
char * tmp ;
2008-01-28 07:26:10 +00:00
2007-11-16 19:11:16 +00:00
encode_len = new_len ;
2008-01-28 07:26:10 +00:00
2007-11-16 19:11:16 +00:00
tmp = realloc ( encode_buf , encode_len ) ;
2007-12-11 19:23:57 +00:00
switch_assert ( tmp ) ;
2007-11-16 19:11:16 +00:00
encode_buf = tmp ;
}
2008-05-21 21:31:17 +00:00
switch_url_encode ( ( char * ) val , encode_buf , encode_len ) ;
2007-11-16 19:11:16 +00:00
stream . write_function ( & stream , " %s=%s& " , ( char * ) var , encode_buf ) ;
}
switch_channel_variable_last ( channel ) ;
}
e = ( char * ) stream . data + ( strlen ( ( char * ) stream . data ) - 1 ) ;
if ( e & & * e = = ' & ' ) {
* e = ' \0 ' ;
}
switch_safe_free ( encode_buf ) ;
return stream . data ;
}
2009-10-21 18:48:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_channel_pass_callee_id ( switch_channel_t * channel , switch_channel_t * other_channel )
{
int x = 0 ;
switch_assert ( channel ) ;
switch_assert ( other_channel ) ;
switch_mutex_lock ( channel - > profile_mutex ) ;
switch_mutex_lock ( other_channel - > profile_mutex ) ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( channel - > caller_profile - > callee_id_name ) ) {
2009-10-21 18:48:28 +00:00
other_channel - > caller_profile - > callee_id_name = switch_core_strdup ( channel - > caller_profile - > pool , channel - > caller_profile - > callee_id_name ) ;
x + + ;
}
2009-10-23 16:03:42 +00:00
if ( ! zstr ( channel - > caller_profile - > callee_id_number ) ) {
2009-10-21 18:48:28 +00:00
other_channel - > caller_profile - > callee_id_number = switch_core_strdup ( channel - > caller_profile - > pool , channel - > caller_profile - > callee_id_number ) ;
x + + ;
}
switch_mutex_unlock ( other_channel - > profile_mutex ) ;
switch_mutex_unlock ( channel - > profile_mutex ) ;
return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE ;
}
2008-07-17 19:46:25 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_channel_get_variables ( switch_channel_t * channel , switch_event_t * * event )
{
switch_status_t status ;
switch_mutex_lock ( channel - > profile_mutex ) ;
status = switch_event_dup ( event , channel - > variables ) ;
2008-11-03 15:45:38 +00:00
switch_mutex_unlock ( channel - > profile_mutex ) ;
2008-07-17 19:46:25 +00:00
return status ;
}
2007-12-20 18:04:07 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_channel_set_timestamps ( switch_channel_t * channel )
{
switch_status_t status = SWITCH_STATUS_SUCCESS ;
const char * cid_buf = NULL ;
switch_caller_profile_t * caller_profile , * ocp ;
switch_app_log_t * app_log , * ap ;
char * last_app = NULL , * last_arg = NULL ;
2008-05-24 01:43:12 +00:00
char start [ 80 ] = " " , answer [ 80 ] = " " , progress [ 80 ] = " " , progress_media [ 80 ] = " " , end [ 80 ] = " " , tmp [ 80 ] = " " , profile_start [ 80 ] = " " ;
2008-05-24 03:24:12 +00:00
int32_t duration = 0 , legbillsec = 0 , billsec = 0 , mduration = 0 , billmsec = 0 , legbillmsec = 0 , progressmsec = 0 , progress_mediamsec = 0 ;
2009-08-24 17:12:36 +00:00
int32_t answersec = 0 , answermsec = 0 ;
switch_time_t answerusec = 0 ;
2008-05-24 03:24:12 +00:00
switch_time_t uduration = 0 , legbillusec = 0 , billusec = 0 , progresssec = 0 , progressusec = 0 , progress_mediasec = 0 , progress_mediausec = 0 ;
2008-05-27 04:30:03 +00:00
time_t tt_created = 0 , tt_answered = 0 , tt_progress = 0 , tt_progress_media = 0 , tt_hungup = 0 , mtt_created = 0 , mtt_answered = 0 , mtt_hungup =
0 , tt_prof_created , mtt_prof_created , mtt_progress = 0 , mtt_progress_media = 0 ;
2009-02-23 16:31:59 +00:00
void * pop ;
char dtstr [ SWITCH_DTMF_LOG_LEN + 1 ] = " " ;
int x = 0 ;
2007-12-20 18:04:07 +00:00
2009-05-12 14:54:34 +00:00
if ( switch_channel_test_flag ( channel , CF_TIMESTAMP_SET ) ) {
return SWITCH_STATUS_FALSE ;
}
switch_channel_set_flag ( channel , CF_TIMESTAMP_SET ) ;
2008-03-14 20:08:58 +00:00
if ( ! ( caller_profile = switch_channel_get_caller_profile ( channel ) ) | | ! channel - > variables ) {
2008-03-11 21:32:56 +00:00
return SWITCH_STATUS_FALSE ;
}
2007-12-20 18:04:07 +00:00
2008-03-14 20:08:58 +00:00
if ( ( app_log = switch_core_session_get_app_log ( channel - > session ) ) ) {
for ( ap = app_log ; ap & & ap - > next ; ap = ap - > next ) ;
last_app = ap - > app ;
last_arg = ap - > arg ;
}
2008-05-27 04:30:03 +00:00
2007-12-20 18:04:07 +00:00
if ( ! ( ocp = switch_channel_get_originatee_caller_profile ( channel ) ) ) {
ocp = switch_channel_get_originator_caller_profile ( channel ) ;
}
2009-10-23 16:03:42 +00:00
if ( ! zstr ( caller_profile - > caller_id_name ) ) {
2008-05-27 04:30:03 +00:00
cid_buf = switch_core_session_sprintf ( channel - > session , " \" %s \" <%s> " , caller_profile - > caller_id_name ,
2008-03-11 21:32:56 +00:00
switch_str_nil ( caller_profile - > caller_id_number ) ) ;
2007-12-20 18:04:07 +00:00
} else {
cid_buf = caller_profile - > caller_id_number ;
}
2009-02-23 16:31:59 +00:00
while ( x < SWITCH_DTMF_LOG_LEN & & switch_queue_trypop ( channel - > dtmf_log_queue , & pop ) = = SWITCH_STATUS_SUCCESS ) {
switch_dtmf_t * dt = ( switch_dtmf_t * ) pop ;
if ( dt ) {
dtstr [ x + + ] = dt - > digit ;
free ( dt ) ;
dt = NULL ;
}
}
if ( x ) {
switch_channel_set_variable ( channel , " digits_dialed " , dtstr ) ;
} else {
switch_channel_set_variable ( channel , " digits_dialed " , " none " ) ;
}
2007-12-20 18:04:07 +00:00
if ( caller_profile - > times ) {
switch_time_exp_t tm ;
switch_size_t retsize ;
const char * fmt = " %Y-%m-%d %T " ;
switch_time_exp_lt ( & tm , caller_profile - > times - > created ) ;
2008-10-12 21:51:51 +00:00
switch_strftime_nocheck ( start , & retsize , sizeof ( start ) , fmt , & tm ) ;
2007-12-20 18:04:07 +00:00
switch_channel_set_variable ( channel , " start_stamp " , start ) ;
switch_time_exp_lt ( & tm , caller_profile - > times - > profile_created ) ;
2008-10-12 21:51:51 +00:00
switch_strftime_nocheck ( profile_start , & retsize , sizeof ( profile_start ) , fmt , & tm ) ;
2007-12-20 18:04:07 +00:00
switch_channel_set_variable ( channel , " profile_start_stamp " , profile_start ) ;
2008-02-26 21:55:59 +00:00
if ( caller_profile - > times - > answered ) {
switch_time_exp_lt ( & tm , caller_profile - > times - > answered ) ;
2008-10-12 21:51:51 +00:00
switch_strftime_nocheck ( answer , & retsize , sizeof ( answer ) , fmt , & tm ) ;
2008-02-26 21:55:59 +00:00
switch_channel_set_variable ( channel , " answer_stamp " , answer ) ;
}
2007-12-20 18:04:07 +00:00
2008-05-24 01:43:12 +00:00
if ( caller_profile - > times - > progress ) {
switch_time_exp_lt ( & tm , caller_profile - > times - > progress ) ;
2008-10-12 21:51:51 +00:00
switch_strftime_nocheck ( progress , & retsize , sizeof ( progress ) , fmt , & tm ) ;
2008-05-24 01:43:12 +00:00
switch_channel_set_variable ( channel , " progress_stamp " , progress ) ;
}
if ( caller_profile - > times - > progress_media ) {
switch_time_exp_lt ( & tm , caller_profile - > times - > progress_media ) ;
2008-10-12 21:51:51 +00:00
switch_strftime_nocheck ( progress_media , & retsize , sizeof ( progress_media ) , fmt , & tm ) ;
2008-05-24 01:43:12 +00:00
switch_channel_set_variable ( channel , " progress_media_stamp " , progress_media ) ;
}
2007-12-20 18:04:07 +00:00
switch_time_exp_lt ( & tm , caller_profile - > times - > hungup ) ;
2008-10-12 21:51:51 +00:00
switch_strftime_nocheck ( end , & retsize , sizeof ( end ) , fmt , & tm ) ;
2007-12-20 18:04:07 +00:00
switch_channel_set_variable ( channel , " end_stamp " , end ) ;
tt_created = ( time_t ) ( caller_profile - > times - > created / 1000000 ) ;
mtt_created = ( time_t ) ( caller_profile - > times - > created / 1000 ) ;
tt_prof_created = ( time_t ) ( caller_profile - > times - > profile_created / 1000000 ) ;
mtt_prof_created = ( time_t ) ( caller_profile - > times - > profile_created / 1000 ) ;
switch_snprintf ( tmp , sizeof ( tmp ) , " % " TIME_T_FMT , tt_created ) ;
switch_channel_set_variable ( channel , " start_epoch " , tmp ) ;
switch_snprintf ( tmp , sizeof ( tmp ) , " % " SWITCH_TIME_T_FMT , caller_profile - > times - > created ) ;
switch_channel_set_variable ( channel , " start_uepoch " , tmp ) ;
switch_snprintf ( tmp , sizeof ( tmp ) , " % " TIME_T_FMT , tt_prof_created ) ;
switch_channel_set_variable ( channel , " profile_start_epoch " , tmp ) ;
switch_snprintf ( tmp , sizeof ( tmp ) , " % " SWITCH_TIME_T_FMT , caller_profile - > times - > profile_created ) ;
switch_channel_set_variable ( channel , " profile_start_uepoch " , tmp ) ;
2008-01-28 07:26:10 +00:00
2007-12-20 18:04:07 +00:00
tt_answered = ( time_t ) ( caller_profile - > times - > answered / 1000000 ) ;
mtt_answered = ( time_t ) ( caller_profile - > times - > answered / 1000 ) ;
switch_snprintf ( tmp , sizeof ( tmp ) , " % " TIME_T_FMT , tt_answered ) ;
switch_channel_set_variable ( channel , " answer_epoch " , tmp ) ;
switch_snprintf ( tmp , sizeof ( tmp ) , " % " SWITCH_TIME_T_FMT , caller_profile - > times - > answered ) ;
2008-05-27 04:30:03 +00:00
switch_channel_set_variable ( channel , " answer_uepoch " , tmp ) ;
2007-12-20 18:04:07 +00:00
2008-05-24 01:43:12 +00:00
tt_progress = ( time_t ) ( caller_profile - > times - > progress / 1000000 ) ;
mtt_progress = ( time_t ) ( caller_profile - > times - > progress / 1000 ) ;
switch_snprintf ( tmp , sizeof ( tmp ) , " % " TIME_T_FMT , tt_progress ) ;
2009-01-14 13:36:32 +00:00
switch_channel_set_variable ( channel , " progress_epoch " , tmp ) ;
2008-05-24 01:43:12 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " % " SWITCH_TIME_T_FMT , caller_profile - > times - > progress ) ;
2009-01-14 13:36:32 +00:00
switch_channel_set_variable ( channel , " progress_uepoch " , tmp ) ;
2008-05-24 01:43:12 +00:00
tt_progress_media = ( time_t ) ( caller_profile - > times - > progress_media / 1000000 ) ;
mtt_progress_media = ( time_t ) ( caller_profile - > times - > progress_media / 1000 ) ;
switch_snprintf ( tmp , sizeof ( tmp ) , " % " TIME_T_FMT , tt_progress_media ) ;
2009-01-14 13:36:32 +00:00
switch_channel_set_variable ( channel , " progress_media_epoch " , tmp ) ;
2008-05-24 01:43:12 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " % " SWITCH_TIME_T_FMT , caller_profile - > times - > progress_media ) ;
2009-01-14 13:36:32 +00:00
switch_channel_set_variable ( channel , " progress_media_uepoch " , tmp ) ;
2008-05-24 01:43:12 +00:00
2007-12-20 18:04:07 +00:00
tt_hungup = ( time_t ) ( caller_profile - > times - > hungup / 1000000 ) ;
mtt_hungup = ( time_t ) ( caller_profile - > times - > hungup / 1000 ) ;
switch_snprintf ( tmp , sizeof ( tmp ) , " % " TIME_T_FMT , tt_hungup ) ;
switch_channel_set_variable ( channel , " end_epoch " , tmp ) ;
switch_snprintf ( tmp , sizeof ( tmp ) , " % " SWITCH_TIME_T_FMT , caller_profile - > times - > hungup ) ;
switch_channel_set_variable ( channel , " end_uepoch " , tmp ) ;
uduration = caller_profile - > times - > hungup - caller_profile - > times - > created ;
2008-05-27 04:30:03 +00:00
duration = ( int32_t ) ( tt_hungup - tt_created ) ;
mduration = ( int32_t ) ( mtt_hungup - mtt_created ) ;
2008-01-28 07:26:10 +00:00
2007-12-20 18:04:07 +00:00
if ( caller_profile - > times - > answered ) {
2008-05-27 04:30:03 +00:00
billsec = ( int32_t ) ( tt_hungup - tt_answered ) ;
billmsec = ( int32_t ) ( mtt_hungup - mtt_answered ) ;
2007-12-20 18:04:07 +00:00
billusec = caller_profile - > times - > hungup - caller_profile - > times - > answered ;
2008-05-27 04:30:03 +00:00
legbillsec = ( int32_t ) ( tt_hungup - tt_prof_created ) ;
legbillmsec = ( int32_t ) ( mtt_hungup - mtt_prof_created ) ;
2007-12-20 18:04:07 +00:00
legbillusec = caller_profile - > times - > hungup - caller_profile - > times - > profile_created ;
2009-08-24 17:12:36 +00:00
answersec = ( int32_t ) ( tt_answered - tt_prof_created ) ;
answermsec = ( int32_t ) ( mtt_answered - mtt_prof_created ) ;
answerusec = caller_profile - > times - > answered - caller_profile - > times - > profile_created ;
2007-12-20 18:04:07 +00:00
}
2008-05-24 03:24:12 +00:00
if ( caller_profile - > times - > progress ) {
2008-05-27 04:30:03 +00:00
progresssec = ( int32_t ) ( tt_progress - tt_created ) ;
progressmsec = ( int32_t ) ( mtt_progress - mtt_created ) ;
2008-05-24 03:24:12 +00:00
progressusec = caller_profile - > times - > progress - caller_profile - > times - > created ;
}
if ( caller_profile - > times - > progress_media ) {
2009-02-12 20:10:51 +00:00
progress_mediasec = ( int32_t ) ( tt_progress_media - tt_created ) ;
progress_mediamsec = ( int32_t ) ( mtt_progress_media - mtt_created ) ;
progress_mediausec = caller_profile - > times - > progress_media - caller_profile - > times - > created ;
2008-05-24 03:24:12 +00:00
}
2007-12-20 18:04:07 +00:00
}
2008-01-27 17:36:53 +00:00
2007-12-20 18:04:07 +00:00
switch_channel_set_variable ( channel , " last_app " , last_app ) ;
switch_channel_set_variable ( channel , " last_arg " , last_arg ) ;
switch_channel_set_variable ( channel , " caller_id " , cid_buf ) ;
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , duration ) ;
switch_channel_set_variable ( channel , " duration " , tmp ) ;
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , billsec ) ;
switch_channel_set_variable ( channel , " billsec " , tmp ) ;
2008-09-05 16:16:36 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " % " SWITCH_TIME_T_FMT , progresssec ) ;
2008-05-24 03:24:12 +00:00
switch_channel_set_variable ( channel , " progresssec " , tmp ) ;
2009-08-24 17:12:36 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " % " SWITCH_TIME_T_FMT , answersec ) ;
switch_channel_set_variable ( channel , " answersec " , tmp ) ;
2008-09-05 16:16:36 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " % " SWITCH_TIME_T_FMT , progress_mediasec ) ;
2008-05-24 03:24:12 +00:00
switch_channel_set_variable ( channel , " progress_mediasec " , tmp ) ;
2007-12-20 18:04:07 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , legbillsec ) ;
switch_channel_set_variable ( channel , " flow_billsec " , tmp ) ;
2008-01-28 07:26:10 +00:00
2007-12-20 18:04:07 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , mduration ) ;
switch_channel_set_variable ( channel , " mduration " , tmp ) ;
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , billmsec ) ;
switch_channel_set_variable ( channel , " billmsec " , tmp ) ;
2008-05-24 03:24:12 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , progressmsec ) ;
switch_channel_set_variable ( channel , " progressmsec " , tmp ) ;
2009-08-24 17:12:36 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , answermsec ) ;
switch_channel_set_variable ( channel , " answermsec " , tmp ) ;
2008-12-05 19:14:51 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , progressmsec ) ;
2008-05-24 03:24:12 +00:00
switch_channel_set_variable ( channel , " progress_mediamsec " , tmp ) ;
2007-12-20 18:04:07 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , legbillmsec ) ;
switch_channel_set_variable ( channel , " flow_billmsec " , tmp ) ;
switch_snprintf ( tmp , sizeof ( tmp ) , " % " SWITCH_TIME_T_FMT , uduration ) ;
switch_channel_set_variable ( channel , " uduration " , tmp ) ;
switch_snprintf ( tmp , sizeof ( tmp ) , " % " SWITCH_TIME_T_FMT , billusec ) ;
switch_channel_set_variable ( channel , " billusec " , tmp ) ;
2008-05-24 03:24:12 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " % " SWITCH_TIME_T_FMT , progressusec ) ;
switch_channel_set_variable ( channel , " progressusec " , tmp ) ;
2009-08-24 17:12:36 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " % " SWITCH_TIME_T_FMT , answerusec ) ;
switch_channel_set_variable ( channel , " answerusec " , tmp ) ;
2008-05-24 03:24:12 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " % " SWITCH_TIME_T_FMT , progress_mediausec ) ;
switch_channel_set_variable ( channel , " progress_mediausec " , tmp ) ;
2007-12-20 18:04:07 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " % " SWITCH_TIME_T_FMT , legbillusec ) ;
switch_channel_set_variable ( channel , " flow_billusec " , tmp ) ;
2009-05-11 16:52:01 +00:00
2007-12-20 18:04:07 +00:00
return status ;
}
2007-11-16 19:11:16 +00:00
2006-11-27 22:30:48 +00:00
/* For Emacs:
* Local Variables :
* mode : c
2008-02-03 22:14:57 +00:00
* indent - tabs - mode : t
2006-11-27 22:30:48 +00:00
* tab - width : 4
* c - basic - offset : 4
* End :
* For VIM :
2008-07-03 19:12:26 +00:00
* vim : set softtabstop = 4 shiftwidth = 4 tabstop = 4 :
2006-11-27 22:30:48 +00:00
*/