@ -1738,6 +1738,60 @@ static int analogsub_to_dahdisub(enum analog_sub analogsub)
return index ;
return index ;
}
}
/*!
* \ internal
* \ brief Send a dial string to DAHDI .
* \ since 12.0 .0
*
* \ param pvt DAHDI private pointer
* \ param operation DAHDI dial operation to do to string
* \ param dial_str Dial string to send
*
* \ retval 0 on success .
* \ retval non - zero on error .
*/
static int dahdi_dial_str ( struct dahdi_pvt * pvt , int operation , const char * dial_str )
{
int res ;
int offset ;
const char * pos ;
struct dahdi_dialoperation zo = {
. op = operation ,
} ;
/* Convert the W's to ww. */
pos = dial_str ;
for ( offset = 0 ; offset < sizeof ( zo . dialstr ) - 1 ; + + offset ) {
if ( ! * pos ) {
break ;
}
if ( * pos = = ' W ' ) {
/* Convert 'W' to "ww" */
+ + pos ;
if ( offset > = sizeof ( zo . dialstr ) - 3 ) {
/* No room to expand */
break ;
}
zo . dialstr [ offset ] = ' w ' ;
+ + offset ;
zo . dialstr [ offset ] = ' w ' ;
continue ;
}
zo . dialstr [ offset ] = * pos + + ;
}
/* The zo initialization has already terminated the dialstr. */
ast_debug ( 1 , " Channel %d: Dial str '%s' expanded to '%s' sent to DAHDI_DIAL. \n " ,
pvt - > channel , dial_str , zo . dialstr ) ;
res = ioctl ( pvt - > subs [ SUB_REAL ] . dfd , DAHDI_DIAL , & zo ) ;
if ( res ) {
ast_log ( LOG_WARNING , " Channel %d: Couldn't dial '%s': %s \n " ,
pvt - > channel , dial_str , strerror ( errno ) ) ;
}
return res ;
}
static enum analog_event dahdievent_to_analogevent ( int event ) ;
static enum analog_event dahdievent_to_analogevent ( int event ) ;
static int bump_gains ( struct dahdi_pvt * p ) ;
static int bump_gains ( struct dahdi_pvt * p ) ;
static int dahdi_setlinear ( int dfd , int linear ) ;
static int dahdi_setlinear ( int dfd , int linear ) ;
@ -2792,19 +2846,13 @@ static void my_pri_ss7_open_media(void *p)
*/
*/
static void my_pri_dial_digits ( void * p , const char * dial_string )
static void my_pri_dial_digits ( void * p , const char * dial_string )
{
{
struct dahdi_dialoperation zo = {
char dial_str [ DAHDI_MAX_DTMF_BUF ] ;
. op = DAHDI_DIAL_OP_APPEND ,
} ;
struct dahdi_pvt * pvt = p ;
struct dahdi_pvt * pvt = p ;
int res ;
int res ;
snprintf ( zo . dialstr , sizeof ( zo . dialstr ) , " T%s " , dial_string ) ;
snprintf ( dial_str , sizeof ( dial_str ) , " T%s " , dial_string ) ;
ast_debug ( 1 , " Channel %d: Sending '%s' to DAHDI_DIAL. \n " , pvt - > channel , zo . dialstr ) ;
res = dahdi_dial_str ( pvt , DAHDI_DIAL_OP_APPEND , dial_str ) ;
res = ioctl ( pvt - > subs [ SUB_REAL ] . dfd , DAHDI_DIAL , & zo ) ;
if ( ! res ) {
if ( res ) {
ast_log ( LOG_WARNING , " Channel %d: Couldn't dial '%s': %s \n " ,
pvt - > channel , dial_string , strerror ( errno ) ) ;
} else {
pvt - > dialing = 1 ;
pvt - > dialing = 1 ;
}
}
}
}
@ -3095,10 +3143,7 @@ static int my_start(void *pvt)
static int my_dial_digits ( void * pvt , enum analog_sub sub , struct analog_dialoperation * dop )
static int my_dial_digits ( void * pvt , enum analog_sub sub , struct analog_dialoperation * dop )
{
{
int index = analogsub_to_dahdisub ( sub ) ;
int res ;
struct dahdi_pvt * p = pvt ;
struct dahdi_pvt * p = pvt ;
struct dahdi_dialoperation ddop ;
if ( dop - > op ! = ANALOG_DIAL_OP_REPLACE ) {
if ( dop - > op ! = ANALOG_DIAL_OP_REPLACE ) {
ast_log ( LOG_ERROR , " Fix the dial_digits callback! \n " ) ;
ast_log ( LOG_ERROR , " Fix the dial_digits callback! \n " ) ;
@ -3111,17 +3156,7 @@ static int my_dial_digits(void *pvt, enum analog_sub sub, struct analog_dialoper
return - 1 ;
return - 1 ;
}
}
ddop . op = DAHDI_DIAL_OP_REPLACE ;
return dahdi_dial_str ( p , DAHDI_DIAL_OP_REPLACE , dop - > dialstr ) ;
ast_copy_string ( ddop . dialstr , dop - > dialstr , sizeof ( ddop . dialstr ) ) ;
ast_debug ( 1 , " Channel %d: Sending '%s' to DAHDI_DIAL. \n " , p - > channel , ddop . dialstr ) ;
res = ioctl ( p - > subs [ index ] . dfd , DAHDI_DIAL , & ddop ) ;
if ( res = = - 1 ) {
ast_debug ( 1 , " DAHDI_DIAL ioctl failed on %s: %s \n " , ast_channel_name ( p - > owner ) , strerror ( errno ) ) ;
}
return res ;
}
}
static void dahdi_train_ec ( struct dahdi_pvt * p ) ;
static void dahdi_train_ec ( struct dahdi_pvt * p ) ;
@ -4635,18 +4670,12 @@ static int dahdi_digit_begin(struct ast_channel *chan, char digit)
goto out ;
goto out ;
if ( pvt - > pulse | | ioctl ( pvt - > subs [ SUB_REAL ] . dfd , DAHDI_SENDTONE , & dtmf ) ) {
if ( pvt - > pulse | | ioctl ( pvt - > subs [ SUB_REAL ] . dfd , DAHDI_SENDTONE , & dtmf ) ) {
struct dahdi_dialoperation zo = {
char dial_str [ ] = { ' T ' , digit , ' \0 ' } ;
. op = DAHDI_DIAL_OP_APPEND ,
} ;
zo . dialstr [ 0 ] = ' T ' ;
res = dahdi_dial_str ( pvt , DAHDI_DIAL_OP_APPEND , dial_str ) ;
zo . dialstr [ 1 ] = digit ;
if ( ! res ) {
zo . dialstr [ 2 ] = ' \0 ' ;
if ( ( res = ioctl ( pvt - > subs [ SUB_REAL ] . dfd , DAHDI_DIAL , & zo ) ) )
ast_log ( LOG_WARNING , " Channel %s couldn't dial digit %c: %s \n " ,
ast_channel_name ( chan ) , digit , strerror ( errno ) ) ;
else
pvt - > dialing = 1 ;
pvt - > dialing = 1 ;
}
} else {
} else {
ast_debug ( 1 , " Channel %s started VLDTMF digit '%c' \n " ,
ast_debug ( 1 , " Channel %s started VLDTMF digit '%c' \n " ,
ast_channel_name ( chan ) , digit ) ;
ast_channel_name ( chan ) , digit ) ;
@ -8196,7 +8225,7 @@ static struct ast_frame *dahdi_handle_event(struct ast_channel *ast)
dahdi_train_ec ( p ) ;
dahdi_train_ec ( p ) ;
ast_copy_string ( p - > dop . dialstr , p - > echorest , sizeof ( p - > dop . dialstr ) ) ;
ast_copy_string ( p - > dop . dialstr , p - > echorest , sizeof ( p - > dop . dialstr ) ) ;
p - > dop . op = DAHDI_DIAL_OP_REPLACE ;
p - > dop . op = DAHDI_DIAL_OP_REPLACE ;
res = ioctl( p - > subs [ SUB_REAL ] . dfd , DAHDI_DIAL , & p - > dop ) ;
res = dahdi_dial_str( p , p - > dop . op , p - > dop . dialstr ) ;
p - > echobreak = 0 ;
p - > echobreak = 0 ;
} else {
} else {
p - > dialing = 0 ;
p - > dialing = 0 ;
@ -8431,12 +8460,9 @@ static struct ast_frame *dahdi_handle_event(struct ast_channel *ast)
p - > dop . dialstr [ strlen ( p - > dop . dialstr ) - 2 ] = ' \0 ' ;
p - > dop . dialstr [ strlen ( p - > dop . dialstr ) - 2 ] = ' \0 ' ;
} else
} else
p - > echobreak = 0 ;
p - > echobreak = 0 ;
if ( ioctl ( p - > subs [ SUB_REAL ] . dfd , DAHDI_DIAL , & p - > dop ) ) {
if ( dahdi_dial_str ( p , p - > dop . op , p - > dop . dialstr ) ) {
int saveerr = errno ;
x = DAHDI_ONHOOK ;
x = DAHDI_ONHOOK ;
ioctl ( p - > subs [ SUB_REAL ] . dfd , DAHDI_HOOK , & x ) ;
ioctl ( p - > subs [ SUB_REAL ] . dfd , DAHDI_HOOK , & x ) ;
ast_log ( LOG_WARNING , " Dialing failed on channel %d: %s \n " , p - > channel , strerror ( saveerr ) ) ;
return NULL ;
return NULL ;
}
}
p - > dialing = 1 ;
p - > dialing = 1 ;
@ -8470,9 +8496,8 @@ static struct ast_frame *dahdi_handle_event(struct ast_channel *ast)
p - > subs [ idx ] . f . subclass . integer = 0 ;
p - > subs [ idx ] . f . subclass . integer = 0 ;
} else if ( ! ast_strlen_zero ( p - > dop . dialstr ) ) {
} else if ( ! ast_strlen_zero ( p - > dop . dialstr ) ) {
/* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
/* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
res = ioctl ( p - > subs [ SUB_REAL ] . dfd , DAHDI_DIAL , & p - > dop ) ;
res = dahdi_dial_str ( p , p - > dop . op , p - > dop . dialstr ) ;
if ( res < 0 ) {
if ( res ) {
ast_log ( LOG_WARNING , " Unable to initiate dialing on trunk channel %d: %s \n " , p - > channel , strerror ( errno ) ) ;
p - > dop . dialstr [ 0 ] = ' \0 ' ;
p - > dop . dialstr [ 0 ] = ' \0 ' ;
return NULL ;
return NULL ;
} else {
} else {
@ -8843,9 +8868,8 @@ winkflashdone:
case SIG_EMWINK :
case SIG_EMWINK :
/* FGD MF and EMWINK *Must* wait for wink */
/* FGD MF and EMWINK *Must* wait for wink */
if ( ! ast_strlen_zero ( p - > dop . dialstr ) ) {
if ( ! ast_strlen_zero ( p - > dop . dialstr ) ) {
res = ioctl ( p - > subs [ SUB_REAL ] . dfd , DAHDI_DIAL , & p - > dop ) ;
res = dahdi_dial_str ( p , p - > dop . op , p - > dop . dialstr ) ;
if ( res < 0 ) {
if ( res ) {
ast_log ( LOG_WARNING , " Unable to initiate dialing on trunk channel %d: %s \n " , p - > channel , strerror ( errno ) ) ;
p - > dop . dialstr [ 0 ] = ' \0 ' ;
p - > dop . dialstr [ 0 ] = ' \0 ' ;
return NULL ;
return NULL ;
} else
} else
@ -8873,9 +8897,8 @@ winkflashdone:
case SIG_SFWINK :
case SIG_SFWINK :
case SIG_SF_FEATD :
case SIG_SF_FEATD :
if ( ! ast_strlen_zero ( p - > dop . dialstr ) ) {
if ( ! ast_strlen_zero ( p - > dop . dialstr ) ) {
res = ioctl ( p - > subs [ SUB_REAL ] . dfd , DAHDI_DIAL , & p - > dop ) ;
res = dahdi_dial_str ( p , p - > dop . op , p - > dop . dialstr ) ;
if ( res < 0 ) {
if ( res ) {
ast_log ( LOG_WARNING , " Unable to initiate dialing on trunk channel %d: %s \n " , p - > channel , strerror ( errno ) ) ;
p - > dop . dialstr [ 0 ] = ' \0 ' ;
p - > dop . dialstr [ 0 ] = ' \0 ' ;
return NULL ;
return NULL ;
} else
} else
@ -9473,9 +9496,8 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast)
ast_dsp_set_features ( p - > dsp , p - > dsp_features ) ;
ast_dsp_set_features ( p - > dsp , p - > dsp_features ) ;
ast_debug ( 1 , " Got 10 samples of dialtone! \n " ) ;
ast_debug ( 1 , " Got 10 samples of dialtone! \n " ) ;
if ( ! ast_strlen_zero ( p - > dop . dialstr ) ) { /* Dial deferred digits */
if ( ! ast_strlen_zero ( p - > dop . dialstr ) ) { /* Dial deferred digits */
res = ioctl ( p - > subs [ SUB_REAL ] . dfd , DAHDI_DIAL , & p - > dop ) ;
res = dahdi_dial_str ( p , p - > dop . op , p - > dop . dialstr ) ;
if ( res < 0 ) {
if ( res ) {
ast_log ( LOG_WARNING , " Unable to initiate dialing on trunk channel %d \n " , p - > channel ) ;
p - > dop . dialstr [ 0 ] = ' \0 ' ;
p - > dop . dialstr [ 0 ] = ' \0 ' ;
ast_mutex_unlock ( & p - > lock ) ;
ast_mutex_unlock ( & p - > lock ) ;
ast_frfree ( f ) ;
ast_frfree ( f ) ;