2007-05-16 20:36:40 +00:00
/*
* Copyright ( c ) 2007 , Anthony Minessale II
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
*
* * Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
*
* * Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
*
* * Neither the name of the original author ; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission .
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* " AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL ,
* EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED TO ,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE , DATA , OR
* PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING
* NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
# include "openzap.h"
2008-08-29 15:58:59 +00:00
# include "ozmod_zt.h"
2007-05-16 20:36:40 +00:00
2007-05-30 01:01:32 +00:00
static struct {
uint32_t codec_ms ;
uint32_t wink_ms ;
uint32_t flash_ms ;
2007-06-01 15:58:27 +00:00
uint32_t eclevel ;
2007-06-21 02:13:41 +00:00
uint32_t etlevel ;
2009-06-04 16:18:22 +00:00
float rxgain ;
float txgain ;
2007-05-30 01:01:32 +00:00
} zt_globals ;
2009-03-04 21:31:08 +00:00
struct ioctl_codes {
int GET_BLOCKSIZE ;
int SET_BLOCKSIZE ;
int FLUSH ;
int SYNC ;
int GET_PARAMS ;
int SET_PARAMS ;
int HOOK ;
int GETEVENT ;
int IOMUX ;
int SPANSTAT ;
int MAINT ;
int GETCONF ;
int SETCONF ;
int CONFLINK ;
int CONFDIAG ;
int GETGAINS ;
int SETGAINS ;
int SPANCONFIG ;
int CHANCONFIG ;
int SET_BUFINFO ;
int GET_BUFINFO ;
int AUDIOMODE ;
int ECHOCANCEL ;
int HDLCRAWMODE ;
int HDLCFCSMODE ;
int SPECIFY ;
int SETLAW ;
int SETLINEAR ;
int GETCONFMUTE ;
int ECHOTRAIN ;
int SETTXBITS ;
int GETRXBITS ;
} ;
static struct ioctl_codes zt_ioctl_codes = {
. GET_BLOCKSIZE = ZT_GET_BLOCKSIZE ,
. SET_BLOCKSIZE = ZT_SET_BLOCKSIZE ,
. FLUSH = ZT_FLUSH ,
. SYNC = ZT_SYNC ,
. GET_PARAMS = ZT_GET_PARAMS ,
. SET_PARAMS = ZT_SET_PARAMS ,
. HOOK = ZT_HOOK ,
. GETEVENT = ZT_GETEVENT ,
. IOMUX = ZT_IOMUX ,
. SPANSTAT = ZT_SPANSTAT ,
. MAINT = ZT_MAINT ,
. GETCONF = ZT_GETCONF ,
. SETCONF = ZT_SETCONF ,
. CONFLINK = ZT_CONFLINK ,
. CONFDIAG = ZT_CONFDIAG ,
. GETGAINS = ZT_GETGAINS ,
. SETGAINS = ZT_SETGAINS ,
. SPANCONFIG = ZT_SPANCONFIG ,
. CHANCONFIG = ZT_CHANCONFIG ,
. SET_BUFINFO = ZT_SET_BUFINFO ,
. GET_BUFINFO = ZT_GET_BUFINFO ,
. AUDIOMODE = ZT_AUDIOMODE ,
. ECHOCANCEL = ZT_ECHOCANCEL ,
. HDLCRAWMODE = ZT_HDLCRAWMODE ,
. HDLCFCSMODE = ZT_HDLCFCSMODE ,
. SPECIFY = ZT_SPECIFY ,
. SETLAW = ZT_SETLAW ,
. SETLINEAR = ZT_SETLINEAR ,
. GETCONFMUTE = ZT_GETCONFMUTE ,
. ECHOTRAIN = ZT_ECHOTRAIN ,
. SETTXBITS = ZT_SETTXBITS ,
. GETRXBITS = ZT_GETRXBITS
} ;
static struct ioctl_codes dahdi_ioctl_codes = {
. GET_BLOCKSIZE = DAHDI_GET_BLOCKSIZE ,
. SET_BLOCKSIZE = DAHDI_SET_BLOCKSIZE ,
. FLUSH = DAHDI_FLUSH ,
. SYNC = DAHDI_SYNC ,
. GET_PARAMS = DAHDI_GET_PARAMS ,
. SET_PARAMS = DAHDI_SET_PARAMS ,
. HOOK = DAHDI_HOOK ,
. GETEVENT = DAHDI_GETEVENT ,
. IOMUX = DAHDI_IOMUX ,
. SPANSTAT = DAHDI_SPANSTAT ,
. MAINT = DAHDI_MAINT ,
. GETCONF = DAHDI_GETCONF ,
. SETCONF = DAHDI_SETCONF ,
. CONFLINK = DAHDI_CONFLINK ,
. CONFDIAG = DAHDI_CONFDIAG ,
. GETGAINS = DAHDI_GETGAINS ,
. SETGAINS = DAHDI_SETGAINS ,
. SPANCONFIG = DAHDI_SPANCONFIG ,
. CHANCONFIG = DAHDI_CHANCONFIG ,
. SET_BUFINFO = DAHDI_SET_BUFINFO ,
. GET_BUFINFO = DAHDI_GET_BUFINFO ,
. AUDIOMODE = DAHDI_AUDIOMODE ,
. ECHOCANCEL = DAHDI_ECHOCANCEL ,
. HDLCRAWMODE = DAHDI_HDLCRAWMODE ,
. HDLCFCSMODE = DAHDI_HDLCFCSMODE ,
. SPECIFY = DAHDI_SPECIFY ,
. SETLAW = DAHDI_SETLAW ,
. SETLINEAR = DAHDI_SETLINEAR ,
. GETCONFMUTE = DAHDI_GETCONFMUTE ,
. ECHOTRAIN = DAHDI_ECHOTRAIN ,
. SETTXBITS = DAHDI_SETTXBITS ,
. GETRXBITS = DAHDI_GETRXBITS
} ;
2007-05-30 01:01:32 +00:00
# define ZT_INVALID_SOCKET -1
2009-03-04 21:31:08 +00:00
static struct ioctl_codes codes ;
static const char * ctlpath = NULL ;
static const char * chanpath = NULL ;
static const char dahdi_ctlpath [ ] = " /dev/dahdi/ctl " ;
static const char dahdi_chanpath [ ] = " /dev/dahdi/channel " ;
static const char zt_ctlpath [ ] = " /dev/zap/ctl " ;
static const char zt_chanpath [ ] = " /dev/zap/channel " ;
2007-06-23 18:51:10 +00:00
static zap_socket_t CONTROL_FD = ZT_INVALID_SOCKET ;
2007-05-30 01:01:32 +00:00
2008-02-18 17:17:38 +00:00
ZIO_SPAN_NEXT_EVENT_FUNCTION ( zt_next_event ) ;
ZIO_SPAN_POLL_EVENT_FUNCTION ( zt_poll_event ) ;
2009-06-04 16:18:22 +00:00
static void zt_build_gains ( struct zt_gains * g , float rxgain , float txgain , int codec )
{
int j ;
int k ;
float linear_rxgain = pow ( 10.0 , rxgain / 20.0 ) ;
float linear_txgain = pow ( 10.0 , txgain / 20.0 ) ;
switch ( codec ) {
case ZAP_CODEC_ALAW :
for ( j = 0 ; j < ( sizeof ( g - > receive_gain ) / sizeof ( g - > receive_gain [ 0 ] ) ) ; j + + ) {
if ( rxgain ) {
k = ( int ) ( ( ( float ) alaw_to_linear ( j ) ) * linear_rxgain ) ;
if ( k > 32767 ) k = 32767 ;
if ( k < - 32767 ) k = - 32767 ;
g - > receive_gain [ j ] = linear_to_alaw ( k ) ;
} else {
g - > receive_gain [ j ] = j ;
}
if ( txgain ) {
k = ( int ) ( ( ( float ) alaw_to_linear ( j ) ) * linear_txgain ) ;
if ( k > 32767 ) k = 32767 ;
if ( k < - 32767 ) k = - 32767 ;
g - > transmit_gain [ j ] = linear_to_alaw ( k ) ;
} else {
g - > transmit_gain [ j ] = j ;
}
}
break ;
case ZAP_CODEC_ULAW :
for ( j = 0 ; j < ( sizeof ( g - > receive_gain ) / sizeof ( g - > receive_gain [ 0 ] ) ) ; j + + ) {
if ( rxgain ) {
k = ( int ) ( ( ( float ) ulaw_to_linear ( j ) ) * linear_rxgain ) ;
if ( k > 32767 ) k = 32767 ;
if ( k < - 32767 ) k = - 32767 ;
g - > receive_gain [ j ] = linear_to_ulaw ( k ) ;
} else {
g - > receive_gain [ j ] = j ;
}
if ( txgain ) {
k = ( int ) ( ( ( float ) ulaw_to_linear ( j ) ) * linear_txgain ) ;
if ( k > 32767 ) k = 32767 ;
if ( k < - 32767 ) k = - 32767 ;
g - > transmit_gain [ j ] = linear_to_ulaw ( k ) ;
} else {
g - > transmit_gain [ j ] = j ;
}
}
break ;
}
}
2008-10-10 16:02:09 +00:00
static unsigned zt_open_range ( zap_span_t * span , unsigned start , unsigned end , zap_chan_type_t type , char * name , char * number , unsigned char cas_bits )
2007-05-30 01:01:32 +00:00
{
unsigned configured = 0 , x ;
2007-06-05 04:37:50 +00:00
zt_params_t ztp ;
memset ( & ztp , 0 , sizeof ( ztp ) ) ;
2007-05-30 01:01:32 +00:00
2008-10-10 16:02:09 +00:00
if ( type = = ZAP_CHAN_TYPE_CAS ) {
zap_log ( ZAP_LOG_DEBUG , " Configuring CAS channels with abcd == 0x%X \n " , cas_bits ) ;
}
2007-05-30 01:01:32 +00:00
for ( x = start ; x < end ; x + + ) {
2007-06-21 02:13:41 +00:00
zap_channel_t * zchan ;
2007-05-30 01:01:32 +00:00
zap_socket_t sockfd = ZT_INVALID_SOCKET ;
2007-05-31 02:41:50 +00:00
int len ;
2007-05-30 01:01:32 +00:00
2009-03-04 21:31:08 +00:00
sockfd = open ( chanpath , O_RDWR ) ;
2007-06-21 02:13:41 +00:00
if ( sockfd ! = ZT_INVALID_SOCKET & & zap_span_add_channel ( span , sockfd , type , & zchan ) = = ZAP_SUCCESS ) {
2007-06-20 20:30:10 +00:00
2009-03-04 21:31:08 +00:00
if ( ioctl ( sockfd , codes . SPECIFY , & x ) ) {
zap_log ( ZAP_LOG_ERROR , " failure configuring device %s chan %d fd %d (%s) \n " , chanpath , x , sockfd , strerror ( errno ) ) ;
2007-06-20 20:30:10 +00:00
close ( sockfd ) ;
continue ;
}
2007-06-21 02:13:41 +00:00
if ( zchan - > type = = ZAP_CHAN_TYPE_DQ921 ) {
2007-06-20 20:30:10 +00:00
struct zt_bufferinfo binfo ;
memset ( & binfo , 0 , sizeof ( binfo ) ) ;
binfo . txbufpolicy = 0 ;
binfo . rxbufpolicy = 0 ;
binfo . numbufs = 32 ;
binfo . bufsize = 1024 ;
2009-03-04 21:31:08 +00:00
if ( ioctl ( sockfd , codes . SET_BUFINFO , & binfo ) ) {
zap_log ( ZAP_LOG_ERROR , " failure configuring device %s as OpenZAP device %d:%d fd:%d \n " , chanpath , zchan - > span_id , zchan - > chan_id , sockfd ) ;
2007-06-20 20:30:10 +00:00
close ( sockfd ) ;
continue ;
}
}
2007-06-20 17:53:09 +00:00
2007-06-18 21:32:56 +00:00
if ( type = = ZAP_CHAN_TYPE_FXS | | type = = ZAP_CHAN_TYPE_FXO ) {
struct zt_chanconfig cc ;
memset ( & cc , 0 , sizeof ( cc ) ) ;
cc . chan = cc . master = x ;
2008-02-18 16:15:24 +00:00
2007-06-18 21:32:56 +00:00
switch ( type ) {
case ZAP_CHAN_TYPE_FXS :
{
switch ( span - > start_type ) {
case ZAP_ANALOG_START_KEWL :
cc . sigtype = ZT_SIG_FXOKS ;
break ;
case ZAP_ANALOG_START_LOOP :
cc . sigtype = ZT_SIG_FXOLS ;
break ;
case ZAP_ANALOG_START_GROUND :
cc . sigtype = ZT_SIG_FXOGS ;
break ;
default :
break ;
}
}
break ;
case ZAP_CHAN_TYPE_FXO :
{
switch ( span - > start_type ) {
case ZAP_ANALOG_START_KEWL :
cc . sigtype = ZT_SIG_FXSKS ;
break ;
case ZAP_ANALOG_START_LOOP :
cc . sigtype = ZT_SIG_FXSLS ;
break ;
case ZAP_ANALOG_START_GROUND :
cc . sigtype = ZT_SIG_FXSGS ;
break ;
default :
break ;
}
}
break ;
default :
break ;
}
2008-02-18 16:15:24 +00:00
2009-03-04 21:31:08 +00:00
if ( ioctl ( CONTROL_FD , codes . CHANCONFIG , & cc ) ) {
zap_log ( ZAP_LOG_WARNING , " this ioctl fails on older zaptel but is harmless if you used ztcfg \n [device %s chan %d fd %d (%s)] \n " , chanpath , x , CONTROL_FD , strerror ( errno ) ) ;
2007-06-18 21:32:56 +00:00
}
2007-05-30 01:01:32 +00:00
}
2007-05-31 02:41:50 +00:00
2008-10-10 16:02:09 +00:00
if ( type = = ZAP_CHAN_TYPE_CAS ) {
struct zt_chanconfig cc ;
memset ( & cc , 0 , sizeof ( cc ) ) ;
cc . chan = cc . master = x ;
cc . sigtype = ZT_SIG_CAS ;
cc . idlebits = cas_bits ;
2009-03-04 21:31:08 +00:00
if ( ioctl ( CONTROL_FD , codes . CHANCONFIG , & cc ) ) {
zap_log ( ZAP_LOG_ERROR , " failure configuring device %s as OpenZAP device %d:%d fd:%d err:%s " , chanpath , zchan - > span_id , zchan - > chan_id , sockfd , strerror ( errno ) ) ;
2008-10-10 16:02:09 +00:00
close ( sockfd ) ;
continue ;
}
}
2007-06-21 02:13:41 +00:00
if ( zchan - > type ! = ZAP_CHAN_TYPE_DQ921 & & zchan - > type ! = ZAP_CHAN_TYPE_DQ931 ) {
2007-06-20 17:53:09 +00:00
len = zt_globals . codec_ms * 8 ;
2009-03-04 21:31:08 +00:00
if ( ioctl ( zchan - > sockfd , codes . SET_BLOCKSIZE , & len ) ) {
2007-06-21 02:13:41 +00:00
zap_log ( ZAP_LOG_ERROR , " failure configuring device %s as OpenZAP device %d:%d fd:%d err:%s \n " ,
2009-03-04 21:31:08 +00:00
chanpath , zchan - > span_id , zchan - > chan_id , sockfd , strerror ( errno ) ) ;
2007-06-20 17:53:09 +00:00
close ( sockfd ) ;
continue ;
}
2007-06-21 02:13:41 +00:00
zchan - > packet_len = len ;
zchan - > effective_interval = zchan - > native_interval = zchan - > packet_len / 8 ;
2007-05-30 01:01:32 +00:00
2007-06-21 02:13:41 +00:00
if ( zchan - > effective_codec = = ZAP_CODEC_SLIN ) {
zchan - > packet_len * = 2 ;
2007-06-20 17:53:09 +00:00
}
2007-05-31 02:41:50 +00:00
}
2007-05-30 01:01:32 +00:00
2009-03-04 21:31:08 +00:00
if ( ioctl ( sockfd , codes . GET_PARAMS , & ztp ) < 0 ) {
zap_log ( ZAP_LOG_ERROR , " failure configuring device %s as OpenZAP device %d:%d fd:%d \n " , chanpath , zchan - > span_id , zchan - > chan_id , sockfd ) ;
2007-05-31 02:41:50 +00:00
close ( sockfd ) ;
2007-05-30 01:01:32 +00:00
continue ;
}
2007-06-21 02:13:41 +00:00
if ( zchan - > type = = ZAP_CHAN_TYPE_DQ921 ) {
2007-06-20 20:30:10 +00:00
if ( ( ztp . sig_type ! = ZT_SIG_HDLCRAW ) & & ( ztp . sig_type ! = ZT_SIG_HDLCFCS ) ) {
2009-03-04 21:31:08 +00:00
zap_log ( ZAP_LOG_ERROR , " failure configuring device %s as OpenZAP device %d:%d fd:%d \n " , chanpath , zchan - > span_id , zchan - > chan_id , sockfd ) ;
2007-06-20 20:30:10 +00:00
close ( sockfd ) ;
continue ;
}
}
2007-06-18 21:32:56 +00:00
2009-03-04 21:31:08 +00:00
zap_log ( ZAP_LOG_INFO , " configuring device %s channel %d as OpenZAP device %d:%d fd:%d \n " , chanpath , x , zchan - > span_id , zchan - > chan_id , sockfd ) ;
2007-06-20 20:30:10 +00:00
2007-06-21 02:13:41 +00:00
zchan - > rate = 8000 ;
zchan - > physical_span_id = ztp . span_no ;
zchan - > physical_chan_id = ztp . chan_no ;
2007-06-04 14:53:12 +00:00
2008-09-17 02:21:28 +00:00
if ( type = = ZAP_CHAN_TYPE_FXS | | type = = ZAP_CHAN_TYPE_FXO | | type = = ZAP_CHAN_TYPE_EM | | type = = ZAP_CHAN_TYPE_B ) {
2007-05-30 01:01:32 +00:00
if ( ztp . g711_type = = ZT_G711_ALAW ) {
2007-06-21 02:13:41 +00:00
zchan - > native_codec = zchan - > effective_codec = ZAP_CODEC_ALAW ;
2007-07-02 14:15:43 +00:00
} else if ( ztp . g711_type = = ZT_G711_MULAW ) {
2007-06-21 02:13:41 +00:00
zchan - > native_codec = zchan - > effective_codec = ZAP_CODEC_ULAW ;
2007-07-02 14:15:43 +00:00
} else {
int type ;
if ( zchan - > span - > trunk_type = = ZAP_TRUNK_E1 ) {
type = ZAP_CODEC_ALAW ;
} else {
type = ZAP_CODEC_ULAW ;
}
zchan - > native_codec = zchan - > effective_codec = type ;
2007-05-30 01:01:32 +00:00
}
2009-06-04 16:18:22 +00:00
if ( zt_globals . rxgain | | zt_globals . txgain ) {
struct zt_gains gains ;
memset ( & gains , 0 , sizeof ( gains ) ) ;
gains . chan_no = ztp . chan_no ;
zt_build_gains ( & gains , zt_globals . rxgain , zt_globals . txgain , zchan - > native_codec ) ;
if ( zt_globals . rxgain )
zap_log ( ZAP_LOG_INFO , " Setting rxgain to %f on channel %d \n " , zt_globals . rxgain , gains . chan_no ) ;
if ( zt_globals . txgain )
zap_log ( ZAP_LOG_INFO , " Setting txgain to %f on channel %d \n " , zt_globals . txgain , gains . chan_no ) ;
if ( ioctl ( sockfd , codes . SETGAINS , & gains ) < 0 ) {
zap_log ( ZAP_LOG_ERROR , " failure configuring device %s as OpenZAP device %d:%d fd:%d \n " , chanpath , zchan - > span_id , zchan - > chan_id , sockfd ) ;
close ( sockfd ) ;
continue ;
}
}
2007-05-30 01:01:32 +00:00
}
2007-06-20 17:53:09 +00:00
2007-05-31 02:41:50 +00:00
ztp . wink_time = zt_globals . wink_ms ;
ztp . flash_time = zt_globals . flash_ms ;
2007-05-30 01:01:32 +00:00
2009-03-04 21:31:08 +00:00
if ( ioctl ( sockfd , codes . SET_PARAMS , & ztp ) < 0 ) {
zap_log ( ZAP_LOG_ERROR , " failure configuring device %s as OpenZAP device %d:%d fd:%d \n " , chanpath , zchan - > span_id , zchan - > chan_id , sockfd ) ;
2007-05-31 02:41:50 +00:00
close ( sockfd ) ;
continue ;
}
2007-06-20 20:30:10 +00:00
2007-05-30 01:01:32 +00:00
if ( ! zap_strlen_zero ( name ) ) {
2007-06-21 02:13:41 +00:00
zap_copy_string ( zchan - > chan_name , name , sizeof ( zchan - > chan_name ) ) ;
2007-05-30 01:01:32 +00:00
}
if ( ! zap_strlen_zero ( number ) ) {
2007-06-21 02:13:41 +00:00
zap_copy_string ( zchan - > chan_number , number , sizeof ( zchan - > chan_number ) ) ;
2007-05-30 01:01:32 +00:00
}
configured + + ;
} else {
2009-03-04 21:31:08 +00:00
zap_log ( ZAP_LOG_ERROR , " failure configuring device %s \n " , chanpath ) ;
2007-05-30 01:01:32 +00:00
}
}
2007-06-23 18:51:10 +00:00
2007-06-18 21:32:56 +00:00
2007-05-30 01:01:32 +00:00
return configured ;
}
2007-05-29 06:53:39 +00:00
static ZIO_CONFIGURE_SPAN_FUNCTION ( zt_configure_span )
2007-05-16 21:59:11 +00:00
{
2007-05-30 01:01:32 +00:00
int items , i ;
2008-10-10 16:02:09 +00:00
char * mydata , * item_list [ 10 ] ;
2007-05-30 01:01:32 +00:00
char * ch , * mx ;
2008-10-10 16:02:09 +00:00
unsigned char cas_bits = 0 ;
2007-05-30 01:01:32 +00:00
int channo ;
int top = 0 ;
unsigned configured = 0 ;
assert ( str ! = NULL ) ;
mydata = strdup ( str ) ;
assert ( mydata ! = NULL ) ;
items = zap_separate_string ( mydata , ' , ' , item_list , ( sizeof ( item_list ) / sizeof ( item_list [ 0 ] ) ) ) ;
for ( i = 0 ; i < items ; i + + ) {
ch = item_list [ i ] ;
if ( ! ( ch ) ) {
zap_log ( ZAP_LOG_ERROR , " Invalid input \n " ) ;
continue ;
}
channo = atoi ( ch ) ;
if ( channo < 0 ) {
zap_log ( ZAP_LOG_ERROR , " Invalid channel number %d \n " , channo ) ;
continue ;
}
if ( ( mx = strchr ( ch , ' - ' ) ) ) {
mx + + ;
top = atoi ( mx ) + 1 ;
} else {
top = channo + 1 ;
}
if ( top < 0 ) {
zap_log ( ZAP_LOG_ERROR , " Invalid range number %d \n " , top ) ;
continue ;
}
2008-10-10 16:02:09 +00:00
if ( ZAP_CHAN_TYPE_CAS = = type & & zap_config_get_cas_bits ( ch , & cas_bits ) ) {
zap_log ( ZAP_LOG_ERROR , " Failed to get CAS bits in CAS channel \n " ) ;
continue ;
}
configured + = zt_open_range ( span , channo , top , type , name , number , cas_bits ) ;
2007-05-30 01:01:32 +00:00
}
free ( mydata ) ;
return configured ;
2007-05-16 21:59:11 +00:00
}
2007-05-29 06:53:39 +00:00
static ZIO_CONFIGURE_FUNCTION ( zt_configure )
2007-05-16 21:59:11 +00:00
{
2007-05-31 02:41:50 +00:00
int num ;
2009-06-04 16:18:22 +00:00
float fnum ;
2007-05-31 02:41:50 +00:00
2007-05-30 01:01:32 +00:00
if ( ! strcasecmp ( category , " defaults " ) ) {
if ( ! strcasecmp ( var , " codec_ms " ) ) {
2007-05-31 02:41:50 +00:00
num = atoi ( val ) ;
if ( num < 10 | | num > 60 ) {
2007-05-30 01:01:32 +00:00
zap_log ( ZAP_LOG_WARNING , " invalid codec ms at line %d \n " , lineno ) ;
} else {
2007-05-31 02:41:50 +00:00
zt_globals . codec_ms = num ;
}
} else if ( ! strcasecmp ( var , " wink_ms " ) ) {
num = atoi ( val ) ;
2007-06-01 15:58:27 +00:00
if ( num < 50 | | num > 3000 ) {
2007-05-31 02:41:50 +00:00
zap_log ( ZAP_LOG_WARNING , " invalid wink ms at line %d \n " , lineno ) ;
} else {
zt_globals . wink_ms = num ;
}
} else if ( ! strcasecmp ( var , " flash_ms " ) ) {
num = atoi ( val ) ;
2007-06-01 15:58:27 +00:00
if ( num < 50 | | num > 3000 ) {
2007-05-31 02:41:50 +00:00
zap_log ( ZAP_LOG_WARNING , " invalid flash ms at line %d \n " , lineno ) ;
} else {
zt_globals . flash_ms = num ;
2007-05-30 01:01:32 +00:00
}
2007-06-01 15:58:27 +00:00
} else if ( ! strcasecmp ( var , " echo_cancel_level " ) ) {
num = atoi ( val ) ;
if ( num < 0 | | num > 256 ) {
zap_log ( ZAP_LOG_WARNING , " invalid echo can val at line %d \n " , lineno ) ;
} else {
zt_globals . eclevel = num ;
}
2009-06-04 16:18:22 +00:00
} else if ( ! strcasecmp ( var , " rxgain " ) ) {
fnum = ( float ) atof ( val ) ;
if ( fnum < - 100.0 | | fnum > 100.0 ) {
zap_log ( ZAP_LOG_WARNING , " invalid rxgain val at line %d \n " , lineno ) ;
} else {
zt_globals . rxgain = fnum ;
zap_log ( ZAP_LOG_INFO , " Setting rxgain val to %f \n " , fnum ) ;
}
} else if ( ! strcasecmp ( var , " txgain " ) ) {
fnum = ( float ) atof ( val ) ;
if ( fnum < - 100.0 | | fnum > 100.0 ) {
zap_log ( ZAP_LOG_WARNING , " invalid txgain val at line %d \n " , lineno ) ;
} else {
zt_globals . txgain = fnum ;
zap_log ( ZAP_LOG_INFO , " Setting txgain val to %f \n " , fnum ) ;
}
2007-05-30 01:01:32 +00:00
}
}
2007-05-31 02:41:50 +00:00
2007-05-30 01:01:32 +00:00
return ZAP_SUCCESS ;
2007-05-16 21:59:11 +00:00
}
2007-05-29 06:53:39 +00:00
static ZIO_OPEN_FUNCTION ( zt_open )
2007-05-16 21:59:11 +00:00
{
2007-06-27 19:18:13 +00:00
zap_channel_set_feature ( zchan , ZAP_CHANNEL_FEATURE_INTERVAL ) ;
2008-02-18 16:15:24 +00:00
2007-06-20 17:53:09 +00:00
if ( zchan - > type = = ZAP_CHAN_TYPE_DQ921 | | zchan - > type = = ZAP_CHAN_TYPE_DQ931 ) {
zchan - > native_codec = zchan - > effective_codec = ZAP_CODEC_NONE ;
} else {
2007-06-20 20:30:10 +00:00
int blocksize = zt_globals . codec_ms * ( zchan - > rate / 1000 ) ;
2007-06-20 17:53:09 +00:00
int err ;
2009-03-04 21:31:08 +00:00
if ( ( err = ioctl ( zchan - > sockfd , codes . SET_BLOCKSIZE , & blocksize ) ) ) {
2007-06-20 17:53:09 +00:00
snprintf ( zchan - > last_error , sizeof ( zchan - > last_error ) , " %s " , strerror ( errno ) ) ;
return ZAP_FAIL ;
} else {
2007-06-20 20:30:10 +00:00
zchan - > effective_interval = zchan - > native_interval ;
zchan - > packet_len = blocksize ;
2007-06-20 17:53:09 +00:00
zchan - > native_codec = zchan - > effective_codec ;
}
2007-06-21 02:13:41 +00:00
if ( zchan - > type = = ZAP_CHAN_TYPE_B ) {
int one = 1 ;
2009-03-04 21:31:08 +00:00
if ( ioctl ( zchan - > sockfd , codes . AUDIOMODE , & one ) ) {
2007-06-21 02:13:41 +00:00
snprintf ( zchan - > last_error , sizeof ( zchan - > last_error ) , " %s " , strerror ( errno ) ) ;
zap_log ( ZAP_LOG_ERROR , " %s \n " , zchan - > last_error ) ;
return ZAP_FAIL ;
}
2008-09-17 02:21:28 +00:00
} else if ( zchan - > type = = ZAP_CHAN_TYPE_FXS | | zchan - > type = = ZAP_CHAN_TYPE_FXO | | zchan - > type = = ZAP_CHAN_TYPE_EM ) {
2007-06-21 02:13:41 +00:00
int len = zt_globals . eclevel ;
2009-03-04 21:31:08 +00:00
if ( ioctl ( zchan - > sockfd , codes . ECHOCANCEL , & len ) ) {
2008-05-14 15:53:02 +00:00
zap_log ( ZAP_LOG_WARNING , " Echo cancel not available for %d:%d \n " , zchan - > span_id , zchan - > chan_id ) ;
//snprintf(zchan->last_error, sizeof(zchan->last_error), "%s", strerror(errno));
//zap_log(ZAP_LOG_ERROR, "%s\n", zchan->last_error);
//return ZAP_FAIL;
} else {
len = zt_globals . etlevel ;
2009-03-04 21:31:08 +00:00
if ( ioctl ( zchan - > sockfd , codes . ECHOTRAIN , & len ) ) {
2008-05-14 15:53:02 +00:00
zap_log ( ZAP_LOG_WARNING , " Echo training not available for %d:%d \n " , zchan - > span_id , zchan - > chan_id ) ;
//snprintf(zchan->last_error, sizeof(zchan->last_error), "%s", strerror(errno));
//zap_log(ZAP_LOG_ERROR, "%s\n", zchan->last_error);
//return ZAP_FAIL;
}
2007-06-21 02:13:41 +00:00
}
}
2007-06-20 17:53:09 +00:00
}
2007-05-30 01:01:32 +00:00
return ZAP_SUCCESS ;
2007-05-16 21:59:11 +00:00
}
2007-05-29 06:53:39 +00:00
static ZIO_CLOSE_FUNCTION ( zt_close )
2007-05-16 21:59:11 +00:00
{
2007-05-30 01:01:32 +00:00
return ZAP_SUCCESS ;
2007-05-16 21:59:11 +00:00
}
2007-05-29 06:53:39 +00:00
static ZIO_COMMAND_FUNCTION ( zt_command )
2007-05-16 21:59:11 +00:00
{
2007-06-05 04:37:50 +00:00
zt_params_t ztp ;
2007-05-30 01:01:32 +00:00
int err = 0 ;
2007-06-05 04:37:50 +00:00
memset ( & ztp , 0 , sizeof ( ztp ) ) ;
2007-05-30 01:01:32 +00:00
switch ( command ) {
2008-07-30 15:05:07 +00:00
case ZAP_COMMAND_ENABLE_ECHOCANCEL :
{
int level = ZAP_COMMAND_OBJ_INT ;
2009-03-04 21:31:08 +00:00
err = ioctl ( zchan - > sockfd , codes . ECHOCANCEL , & level ) ;
2008-07-30 15:05:07 +00:00
ZAP_COMMAND_OBJ_INT = level ;
}
case ZAP_COMMAND_DISABLE_ECHOCANCEL :
{
int level = 0 ;
2009-03-04 21:31:08 +00:00
err = ioctl ( zchan - > sockfd , codes . ECHOCANCEL , & level ) ;
2008-07-30 15:05:07 +00:00
ZAP_COMMAND_OBJ_INT = level ;
}
break ;
case ZAP_COMMAND_ENABLE_ECHOTRAIN :
{
int level = ZAP_COMMAND_OBJ_INT ;
2009-03-04 21:31:08 +00:00
err = ioctl ( zchan - > sockfd , codes . ECHOTRAIN , & level ) ;
2008-07-30 15:05:07 +00:00
ZAP_COMMAND_OBJ_INT = level ;
}
case ZAP_COMMAND_DISABLE_ECHOTRAIN :
{
int level = 0 ;
2009-03-04 21:31:08 +00:00
err = ioctl ( zchan - > sockfd , codes . ECHOTRAIN , & level ) ;
2008-07-30 15:05:07 +00:00
ZAP_COMMAND_OBJ_INT = level ;
}
break ;
2007-05-31 20:15:16 +00:00
case ZAP_COMMAND_OFFHOOK :
{
int command = ZT_OFFHOOK ;
2009-03-04 21:31:08 +00:00
if ( ioctl ( zchan - > sockfd , codes . HOOK , & command ) ) {
2007-05-31 20:15:16 +00:00
snprintf ( zchan - > last_error , sizeof ( zchan - > last_error ) , " OFFHOOK Failed " ) ;
return ZAP_FAIL ;
}
zap_set_flag_locked ( zchan , ZAP_CHANNEL_OFFHOOK ) ;
}
break ;
case ZAP_COMMAND_ONHOOK :
{
int command = ZT_ONHOOK ;
2009-03-04 21:31:08 +00:00
if ( ioctl ( zchan - > sockfd , codes . HOOK , & command ) ) {
2007-05-31 20:15:16 +00:00
snprintf ( zchan - > last_error , sizeof ( zchan - > last_error ) , " ONHOOK Failed " ) ;
return ZAP_FAIL ;
}
zap_clear_flag_locked ( zchan , ZAP_CHANNEL_OFFHOOK ) ;
}
break ;
2008-11-20 23:46:15 +00:00
case ZAP_COMMAND_FLASH :
{
int command = ZT_FLASH ;
2009-03-04 21:31:08 +00:00
if ( ioctl ( zchan - > sockfd , codes . HOOK , & command ) ) {
2008-11-20 23:46:15 +00:00
snprintf ( zchan - > last_error , sizeof ( zchan - > last_error ) , " FLASH Failed " ) ;
return ZAP_FAIL ;
}
}
break ;
2008-12-03 16:02:17 +00:00
case ZAP_COMMAND_WINK :
{
int command = ZT_WINK ;
2009-03-04 21:31:08 +00:00
if ( ioctl ( zchan - > sockfd , codes . HOOK , & command ) ) {
2008-12-03 16:02:17 +00:00
snprintf ( zchan - > last_error , sizeof ( zchan - > last_error ) , " WINK Failed " ) ;
return ZAP_FAIL ;
}
}
break ;
2007-05-31 20:15:16 +00:00
case ZAP_COMMAND_GENERATE_RING_ON :
{
int command = ZT_RING ;
2009-03-04 21:31:08 +00:00
if ( ioctl ( zchan - > sockfd , codes . HOOK , & command ) ) {
2007-05-31 20:15:16 +00:00
snprintf ( zchan - > last_error , sizeof ( zchan - > last_error ) , " Ring Failed " ) ;
return ZAP_FAIL ;
}
zap_set_flag_locked ( zchan , ZAP_CHANNEL_RINGING ) ;
}
break ;
case ZAP_COMMAND_GENERATE_RING_OFF :
{
int command = ZT_RINGOFF ;
2009-03-04 21:31:08 +00:00
if ( ioctl ( zchan - > sockfd , codes . HOOK , & command ) ) {
2007-05-31 20:15:16 +00:00
snprintf ( zchan - > last_error , sizeof ( zchan - > last_error ) , " Ring-off failed " ) ;
return ZAP_FAIL ;
}
zap_clear_flag_locked ( zchan , ZAP_CHANNEL_RINGING ) ;
}
break ;
2007-05-30 01:01:32 +00:00
case ZAP_COMMAND_GET_INTERVAL :
{
2007-06-27 19:18:13 +00:00
2009-03-04 21:31:08 +00:00
if ( ! ( err = ioctl ( zchan - > sockfd , codes . GET_BLOCKSIZE , & zchan - > packet_len ) ) ) {
2007-05-30 01:01:32 +00:00
zchan - > native_interval = zchan - > packet_len / 8 ;
if ( zchan - > effective_codec = = ZAP_CODEC_SLIN ) {
zchan - > packet_len * = 2 ;
}
ZAP_COMMAND_OBJ_INT = zchan - > native_interval ;
2007-06-27 19:18:13 +00:00
}
2007-05-30 01:01:32 +00:00
}
break ;
case ZAP_COMMAND_SET_INTERVAL :
{
int interval = ZAP_COMMAND_OBJ_INT ;
int len = interval * 8 ;
2009-03-04 21:31:08 +00:00
if ( ! ( err = ioctl ( zchan - > sockfd , codes . SET_BLOCKSIZE , & len ) ) ) {
2007-05-30 01:01:32 +00:00
zchan - > packet_len = len ;
zchan - > effective_interval = zchan - > native_interval = zchan - > packet_len / 8 ;
if ( zchan - > effective_codec = = ZAP_CODEC_SLIN ) {
zchan - > packet_len * = 2 ;
}
}
}
break ;
2008-10-10 16:02:09 +00:00
case ZAP_COMMAND_SET_CAS_BITS :
{
int bits = ZAP_COMMAND_OBJ_INT ;
2009-03-04 21:31:08 +00:00
err = ioctl ( zchan - > sockfd , codes . SETTXBITS , & bits ) ;
2008-10-10 16:02:09 +00:00
}
break ;
case ZAP_COMMAND_GET_CAS_BITS :
{
/* probably we should call ZT_GETRXBITS instead? */
ZAP_COMMAND_OBJ_INT = zchan - > cas_bits ;
}
break ;
2007-05-30 01:01:32 +00:00
default :
break ;
} ;
if ( err ) {
snprintf ( zchan - > last_error , sizeof ( zchan - > last_error ) , " %s " , strerror ( errno ) ) ;
return ZAP_FAIL ;
}
return ZAP_SUCCESS ;
2007-05-16 21:59:11 +00:00
}
2007-06-23 18:51:10 +00:00
static ZIO_GET_ALARMS_FUNCTION ( zt_get_alarms )
{
struct zt_spaninfo info ;
memset ( & info , 0 , sizeof ( info ) ) ;
info . span_no = zchan - > physical_span_id ;
2009-03-04 21:31:08 +00:00
if ( ioctl ( CONTROL_FD , codes . SPANSTAT , & info ) ) {
2007-06-23 18:51:10 +00:00
snprintf ( zchan - > last_error , sizeof ( zchan - > last_error ) , " ioctl failed (%s) " , strerror ( errno ) ) ;
snprintf ( zchan - > span - > last_error , sizeof ( zchan - > span - > last_error ) , " ioctl failed (%s) " , strerror ( errno ) ) ;
return ZAP_FAIL ;
}
zchan - > alarm_flags = info . alarms ;
return ZAP_SUCCESS ;
}
2007-05-29 06:53:39 +00:00
static ZIO_WAIT_FUNCTION ( zt_wait )
2007-05-16 21:59:11 +00:00
{
2007-05-30 01:01:32 +00:00
int32_t inflags = 0 ;
int result ;
struct pollfd pfds [ 1 ] ;
if ( * flags & ZAP_READ ) {
inflags | = POLLIN ;
}
if ( * flags & ZAP_WRITE ) {
inflags | = POLLOUT ;
}
if ( * flags & ZAP_EVENTS ) {
inflags | = POLLPRI ;
}
memset ( & pfds [ 0 ] , 0 , sizeof ( pfds [ 0 ] ) ) ;
pfds [ 0 ] . fd = zchan - > sockfd ;
pfds [ 0 ] . events = inflags ;
result = poll ( pfds , 1 , to ) ;
* flags = 0 ;
if ( pfds [ 0 ] . revents & POLLERR ) {
result = - 1 ;
}
if ( result > 0 ) {
2007-06-23 18:51:10 +00:00
inflags = pfds [ 0 ] . revents ;
2007-05-30 01:01:32 +00:00
}
* flags = ZAP_NO_FLAGS ;
if ( result < 0 ) {
snprintf ( zchan - > last_error , sizeof ( zchan - > last_error ) , " Poll failed " ) ;
return ZAP_FAIL ;
}
if ( result = = 0 ) {
return ZAP_TIMEOUT ;
}
if ( inflags & POLLIN ) {
* flags | = ZAP_READ ;
}
if ( inflags & POLLOUT ) {
* flags | = ZAP_WRITE ;
}
if ( inflags & POLLPRI ) {
* flags | = ZAP_EVENTS ;
}
return ZAP_SUCCESS ;
}
ZIO_SPAN_POLL_EVENT_FUNCTION ( zt_poll_event )
{
struct pollfd pfds [ ZAP_MAX_CHANNELS_SPAN ] ;
2007-06-05 04:37:50 +00:00
uint32_t i , j = 0 , k = 0 ;
int r ;
2007-05-30 01:01:32 +00:00
for ( i = 1 ; i < = span - > chan_count ; i + + ) {
memset ( & pfds [ j ] , 0 , sizeof ( pfds [ j ] ) ) ;
2008-09-10 15:25:02 +00:00
pfds [ j ] . fd = span - > channels [ i ] - > sockfd ;
2007-05-30 01:01:32 +00:00
pfds [ j ] . events = POLLPRI ;
j + + ;
}
r = poll ( pfds , j , ms ) ;
if ( r = = 0 ) {
return ZAP_TIMEOUT ;
} else if ( r < 0 | | ( pfds [ i - 1 ] . revents & POLLERR ) ) {
snprintf ( span - > last_error , sizeof ( span - > last_error ) , " %s " , strerror ( errno ) ) ;
return ZAP_FAIL ;
}
for ( i = 1 ; i < = span - > chan_count ; i + + ) {
if ( pfds [ i - 1 ] . revents & POLLPRI ) {
2008-09-10 15:25:02 +00:00
zap_set_flag ( span - > channels [ i ] , ZAP_CHANNEL_EVENT ) ;
span - > channels [ i ] - > last_event_time = zap_current_time_in_ms ( ) ;
2007-05-30 01:01:32 +00:00
k + + ;
}
}
2008-05-09 14:50:21 +00:00
if ( ! k ) {
snprintf ( span - > last_error , sizeof ( span - > last_error ) , " no matching descriptor " ) ;
}
2007-05-30 01:01:32 +00:00
return k ? ZAP_SUCCESS : ZAP_FAIL ;
}
ZIO_SPAN_NEXT_EVENT_FUNCTION ( zt_next_event )
{
2008-01-10 00:47:04 +00:00
uint32_t i , event_id = 0 ;
zap_oob_event_t zt_event_id = 0 ;
2007-05-30 01:01:32 +00:00
for ( i = 1 ; i < = span - > chan_count ; i + + ) {
2008-09-10 15:25:02 +00:00
if ( zap_test_flag ( span - > channels [ i ] , ZAP_CHANNEL_EVENT ) ) {
zap_clear_flag ( span - > channels [ i ] , ZAP_CHANNEL_EVENT ) ;
2009-03-04 21:31:08 +00:00
if ( ioctl ( span - > channels [ i ] - > sockfd , codes . GETEVENT , & zt_event_id ) = = - 1 ) {
2007-05-30 01:01:32 +00:00
snprintf ( span - > last_error , sizeof ( span - > last_error ) , " %s " , strerror ( errno ) ) ;
return ZAP_FAIL ;
}
switch ( zt_event_id ) {
2007-05-31 20:15:16 +00:00
case ZT_EVENT_RINGEROFF :
{
return ZAP_FAIL ;
}
break ;
case ZT_EVENT_RINGERON :
{
return ZAP_FAIL ;
}
break ;
case ZT_EVENT_RINGBEGIN :
{
event_id = ZAP_OOB_RING_START ;
}
break ;
2007-05-30 01:01:32 +00:00
case ZT_EVENT_ONHOOK :
{
event_id = ZAP_OOB_ONHOOK ;
}
break ;
2007-05-31 02:41:50 +00:00
case ZT_EVENT_WINKFLASH :
{
2008-09-17 02:21:28 +00:00
if ( span - > channels [ i ] - > state = = ZAP_CHANNEL_STATE_DOWN | | span - > channels [ i ] - > state = = ZAP_CHANNEL_STATE_DIALING ) {
2007-05-31 02:41:50 +00:00
event_id = ZAP_OOB_WINK ;
} else {
event_id = ZAP_OOB_FLASH ;
}
}
break ;
2007-05-30 01:01:32 +00:00
case ZT_EVENT_RINGOFFHOOK :
{
2008-09-17 02:21:28 +00:00
if ( span - > channels [ i ] - > type = = ZAP_CHAN_TYPE_FXS | | ( span - > channels [ i ] - > type = = ZAP_CHAN_TYPE_EM & & span - > channels [ i ] - > state ! = ZAP_CHANNEL_STATE_UP ) ) {
2008-09-10 15:25:02 +00:00
zap_set_flag_locked ( span - > channels [ i ] , ZAP_CHANNEL_OFFHOOK ) ;
2007-05-30 01:01:32 +00:00
event_id = ZAP_OOB_OFFHOOK ;
2008-09-10 15:25:02 +00:00
} else if ( span - > channels [ i ] - > type = = ZAP_CHAN_TYPE_FXO ) {
2007-05-30 01:01:32 +00:00
event_id = ZAP_OOB_RING_START ;
}
}
break ;
2007-06-23 18:51:10 +00:00
case ZT_EVENT_ALARM :
{
event_id = ZAP_OOB_ALARM_TRAP ;
}
break ;
case ZT_EVENT_NOALARM :
{
event_id = ZAP_OOB_ALARM_CLEAR ;
}
break ;
2008-10-10 16:02:09 +00:00
case ZT_EVENT_BITSCHANGED :
{
event_id = ZAP_OOB_CAS_BITS_CHANGE ;
int bits = 0 ;
2009-03-04 21:31:08 +00:00
int err = ioctl ( span - > channels [ i ] - > sockfd , codes . GETRXBITS , & bits ) ;
2008-10-10 16:02:09 +00:00
if ( err ) {
return ZAP_FAIL ;
}
span - > channels [ i ] - > cas_bits = bits ;
}
break ;
2007-05-30 01:01:32 +00:00
default :
{
2009-01-13 17:26:36 +00:00
zap_log ( ZAP_LOG_WARNING , " Unhandled event %d for %d:%d \n " , zt_event_id , span - > span_id , i ) ;
2007-05-30 01:01:32 +00:00
event_id = ZAP_OOB_INVALID ;
}
break ;
}
2008-09-10 15:25:02 +00:00
span - > channels [ i ] - > last_event_time = 0 ;
2007-05-30 01:01:32 +00:00
span - > event_header . e_type = ZAP_EVENT_OOB ;
span - > event_header . enum_id = event_id ;
2008-09-10 15:25:02 +00:00
span - > event_header . channel = span - > channels [ i ] ;
2007-05-30 01:01:32 +00:00
* event = & span - > event_header ;
return ZAP_SUCCESS ;
}
}
2007-05-16 21:59:11 +00:00
return ZAP_FAIL ;
2007-05-30 01:01:32 +00:00
2007-05-16 21:59:11 +00:00
}
2007-05-30 01:01:32 +00:00
2007-05-29 06:53:39 +00:00
static ZIO_READ_FUNCTION ( zt_read )
2007-05-16 21:59:11 +00:00
{
2007-05-30 01:01:32 +00:00
zap_ssize_t r = 0 ;
2008-01-25 16:42:06 +00:00
int errs = 0 ;
2007-05-30 01:01:32 +00:00
2009-04-13 19:11:27 +00:00
while ( errs + + < 300 ) {
2008-01-25 16:42:06 +00:00
if ( ( r = read ( zchan - > sockfd , data , * datalen ) ) > 0 ) {
break ;
}
2009-04-22 21:22:42 +00:00
if ( r = = 0 ) {
errs - - ;
}
2008-01-25 16:42:06 +00:00
}
2007-06-20 20:30:10 +00:00
2008-01-25 16:42:06 +00:00
if ( r > 0 ) {
2007-05-30 01:01:32 +00:00
* datalen = r ;
2007-06-20 20:30:10 +00:00
if ( zchan - > type = = ZAP_CHAN_TYPE_DQ921 ) {
* datalen - = 2 ;
}
2007-05-30 01:01:32 +00:00
return ZAP_SUCCESS ;
}
2009-04-22 21:22:42 +00:00
return r = = 0 ? ZAP_TIMEOUT : ZAP_FAIL ;
2007-05-16 21:59:11 +00:00
}
2007-05-29 06:53:39 +00:00
static ZIO_WRITE_FUNCTION ( zt_write )
2007-05-16 21:59:11 +00:00
{
2007-05-30 01:01:32 +00:00
zap_ssize_t w = 0 ;
2007-06-20 20:30:10 +00:00
zap_size_t bytes = * datalen ;
2007-05-30 01:01:32 +00:00
2007-06-20 20:30:10 +00:00
if ( zchan - > type = = ZAP_CHAN_TYPE_DQ921 ) {
memset ( data + bytes , 0 , 2 ) ;
bytes + = 2 ;
}
2007-05-30 01:01:32 +00:00
2007-06-20 20:30:10 +00:00
w = write ( zchan - > sockfd , data , bytes ) ;
2007-05-30 01:01:32 +00:00
if ( w > = 0 ) {
* datalen = w ;
return ZAP_SUCCESS ;
}
2007-05-16 21:59:11 +00:00
return ZAP_FAIL ;
}
2007-06-23 18:51:10 +00:00
static ZIO_CHANNEL_DESTROY_FUNCTION ( zt_channel_destroy )
2007-05-31 02:41:50 +00:00
{
close ( zchan - > sockfd ) ;
zchan - > sockfd = ZT_INVALID_SOCKET ;
return ZAP_SUCCESS ;
}
2007-05-29 06:53:39 +00:00
static zap_io_interface_t zt_interface ;
2007-05-16 21:59:11 +00:00
2008-08-29 15:58:59 +00:00
static ZIO_IO_LOAD_FUNCTION ( zt_init )
2007-05-16 20:36:40 +00:00
{
2007-05-29 06:53:39 +00:00
assert ( zio ! = NULL ) ;
2009-03-04 21:31:08 +00:00
struct stat statbuf ;
2007-05-16 21:59:11 +00:00
memset ( & zt_interface , 0 , sizeof ( zt_interface ) ) ;
2007-05-30 01:01:32 +00:00
memset ( & zt_globals , 0 , sizeof ( zt_globals ) ) ;
2009-03-04 21:31:08 +00:00
if ( ! stat ( zt_ctlpath , & statbuf ) ) {
zap_log ( ZAP_LOG_NOTICE , " Using Zaptel control device \n " ) ;
ctlpath = zt_ctlpath ;
chanpath = zt_chanpath ;
memcpy ( & codes , & zt_ioctl_codes , sizeof ( codes ) ) ;
} else if ( ! stat ( dahdi_ctlpath , & statbuf ) ) {
zap_log ( ZAP_LOG_NOTICE , " Using DAHDI control device \n " ) ;
ctlpath = dahdi_ctlpath ;
chanpath = dahdi_chanpath ;
memcpy ( & codes , & dahdi_ioctl_codes , sizeof ( codes ) ) ;
} else {
zap_log ( ZAP_LOG_ERROR , " No DAHDI or Zap control device found in /dev/ \n " ) ;
return ZAP_FAIL ;
}
2007-06-23 18:51:10 +00:00
if ( ( CONTROL_FD = open ( ctlpath , O_RDWR ) ) < 0 ) {
2009-03-04 21:31:08 +00:00
zap_log ( ZAP_LOG_ERROR , " Cannot open control device %s: %s \n " , ctlpath , strerror ( errno ) ) ;
2007-11-06 16:49:29 +00:00
return ZAP_FAIL ;
2007-06-23 18:51:10 +00:00
}
2007-05-30 01:01:32 +00:00
zt_globals . codec_ms = 20 ;
zt_globals . wink_ms = 150 ;
zt_globals . flash_ms = 750 ;
2007-06-01 15:58:27 +00:00
zt_globals . eclevel = 64 ;
2007-06-21 02:13:41 +00:00
zt_globals . etlevel = 0 ;
2007-06-01 15:58:27 +00:00
2007-05-16 21:59:11 +00:00
zt_interface . name = " zt " ;
2007-05-30 01:01:32 +00:00
zt_interface . configure = zt_configure ;
zt_interface . configure_span = zt_configure_span ;
2007-05-16 21:59:11 +00:00
zt_interface . open = zt_open ;
zt_interface . close = zt_close ;
2007-05-31 20:15:16 +00:00
zt_interface . command = zt_command ;
2007-05-16 21:59:11 +00:00
zt_interface . wait = zt_wait ;
zt_interface . read = zt_read ;
zt_interface . write = zt_write ;
2007-05-30 01:01:32 +00:00
zt_interface . poll_event = zt_poll_event ;
zt_interface . next_event = zt_next_event ;
2007-06-23 18:51:10 +00:00
zt_interface . channel_destroy = zt_channel_destroy ;
zt_interface . get_alarms = zt_get_alarms ;
2007-05-29 06:53:39 +00:00
* zio = & zt_interface ;
2007-05-16 20:36:40 +00:00
2007-05-30 01:01:32 +00:00
return ZAP_SUCCESS ;
2007-05-16 20:36:40 +00:00
}
2008-08-29 15:58:59 +00:00
static ZIO_IO_UNLOAD_FUNCTION ( zt_destroy )
2007-05-16 20:36:40 +00:00
{
2007-06-23 18:51:10 +00:00
close ( CONTROL_FD ) ;
2007-05-31 02:41:50 +00:00
memset ( & zt_interface , 0 , sizeof ( zt_interface ) ) ;
return ZAP_SUCCESS ;
2007-05-16 20:36:40 +00:00
}
2007-06-04 14:53:12 +00:00
2008-08-29 15:58:59 +00:00
zap_module_t zap_module = {
" zt " ,
zt_init ,
zt_destroy ,
} ;
2007-06-04 14:53:12 +00:00
/* For Emacs:
* Local Variables :
* mode : c
* indent - tabs - mode : t
* tab - width : 4
* c - basic - offset : 4
* End :
* For VIM :
* vim : set softtabstop = 4 shiftwidth = 4 tabstop = 4 expandtab :
*/