2006-02-22 17:16:47 +00:00
/*
2006-01-03 22:13:59 +00:00
* FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
* Copyright ( C ) 2005 / 2006 , Anthony Minessale II < anthmct @ yahoo . com >
*
* Version : MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 ( the " License " ) ; you may not use this file except in compliance with
* the License . You may obtain a copy of the License at
* http : //www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an " AS IS " basis ,
* WITHOUT WARRANTY OF ANY KIND , either express or implied . See the License
* for the specific language governing rights and limitations under the
* License .
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
*
* The Initial Developer of the Original Code is
* Anthony Minessale II < anthmct @ yahoo . com >
* Portions created by the Initial Developer are Copyright ( C )
* the Initial Developer . All Rights Reserved .
*
* Contributor ( s ) :
*
* Anthony Minessale II < anthmct @ yahoo . com >
*
*
2006-01-13 14:23:34 +00:00
* mod_wanpipe . c - - WANPIPE PRI Channel Module
2006-01-03 22:13:59 +00:00
*
*/
2006-02-22 16:47:07 +00:00
2006-01-03 22:13:59 +00:00
# include <switch.h>
# include <libsangoma.h>
# include <sangoma_pri.h>
2006-02-22 16:47:07 +00:00
# include <libteletone.h>
2006-12-04 20:51:16 +00:00
# ifndef INVALID_HANDLE_VALUE
# define INVALID_HANDLE_VALUE -1
# endif
2006-03-17 14:47:41 +00:00
//#define DOTRACE
2006-01-13 14:23:34 +00:00
static const char modname [ ] = " mod_wanpipe " ;
2006-01-03 22:13:59 +00:00
# define STRLEN 15
2006-04-29 06:58:08 +00:00
static switch_memory_pool_t * module_pool = NULL ;
2006-01-03 22:13:59 +00:00
typedef enum {
PFLAG_ANSWER = ( 1 < < 0 ) ,
PFLAG_HANGUP = ( 1 < < 1 ) ,
} PFLAGS ;
typedef enum {
PPFLAG_RING = ( 1 < < 0 ) ,
} PPFLAGS ;
typedef enum {
TFLAG_MEDIA = ( 1 < < 0 ) ,
TFLAG_INBOUND = ( 1 < < 1 ) ,
TFLAG_OUTBOUND = ( 1 < < 2 ) ,
TFLAG_INCOMING = ( 1 < < 3 ) ,
TFLAG_PARSE_INCOMING = ( 1 < < 4 ) ,
TFLAG_ACTIVATE = ( 1 < < 5 ) ,
TFLAG_DTMF = ( 1 < < 6 ) ,
TFLAG_DESTROY = ( 1 < < 7 ) ,
TFLAG_ABORT = ( 1 < < 8 ) ,
TFLAG_SWITCH = ( 1 < < 9 ) ,
2006-03-26 17:42:06 +00:00
TFLAG_NOSIG = ( 1 < < 10 ) ,
TFLAG_BYE = ( 1 < < 11 )
2006-01-03 22:13:59 +00:00
} TFLAGS ;
2006-02-24 19:11:49 +00:00
2007-02-09 20:03:07 +00:00
# define DEFAULT_SAMPLES_PER_FRAME 160
2006-01-03 22:13:59 +00:00
static struct {
int debug ;
int panic ;
2007-02-09 20:03:07 +00:00
uint32_t samples_per_frame ;
2006-02-22 18:32:15 +00:00
int dtmf_on ;
int dtmf_off ;
2006-02-23 22:41:08 +00:00
int supress_dtmf_tone ;
2006-02-24 16:47:22 +00:00
int configured_spans ;
2006-02-12 20:38:24 +00:00
char * dialplan ;
2006-09-24 15:25:36 +00:00
switch_hash_t * call_hash ;
switch_mutex_t * hash_mutex ;
2007-02-09 01:34:01 +00:00
switch_mutex_t * channel_mutex ;
2006-02-12 20:38:24 +00:00
} globals ;
struct wanpipe_pri_span {
2006-01-03 22:13:59 +00:00
int span ;
int dchan ;
2006-02-12 20:38:24 +00:00
unsigned int bchans ;
2006-01-03 22:13:59 +00:00
int node ;
int pswitch ;
char * dialplan ;
2006-02-12 20:38:24 +00:00
unsigned int l1 ;
unsigned int dp ;
struct sangoma_pri spri ;
} ;
2006-01-03 22:13:59 +00:00
2006-09-24 15:25:36 +00:00
struct wpsock {
2006-12-04 20:51:16 +00:00
sng_fd_t fd ;
2006-09-24 15:25:36 +00:00
char * name ;
struct private_object * tech_pvt ;
} ;
typedef struct wpsock wpsock_t ;
2006-02-12 20:38:24 +00:00
# define MAX_SPANS 128
static struct wanpipe_pri_span * SPANS [ MAX_SPANS ] ;
2006-01-03 22:13:59 +00:00
struct private_object {
2006-01-20 15:05:05 +00:00
unsigned int flags ; /* FLAGS */
2006-04-29 06:58:08 +00:00
switch_frame_t read_frame ; /* Frame for Writing */
switch_core_session_t * session ;
switch_codec_t read_codec ;
switch_codec_t write_codec ;
2006-01-14 16:44:52 +00:00
unsigned char databuf [ SWITCH_RECCOMMENDED_BUFFER_SIZE ] ;
2006-01-03 22:13:59 +00:00
struct sangoma_pri * spri ;
sangoma_api_hdr_t hdrframe ;
2006-04-29 06:58:08 +00:00
switch_caller_profile_t * caller_profile ;
2006-09-24 15:25:36 +00:00
wpsock_t * wpsock ;
2006-01-03 22:13:59 +00:00
int callno ;
2006-02-22 18:32:15 +00:00
int span ;
2006-01-03 22:13:59 +00:00
int cause ;
2006-02-10 22:26:00 +00:00
q931_call * call ;
2006-02-22 18:32:15 +00:00
teletone_dtmf_detect_state_t dtmf_detect ;
2006-02-22 16:47:07 +00:00
teletone_generation_session_t tone_session ;
2006-04-29 06:58:08 +00:00
switch_buffer_t * dtmf_buffer ;
2006-03-17 14:47:41 +00:00
unsigned int skip_read_frames ;
unsigned int skip_write_frames ;
2006-06-23 16:59:47 +00:00
switch_mutex_t * flag_mutex ;
2007-02-09 20:03:07 +00:00
int frame_size ;
2006-03-17 14:47:41 +00:00
# ifdef DOTRACE
int fd ;
int fd2 ;
# endif
2006-01-03 22:13:59 +00:00
} ;
2007-02-09 01:34:01 +00:00
typedef struct private_object private_object_t ;
2006-01-03 22:13:59 +00:00
struct channel_map {
2007-02-09 01:34:01 +00:00
char map [ SANGOMA_MAX_CHAN_PER_SPAN ] [ SWITCH_UUID_FORMATTED_LENGTH + 1 ] ;
2006-01-03 22:13:59 +00:00
} ;
2007-02-09 01:34:01 +00:00
static int wp_close ( private_object_t * tech_pvt )
2006-09-24 15:25:36 +00:00
{
int ret = 0 ;
switch_mutex_lock ( globals . hash_mutex ) ;
if ( tech_pvt - > wpsock & & tech_pvt - > wpsock - > tech_pvt = = tech_pvt ) {
tech_pvt - > wpsock - > tech_pvt = NULL ;
ret = 1 ;
}
switch_mutex_unlock ( globals . hash_mutex ) ;
return ret ;
}
2007-02-09 01:34:01 +00:00
static int wp_open ( private_object_t * tech_pvt , int span , int chan )
2006-09-24 15:25:36 +00:00
{
2006-12-04 20:51:16 +00:00
sng_fd_t fd ;
2006-09-24 15:25:36 +00:00
wpsock_t * sock ;
char name [ 25 ] ;
snprintf ( name , sizeof ( name ) , " s%dc%d " , span , chan ) ;
switch_mutex_lock ( globals . hash_mutex ) ;
if ( ( sock = switch_core_hash_find ( globals . call_hash , name ) ) ) {
fd = sock - > fd ;
} else {
2006-12-04 20:51:16 +00:00
if ( ( fd = sangoma_open_tdmapi_span_chan ( span , chan ) ) ! = INVALID_HANDLE_VALUE ) {
2006-09-24 15:25:36 +00:00
if ( ( sock = malloc ( sizeof ( * sock ) ) ) ) {
memset ( sock , 0 , sizeof ( * sock ) ) ;
sock - > fd = fd ;
sock - > name = strdup ( name ) ;
switch_core_hash_insert ( globals . call_hash , sock - > name , sock ) ;
}
}
}
if ( sock ) {
if ( sock - > tech_pvt ) {
if ( tech_pvt - > session ) {
switch_channel_t * channel = switch_core_session_get_channel ( tech_pvt - > session ) ;
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
}
}
sock - > tech_pvt = tech_pvt ;
tech_pvt - > wpsock = sock ;
}
switch_mutex_unlock ( globals . hash_mutex ) ;
return sock ? 1 : 0 ;
}
static int wp_restart ( int span , int chan )
{
wpsock_t * sock ;
2006-12-04 20:51:16 +00:00
sng_fd_t fd ;
2006-09-24 15:25:36 +00:00
char name [ 25 ] ;
snprintf ( name , sizeof ( name ) , " s%dc%d " , span , chan ) ;
switch_mutex_lock ( globals . hash_mutex ) ;
if ( ( sock = switch_core_hash_find ( globals . call_hash , name ) ) ) {
switch_core_hash_delete ( globals . call_hash , sock - > name ) ;
fd = sock - > fd ;
} else {
fd = sangoma_open_tdmapi_span_chan ( span , chan ) ;
}
switch_mutex_unlock ( globals . hash_mutex ) ;
2006-12-04 20:51:16 +00:00
if ( fd ! = INVALID_HANDLE_VALUE ) {
sangoma_socket_close ( & fd ) ;
2006-09-24 15:25:36 +00:00
return 0 ;
}
return - 1 ;
}
2006-01-03 22:13:59 +00:00
static void set_global_dialplan ( char * dialplan )
{
if ( globals . dialplan ) {
free ( globals . dialplan ) ;
globals . dialplan = NULL ;
}
2006-01-20 15:05:05 +00:00
2006-01-03 22:13:59 +00:00
globals . dialplan = strdup ( dialplan ) ;
}
static int str2node ( char * node )
{
if ( ! strcasecmp ( node , " cpe " ) )
return PRI_CPE ;
if ( ! strcasecmp ( node , " network " ) )
return PRI_NETWORK ;
return - 1 ;
}
static int str2switch ( char * swtype )
{
2007-02-09 21:32:12 +00:00
if ( ! strcasecmp ( swtype , " ni1 " ) )
return PRI_SWITCH_NI1 ;
2006-01-03 22:13:59 +00:00
if ( ! strcasecmp ( swtype , " ni2 " ) )
return PRI_SWITCH_NI2 ;
if ( ! strcasecmp ( swtype , " dms100 " ) )
return PRI_SWITCH_DMS100 ;
if ( ! strcasecmp ( swtype , " lucent5e " ) )
return PRI_SWITCH_LUCENT5E ;
if ( ! strcasecmp ( swtype , " att4ess " ) )
return PRI_SWITCH_ATT4ESS ;
if ( ! strcasecmp ( swtype , " euroisdn " ) )
return PRI_SWITCH_EUROISDN_E1 ;
if ( ! strcasecmp ( swtype , " gr303eoc " ) )
return PRI_SWITCH_GR303_EOC ;
if ( ! strcasecmp ( swtype , " gr303tmc " ) )
return PRI_SWITCH_GR303_TMC ;
return - 1 ;
}
2006-02-12 20:38:24 +00:00
static int str2l1 ( char * l1 )
{
if ( ! strcasecmp ( l1 , " alaw " ) )
return PRI_LAYER_1_ALAW ;
return PRI_LAYER_1_ULAW ;
}
static int str2dp ( char * dp )
{
if ( ! strcasecmp ( dp , " international " ) )
return PRI_INTERNATIONAL_ISDN ;
if ( ! strcasecmp ( dp , " national " ) )
return PRI_NATIONAL_ISDN ;
if ( ! strcasecmp ( dp , " local " ) )
return PRI_LOCAL_ISDN ;
if ( ! strcasecmp ( dp , " private " ) )
return PRI_PRIVATE ;
if ( ! strcasecmp ( dp , " unknown " ) )
return PRI_UNKNOWN ;
return PRI_UNKNOWN ;
}
2006-03-30 23:02:50 +00:00
2006-01-03 22:13:59 +00:00
static void set_global_dialplan ( char * dialplan ) ;
static int str2node ( char * node ) ;
static int str2switch ( char * swtype ) ;
2006-05-01 04:29:44 +00:00
static switch_status_t wanpipe_on_init ( switch_core_session_t * session ) ;
static switch_status_t wanpipe_on_hangup ( switch_core_session_t * session ) ;
static switch_status_t wanpipe_on_loopback ( switch_core_session_t * session ) ;
static switch_status_t wanpipe_on_transmit ( switch_core_session_t * session ) ;
2007-02-09 20:03:07 +00:00
static switch_call_cause_t wanpipe_outgoing_channel ( switch_core_session_t * session , switch_caller_profile_t * outbound_profile ,
switch_core_session_t * * new_session , switch_memory_pool_t * pool ) ;
2006-05-01 04:29:44 +00:00
static switch_status_t wanpipe_read_frame ( switch_core_session_t * session , switch_frame_t * * frame , int timeout ,
switch_io_flag_t flags , int stream_id ) ;
static switch_status_t wanpipe_write_frame ( switch_core_session_t * session , switch_frame_t * frame , int timeout ,
switch_io_flag_t flags , int stream_id ) ;
2006-12-04 20:51:16 +00:00
static int on_info ( struct sangoma_pri * spri , sangoma_pri_event_t event_type , pri_event * pevent ) ;
static int on_hangup ( struct sangoma_pri * spri , sangoma_pri_event_t event_type , pri_event * pevent ) ;
static int on_ring ( struct sangoma_pri * spri , sangoma_pri_event_t event_type , pri_event * pevent ) ;
2006-01-03 22:13:59 +00:00
static int check_flags ( struct sangoma_pri * spri ) ;
2006-12-04 20:51:16 +00:00
static int on_restart ( struct sangoma_pri * spri , sangoma_pri_event_t event_type , pri_event * pevent ) ;
static int on_anything ( struct sangoma_pri * spri , sangoma_pri_event_t event_type , pri_event * pevent ) ;
static void * SWITCH_THREAD_FUNC pri_thread_run ( switch_thread_t * thread , void * obj ) ;
2006-05-01 04:29:44 +00:00
static switch_status_t config_wanpipe ( int reload ) ;
2006-01-03 22:13:59 +00:00
/*
State methods they get called when the state changes to the specific state
returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next
so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it .
*/
2006-05-01 04:29:44 +00:00
static switch_status_t wanpipe_on_init ( switch_core_session_t * session )
2006-01-03 22:13:59 +00:00
{
2007-02-09 01:34:01 +00:00
private_object_t * tech_pvt ;
2006-04-29 06:58:08 +00:00
switch_channel_t * channel = NULL ;
2006-09-21 01:14:30 +00:00
wanpipe_tdm_api_t tdm_api = { { 0 } } ;
2006-02-10 22:26:00 +00:00
int err = 0 ;
unsigned int rate = 8000 ;
2007-02-09 20:03:07 +00:00
2006-01-03 22:13:59 +00:00
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
2006-02-10 22:26:00 +00:00
tech_pvt - > read_frame . data = tech_pvt - > databuf ;
2006-01-20 15:05:05 +00:00
2006-09-24 15:25:36 +00:00
err = sangoma_tdm_set_codec ( tech_pvt - > wpsock - > fd , & tdm_api , WP_SLINEAR ) ;
2006-03-18 04:04:59 +00:00
2007-02-09 20:03:07 +00:00
sangoma_tdm_set_usr_period ( tech_pvt - > wpsock - > fd , & tdm_api , globals . samples_per_frame / 8 ) ;
tech_pvt - > frame_size = sangoma_tdm_get_usr_mtu_mru ( tech_pvt - > wpsock - > fd , & tdm_api ) ;
2006-02-10 22:26:00 +00:00
if ( switch_core_codec_init
2007-02-09 20:03:07 +00:00
( & tech_pvt - > read_codec , " L16 " , NULL , rate , globals . samples_per_frame / 8 , 1 , SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , NULL ,
2006-02-10 22:26:00 +00:00
switch_core_session_get_pool ( session ) ) ! = SWITCH_STATUS_SUCCESS ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " %s Cannot set read codec \n " , switch_channel_get_name ( channel ) ) ;
2006-04-22 03:05:25 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2006-02-10 22:26:00 +00:00
return SWITCH_STATUS_FALSE ;
}
if ( switch_core_codec_init
2007-02-09 20:03:07 +00:00
( & tech_pvt - > write_codec , " L16 " , NULL , rate , globals . samples_per_frame / 8 , 1 , SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , NULL ,
2006-02-10 22:26:00 +00:00
switch_core_session_get_pool ( session ) ) ! = SWITCH_STATUS_SUCCESS ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " %s Cannot set read codec \n " , switch_channel_get_name ( channel ) ) ;
2006-04-22 03:05:25 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2006-02-10 22:26:00 +00:00
return SWITCH_STATUS_FALSE ;
}
tech_pvt - > read_frame . rate = rate ;
tech_pvt - > read_frame . codec = & tech_pvt - > read_codec ;
switch_core_session_set_read_codec ( session , & tech_pvt - > read_codec ) ;
switch_core_session_set_write_codec ( session , & tech_pvt - > write_codec ) ;
2006-01-20 15:05:05 +00:00
2006-03-17 14:47:41 +00:00
# ifdef DOTRACE
tech_pvt - > fd = open ( " /tmp/wp-in.raw " , O_WRONLY | O_TRUNC | O_CREAT ) ;
tech_pvt - > fd2 = open ( " /tmp/wp-out.raw " , O_WRONLY | O_TRUNC | O_CREAT ) ;
# endif
2006-02-22 18:32:15 +00:00
/* Setup artificial DTMF stuff */
memset ( & tech_pvt - > tone_session , 0 , sizeof ( tech_pvt - > tone_session ) ) ;
2006-02-22 16:47:07 +00:00
teletone_init_session ( & tech_pvt - > tone_session , 1024 , NULL , NULL ) ;
2006-02-22 18:32:15 +00:00
if ( globals . debug ) {
2006-02-22 16:47:07 +00:00
tech_pvt - > tone_session . debug = globals . debug ;
tech_pvt - > tone_session . debug_stream = stdout ;
}
tech_pvt - > tone_session . rate = rate ;
2006-02-22 18:32:15 +00:00
tech_pvt - > tone_session . duration = globals . dtmf_on * ( tech_pvt - > tone_session . rate / 1000 ) ;
tech_pvt - > tone_session . wait = globals . dtmf_off * ( tech_pvt - > tone_session . rate / 1000 ) ;
2006-02-22 16:47:07 +00:00
2006-02-22 18:32:15 +00:00
teletone_dtmf_detect_init ( & tech_pvt - > dtmf_detect , rate ) ;
2006-03-18 04:04:59 +00:00
if ( switch_test_flag ( tech_pvt , TFLAG_NOSIG ) ) {
2007-02-09 01:34:01 +00:00
switch_channel_mark_answered ( channel ) ;
2006-03-18 04:04:59 +00:00
}
2006-02-22 16:47:07 +00:00
2006-01-03 22:13:59 +00:00
/* Move Channel's State Machine to RING */
switch_channel_set_state ( channel , CS_RING ) ;
return SWITCH_STATUS_SUCCESS ;
}
2006-05-01 04:29:44 +00:00
static switch_status_t wanpipe_on_ring ( switch_core_session_t * session )
2006-01-03 22:13:59 +00:00
{
2006-04-29 06:58:08 +00:00
switch_channel_t * channel = NULL ;
2007-02-09 01:34:01 +00:00
private_object_t * tech_pvt = NULL ;
2006-01-03 22:13:59 +00:00
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " WANPIPE RING \n " ) ;
2006-01-03 22:13:59 +00:00
2006-02-10 22:26:00 +00:00
2006-01-03 22:13:59 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-05-01 04:29:44 +00:00
static switch_status_t wanpipe_on_hangup ( switch_core_session_t * session )
2006-01-03 22:13:59 +00:00
{
2007-02-09 01:34:01 +00:00
private_object_t * tech_pvt ;
2006-04-29 06:58:08 +00:00
switch_channel_t * channel = NULL ;
2006-03-17 14:47:41 +00:00
struct channel_map * chanmap = NULL ;
2006-02-10 22:26:00 +00:00
2006-01-03 22:13:59 +00:00
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
2006-06-23 16:59:47 +00:00
switch_set_flag_locked ( tech_pvt , TFLAG_BYE ) ;
2006-03-17 14:47:41 +00:00
if ( ! switch_test_flag ( tech_pvt , TFLAG_NOSIG ) ) {
chanmap = tech_pvt - > spri - > private_info ;
}
2006-01-20 15:05:05 +00:00
2006-09-24 15:25:36 +00:00
//sangoma_socket_close(&tech_pvt->wpsock->fd);
wp_close ( tech_pvt ) ;
2006-02-10 22:26:00 +00:00
switch_core_codec_destroy ( & tech_pvt - > read_codec ) ;
switch_core_codec_destroy ( & tech_pvt - > write_codec ) ;
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " WANPIPE HANGUP \n " ) ;
2006-02-10 22:26:00 +00:00
2006-03-17 14:47:41 +00:00
if ( ! switch_test_flag ( tech_pvt , TFLAG_NOSIG ) ) {
2007-02-09 20:03:07 +00:00
pri_hangup ( tech_pvt - > spri - > pri , tech_pvt - > call , switch_channel_get_cause ( channel ) ) ;
2006-03-17 14:47:41 +00:00
pri_destroycall ( tech_pvt - > spri - > pri , tech_pvt - > call ) ;
2006-02-10 22:26:00 +00:00
2007-02-09 20:03:07 +00:00
switch_mutex_lock ( globals . channel_mutex ) ;
2006-03-17 14:47:41 +00:00
if ( chanmap - > map [ tech_pvt - > callno ] ) {
2007-02-09 01:34:01 +00:00
chanmap - > map [ tech_pvt - > callno ] [ 0 ] = ' \0 ' ;
2006-03-17 14:47:41 +00:00
}
2007-02-09 20:03:07 +00:00
switch_mutex_unlock ( globals . channel_mutex ) ;
2006-03-17 14:47:41 +00:00
/*
pri_hangup ( tech_pvt - > spri - > pri ,
tech_pvt - > hangup_event . hangup . call ? tech_pvt - > hangup_event . hangup . call : tech_pvt - > ring_event . ring . call ,
tech_pvt - > cause ) ;
pri_destroycall ( tech_pvt - > spri - > pri ,
tech_pvt - > hangup_event . hangup . call ? tech_pvt - > hangup_event . hangup . call : tech_pvt - > ring_event . ring . call ) ;
*/
2006-02-10 22:26:00 +00:00
}
2006-02-22 16:47:07 +00:00
teletone_destroy_session ( & tech_pvt - > tone_session ) ;
2006-09-08 18:57:24 +00:00
switch_buffer_destroy ( & tech_pvt - > dtmf_buffer ) ;
2006-01-03 22:13:59 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-05-01 04:29:44 +00:00
static switch_status_t wanpipe_on_loopback ( switch_core_session_t * session )
2006-01-03 22:13:59 +00:00
{
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " WANPIPE LOOPBACK \n " ) ;
2006-01-03 22:13:59 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-05-01 04:29:44 +00:00
static switch_status_t wanpipe_on_transmit ( switch_core_session_t * session )
2006-01-03 22:13:59 +00:00
{
2007-02-09 01:34:01 +00:00
private_object_t * tech_pvt ;
2006-04-29 06:58:08 +00:00
switch_channel_t * channel ;
2006-03-18 04:04:59 +00:00
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " WANPIPE TRANSMIT \n " ) ;
2006-01-03 22:13:59 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-05-01 04:29:44 +00:00
static switch_status_t wanpipe_answer_channel ( switch_core_session_t * session )
2006-01-03 22:13:59 +00:00
{
2007-02-09 01:34:01 +00:00
private_object_t * tech_pvt ;
2006-04-29 06:58:08 +00:00
switch_channel_t * channel = NULL ;
2006-01-20 15:05:05 +00:00
2006-01-03 22:13:59 +00:00
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
2006-03-17 14:47:41 +00:00
if ( switch_test_flag ( tech_pvt , TFLAG_INBOUND ) & & ! switch_test_flag ( tech_pvt , TFLAG_NOSIG ) ) {
2006-02-10 22:26:00 +00:00
pri_answer ( tech_pvt - > spri - > pri , tech_pvt - > call , 0 , 1 ) ;
}
2006-01-03 22:13:59 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-05-01 04:29:44 +00:00
static switch_status_t wanpipe_read_frame ( switch_core_session_t * session , switch_frame_t * * frame , int timeout ,
switch_io_flag_t flags , int stream_id )
2006-01-03 22:13:59 +00:00
{
2007-02-09 01:34:01 +00:00
private_object_t * tech_pvt ;
2006-04-29 06:58:08 +00:00
switch_channel_t * channel = NULL ;
2006-03-30 23:02:50 +00:00
uint8_t * bp ;
2006-12-04 20:51:16 +00:00
uint32_t bytes = 0 ;
2007-02-09 20:03:07 +00:00
int bread = 0 ;
2006-02-22 18:32:15 +00:00
char digit_str [ 80 ] ;
2006-01-03 22:13:59 +00:00
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
2006-01-20 15:05:05 +00:00
2006-09-24 15:25:36 +00:00
if ( switch_test_flag ( tech_pvt , TFLAG_BYE ) | | tech_pvt - > wpsock - > fd < 0 ) {
2006-02-10 22:26:00 +00:00
return SWITCH_STATUS_GENERR ;
}
2006-01-03 22:13:59 +00:00
bp = tech_pvt - > databuf ;
* frame = NULL ;
memset ( tech_pvt - > databuf , 0 , sizeof ( tech_pvt - > databuf ) ) ;
2007-02-09 20:03:07 +00:00
while ( bytes < globals . samples_per_frame * 2 ) {
2006-09-24 15:25:36 +00:00
if ( switch_test_flag ( tech_pvt , TFLAG_BYE ) | | tech_pvt - > wpsock - > fd < 0 ) {
2006-03-26 17:42:06 +00:00
return SWITCH_STATUS_GENERR ;
}
2006-04-20 23:57:04 +00:00
2006-09-24 15:25:36 +00:00
if ( sangoma_socket_waitfor ( tech_pvt - > wpsock - > fd , 1000 , POLLIN | POLLERR | POLLHUP ) < = 0 ) {
2006-01-03 22:13:59 +00:00
return SWITCH_STATUS_GENERR ;
}
2007-02-09 20:03:07 +00:00
if ( ( bread = sangoma_readmsg_socket ( tech_pvt - > wpsock - > fd ,
2006-01-03 22:13:59 +00:00
& tech_pvt - > hdrframe ,
2006-01-20 15:05:05 +00:00
sizeof ( tech_pvt - > hdrframe ) , bp , sizeof ( tech_pvt - > databuf ) - bytes , 0 ) ) < 0 ) {
2006-01-03 22:13:59 +00:00
if ( errno = = EBUSY ) {
continue ;
} else {
return SWITCH_STATUS_GENERR ;
}
2006-03-17 14:47:41 +00:00
2006-01-03 22:13:59 +00:00
}
2007-02-09 20:03:07 +00:00
bytes + = bread ;
2006-01-03 22:13:59 +00:00
bp + = bytes ;
}
2006-03-26 17:42:06 +00:00
2006-09-24 15:25:36 +00:00
if ( ! bytes | | switch_test_flag ( tech_pvt , TFLAG_BYE ) | | tech_pvt - > wpsock - > fd < 0 ) {
2006-03-26 17:42:06 +00:00
return SWITCH_STATUS_GENERR ;
}
2006-02-10 22:26:00 +00:00
tech_pvt - > read_frame . datalen = bytes ;
2006-02-22 18:32:15 +00:00
tech_pvt - > read_frame . samples = bytes / 2 ;
2007-02-09 20:03:07 +00:00
teletone_dtmf_detect ( & tech_pvt - > dtmf_detect , tech_pvt - > read_frame . data , tech_pvt - > read_frame . samples ) ;
teletone_dtmf_get ( & tech_pvt - > dtmf_detect , digit_str , sizeof ( digit_str ) ) ;
2006-02-22 18:32:15 +00:00
if ( digit_str [ 0 ] ) {
switch_channel_queue_dtmf ( channel , digit_str ) ;
if ( globals . debug ) {
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " DTMF DETECTED: [%s] \n " , digit_str ) ;
2006-02-22 18:32:15 +00:00
}
2006-02-23 22:41:08 +00:00
if ( globals . supress_dtmf_tone ) {
memset ( tech_pvt - > read_frame . data , 0 , tech_pvt - > read_frame . datalen ) ;
}
2006-02-22 18:32:15 +00:00
}
2006-01-20 15:05:05 +00:00
2006-03-18 04:04:59 +00:00
if ( tech_pvt - > skip_read_frames > 0 ) {
memset ( tech_pvt - > read_frame . data , 0 , tech_pvt - > read_frame . datalen ) ;
2006-03-17 14:47:41 +00:00
tech_pvt - > skip_read_frames - - ;
}
# ifdef DOTRACE
write ( tech_pvt - > fd2 , tech_pvt - > read_frame . data , ( int ) tech_pvt - > read_frame . datalen ) ;
# endif
//printf("read %d\n", tech_pvt->read_frame.datalen);
2006-02-10 22:26:00 +00:00
* frame = & tech_pvt - > read_frame ;
2006-01-03 22:13:59 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-05-01 04:29:44 +00:00
static switch_status_t wanpipe_write_frame ( switch_core_session_t * session , switch_frame_t * frame , int timeout ,
switch_io_flag_t flags , int stream_id )
2006-01-03 22:13:59 +00:00
{
2007-02-09 01:34:01 +00:00
private_object_t * tech_pvt ;
2006-04-29 06:58:08 +00:00
switch_channel_t * channel = NULL ;
2006-12-04 20:51:16 +00:00
uint32_t result = 0 ;
uint32_t bytes = frame - > datalen ;
2006-03-30 23:02:50 +00:00
uint8_t * bp = frame - > data ;
2006-02-22 18:32:15 +00:00
unsigned char dtmf [ 1024 ] ;
2006-12-04 20:51:16 +00:00
uint32_t bwrote = 0 ;
size_t bread ;
2006-05-01 04:29:44 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2006-01-03 22:13:59 +00:00
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
2006-03-17 14:47:41 +00:00
2006-03-30 23:02:50 +00:00
while ( tech_pvt - > dtmf_buffer & & bwrote < frame - > datalen & & bytes > 0 & & switch_buffer_inuse ( tech_pvt - > dtmf_buffer ) > 0 ) {
2006-09-24 15:25:36 +00:00
if ( switch_test_flag ( tech_pvt , TFLAG_BYE ) | | tech_pvt - > wpsock - > fd < 0 ) {
2006-03-26 17:42:06 +00:00
return SWITCH_STATUS_GENERR ;
}
2007-02-09 20:03:07 +00:00
if ( ( bread = switch_buffer_read ( tech_pvt - > dtmf_buffer , dtmf , tech_pvt - > frame_size ) ) < tech_pvt - > frame_size ) {
while ( bread < tech_pvt - > frame_size ) {
2006-02-22 18:32:15 +00:00
dtmf [ bread + + ] = 0 ;
}
}
2006-03-26 17:42:06 +00:00
2006-09-24 15:25:36 +00:00
if ( sangoma_socket_waitfor ( tech_pvt - > wpsock - > fd , 1000 , POLLOUT | POLLERR | POLLHUP ) < = 0 ) {
2006-04-20 23:57:04 +00:00
return SWITCH_STATUS_GENERR ;
}
2006-03-17 14:47:41 +00:00
# ifdef DOTRACE
write ( tech_pvt - > fd , dtmf , ( int ) bread ) ;
# endif
2006-09-24 15:25:36 +00:00
result = sangoma_sendmsg_socket ( tech_pvt - > wpsock - > fd ,
2006-12-04 20:51:16 +00:00
& tech_pvt - > hdrframe , sizeof ( tech_pvt - > hdrframe ) , dtmf , ( unsigned short ) bread , 0 ) ;
2006-03-30 23:02:50 +00:00
if ( result < 0 ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR ,
2006-02-22 18:32:15 +00:00
" Bad Write %d bytes returned %d (%s)! \n " , bread ,
2006-03-30 23:02:50 +00:00
result , strerror ( errno ) ) ;
2006-02-22 18:32:15 +00:00
if ( errno = = EBUSY ) {
continue ;
}
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Write Failed! \n " ) ;
2006-02-22 18:32:15 +00:00
status = SWITCH_STATUS_GENERR ;
break ;
} else {
2006-03-30 23:02:50 +00:00
bytes - = result ;
bwrote + = result ;
bp + = result ;
result = 0 ;
2006-02-22 18:32:15 +00:00
}
}
2006-09-24 15:25:36 +00:00
if ( switch_test_flag ( tech_pvt , TFLAG_BYE ) | | tech_pvt - > wpsock - > fd < 0 ) {
2006-03-26 17:42:06 +00:00
return SWITCH_STATUS_GENERR ;
}
2006-03-17 14:47:41 +00:00
if ( tech_pvt - > skip_write_frames ) {
tech_pvt - > skip_write_frames - - ;
return SWITCH_STATUS_SUCCESS ;
}
2006-01-03 22:13:59 +00:00
while ( bytes > 0 ) {
2006-12-04 20:51:16 +00:00
uint32_t towrite ;
2006-04-20 23:57:04 +00:00
2006-06-08 19:22:54 +00:00
# if 1
2006-09-24 15:25:36 +00:00
if ( sangoma_socket_waitfor ( tech_pvt - > wpsock - > fd , 1000 , POLLOUT | POLLERR | POLLHUP ) < = 0 ) {
2006-03-26 17:42:06 +00:00
return SWITCH_STATUS_GENERR ;
}
2006-04-20 23:57:04 +00:00
# endif
2006-03-26 17:42:06 +00:00
2006-03-17 14:47:41 +00:00
# ifdef DOTRACE
2007-02-09 20:03:07 +00:00
write ( tech_pvt - > fd , bp , ( int ) tech_pvt - > frame_size ) ;
2006-03-17 14:47:41 +00:00
# endif
2007-02-09 20:03:07 +00:00
towrite = bytes > = tech_pvt - > frame_size ? tech_pvt - > frame_size : bytes ;
2006-03-18 04:04:59 +00:00
2007-02-09 20:03:07 +00:00
if ( towrite < tech_pvt - > frame_size ) {
int diff = tech_pvt - > frame_size - towrite ;
2006-06-06 23:49:02 +00:00
memset ( bp + towrite , 0 , diff ) ;
2007-02-09 20:03:07 +00:00
towrite = tech_pvt - > frame_size ;
2006-06-06 23:49:02 +00:00
}
2006-09-24 15:25:36 +00:00
result = sangoma_sendmsg_socket ( tech_pvt - > wpsock - > fd ,
2006-12-04 20:51:16 +00:00
& tech_pvt - > hdrframe , sizeof ( tech_pvt - > hdrframe ) , bp , ( unsigned short ) towrite , 0 ) ;
2006-03-30 23:02:50 +00:00
if ( result < 0 ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR ,
2006-06-06 23:49:02 +00:00
" Bad Write frame len %u write %d bytes returned %d (%s)! \n " , towrite ,
2007-02-09 20:03:07 +00:00
tech_pvt - > frame_size , result , strerror ( errno ) ) ;
2006-01-03 22:13:59 +00:00
if ( errno = = EBUSY ) {
continue ;
}
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Write Failed! \n " ) ;
2006-01-03 22:13:59 +00:00
status = SWITCH_STATUS_GENERR ;
break ;
} else {
2006-03-30 23:02:50 +00:00
bytes - = result ;
bp + = result ;
result = 0 ;
2006-01-03 22:13:59 +00:00
}
}
2006-03-18 04:04:59 +00:00
//printf("write %d %d\n", frame->datalen, status);
2006-01-03 22:13:59 +00:00
return status ;
}
2006-05-01 04:29:44 +00:00
static switch_status_t wanpipe_send_dtmf ( switch_core_session_t * session , char * digits )
2006-02-22 16:47:07 +00:00
{
2007-02-09 01:34:01 +00:00
private_object_t * tech_pvt ;
2006-04-29 06:58:08 +00:00
switch_channel_t * channel = NULL ;
2006-05-01 04:29:44 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2006-02-22 16:47:07 +00:00
int wrote = 0 ;
char * cur = NULL ;
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
if ( ! tech_pvt - > dtmf_buffer ) {
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Allocate DTMF Buffer.... " ) ;
2006-09-08 18:57:24 +00:00
if ( switch_buffer_create_dynamic ( & tech_pvt - > dtmf_buffer , 1024 , 3192 , 0 ) ! = SWITCH_STATUS_SUCCESS ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG_CLEAN , SWITCH_LOG_ERROR , " Failed to allocate DTMF Buffer! \n " ) ;
2006-02-22 16:47:07 +00:00
return SWITCH_STATUS_FALSE ;
} else {
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG_CLEAN , SWITCH_LOG_DEBUG , " SUCCESS! \n " ) ;
2006-02-22 16:47:07 +00:00
}
}
for ( cur = digits ; * cur ; cur + + ) {
if ( ( wrote = teletone_mux_tones ( & tech_pvt - > tone_session , & tech_pvt - > tone_session . TONES [ ( int ) * cur ] ) ) ) {
switch_buffer_write ( tech_pvt - > dtmf_buffer , tech_pvt - > tone_session . buffer , wrote * 2 ) ;
}
}
2006-03-17 14:47:41 +00:00
tech_pvt - > skip_read_frames = 200 ;
2006-02-22 16:47:07 +00:00
return status ;
}
2006-05-01 04:29:44 +00:00
static switch_status_t wanpipe_receive_message ( switch_core_session_t * session , switch_core_session_message_t * msg )
2006-02-22 16:47:07 +00:00
{
2007-02-09 01:34:01 +00:00
switch_channel_t * channel ;
private_object_t * tech_pvt ;
switch_status_t status ;
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
tech_pvt = ( private_object_t * ) switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
switch ( msg - > message_id ) {
case SWITCH_MESSAGE_INDICATE_NOMEDIA :
break ;
case SWITCH_MESSAGE_INDICATE_MEDIA :
break ;
case SWITCH_MESSAGE_INDICATE_HOLD :
break ;
case SWITCH_MESSAGE_INDICATE_UNHOLD :
break ;
case SWITCH_MESSAGE_INDICATE_BRIDGE :
break ;
case SWITCH_MESSAGE_INDICATE_UNBRIDGE :
break ;
case SWITCH_MESSAGE_INDICATE_REDIRECT :
break ;
case SWITCH_MESSAGE_INDICATE_PROGRESS :
break ;
case SWITCH_MESSAGE_INDICATE_RINGING :
break ;
}
return SWITCH_STATUS_SUCCESS ;
2006-02-22 16:47:07 +00:00
}
2006-05-01 04:29:44 +00:00
static switch_status_t wanpipe_kill_channel ( switch_core_session_t * session , int sig )
2006-02-22 16:47:07 +00:00
{
2007-02-09 01:34:01 +00:00
private_object_t * tech_pvt ;
2006-04-29 06:58:08 +00:00
switch_channel_t * channel = NULL ;
2006-02-22 16:47:07 +00:00
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
2006-12-21 16:46:11 +00:00
switch ( sig ) {
case SWITCH_SIG_KILL :
switch_mutex_lock ( tech_pvt - > flag_mutex ) ;
switch_set_flag ( tech_pvt , TFLAG_BYE ) ;
switch_clear_flag ( tech_pvt , TFLAG_MEDIA ) ;
switch_mutex_unlock ( tech_pvt - > flag_mutex ) ;
break ;
default :
break ;
}
2006-09-24 15:25:36 +00:00
//sangoma_socket_close(&tech_pvt->wpsock->fd);
//wp_close(tech_pvt);
2006-02-22 16:47:07 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-05-01 04:29:44 +00:00
static const switch_io_routines_t wanpipe_io_routines = {
2006-01-20 15:05:05 +00:00
/*.outgoing_channel */ wanpipe_outgoing_channel ,
2006-02-10 22:26:00 +00:00
/*.answer_channel */ wanpipe_answer_channel ,
/*.read_frame */ wanpipe_read_frame ,
2006-02-22 16:47:07 +00:00
/*.write_frame */ wanpipe_write_frame ,
/*.kill_channel */ wanpipe_kill_channel ,
/*.waitfor_read */ NULL ,
/*.waitfor_read */ NULL ,
/*.send_dtmf*/ wanpipe_send_dtmf ,
/*.receive_message*/ wanpipe_receive_message
2006-01-03 22:13:59 +00:00
} ;
2006-04-29 06:58:08 +00:00
static const switch_state_handler_table_t wanpipe_state_handlers = {
2006-01-20 15:05:05 +00:00
/*.on_init */ wanpipe_on_init ,
/*.on_ring */ wanpipe_on_ring ,
/*.on_execute */ NULL ,
/*.on_hangup */ wanpipe_on_hangup ,
/*.on_loopback */ wanpipe_on_loopback ,
/*.on_transmit */ wanpipe_on_transmit
2006-01-03 22:13:59 +00:00
} ;
2006-05-01 04:29:44 +00:00
static const switch_endpoint_interface_t wanpipe_endpoint_interface = {
2006-01-20 15:05:05 +00:00
/*.interface_name */ " wanpipe " ,
/*.io_routines */ & wanpipe_io_routines ,
2006-02-10 22:26:00 +00:00
/*.state_handlers */ & wanpipe_state_handlers ,
2006-01-20 15:05:05 +00:00
/*.private */ NULL ,
/*.next */ NULL
2006-01-03 22:13:59 +00:00
} ;
2006-05-01 04:29:44 +00:00
static const switch_loadable_module_interface_t wanpipe_module_interface = {
2006-01-20 15:05:05 +00:00
/*.module_name */ modname ,
/*.endpoint_interface */ & wanpipe_endpoint_interface ,
/*.timer_interface */ NULL ,
/*.dialplan_interface */ NULL ,
/*.codec_interface */ NULL ,
/*.application_interface */ NULL
2006-01-03 22:13:59 +00:00
} ;
2006-03-30 23:02:50 +00:00
2007-02-09 20:03:07 +00:00
static switch_call_cause_t wanpipe_outgoing_channel ( switch_core_session_t * session , switch_caller_profile_t * outbound_profile ,
switch_core_session_t * * new_session , switch_memory_pool_t * pool )
2006-03-30 23:02:50 +00:00
{
char * bchan = NULL ;
char name [ 128 ] = " " ;
if ( outbound_profile & & outbound_profile - > destination_number ) {
bchan = strchr ( outbound_profile - > destination_number , ' = ' ) ;
} else {
return SWITCH_STATUS_FALSE ;
}
if ( bchan ) {
bchan + + ;
if ( ! bchan ) {
2007-02-09 20:03:07 +00:00
return SWITCH_CAUSE_BEARERCAPABILITY_NOTAVAIL ;
2006-03-30 23:02:50 +00:00
}
outbound_profile - > destination_number + + ;
} else if ( ! globals . configured_spans ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error No Spans Configured. \n " ) ;
2007-02-09 20:03:07 +00:00
SWITCH_CAUSE_NETWORK_OUT_OF_ORDER ;
2006-03-30 23:02:50 +00:00
}
if ( ( * new_session = switch_core_session_request ( & wanpipe_endpoint_interface , pool ) ) ) {
2007-02-09 01:34:01 +00:00
private_object_t * tech_pvt ;
2006-04-29 06:58:08 +00:00
switch_channel_t * channel ;
2006-03-30 23:02:50 +00:00
switch_core_session_add_stream ( * new_session , NULL ) ;
2007-02-09 01:34:01 +00:00
if ( ( tech_pvt = ( private_object_t * ) switch_core_session_alloc ( * new_session , sizeof ( private_object_t ) ) ) ) {
2006-03-30 23:02:50 +00:00
memset ( tech_pvt , 0 , sizeof ( * tech_pvt ) ) ;
2006-06-23 16:59:47 +00:00
switch_mutex_init ( & tech_pvt - > flag_mutex , SWITCH_MUTEX_NESTED , switch_core_session_get_pool ( * new_session ) ) ;
2006-03-30 23:02:50 +00:00
channel = switch_core_session_get_channel ( * new_session ) ;
switch_core_session_set_private ( * new_session , tech_pvt ) ;
tech_pvt - > session = * new_session ;
} else {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Hey where is my memory pool? \n " ) ;
2006-03-30 23:02:50 +00:00
switch_core_session_destroy ( new_session ) ;
2007-02-09 20:03:07 +00:00
SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
2006-03-30 23:02:50 +00:00
}
if ( outbound_profile ) {
2006-04-29 06:58:08 +00:00
switch_caller_profile_t * caller_profile ;
2006-03-30 23:02:50 +00:00
struct sangoma_pri * spri ;
int span = 0 , autospan = 0 , autochan = 0 ;
char * num , * p ;
int channo = 0 ;
struct channel_map * chanmap = NULL ;
caller_profile = switch_caller_profile_clone ( * new_session , outbound_profile ) ;
if ( ! bchan ) {
num = caller_profile - > destination_number ;
if ( ( p = strchr ( num , ' / ' ) ) ) {
* p + + = ' \0 ' ;
2007-02-09 20:03:07 +00:00
if ( * num = = ' a ' ) {
span = 1 ;
autospan = 1 ;
} else if ( * num = ' A ' ) {
span = MAX_SPANS - 1 ;
autospan = - 1 ;
} else {
2006-03-30 23:02:50 +00:00
if ( num & & * num > 47 & & * num < 58 ) {
span = atoi ( num ) ;
} else {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invlid Syntax \n " ) ;
2006-03-30 23:02:50 +00:00
switch_core_session_destroy ( new_session ) ;
2007-02-09 20:03:07 +00:00
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
2006-03-30 23:02:50 +00:00
}
}
num = p ;
if ( ( p = strchr ( num , ' / ' ) ) ) {
* p + + = ' \0 ' ;
if ( * num = = ' a ' ) {
autochan = 1 ;
} else if ( * num = = ' A ' ) {
autochan = - 1 ;
} else if ( num & & * num > 47 & & * num < 58 ) {
channo = atoi ( num ) ;
} else {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invlid Syntax \n " ) ;
2006-03-30 23:02:50 +00:00
switch_core_session_destroy ( new_session ) ;
2007-02-09 20:03:07 +00:00
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
2006-03-30 23:02:50 +00:00
}
caller_profile - > destination_number = p ;
} else {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invlid Syntax \n " ) ;
2006-03-30 23:02:50 +00:00
switch_core_session_destroy ( new_session ) ;
2007-02-09 20:03:07 +00:00
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
2006-03-30 23:02:50 +00:00
}
}
}
tech_pvt - > caller_profile = caller_profile ;
if ( bchan ) {
int chan , span ;
2006-09-24 15:25:36 +00:00
2006-03-30 23:02:50 +00:00
if ( sangoma_span_chan_fromif ( bchan , & span , & chan ) ) {
2006-09-24 15:25:36 +00:00
if ( ! wp_open ( tech_pvt , span , chan ) ) {
2006-04-20 23:57:04 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Can't open fd for s%dc%d! [%s] \n " , span , chan , strerror ( errno ) ) ;
2006-03-30 23:02:50 +00:00
switch_core_session_destroy ( new_session ) ;
2007-02-09 20:03:07 +00:00
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
2006-03-30 23:02:50 +00:00
}
2006-06-23 16:59:47 +00:00
switch_set_flag_locked ( tech_pvt , TFLAG_NOSIG ) ;
2007-02-09 20:03:07 +00:00
snprintf ( name , sizeof ( name ) , " WanPipe/%s/nosig " , bchan ) ;
2006-03-30 23:02:50 +00:00
switch_channel_set_name ( channel , name ) ;
2006-04-13 21:34:04 +00:00
switch_channel_set_caller_profile ( channel , caller_profile ) ;
2006-03-30 23:02:50 +00:00
} else {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invalid address \n " ) ;
2006-03-30 23:02:50 +00:00
switch_core_session_destroy ( new_session ) ;
2007-02-09 20:03:07 +00:00
return SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL ;
2006-03-30 23:02:50 +00:00
}
} else {
2007-02-09 01:34:01 +00:00
switch_mutex_lock ( globals . channel_mutex ) ;
2007-02-09 20:03:07 +00:00
channo = 0 ;
while ( ! channo ) {
if ( autospan > 0 & & span = = MAX_SPANS - 1 ) {
break ;
2006-03-30 23:02:50 +00:00
}
2007-02-09 20:03:07 +00:00
if ( autospan < 0 & & span = = 0 ) {
break ;
}
if ( SPANS [ span ] & & ( spri = & SPANS [ span ] - > spri ) & & switch_test_flag ( spri , SANGOMA_PRI_READY ) ) {
2006-03-30 23:02:50 +00:00
chanmap = spri - > private_info ;
2007-02-09 20:03:07 +00:00
if ( autochan > 0 ) {
for ( channo = 1 ; channo < SANGOMA_MAX_CHAN_PER_SPAN ; channo + + ) {
if ( ( SPANS [ span ] - > bchans & ( 1 < < channo ) ) & & ! chanmap - > map [ channo ] [ 0 ] ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Choosing channel s%dc%d \n " , span , channo ) ;
goto done ;
2006-03-30 23:02:50 +00:00
}
}
2007-02-09 20:03:07 +00:00
channo = 0 ;
} else if ( autochan < 0 ) {
for ( channo = SANGOMA_MAX_CHAN_PER_SPAN ; channo > 0 ; channo - - ) {
if ( ( SPANS [ span ] - > bchans & ( 1 < < channo ) ) & & ! chanmap - > map [ channo ] [ 0 ] ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Choosing channel s%dc%d \n " , span , channo ) ;
goto done ;
}
2006-03-30 23:02:50 +00:00
}
2007-02-09 20:03:07 +00:00
channo = 0 ;
2006-03-30 23:02:50 +00:00
}
}
2007-02-09 20:03:07 +00:00
if ( autospan > 0 ) {
span + + ;
} else if ( autospan < 0 ) {
span - - ;
}
}
done :
2007-02-09 01:34:01 +00:00
switch_mutex_unlock ( globals . channel_mutex ) ;
2007-02-09 20:03:07 +00:00
2006-03-30 23:02:50 +00:00
if ( ! spri | | channo = = 0 | | channo = = ( SANGOMA_MAX_CHAN_PER_SPAN ) ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " No Free Channels! \n " ) ;
2006-03-30 23:02:50 +00:00
switch_core_session_destroy ( new_session ) ;
2007-02-09 20:03:07 +00:00
return SWITCH_CAUSE_SWITCH_CONGESTION ;
2006-03-30 23:02:50 +00:00
}
if ( spri & & ( tech_pvt - > call = pri_new_call ( spri - > pri ) ) ) {
struct pri_sr * sr ;
2007-02-09 20:03:07 +00:00
snprintf ( name , sizeof ( name ) , " WanPipe/s%dc%d/%s " , spri - > span , channo , caller_profile - > destination_number ) ;
2006-03-30 23:02:50 +00:00
switch_channel_set_name ( channel , name ) ;
2006-04-13 21:34:04 +00:00
switch_channel_set_caller_profile ( channel , caller_profile ) ;
2006-03-30 23:02:50 +00:00
sr = pri_sr_new ( ) ;
pri_sr_set_channel ( sr , channo , 0 , 0 ) ;
pri_sr_set_bearer ( sr , 0 , SPANS [ span ] - > l1 ) ;
pri_sr_set_called ( sr , caller_profile - > destination_number , SPANS [ span ] - > dp , 1 ) ;
pri_sr_set_caller ( sr ,
caller_profile - > caller_id_number ,
caller_profile - > caller_id_name ,
SPANS [ span ] - > dp ,
PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN ) ;
pri_sr_set_redirecting ( sr ,
caller_profile - > caller_id_number ,
SPANS [ span ] - > dp ,
PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN ,
PRI_REDIR_UNCONDITIONAL ) ;
if ( pri_setup ( spri - > pri , tech_pvt - > call , sr ) ) {
switch_core_session_destroy ( new_session ) ;
pri_sr_free ( sr ) ;
2007-02-09 20:03:07 +00:00
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
2006-03-30 23:02:50 +00:00
}
2006-09-24 15:25:36 +00:00
if ( ! wp_open ( tech_pvt , spri - > span , channo ) ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Can't open fd! \n " ) ;
2006-03-30 23:02:50 +00:00
switch_core_session_destroy ( new_session ) ;
pri_sr_free ( sr ) ;
2007-02-09 20:03:07 +00:00
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
2006-03-30 23:02:50 +00:00
}
pri_sr_free ( sr ) ;
2007-02-09 01:34:01 +00:00
switch_copy_string ( chanmap - > map [ channo ] ,
switch_core_session_get_uuid ( * new_session ) ,
sizeof ( chanmap - > map [ channo ] ) ) ;
2006-03-30 23:02:50 +00:00
tech_pvt - > spri = spri ;
}
}
} else {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Doh! no caller profile \n " ) ;
2006-03-30 23:02:50 +00:00
switch_core_session_destroy ( new_session ) ;
2007-02-09 20:03:07 +00:00
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
2006-03-30 23:02:50 +00:00
}
switch_channel_set_flag ( channel , CF_OUTBOUND ) ;
2006-06-23 16:59:47 +00:00
switch_set_flag_locked ( tech_pvt , TFLAG_OUTBOUND ) ;
2006-03-30 23:02:50 +00:00
switch_channel_set_state ( channel , CS_INIT ) ;
2007-02-09 20:03:07 +00:00
return SWITCH_CAUSE_SUCCESS ;
2006-03-30 23:02:50 +00:00
}
2007-02-09 20:03:07 +00:00
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
2006-03-30 23:02:50 +00:00
}
2006-12-04 22:25:31 +00:00
# ifdef WIN32
static void s_pri_error ( char * s )
# else
2006-02-24 19:11:49 +00:00
static void s_pri_error ( struct pri * pri , char * s )
2006-12-04 22:25:31 +00:00
# endif
2006-02-24 19:11:49 +00:00
{
2006-03-24 16:40:31 +00:00
if ( globals . debug ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , s ) ;
2006-03-24 16:40:31 +00:00
}
2006-02-24 19:11:49 +00:00
}
2006-12-04 22:25:31 +00:00
# ifdef WIN32
static void s_pri_message ( char * s )
{
s_pri_error ( s ) ;
}
# else
2006-02-24 19:11:49 +00:00
static void s_pri_message ( struct pri * pri , char * s )
{
s_pri_error ( pri , s ) ;
}
2006-12-04 22:25:31 +00:00
# endif
2006-02-24 19:11:49 +00:00
2006-05-01 04:29:44 +00:00
SWITCH_MOD_DECLARE ( switch_status_t ) switch_module_load ( const switch_loadable_module_interface_t * * interface , char * filename )
2006-01-20 15:05:05 +00:00
{
2006-05-01 04:29:44 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2006-01-03 22:13:59 +00:00
2006-02-12 20:38:24 +00:00
memset ( SPANS , 0 , sizeof ( SPANS ) ) ;
2006-01-03 22:13:59 +00:00
2006-03-24 16:40:31 +00:00
pri_set_error ( s_pri_error ) ;
pri_set_message ( s_pri_message ) ;
2006-01-03 22:13:59 +00:00
if ( switch_core_new_memory_pool ( & module_pool ) ! = SWITCH_STATUS_SUCCESS ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " OH OH no pool \n " ) ;
2006-01-03 22:13:59 +00:00
return SWITCH_STATUS_TERM ;
}
2006-01-20 15:05:05 +00:00
2006-09-24 15:25:36 +00:00
memset ( & globals , 0 , sizeof ( globals ) ) ;
switch_core_hash_init ( & globals . call_hash , module_pool ) ;
switch_mutex_init ( & globals . hash_mutex , SWITCH_MUTEX_NESTED , module_pool ) ;
2007-02-09 01:34:01 +00:00
switch_mutex_init ( & globals . channel_mutex , SWITCH_MUTEX_NESTED , module_pool ) ;
2006-09-24 15:25:36 +00:00
2006-02-12 20:38:24 +00:00
/* start the pri's */
2006-03-30 23:02:50 +00:00
if ( ( status = config_wanpipe ( 0 ) ) ! = SWITCH_STATUS_SUCCESS ) {
2006-02-24 19:11:49 +00:00
return status ;
}
2006-01-03 22:13:59 +00:00
/* connect my internal structure to the blank pointer passed to me */
2006-01-13 14:23:34 +00:00
* interface = & wanpipe_module_interface ;
2006-01-03 22:13:59 +00:00
/* indicate that the module should continue to be loaded */
2006-02-24 19:11:49 +00:00
return status ;
2006-01-03 22:13:59 +00:00
}
2006-02-10 22:26:00 +00:00
/*event Handlers */
2006-01-03 22:13:59 +00:00
2006-12-04 20:51:16 +00:00
static int on_info ( struct sangoma_pri * spri , sangoma_pri_event_t event_type , pri_event * pevent )
2006-01-03 22:13:59 +00:00
{
2006-12-04 20:51:16 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " number is: %s \n " , pevent - > ring . callednum ) ;
if ( strlen ( pevent - > ring . callednum ) > 3 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " final number is: %s \n " , pevent - > ring . callednum ) ;
pri_answer ( spri - > pri , pevent - > ring . call , 0 , 1 ) ;
2006-01-03 22:13:59 +00:00
}
return 0 ;
}
2006-12-04 20:51:16 +00:00
static int on_hangup ( struct sangoma_pri * spri , sangoma_pri_event_t event_type , pri_event * pevent )
2006-01-03 22:13:59 +00:00
{
struct channel_map * chanmap ;
2006-04-29 06:58:08 +00:00
switch_core_session_t * session ;
2007-02-09 01:34:01 +00:00
private_object_t * tech_pvt ;
2006-01-03 22:13:59 +00:00
2006-02-26 04:52:34 +00:00
chanmap = spri - > private_info ;
2007-02-09 01:34:01 +00:00
if ( ( session = switch_core_session_locate ( chanmap - > map [ pevent - > hangup . channel ] ) ) ) {
2006-04-29 06:58:08 +00:00
switch_channel_t * channel = NULL ;
2006-01-03 22:13:59 +00:00
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
tech_pvt = switch_core_session_get_private ( session ) ;
assert ( tech_pvt ! = NULL ) ;
2006-01-20 15:05:05 +00:00
2006-02-10 22:26:00 +00:00
if ( ! tech_pvt - > call ) {
2006-12-04 20:51:16 +00:00
tech_pvt - > call = pevent - > hangup . call ;
2006-02-10 22:26:00 +00:00
}
2006-12-04 20:51:16 +00:00
tech_pvt - > cause = pevent - > hangup . cause ;
2006-01-03 22:13:59 +00:00
2007-02-09 20:03:07 +00:00
switch_channel_hangup ( channel , tech_pvt - > cause ) ;
2006-05-12 01:10:31 +00:00
2007-02-09 20:03:07 +00:00
switch_mutex_lock ( globals . channel_mutex ) ;
2007-02-09 01:34:01 +00:00
chanmap - > map [ pevent - > hangup . channel ] [ 0 ] = ' \0 ' ;
2007-02-09 20:03:07 +00:00
switch_mutex_unlock ( globals . channel_mutex ) ;
2007-02-09 01:34:01 +00:00
switch_core_session_rwunlock ( session ) ;
2006-01-03 22:13:59 +00:00
}
2006-01-20 15:05:05 +00:00
2006-12-04 20:51:16 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " -- Hanging up channel s%dc%d \n " , spri - > span , pevent - > hangup . channel ) ;
2006-01-03 22:13:59 +00:00
return 0 ;
}
2006-12-04 20:51:16 +00:00
static int on_answer ( struct sangoma_pri * spri , sangoma_pri_event_t event_type , pri_event * pevent )
2006-02-10 22:26:00 +00:00
{
2006-04-29 06:58:08 +00:00
switch_core_session_t * session ;
switch_channel_t * channel ;
2006-02-10 22:26:00 +00:00
struct channel_map * chanmap ;
2006-03-17 14:47:41 +00:00
2006-02-26 04:52:34 +00:00
chanmap = spri - > private_info ;
2006-02-10 22:26:00 +00:00
2007-02-09 01:34:01 +00:00
if ( ( session = switch_core_session_locate ( chanmap - > map [ pevent - > answer . channel ] ) ) ) {
2006-12-04 20:51:16 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " -- Answer on channel s%dc%d \n " , spri - > span , pevent - > answer . channel ) ;
2006-02-10 22:26:00 +00:00
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
2007-02-09 01:34:01 +00:00
switch_channel_mark_answered ( channel ) ;
switch_core_session_rwunlock ( session ) ;
2006-02-10 22:26:00 +00:00
} else {
2006-12-04 20:51:16 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " -- Answer on channel s%dc%d but it's not in use? \n " , spri - > span , pevent - > answer . channel ) ;
2006-02-10 22:26:00 +00:00
}
2006-03-17 14:47:41 +00:00
2006-02-10 22:26:00 +00:00
return 0 ;
}
2006-02-22 02:50:33 +00:00
2006-12-04 20:51:16 +00:00
static int on_proceed ( struct sangoma_pri * spri , sangoma_pri_event_t event_type , pri_event * pevent )
2006-02-22 02:50:33 +00:00
{
2006-04-29 06:58:08 +00:00
switch_core_session_t * session ;
switch_channel_t * channel ;
2006-02-22 02:50:33 +00:00
struct channel_map * chanmap ;
2006-02-26 04:52:34 +00:00
chanmap = spri - > private_info ;
2006-02-22 02:50:33 +00:00
2007-02-09 01:34:01 +00:00
if ( ( session = switch_core_session_locate ( chanmap - > map [ pevent - > proceeding . channel ] ) ) ) {
char * uuid ;
switch_core_session_message_t * msg ;
2006-02-22 02:50:33 +00:00
2006-12-04 20:51:16 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " -- Proceeding on channel s%dc%d \n " , spri - > span , pevent - > proceeding . channel ) ;
2007-02-09 20:03:07 +00:00
2006-02-22 02:50:33 +00:00
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
2007-02-09 01:34:01 +00:00
if ( ( msg = malloc ( sizeof ( * msg ) ) ) ) {
memset ( msg , 0 , sizeof ( * msg ) ) ;
msg - > message_id = SWITCH_MESSAGE_INDICATE_PROGRESS ;
msg - > from = __FILE__ ;
switch_core_session_queue_message ( session , msg ) ;
switch_set_flag ( msg , SCSMF_DYNAMIC ) ;
switch_channel_mark_pre_answered ( channel ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Memory Error! \n " ) ;
2006-02-22 02:50:33 +00:00
}
2007-02-09 20:03:07 +00:00
2007-02-09 01:34:01 +00:00
switch_core_session_rwunlock ( session ) ;
2006-02-22 02:50:33 +00:00
} else {
2007-02-09 01:34:01 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " -- Proceeding on channel s%dc%d but it's not in use? \n " ,
spri - > span , pevent - > proceeding . channel ) ;
2006-02-22 02:50:33 +00:00
}
return 0 ;
}
2007-02-09 01:34:01 +00:00
2006-12-04 20:51:16 +00:00
static int on_ringing ( struct sangoma_pri * spri , sangoma_pri_event_t event_type , pri_event * pevent )
2006-02-10 22:26:00 +00:00
{
2006-04-29 06:58:08 +00:00
switch_core_session_t * session ;
switch_channel_t * channel ;
2006-02-10 22:26:00 +00:00
struct channel_map * chanmap ;
2007-02-09 01:34:01 +00:00
private_object_t * tech_pvt ;
switch_core_session_message_t * msg ;
2006-02-10 22:26:00 +00:00
2006-02-26 04:52:34 +00:00
chanmap = spri - > private_info ;
2006-02-10 22:26:00 +00:00
2007-02-09 01:34:01 +00:00
if ( ( session = switch_core_session_locate ( chanmap - > map [ pevent - > ringing . channel ] ) ) ) {
2006-12-04 20:51:16 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " -- Ringing on channel s%dc%d \n " , spri - > span , pevent - > ringing . channel ) ;
2006-02-10 22:26:00 +00:00
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
2007-02-09 01:34:01 +00:00
if ( ( msg = malloc ( sizeof ( * msg ) ) ) ) {
memset ( msg , 0 , sizeof ( * msg ) ) ;
msg - > message_id = SWITCH_MESSAGE_INDICATE_RINGING ;
msg - > from = __FILE__ ;
switch_core_session_queue_message ( session , msg ) ;
switch_set_flag ( msg , SCSMF_DYNAMIC ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Memory Error! \n " ) ;
2006-02-10 22:26:00 +00:00
}
2007-02-09 01:34:01 +00:00
switch_core_session_rwunlock ( session ) ;
2006-02-10 22:26:00 +00:00
} else {
2007-02-09 01:34:01 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " -- Ringing on channel s%dc%d %s but it's not in use? \n " , spri - > span , pevent - > ringing . channel , chanmap - > map [ pevent - > ringing . channel ] ) ;
2006-02-10 22:26:00 +00:00
}
return 0 ;
}
2007-02-09 01:34:01 +00:00
2006-02-10 22:26:00 +00:00
2006-12-04 20:51:16 +00:00
static int on_ring ( struct sangoma_pri * spri , sangoma_pri_event_t event_type , pri_event * pevent )
2006-01-03 22:13:59 +00:00
{
char name [ 128 ] ;
2006-04-29 06:58:08 +00:00
switch_core_session_t * session ;
switch_channel_t * channel ;
2006-01-03 22:13:59 +00:00
struct channel_map * chanmap ;
2007-02-09 01:34:01 +00:00
int ret = 0 ;
switch_mutex_lock ( globals . channel_mutex ) ;
2006-01-03 22:13:59 +00:00
2006-02-26 04:52:34 +00:00
chanmap = spri - > private_info ;
2007-02-09 01:34:01 +00:00
if ( switch_core_session_locate ( chanmap - > map [ pevent - > ring . channel ] ) ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " --Duplicate Ring on channel s%dc%d (ignored) \n " ,
2006-12-04 20:51:16 +00:00
spri - > span , pevent - > ring . channel ) ;
2007-02-09 01:34:01 +00:00
switch_core_session_rwunlock ( session ) ;
ret = 0 ;
goto done ;
2006-01-03 22:13:59 +00:00
}
2006-12-04 20:51:16 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " -- Ring on channel s%dc%d (from %s to %s) \n " , spri - > span , pevent - > ring . channel ,
pevent - > ring . callingnum , pevent - > ring . callednum ) ;
2006-01-03 22:13:59 +00:00
2006-02-10 22:26:00 +00:00
2006-12-04 20:51:16 +00:00
pri_proceeding ( spri - > pri , pevent - > ring . call , pevent - > ring . channel , 0 ) ;
pri_acknowledge ( spri - > pri , pevent - > ring . call , pevent - > ring . channel , 0 ) ;
2006-02-10 22:26:00 +00:00
2006-01-13 14:23:34 +00:00
if ( ( session = switch_core_session_request ( & wanpipe_endpoint_interface , NULL ) ) ) {
2007-02-09 01:34:01 +00:00
private_object_t * tech_pvt ;
2006-12-04 20:51:16 +00:00
char ani2str [ 4 ] = " " ;
2006-01-03 22:13:59 +00:00
//wanpipe_tdm_api_t tdm_api;
2006-01-09 18:40:56 +00:00
switch_core_session_add_stream ( session , NULL ) ;
2007-02-09 01:34:01 +00:00
if ( ( tech_pvt = ( private_object_t * ) switch_core_session_alloc ( session , sizeof ( private_object_t ) ) ) ) {
2006-01-03 22:13:59 +00:00
memset ( tech_pvt , 0 , sizeof ( * tech_pvt ) ) ;
2006-06-23 16:59:47 +00:00
switch_mutex_init ( & tech_pvt - > flag_mutex , SWITCH_MUTEX_NESTED , switch_core_session_get_pool ( session ) ) ;
2006-01-03 22:13:59 +00:00
channel = switch_core_session_get_channel ( session ) ;
switch_core_session_set_private ( session , tech_pvt ) ;
2006-12-04 20:51:16 +00:00
sprintf ( name , " s%dc%d " , spri - > span , pevent - > ring . channel ) ;
2006-02-10 22:26:00 +00:00
switch_channel_set_name ( channel , name ) ;
2006-02-22 02:50:33 +00:00
2006-01-03 22:13:59 +00:00
} else {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Hey where is my memory pool? \n " ) ;
2006-01-03 22:13:59 +00:00
switch_core_session_destroy ( & session ) ;
2007-02-09 01:34:01 +00:00
ret = 0 ;
goto done ;
2006-01-03 22:13:59 +00:00
}
2006-01-20 15:05:05 +00:00
2006-12-04 20:51:16 +00:00
if ( pevent - > ring . ani2 > = 0 ) {
snprintf ( ani2str , 5 , " %.2d " , pevent - > ring . ani2 ) ;
2006-01-03 22:13:59 +00:00
}
2006-03-01 22:55:28 +00:00
if ( ( tech_pvt - > caller_profile = switch_caller_profile_new ( switch_core_session_get_pool ( session ) ,
2006-05-26 16:00:08 +00:00
NULL ,
2006-01-20 15:05:05 +00:00
globals . dialplan ,
2006-05-16 13:37:59 +00:00
" FreeSWITCH " ,
2006-12-04 20:51:16 +00:00
pevent - > ring . callingnum ,
# ifdef WIN32
NULL ,
# else
pevent - > ring . callingani ,
# endif
switch_strlen_zero ( ani2str ) ? NULL : ani2str ,
2006-02-10 22:26:00 +00:00
NULL ,
2006-04-21 22:31:08 +00:00
NULL ,
( char * ) modname ,
2006-04-28 19:46:57 +00:00
NULL ,
2006-12-04 20:51:16 +00:00
pevent - > ring . callednum ) ) ) {
2006-01-03 22:13:59 +00:00
switch_channel_set_caller_profile ( channel , tech_pvt - > caller_profile ) ;
}
2006-06-23 16:59:47 +00:00
switch_set_flag_locked ( tech_pvt , TFLAG_INBOUND ) ;
2006-01-03 22:13:59 +00:00
tech_pvt - > spri = spri ;
tech_pvt - > cause = - 1 ;
2006-02-10 22:26:00 +00:00
if ( ! tech_pvt - > call ) {
2006-12-04 20:51:16 +00:00
tech_pvt - > call = pevent - > ring . call ;
2006-02-10 22:26:00 +00:00
}
2006-02-22 18:32:15 +00:00
2006-12-04 20:51:16 +00:00
tech_pvt - > callno = pevent - > ring . channel ;
2006-02-22 18:32:15 +00:00
tech_pvt - > span = spri - > span ;
2006-01-03 22:13:59 +00:00
2006-12-04 20:51:16 +00:00
if ( ! wp_open ( tech_pvt , spri - > span , pevent - > ring . channel ) ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Can't open fd! \n " ) ;
2006-01-03 22:13:59 +00:00
}
2007-02-09 01:34:01 +00:00
switch_copy_string ( chanmap - > map [ pevent - > ring . channel ] , switch_core_session_get_uuid ( session ) , sizeof ( chanmap - > map [ pevent - > ring . channel ] ) ) ;
2006-01-03 22:13:59 +00:00
switch_channel_set_state ( channel , CS_INIT ) ;
switch_core_session_thread_launch ( session ) ;
} else {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Cannot Create new Inbound Channel! \n " ) ;
2006-01-03 22:13:59 +00:00
}
2007-02-09 01:34:01 +00:00
done :
switch_mutex_unlock ( globals . channel_mutex ) ;
return ret ;
2006-01-03 22:13:59 +00:00
}
static int check_flags ( struct sangoma_pri * spri )
{
2006-01-20 15:05:05 +00:00
2006-01-03 22:13:59 +00:00
return 0 ;
}
2006-12-04 20:51:16 +00:00
static int on_restart ( struct sangoma_pri * spri , sangoma_pri_event_t event_type , pri_event * pevent )
2006-01-03 22:13:59 +00:00
{
2006-04-29 06:58:08 +00:00
switch_core_session_t * session ;
2006-02-10 22:26:00 +00:00
struct channel_map * chanmap ;
2006-01-03 22:13:59 +00:00
2006-03-21 00:20:24 +00:00
2006-12-04 20:51:16 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " -- Restarting s%dc%d \n " , spri - > span , pevent - > restart . channel ) ;
2006-01-03 22:13:59 +00:00
2006-12-04 20:51:16 +00:00
if ( pevent - > restart . channel < 1 ) {
2006-03-21 00:20:24 +00:00
return 0 ;
}
2006-02-26 04:52:34 +00:00
chanmap = spri - > private_info ;
2006-02-10 22:26:00 +00:00
2007-02-09 01:34:01 +00:00
if ( ( session = switch_core_session_locate ( chanmap - > map [ pevent - > restart . channel ] ) ) ) {
2006-04-29 06:58:08 +00:00
switch_channel_t * channel ;
2006-02-10 22:26:00 +00:00
channel = switch_core_session_get_channel ( session ) ;
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Hanging Up channel %s \n " , switch_channel_get_name ( channel ) ) ;
2006-04-22 03:05:25 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_NORMAL_CLEARING ) ;
2007-02-09 01:34:01 +00:00
switch_core_session_rwunlock ( session ) ;
2006-02-10 22:26:00 +00:00
}
2006-12-04 20:51:16 +00:00
wp_restart ( spri - > span , pevent - > restart . channel ) ;
2006-09-24 15:25:36 +00:00
2006-01-03 22:13:59 +00:00
return 0 ;
}
2006-12-04 20:51:16 +00:00
static int on_dchan_up ( struct sangoma_pri * spri , sangoma_pri_event_t event_type , pri_event * pevent )
2006-03-24 14:47:53 +00:00
{
if ( ! switch_test_flag ( spri , SANGOMA_PRI_READY ) ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Span %d D-Chan UP! \n " , spri - > span ) ;
2006-03-24 14:47:53 +00:00
switch_set_flag ( spri , SANGOMA_PRI_READY ) ;
}
return 0 ;
}
2006-12-04 20:51:16 +00:00
static int on_dchan_down ( struct sangoma_pri * spri , sangoma_pri_event_t event_type , pri_event * pevent )
2006-03-24 14:47:53 +00:00
{
if ( switch_test_flag ( spri , SANGOMA_PRI_READY ) ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Span %d D-Chan DOWN! \n " , spri - > span ) ;
2006-03-24 14:47:53 +00:00
switch_clear_flag ( spri , SANGOMA_PRI_READY ) ;
}
return 0 ;
}
2006-12-04 20:51:16 +00:00
static int on_anything ( struct sangoma_pri * spri , sangoma_pri_event_t event_type , pri_event * pevent )
2006-01-03 22:13:59 +00:00
{
2006-03-24 14:47:53 +00:00
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Caught Event span %d %u (%s) \n " , spri - > span , event_type ,
2006-01-20 15:05:05 +00:00
sangoma_pri_event_str ( event_type ) ) ;
2006-01-03 22:13:59 +00:00
return 0 ;
}
2006-12-04 20:51:16 +00:00
static void * SWITCH_THREAD_FUNC pri_thread_run ( switch_thread_t * thread , void * obj )
2006-01-03 22:13:59 +00:00
{
struct sangoma_pri * spri = obj ;
2007-02-09 01:34:01 +00:00
struct channel_map chanmap = { 0 } ;
2006-02-22 15:20:46 +00:00
2006-04-29 06:58:08 +00:00
switch_event_t * s_event ;
2006-01-03 22:13:59 +00:00
SANGOMA_MAP_PRI_EVENT ( ( * spri ) , SANGOMA_PRI_EVENT_ANY , on_anything ) ;
SANGOMA_MAP_PRI_EVENT ( ( * spri ) , SANGOMA_PRI_EVENT_RING , on_ring ) ;
2007-02-09 01:34:01 +00:00
SANGOMA_MAP_PRI_EVENT ( ( * spri ) , SANGOMA_PRI_EVENT_RINGING , on_ringing ) ;
2006-03-23 19:22:06 +00:00
//SANGOMA_MAP_PRI_EVENT((*spri), SANGOMA_PRI_EVENT_SETUP_ACK, on_proceed);
2006-02-22 02:50:33 +00:00
SANGOMA_MAP_PRI_EVENT ( ( * spri ) , SANGOMA_PRI_EVENT_PROCEEDING , on_proceed ) ;
2006-02-10 22:26:00 +00:00
SANGOMA_MAP_PRI_EVENT ( ( * spri ) , SANGOMA_PRI_EVENT_ANSWER , on_answer ) ;
2006-03-24 14:47:53 +00:00
SANGOMA_MAP_PRI_EVENT ( ( * spri ) , SANGOMA_PRI_EVENT_DCHAN_UP , on_dchan_up ) ;
SANGOMA_MAP_PRI_EVENT ( ( * spri ) , SANGOMA_PRI_EVENT_DCHAN_DOWN , on_dchan_down ) ;
2006-01-03 22:13:59 +00:00
SANGOMA_MAP_PRI_EVENT ( ( * spri ) , SANGOMA_PRI_EVENT_HANGUP_REQ , on_hangup ) ;
2006-02-22 02:50:33 +00:00
SANGOMA_MAP_PRI_EVENT ( ( * spri ) , SANGOMA_PRI_EVENT_HANGUP , on_hangup ) ;
2006-01-03 22:13:59 +00:00
SANGOMA_MAP_PRI_EVENT ( ( * spri ) , SANGOMA_PRI_EVENT_INFO_RECEIVED , on_info ) ;
SANGOMA_MAP_PRI_EVENT ( ( * spri ) , SANGOMA_PRI_EVENT_RESTART , on_restart ) ;
spri - > on_loop = check_flags ;
2006-02-26 04:52:34 +00:00
spri - > private_info = & chanmap ;
2006-02-14 16:42:26 +00:00
if ( switch_event_create ( & s_event , SWITCH_EVENT_PUBLISH ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header ( s_event , SWITCH_STACK_BOTTOM , " service " , " _pri._tcp " ) ;
switch_event_fire ( & s_event ) ;
}
2006-01-03 22:13:59 +00:00
sangoma_run_pri ( spri ) ;
2006-01-20 15:05:05 +00:00
2006-01-03 22:13:59 +00:00
free ( spri ) ;
return NULL ;
}
2006-02-12 20:38:24 +00:00
static void pri_thread_launch ( struct sangoma_pri * spri )
{
2006-04-29 06:58:08 +00:00
switch_thread_t * thread ;
2006-02-12 20:38:24 +00:00
switch_threadattr_t * thd_attr = NULL ;
switch_threadattr_create ( & thd_attr , module_pool ) ;
switch_threadattr_detach_set ( thd_attr , 1 ) ;
2006-04-26 17:18:33 +00:00
switch_threadattr_stacksize_set ( thd_attr , SWITCH_THREAD_STACKSIZE ) ;
2006-02-12 20:38:24 +00:00
switch_thread_create ( & thread , thd_attr , pri_thread_run , spri , module_pool ) ;
}
2006-01-03 22:13:59 +00:00
2006-05-01 04:29:44 +00:00
static switch_status_t config_wanpipe ( int reload )
2006-01-03 22:13:59 +00:00
{
2006-01-13 14:23:34 +00:00
char * cf = " wanpipe.conf " ;
2007-02-07 23:43:04 +00:00
int current_span = 0 , min_span = 0 , max_span = 0 ;
2006-05-10 03:23:05 +00:00
switch_xml_t cfg , xml , settings , param , span ;
2006-01-03 22:13:59 +00:00
2007-02-09 20:03:07 +00:00
globals . samples_per_frame = DEFAULT_SAMPLES_PER_FRAME ;
2006-02-22 18:32:15 +00:00
globals . dtmf_on = 150 ;
globals . dtmf_off = 50 ;
2006-01-03 22:13:59 +00:00
2006-02-12 20:38:24 +00:00
2006-09-24 15:25:36 +00:00
2006-05-10 15:47:54 +00:00
if ( ! ( xml = switch_xml_open_cfg ( cf , & cfg , NULL ) ) ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " open of %s failed \n " , cf ) ;
2006-01-03 22:13:59 +00:00
return SWITCH_STATUS_TERM ;
}
2006-05-10 03:23:05 +00:00
if ( ( settings = switch_xml_child ( cfg , " settings " ) ) ) {
for ( param = switch_xml_child ( settings , " param " ) ; param ; param = param - > next ) {
2006-05-17 00:58:21 +00:00
char * var = ( char * ) switch_xml_attr_soft ( param , " name " ) ;
char * val = ( char * ) switch_xml_attr_soft ( param , " value " ) ;
2006-05-10 03:23:05 +00:00
2006-01-03 22:13:59 +00:00
if ( ! strcmp ( var , " debug " ) ) {
globals . debug = atoi ( val ) ;
2007-02-09 20:03:07 +00:00
} else if ( ! strcmp ( var , " ms-per-frame " ) ) {
globals . samples_per_frame = atoi ( val ) * 8 ;
2006-05-16 17:08:21 +00:00
} else if ( ! strcmp ( var , " dtmf-on " ) ) {
2006-02-22 18:32:15 +00:00
globals . dtmf_on = atoi ( val ) ;
2006-05-16 17:08:21 +00:00
} else if ( ! strcmp ( var , " dtmf-off " ) ) {
2006-02-22 18:32:15 +00:00
globals . dtmf_off = atoi ( val ) ;
2006-05-16 17:08:21 +00:00
} else if ( ! strcmp ( var , " supress-dtmf-tone " ) ) {
2006-02-23 22:41:08 +00:00
globals . supress_dtmf_tone = switch_true ( val ) ;
2006-02-12 20:38:24 +00:00
}
2006-05-10 03:23:05 +00:00
}
}
for ( span = switch_xml_child ( cfg , " span " ) ; span ; span = span - > next ) {
2007-02-09 01:34:01 +00:00
char * id = ( char * ) switch_xml_attr ( span , " id " ) ;
2007-02-07 23:43:04 +00:00
int32_t i = 0 ;
2006-05-10 03:23:05 +00:00
2007-02-07 23:43:04 +00:00
current_span = 0 ;
if ( id ) {
char * p ;
min_span = atoi ( id ) ;
if ( ( p = strchr ( id , ' - ' ) ) ) {
p + + ;
max_span = atoi ( p ) ;
2006-02-12 20:38:24 +00:00
} else {
2007-02-07 23:43:04 +00:00
max_span = min_span ;
}
if ( min_span < 1 | | max_span < min_span ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Invalid Span Config! [%s] \n " , id ) ;
continue ;
}
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Missing SPAN ID! \n " ) ;
continue ;
}
for ( i = min_span ; i < = max_span ; i + + ) {
current_span = i ;
if ( current_span < = 0 | | current_span > MAX_SPANS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Invalid SPAN %d! \n " , current_span ) ;
current_span = 0 ;
continue ;
}
if ( ! SPANS [ current_span ] ) {
if ( ! ( SPANS [ current_span ] = switch_core_alloc ( module_pool , sizeof ( * SPANS [ current_span ] ) ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " MEMORY ERROR \n " ) ;
break ;
2006-02-12 20:38:24 +00:00
}
2007-02-07 23:43:04 +00:00
SPANS [ current_span ] - > span = current_span ;
}
for ( param = switch_xml_child ( span , " param " ) ; param ; param = param - > next ) {
char * var = ( char * ) switch_xml_attr_soft ( param , " name " ) ;
char * val = ( char * ) switch_xml_attr_soft ( param , " value " ) ;
2006-02-12 20:38:24 +00:00
if ( ! strcmp ( var , " dchan " ) ) {
SPANS [ current_span ] - > dchan = atoi ( val ) ;
} else if ( ! strcmp ( var , " bchan " ) ) {
char from [ 128 ] ;
char * to ;
switch_copy_string ( from , val , sizeof ( from ) ) ;
if ( ( to = strchr ( from , ' - ' ) ) ) {
int fromi , toi , x = 0 ;
* to + + = ' \0 ' ;
fromi = atoi ( from ) ;
toi = atoi ( to ) ;
if ( fromi > 0 & & toi > 0 & & fromi < toi & & fromi < MAX_SPANS & & toi < MAX_SPANS ) {
for ( x = fromi ; x < = toi ; x + + ) {
SPANS [ current_span ] - > bchans | = ( 1 < < x ) ;
}
} else {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Invalid bchan range! \n " ) ;
2006-02-12 20:38:24 +00:00
}
} else {
int i = atoi ( val ) ;
if ( i > 0 & & i < 31 ) {
SPANS [ current_span ] - > bchans | = ( 1 < < i ) ;
} else {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Invalid bchan! \n " ) ;
2006-02-12 20:38:24 +00:00
}
}
} else if ( ! strcmp ( var , " node " ) ) {
SPANS [ current_span ] - > node = str2node ( val ) ;
} else if ( ! strcmp ( var , " switch " ) ) {
SPANS [ current_span ] - > pswitch = str2switch ( val ) ;
} else if ( ! strcmp ( var , " dp " ) ) {
SPANS [ current_span ] - > dp = str2dp ( val ) ;
} else if ( ! strcmp ( var , " l1 " ) ) {
SPANS [ current_span ] - > l1 = str2l1 ( val ) ;
} else if ( ! strcmp ( var , " dialplan " ) ) {
set_global_dialplan ( val ) ;
}
2006-01-20 15:05:05 +00:00
}
2006-01-03 22:13:59 +00:00
}
}
2006-05-10 03:23:05 +00:00
switch_xml_free ( xml ) ;
2006-01-03 22:13:59 +00:00
if ( ! globals . dialplan ) {
set_global_dialplan ( " default " ) ;
}
2006-02-22 15:20:46 +00:00
2006-02-24 16:47:22 +00:00
globals . configured_spans = 0 ;
2006-02-12 20:38:24 +00:00
for ( current_span = 1 ; current_span < MAX_SPANS ; current_span + + ) {
if ( SPANS [ current_span ] ) {
2006-02-21 19:36:51 +00:00
2006-02-12 20:38:24 +00:00
if ( ! SPANS [ current_span ] - > l1 ) {
SPANS [ current_span ] - > l1 = PRI_LAYER_1_ULAW ;
}
2006-02-21 19:36:51 +00:00
if ( sangoma_init_pri ( & SPANS [ current_span ] - > spri ,
current_span ,
SPANS [ current_span ] - > dchan ,
SPANS [ current_span ] - > pswitch ,
SPANS [ current_span ] - > node ,
globals . debug ) ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Cannot launch span %d \n " , current_span ) ;
2006-02-21 19:36:51 +00:00
continue ;
}
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Launch span %d \n " , current_span ) ;
2006-02-12 20:38:24 +00:00
pri_thread_launch ( & SPANS [ current_span ] - > spri ) ;
2006-02-24 16:47:22 +00:00
globals . configured_spans + + ;
2006-02-12 20:38:24 +00:00
}
}
2006-01-20 15:05:05 +00:00
2006-01-03 22:13:59 +00:00
2006-03-30 23:02:50 +00:00
return SWITCH_STATUS_SUCCESS ;
2006-01-03 22:13:59 +00:00
}
2006-12-04 20:51:16 +00:00