2007-05-06 13:54:52 +00:00
/*****************************************************************************\
* * * *
2009-05-11 09:07:58 +00:00
* * LCR * *
2007-05-06 13:54:52 +00:00
* * * *
* * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *
* * Copyright : Andreas Eversberg * *
* * * *
* * mISDN dss1 * *
* * * *
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "main.h"
2008-04-13 17:52:42 +00:00
# include "myisdn.h"
// socket mISDN
2009-05-11 09:07:58 +00:00
//#include <sys/socket.h>
2008-04-13 17:52:42 +00:00
extern " C " {
}
2010-03-11 15:27:28 +00:00
# include <mISDN/q931.h>
2012-07-28 14:24:06 +00:00
# include <mISDN/suppserv.h>
2011-09-24 07:29:28 +00:00
# ifdef OLD_MT_ASSIGN
2008-06-14 06:34:50 +00:00
extern unsigned int mt_assign_pid ;
2011-09-24 07:29:28 +00:00
# endif
2007-05-06 13:54:52 +00:00
# include "ie.cpp"
2010-01-16 10:20:23 +00:00
static int delete_event ( struct lcr_work * work , void * instance , int index ) ;
2007-05-06 13:54:52 +00:00
/*
* constructor
*/
2008-07-26 15:42:16 +00:00
Pdss1 : : Pdss1 ( int type , struct mISDNport * mISDNport , char * portname , struct port_settings * settings , int channel , int exclusive , int mode ) : PmISDN ( type , mISDNport , portname , settings , channel , exclusive , mode )
2007-05-06 13:54:52 +00:00
{
2007-07-07 15:13:20 +00:00
p_callerinfo . itype = ( mISDNport - > ifport - > interface - > extension ) ? INFO_ITYPE_ISDN_EXTENSION : INFO_ITYPE_ISDN ;
2007-05-06 13:54:52 +00:00
p_m_d_ntmode = mISDNport - > ntmode ;
2008-09-21 06:57:51 +00:00
p_m_d_tespecial = mISDNport - > tespecial ;
2007-05-06 13:54:52 +00:00
p_m_d_l3id = 0 ;
2010-01-16 10:20:23 +00:00
memset ( & p_m_d_delete , 0 , sizeof ( p_m_d_delete ) ) ;
add_work ( & p_m_d_delete , delete_event , this , 0 ) ;
2007-05-06 13:54:52 +00:00
p_m_d_ces = - 1 ;
2009-02-15 08:04:14 +00:00
p_m_d_queue [ 0 ] = ' \0 ' ;
2007-05-06 13:54:52 +00:00
p_m_d_notify_pending = NULL ;
2007-07-31 05:34:18 +00:00
p_m_d_collect_cause = 0 ;
p_m_d_collect_location = 0 ;
2007-05-06 13:54:52 +00:00
2008-09-21 06:57:51 +00:00
PDEBUG ( DEBUG_ISDN , " Created new mISDNPort(%s). Currently %d objects use, %s%s port #%d \n " , portname , mISDNport - > use , ( mISDNport - > ntmode ) ? " NT " : " TE " , ( mISDNport - > tespecial ) ? " (special) " : " " , p_m_portnum ) ;
2007-05-06 13:54:52 +00:00
}
/*
* destructor
*/
Pdss1 : : ~ Pdss1 ( )
{
2010-01-16 10:20:23 +00:00
del_work ( & p_m_d_delete ) ;
2007-05-06 13:54:52 +00:00
/* remove queued message */
if ( p_m_d_notify_pending )
message_free ( p_m_d_notify_pending ) ;
}
/*
* create layer 3 message
*/
2008-03-24 10:13:44 +00:00
static struct l3_msg * create_l3msg ( void )
2007-05-06 13:54:52 +00:00
{
2008-03-24 10:13:44 +00:00
struct l3_msg * l3m ;
l3m = alloc_l3_msg ( ) ;
if ( l3m )
return ( l3m ) ;
2007-05-06 13:54:52 +00:00
2007-07-15 10:01:27 +00:00
FATAL ( " Cannot allocate memory, system overloaded. \n " ) ;
exit ( 0 ) ; // make gcc happy
2007-05-06 13:54:52 +00:00
}
/*
* if we received a first reply to the setup message ,
* we will check if we have now channel information
* return : < 0 : error , call is released , - cause is given
* 0 : ok , nothing to do
*/
2008-06-14 06:34:50 +00:00
int Pdss1 : : received_first_reply_to_setup ( unsigned int cmd , int channel , int exclusive )
2007-05-06 13:54:52 +00:00
{
int ret ;
2008-03-24 10:13:44 +00:00
l3_msg * l3m ;
2007-05-06 13:54:52 +00:00
2007-05-27 13:24:02 +00:00
/* correct exclusive to 0, if no explicit channel was given */
2007-05-06 13:54:52 +00:00
if ( exclusive < 0 | | channel < = 0 )
exclusive = 0 ;
/* select scenario */
2009-05-11 09:07:58 +00:00
if ( p_m_b_channel & & p_m_b_exclusive ) {
2007-05-06 13:54:52 +00:00
/*** we gave an exclusive channel (or if we are done) ***/
/* if not first reply, we are done */
if ( p_state ! = PORT_STATE_OUT_SETUP )
return ( 0 ) ;
2007-06-27 06:23:50 +00:00
chan_trace_header ( p_m_mISDNport , this , " CHANNEL SELECTION (first reply to setup) " , DIRECTION_NONE ) ;
2007-05-27 13:24:02 +00:00
add_trace ( " channel " , " request " , " %d (forced) " , p_m_b_channel ) ;
add_trace ( " channel " , " reply " , ( channel > = 0 ) ? " %d " : " (none) " , channel ) ;
2007-05-06 13:54:52 +00:00
/* if give channel not accepted or not equal */
2009-05-11 09:07:58 +00:00
if ( channel ! = - 1 & & p_m_b_channel ! = channel ) {
2007-05-27 13:24:02 +00:00
add_trace ( " conclusion " , NULL , " forced channel not accepted " ) ;
end_trace ( ) ;
2007-05-06 13:54:52 +00:00
ret = - 44 ;
goto channelerror ;
}
2007-05-27 13:24:02 +00:00
add_trace ( " conclusion " , NULL , " channel was accepted " ) ;
add_trace ( " connect " , " channel " , " %d " , p_m_b_channel ) ;
end_trace ( ) ;
2007-05-06 13:54:52 +00:00
/* activate our exclusive channel */
2007-08-12 08:16:19 +00:00
bchannel_event ( p_m_mISDNport , p_m_b_index , B_EVENT_USE ) ;
2007-05-06 13:54:52 +00:00
} else
2009-05-11 09:07:58 +00:00
if ( p_m_b_channel ) {
2007-05-06 13:54:52 +00:00
/*** we gave a non-exclusive channel ***/
/* if not first reply, we are done */
if ( p_state ! = PORT_STATE_OUT_SETUP )
return ( 0 ) ;
2007-06-27 06:23:50 +00:00
chan_trace_header ( p_m_mISDNport , this , " CHANNEL SELECTION (first reply to setup) " , DIRECTION_NONE ) ;
2007-05-27 13:24:02 +00:00
add_trace ( " channel " , " request " , " %d (suggest) " , p_m_b_channel ) ;
add_trace ( " channel " , " reply " , ( channel > = 0 ) ? " %d " : " (none) " , channel ) ;
2007-05-06 13:54:52 +00:00
/* if channel was accepted as given */
2009-05-11 09:07:58 +00:00
if ( channel = = - 1 | | p_m_b_channel = = channel ) {
2007-05-27 13:24:02 +00:00
add_trace ( " conclusion " , NULL , " channel was accepted as given " ) ;
add_trace ( " connect " , " channel " , " %d " , p_m_b_channel ) ;
end_trace ( ) ;
2007-05-06 13:54:52 +00:00
p_m_b_exclusive = 1 ; // we are done
2007-08-12 08:16:19 +00:00
bchannel_event ( p_m_mISDNport , p_m_b_index , B_EVENT_USE ) ;
2007-05-06 13:54:52 +00:00
return ( 0 ) ;
}
/* if channel value is faulty */
2009-05-11 09:07:58 +00:00
if ( channel < = 0 ) {
2007-05-27 13:24:02 +00:00
add_trace ( " conclusion " , NULL , " illegal reply " ) ;
end_trace ( ) ;
2007-05-06 13:54:52 +00:00
ret = - 111 ; // protocol error
goto channelerror ;
}
/* if channel was not accepted, try to get it */
ret = seize_bchannel ( channel , 1 ) ; // exclusively
2007-05-27 13:24:02 +00:00
add_trace ( " channel " , " available " , ret < 0 ? " no " : " yes " ) ;
2009-05-11 09:07:58 +00:00
if ( ret < 0 ) {
2007-05-27 13:24:02 +00:00
add_trace ( " conclusion " , NULL , " replied channel not available " ) ;
end_trace ( ) ;
2007-05-06 13:54:52 +00:00
goto channelerror ;
}
2007-05-27 13:24:02 +00:00
add_trace ( " conclusion " , NULL , " replied channel accepted " ) ;
add_trace ( " connect " , " channel " , " %d " , p_m_b_channel ) ;
end_trace ( ) ;
2007-05-06 13:54:52 +00:00
/* activate channel given by remote */
2007-08-12 08:16:19 +00:00
bchannel_event ( p_m_mISDNport , p_m_b_index , B_EVENT_USE ) ;
2007-05-06 13:54:52 +00:00
} else
2009-05-11 09:07:58 +00:00
if ( p_m_b_reserve ) {
2007-05-06 13:54:52 +00:00
/*** we sent 'any channel acceptable' ***/
/* if not first reply, we are done */
if ( p_state ! = PORT_STATE_OUT_SETUP )
return ( 0 ) ;
2007-06-27 06:23:50 +00:00
chan_trace_header ( p_m_mISDNport , this , " CHANNEL SELECTION (first reply to setup) " , DIRECTION_NONE ) ;
2007-05-27 13:24:02 +00:00
add_trace ( " channel " , " request " , " any " ) ;
add_trace ( " channel " , " reply " , ( channel > = 0 ) ? " %d " : " (none) " , channel ) ;
/* if no channel was replied */
2009-05-11 09:07:58 +00:00
if ( channel < = 0 ) {
2007-05-27 13:24:02 +00:00
add_trace ( " conclusion " , NULL , " no channel, protocol error " ) ;
end_trace ( ) ;
2007-05-06 13:54:52 +00:00
ret = - 111 ; // protocol error
goto channelerror ;
}
/* we will see, if our received channel is available */
ret = seize_bchannel ( channel , 1 ) ; // exclusively
2007-05-27 13:24:02 +00:00
add_trace ( " channel " , " available " , ret < 0 ? " no " : " yes " ) ;
2009-05-11 09:07:58 +00:00
if ( ret < 0 ) {
2007-05-27 13:24:02 +00:00
add_trace ( " conclusion " , NULL , " replied channel not available " ) ;
end_trace ( ) ;
2007-05-06 13:54:52 +00:00
goto channelerror ;
}
2007-05-27 13:24:02 +00:00
add_trace ( " conclusion " , NULL , " replied channel accepted " ) ;
add_trace ( " connect " , " channel " , " %d " , p_m_b_channel ) ;
end_trace ( ) ;
2007-05-06 13:54:52 +00:00
/* activate channel given by remote */
2007-08-12 08:16:19 +00:00
bchannel_event ( p_m_mISDNport , p_m_b_index , B_EVENT_USE ) ;
2009-05-11 09:07:58 +00:00
} else {
2007-05-06 13:54:52 +00:00
/*** we sent 'no channel available' ***/
/* if not the first reply, but a connect, we are forced */
2009-05-11 09:07:58 +00:00
if ( cmd = = MT_CONNECT & & p_state ! = PORT_STATE_OUT_SETUP ) {
2007-06-27 06:23:50 +00:00
chan_trace_header ( p_m_mISDNport , this , " CHANNEL SELECTION (connect) " , DIRECTION_NONE ) ;
2007-05-27 13:24:02 +00:00
add_trace ( " channel " , " request " , " no-channel " ) ;
add_trace ( " channel " , " reply " , ( channel > = 0 ) ? " %d%s " : " (none) " , channel , exclusive ? " (forced) " : " " ) ;
2009-05-11 09:07:58 +00:00
if ( channel > 0 ) {
2007-05-06 13:54:52 +00:00
goto use_from_connect ;
}
ret = seize_bchannel ( CHANNEL_ANY , 0 ) ; // any channel
2007-05-27 13:24:02 +00:00
add_trace ( " channel " , " available " , ret < 0 ? " no " : " yes " ) ;
2009-05-11 09:07:58 +00:00
if ( ret < 0 ) {
2007-05-27 13:24:02 +00:00
add_trace ( " conclusion " , NULL , " no channel available during call-waiting " ) ;
end_trace ( ) ;
2007-05-06 13:54:52 +00:00
goto channelerror ;
}
2007-05-27 13:24:02 +00:00
add_trace ( " conclusion " , NULL , " using channel %d " , p_m_b_channel ) ;
add_trace ( " connect " , " channel " , " %d " , p_m_b_channel ) ;
end_trace ( ) ;
2007-05-06 13:54:52 +00:00
p_m_b_exclusive = 1 ; // we are done
/* activate channel given by remote */
2007-08-12 08:16:19 +00:00
bchannel_event ( p_m_mISDNport , p_m_b_index , B_EVENT_USE ) ;
2007-05-06 13:54:52 +00:00
return ( 0 ) ;
}
/* if not first reply, we are done */
if ( p_state ! = PORT_STATE_OUT_SETUP )
return ( 0 ) ;
2007-06-27 06:23:50 +00:00
chan_trace_header ( p_m_mISDNport , this , " CHANNEL SELECTION (first reply to setup) " , DIRECTION_NONE ) ;
2007-05-27 13:24:02 +00:00
add_trace ( " channel " , " request " , " no-channel " ) ;
add_trace ( " channel " , " reply " , ( channel > = 0 ) ? " %d " : " (none) " , channel ) ;
2007-05-06 13:54:52 +00:00
/* if first reply has no channel, we are done */
2009-05-11 09:07:58 +00:00
if ( channel < = 0 ) {
2007-05-27 13:24:02 +00:00
add_trace ( " conclusion " , NULL , " no channel until connect " ) ;
end_trace ( ) ;
2007-05-06 13:54:52 +00:00
return ( 0 ) ;
}
/* we will see, if our received channel is available */
use_from_connect :
ret = seize_bchannel ( channel , exclusive ) ;
2007-05-27 13:24:02 +00:00
add_trace ( " channel " , " available " , ret < 0 ? " no " : " yes " ) ;
2009-05-11 09:07:58 +00:00
if ( ret < 0 ) {
2007-05-27 13:24:02 +00:00
add_trace ( " conclusion " , NULL , " replied channel not available " ) ;
end_trace ( ) ;
2007-05-06 13:54:52 +00:00
goto channelerror ;
}
2007-05-27 13:24:02 +00:00
add_trace ( " conclusion " , NULL , " replied channel accepted " ) ;
add_trace ( " connect " , " channel " , " %d " , p_m_b_channel ) ;
end_trace ( ) ;
2007-05-06 13:54:52 +00:00
p_m_b_exclusive = 1 ; // we are done
/* activate channel given by remote */
2007-08-12 08:16:19 +00:00
bchannel_event ( p_m_mISDNport , p_m_b_index , B_EVENT_USE ) ;
2007-05-06 13:54:52 +00:00
}
return ( 0 ) ;
channelerror :
2008-03-24 10:13:44 +00:00
/*
* NOTE : we send MT_RELEASE_COMPLETE to " REJECT " the channel
* in response to the setup reply
*/
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_RELEASE_COMPLETE_REQ , DIRECTION_OUT ) ;
2008-03-24 10:13:44 +00:00
enc_ie_cause ( l3m , ( p_m_mISDNport - > locally ) ? LOCATION_PRIVATE_LOCAL : LOCATION_PRIVATE_REMOTE , - ret ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_RELEASE_COMPLETE , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
new_state ( PORT_STATE_RELEASE ) ;
2010-01-16 10:20:23 +00:00
trigger_work ( & p_m_d_delete ) ;
2007-05-06 13:54:52 +00:00
return ( - 34 ) ; /* to epoint: no channel available */
}
2007-06-27 06:23:50 +00:00
/*
2008-01-19 17:10:46 +00:00
* hunt bchannel for incoming setup or retrieve or resume
2007-06-27 06:23:50 +00:00
*/
int Pdss1 : : hunt_bchannel ( int channel , int exclusive )
{
struct select_channel * selchannel ;
struct interface_port * ifport = p_m_mISDNport - > ifport ;
int i ;
chan_trace_header ( p_m_mISDNport , this , " CHANNEL SELECTION (setup) " , DIRECTION_NONE ) ;
if ( exclusive < 0 )
exclusive = 0 ;
if ( channel = = CHANNEL_NO )
add_trace ( " channel " , " request " , " no-channel " ) ;
else
add_trace ( " channel " , " request " , ( channel > 0 ) ? " %d%s " : " any " , channel , exclusive ? " (forced) " : " " ) ;
2009-05-11 09:07:58 +00:00
if ( channel = = CHANNEL_NO & & p_type = = PORT_TYPE_DSS1_TE_IN ) {
2007-06-27 06:23:50 +00:00
add_trace ( " conclusion " , NULL , " incoming call-waiting not supported for TE-mode " ) ;
end_trace ( ) ;
return ( - 6 ) ; // channel unacceptable
}
if ( channel < = 0 ) /* not given, no channel, whatever.. */
channel = CHANNEL_ANY ; /* any channel */
2008-01-05 21:58:22 +00:00
add_trace ( " channel " , " reserved " , " %d " , p_m_mISDNport - > b_reserved ) ;
2009-05-11 09:07:58 +00:00
if ( p_m_mISDNport - > b_reserved > = p_m_mISDNport - > b_num ) { // of out chan..
2007-06-27 06:23:50 +00:00
add_trace ( " conclusion " , NULL , " all channels are reserved " ) ;
end_trace ( ) ;
return ( - 34 ) ; // no channel
}
if ( channel = = CHANNEL_ANY )
goto get_from_list ;
2009-05-11 09:07:58 +00:00
if ( channel > 0 ) {
2007-06-27 06:23:50 +00:00
/* check for given channel in selection list */
selchannel = ifport - > in_channel ;
2009-05-11 09:07:58 +00:00
while ( selchannel ) {
2007-06-27 06:23:50 +00:00
if ( selchannel - > channel = = channel | | selchannel - > channel = = CHANNEL_FREE )
break ;
selchannel = selchannel - > next ;
}
if ( ! selchannel )
channel = 0 ;
/* exclusive channel requests must be in the list */
2009-05-11 09:07:58 +00:00
if ( exclusive ) {
2008-07-08 19:46:35 +00:00
/* no exclusive channel */
2009-05-11 09:07:58 +00:00
if ( ! channel ) {
2007-06-27 06:23:50 +00:00
add_trace ( " conclusion " , NULL , " exclusively requested channel not in list " ) ;
end_trace ( ) ;
return ( - 6 ) ; // channel unacceptable
}
2008-07-08 19:46:35 +00:00
/* get index for channel */
i = channel - 1 - ( channel > = 17 ) ;
2009-05-11 09:07:58 +00:00
if ( i < 0 | | i > = p_m_mISDNport - > b_num | | channel = = 16 ) {
2008-07-08 19:46:35 +00:00
add_trace ( " conclusion " , NULL , " exclusively requested channel outside interface range " ) ;
end_trace ( ) ;
return ( - 6 ) ; // channel unacceptable
}
/* check if busy */
2007-06-27 06:23:50 +00:00
if ( p_m_mISDNport - > b_port [ i ] = = NULL )
goto use_channel ;
add_trace ( " conclusion " , NULL , " exclusively requested channel is busy " ) ;
end_trace ( ) ;
return ( - 6 ) ; // channel unacceptable
}
/* requested channels in list will be used */
2009-05-11 09:07:58 +00:00
if ( channel ) {
2008-07-08 19:46:35 +00:00
/* get index for channel */
i = channel - 1 - ( channel > = 17 ) ;
2009-05-11 09:07:58 +00:00
if ( i < 0 | | i > = p_m_mISDNport - > b_num | | channel = = 16 ) {
2008-07-08 19:46:35 +00:00
add_trace ( " info " , NULL , " requested channel %d outside interface range " , channel ) ;
} else /* if inside range (else) check if available */
2007-06-27 06:23:50 +00:00
if ( p_m_mISDNport - > b_port [ i ] = = NULL )
goto use_channel ;
}
/* if channel is not available or not in list, it must be searched */
get_from_list :
/* check for first free channel in list */
channel = 0 ;
selchannel = ifport - > in_channel ;
2009-05-11 09:07:58 +00:00
while ( selchannel ) {
switch ( selchannel - > channel ) {
2007-06-27 06:23:50 +00:00
case CHANNEL_FREE : /* free channel */
add_trace ( " hunting " , " channel " , " free " ) ;
if ( p_m_mISDNport - > b_reserved > = p_m_mISDNport - > b_num )
break ; /* all channel in use or reserverd */
/* find channel */
i = 0 ;
2009-05-11 09:07:58 +00:00
while ( i < p_m_mISDNport - > b_num ) {
if ( p_m_mISDNport - > b_port [ i ] = = NULL ) {
2007-06-27 06:23:50 +00:00
channel = i + 1 + ( i > = 15 ) ;
break ;
}
i + + ;
}
break ;
default :
add_trace ( " hunting " , " channel " , " %d " , selchannel - > channel ) ;
if ( selchannel - > channel < 1 | | selchannel - > channel = = 16 )
break ; /* invalid channels */
i = selchannel - > channel - 1 - ( selchannel - > channel > = 17 ) ;
if ( i > = p_m_mISDNport - > b_num )
break ; /* channel not in port */
2009-05-11 09:07:58 +00:00
if ( p_m_mISDNport - > b_port [ i ] = = NULL ) {
2007-06-27 06:23:50 +00:00
channel = selchannel - > channel ;
break ;
}
break ;
}
if ( channel )
break ; /* found channel */
selchannel = selchannel - > next ;
}
2009-05-11 09:07:58 +00:00
if ( ! channel ) {
2007-06-27 06:23:50 +00:00
add_trace ( " conclusion " , NULL , " no channel available " ) ;
end_trace ( ) ;
return ( - 6 ) ; // channel unacceptable
}
}
use_channel :
add_trace ( " conclusion " , NULL , " channel available " ) ;
2007-07-07 15:13:20 +00:00
add_trace ( " connect " , " channel " , " %d " , channel ) ;
2007-06-27 06:23:50 +00:00
end_trace ( ) ;
return ( channel ) ;
}
2007-05-06 13:54:52 +00:00
/*
* handles all indications
*/
/* CC_SETUP INDICATION */
2008-04-12 16:24:31 +00:00
void Pdss1 : : setup_ind ( unsigned int cmd , unsigned int pid , struct l3_msg * l3m )
{
2007-06-27 06:23:50 +00:00
int calling_type , calling_plan , calling_present , calling_screen ;
2008-11-04 08:31:09 +00:00
int calling_type2 , calling_plan2 , calling_present2 , calling_screen2 ;
2007-06-27 06:23:50 +00:00
int called_type , called_plan ;
int redir_type , redir_plan , redir_present , redir_screen , redir_reason ;
int hlc_coding , hlc_presentation , hlc_interpretation , hlc_hlc , hlc_exthlc ;
int bearer_coding , bearer_capability , bearer_mode , bearer_rate , bearer_multi , bearer_user ;
2007-05-06 13:54:52 +00:00
int exclusive , channel ;
int ret ;
2009-10-27 07:02:16 +00:00
unsigned char keypad [ 33 ] = " " ;
2007-05-06 13:54:52 +00:00
unsigned char useruser [ 128 ] ;
int useruser_len = 0 , useruser_protocol ;
class Endpoint * epoint ;
2008-04-25 07:06:20 +00:00
struct lcr_msg * message ;
2007-05-06 13:54:52 +00:00
2008-04-13 17:52:42 +00:00
/* process given callref */
l1l2l3_trace_header ( p_m_mISDNport , this , L3_NEW_L3ID_IND , DIRECTION_IN ) ;
add_trace ( " callref " , " new " , " 0x%x " , pid ) ;
2009-05-11 09:07:58 +00:00
if ( p_m_d_l3id ) {
2008-04-24 07:24:04 +00:00
/* release in case the ID is already in use */
2008-04-13 17:52:42 +00:00
add_trace ( " error " , NULL , " callref already in use " ) ;
end_trace ( ) ;
l3m = create_l3msg ( ) ;
l1l2l3_trace_header ( p_m_mISDNport , this , L3_RELEASE_COMPLETE_REQ , DIRECTION_OUT ) ;
enc_ie_cause ( l3m , ( p_m_mISDNport - > locally ) ? LOCATION_PRIVATE_LOCAL : LOCATION_PRIVATE_REMOTE , 47 ) ;
add_trace ( " reason " , NULL , " callref already in use " ) ;
end_trace ( ) ;
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_RELEASE_COMPLETE , pid , l3m ) ;
new_state ( PORT_STATE_RELEASE ) ;
2010-01-16 10:20:23 +00:00
trigger_work ( & p_m_d_delete ) ;
2008-04-13 17:52:42 +00:00
return ;
}
p_m_d_l3id = pid ;
p_m_d_ces = pid > > 16 ;
end_trace ( ) ;
2007-05-27 13:24:02 +00:00
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_SETUP_IND , DIRECTION_IN ) ;
2008-11-04 08:31:09 +00:00
dec_ie_calling_pn ( l3m , & calling_type , & calling_plan , & calling_present , & calling_screen , ( unsigned char * ) p_callerinfo . id , sizeof ( p_callerinfo . id ) , & calling_type2 , & calling_plan2 , & calling_present2 , & calling_screen2 , ( unsigned char * ) p_callerinfo . id2 , sizeof ( p_callerinfo . id2 ) ) ;
2008-04-12 16:24:31 +00:00
dec_ie_called_pn ( l3m , & called_type , & called_plan , ( unsigned char * ) p_dialinginfo . id , sizeof ( p_dialinginfo . id ) ) ;
dec_ie_keypad ( l3m , ( unsigned char * ) keypad , sizeof ( keypad ) ) ;
/* te-mode: CNIP (calling name identification presentation) */
2008-09-21 06:57:51 +00:00
dec_facility_centrex ( l3m , ( unsigned char * ) p_callerinfo . name , sizeof ( p_callerinfo . name ) ) ;
2008-04-12 16:24:31 +00:00
dec_ie_useruser ( l3m , & useruser_protocol , useruser , & useruser_len ) ;
dec_ie_complete ( l3m , & p_dialinginfo . sending_complete ) ;
dec_ie_redir_nr ( l3m , & redir_type , & redir_plan , & redir_present , & redir_screen , & redir_reason , ( unsigned char * ) p_redirinfo . id , sizeof ( p_redirinfo . id ) ) ;
dec_ie_channel_id ( l3m , & exclusive , & channel ) ;
dec_ie_hlc ( l3m , & hlc_coding , & hlc_interpretation , & hlc_presentation , & hlc_hlc , & hlc_exthlc ) ;
dec_ie_bearer ( l3m , & bearer_coding , & bearer_capability , & bearer_mode , & bearer_rate , & bearer_multi , & bearer_user ) ;
2008-07-03 17:08:37 +00:00
dec_ie_display ( l3m , ( unsigned char * ) p_dialinginfo . display , sizeof ( p_dialinginfo . display ) ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-03-24 10:13:44 +00:00
/* if blocked, release call with MT_RELEASE_COMPLETE */
2009-05-11 09:07:58 +00:00
if ( p_m_mISDNport - > ifport - > block ) {
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_RELEASE_COMPLETE_REQ , DIRECTION_OUT ) ;
2008-03-24 10:13:44 +00:00
enc_ie_cause ( l3m , ( p_m_mISDNport - > locally ) ? LOCATION_PRIVATE_LOCAL : LOCATION_PRIVATE_REMOTE , 27 ) ; /* temporary unavailable */
2007-05-27 13:24:02 +00:00
add_trace ( " reason " , NULL , " port blocked " ) ;
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_RELEASE_COMPLETE , p_m_d_l3id , l3m ) ;
2007-05-09 05:39:20 +00:00
new_state ( PORT_STATE_RELEASE ) ;
2010-01-16 10:20:23 +00:00
trigger_work ( & p_m_d_delete ) ;
2007-05-09 05:39:20 +00:00
return ;
}
2007-05-27 13:24:02 +00:00
/* caller info */
2009-05-11 09:07:58 +00:00
switch ( calling_present ) {
2007-05-06 13:54:52 +00:00
case 1 :
p_callerinfo . present = INFO_PRESENT_RESTRICTED ;
break ;
case 2 :
p_callerinfo . present = INFO_PRESENT_NOTAVAIL ;
break ;
default :
p_callerinfo . present = INFO_PRESENT_ALLOWED ;
break ;
}
2009-05-11 09:07:58 +00:00
switch ( calling_screen ) {
2007-05-06 13:54:52 +00:00
case 0 :
p_callerinfo . screen = INFO_SCREEN_USER ;
break ;
2009-09-04 08:26:10 +00:00
case 1 :
p_callerinfo . screen = INFO_SCREEN_USER_VERIFIED_PASSED ;
break ;
case 2 :
p_callerinfo . screen = INFO_SCREEN_USER_VERIFIED_FAILED ;
break ;
2007-05-06 13:54:52 +00:00
default :
p_callerinfo . screen = INFO_SCREEN_NETWORK ;
break ;
}
2009-05-11 09:07:58 +00:00
switch ( calling_type ) {
2007-05-06 13:54:52 +00:00
case - 1 :
2008-11-04 08:31:09 +00:00
p_callerinfo . ntype = INFO_NTYPE_NOTPRESENT ;
break ;
case 0x0 :
2007-05-06 13:54:52 +00:00
p_callerinfo . ntype = INFO_NTYPE_UNKNOWN ;
break ;
case 0x1 :
p_callerinfo . ntype = INFO_NTYPE_INTERNATIONAL ;
break ;
case 0x2 :
p_callerinfo . ntype = INFO_NTYPE_NATIONAL ;
break ;
case 0x4 :
p_callerinfo . ntype = INFO_NTYPE_SUBSCRIBER ;
break ;
default :
p_callerinfo . ntype = INFO_NTYPE_UNKNOWN ;
break ;
}
p_callerinfo . isdn_port = p_m_portnum ;
2007-05-15 20:59:29 +00:00
SCPY ( p_callerinfo . interface , p_m_mISDNport - > ifport - > interface - > name ) ;
2007-05-27 13:24:02 +00:00
2008-11-04 08:31:09 +00:00
/* caller info2 */
2009-05-11 09:07:58 +00:00
switch ( calling_present2 ) {
2008-11-04 08:31:09 +00:00
case 1 :
p_callerinfo . present2 = INFO_PRESENT_RESTRICTED ;
break ;
case 2 :
p_callerinfo . present2 = INFO_PRESENT_NOTAVAIL ;
break ;
default :
p_callerinfo . present2 = INFO_PRESENT_ALLOWED ;
break ;
}
2009-05-11 09:07:58 +00:00
switch ( calling_screen2 ) {
2008-11-04 08:31:09 +00:00
case 0 :
p_callerinfo . screen2 = INFO_SCREEN_USER ;
break ;
2009-09-04 08:26:10 +00:00
case 1 :
p_callerinfo . screen2 = INFO_SCREEN_USER_VERIFIED_PASSED ;
break ;
case 2 :
p_callerinfo . screen2 = INFO_SCREEN_USER_VERIFIED_FAILED ;
break ;
2008-11-04 08:31:09 +00:00
default :
p_callerinfo . screen2 = INFO_SCREEN_NETWORK ;
break ;
}
2009-05-11 09:07:58 +00:00
switch ( calling_type2 ) {
2008-11-04 08:31:09 +00:00
case - 1 :
p_callerinfo . ntype2 = INFO_NTYPE_NOTPRESENT ;
break ;
case 0x0 :
p_callerinfo . ntype2 = INFO_NTYPE_UNKNOWN ;
break ;
case 0x1 :
p_callerinfo . ntype2 = INFO_NTYPE_INTERNATIONAL ;
break ;
case 0x2 :
p_callerinfo . ntype2 = INFO_NTYPE_NATIONAL ;
break ;
case 0x4 :
p_callerinfo . ntype2 = INFO_NTYPE_SUBSCRIBER ;
break ;
default :
p_callerinfo . ntype2 = INFO_NTYPE_UNKNOWN ;
break ;
}
2007-05-06 13:54:52 +00:00
/* dialing information */
2007-07-07 15:13:20 +00:00
SCAT ( p_dialinginfo . id , ( char * ) keypad ) ;
2009-05-11 09:07:58 +00:00
switch ( called_type ) {
2007-05-06 13:54:52 +00:00
case 0x1 :
p_dialinginfo . ntype = INFO_NTYPE_INTERNATIONAL ;
break ;
case 0x2 :
p_dialinginfo . ntype = INFO_NTYPE_NATIONAL ;
break ;
case 0x4 :
p_dialinginfo . ntype = INFO_NTYPE_SUBSCRIBER ;
break ;
default :
p_dialinginfo . ntype = INFO_NTYPE_UNKNOWN ;
break ;
}
2007-06-27 06:23:50 +00:00
/* redir info */
2009-05-11 09:07:58 +00:00
switch ( redir_present ) {
2007-05-06 13:54:52 +00:00
case 1 :
p_redirinfo . present = INFO_PRESENT_RESTRICTED ;
break ;
case 2 :
p_redirinfo . present = INFO_PRESENT_NOTAVAIL ;
break ;
default :
p_redirinfo . present = INFO_PRESENT_ALLOWED ;
break ;
}
2009-05-11 09:07:58 +00:00
switch ( redir_screen ) {
2007-05-06 13:54:52 +00:00
case 0 :
p_redirinfo . screen = INFO_SCREEN_USER ;
break ;
2009-09-04 08:26:10 +00:00
case 1 :
p_redirinfo . screen = INFO_SCREEN_USER_VERIFIED_PASSED ;
break ;
case 2 :
p_redirinfo . screen = INFO_SCREEN_USER_VERIFIED_FAILED ;
break ;
2007-05-06 13:54:52 +00:00
default :
p_redirinfo . screen = INFO_SCREEN_NETWORK ;
break ;
}
2009-05-11 09:07:58 +00:00
switch ( redir_reason ) {
2007-05-06 13:54:52 +00:00
case 1 :
p_redirinfo . reason = INFO_REDIR_BUSY ;
break ;
case 2 :
p_redirinfo . reason = INFO_REDIR_NORESPONSE ;
break ;
case 15 :
p_redirinfo . reason = INFO_REDIR_UNCONDITIONAL ;
break ;
case 10 :
p_redirinfo . reason = INFO_REDIR_CALLDEFLECT ;
break ;
case 9 :
p_redirinfo . reason = INFO_REDIR_OUTOFORDER ;
break ;
default :
p_redirinfo . reason = INFO_REDIR_UNKNOWN ;
break ;
}
2009-05-11 09:07:58 +00:00
switch ( redir_type ) {
2007-05-06 13:54:52 +00:00
case - 1 :
2008-11-04 08:31:09 +00:00
p_redirinfo . ntype = INFO_NTYPE_NOTPRESENT ;
break ;
case 0x0 :
2007-05-06 13:54:52 +00:00
p_redirinfo . ntype = INFO_NTYPE_UNKNOWN ;
break ;
case 0x1 :
p_redirinfo . ntype = INFO_NTYPE_INTERNATIONAL ;
break ;
case 0x2 :
p_redirinfo . ntype = INFO_NTYPE_NATIONAL ;
break ;
case 0x4 :
p_redirinfo . ntype = INFO_NTYPE_SUBSCRIBER ;
break ;
default :
p_redirinfo . ntype = INFO_NTYPE_UNKNOWN ;
break ;
}
p_redirinfo . isdn_port = p_m_portnum ;
2007-05-27 13:24:02 +00:00
2007-05-06 13:54:52 +00:00
/* bearer capability */
2009-05-11 09:07:58 +00:00
switch ( bearer_capability ) {
2007-05-06 13:54:52 +00:00
case - 1 :
p_capainfo . bearer_capa = INFO_BC_AUDIO ;
2007-06-27 06:23:50 +00:00
bearer_user = ( options . law = = ' a ' ) ? 3 : 2 ;
2007-05-06 13:54:52 +00:00
break ;
default :
2007-06-27 06:23:50 +00:00
p_capainfo . bearer_capa = bearer_capability ;
2007-05-06 13:54:52 +00:00
break ;
}
2009-05-11 09:07:58 +00:00
switch ( bearer_mode ) {
2007-05-06 13:54:52 +00:00
case 2 :
p_capainfo . bearer_mode = INFO_BMODE_PACKET ;
break ;
default :
p_capainfo . bearer_mode = INFO_BMODE_CIRCUIT ;
break ;
}
2009-05-11 09:07:58 +00:00
switch ( bearer_user ) {
2007-05-06 13:54:52 +00:00
case - 1 :
p_capainfo . bearer_info1 = INFO_INFO1_NONE ;
break ;
default :
2007-06-27 06:23:50 +00:00
p_capainfo . bearer_info1 = bearer_user + 0x80 ;
2007-05-06 13:54:52 +00:00
break ;
}
/* hlc */
2009-05-11 09:07:58 +00:00
switch ( hlc_hlc ) {
2007-05-06 13:54:52 +00:00
case - 1 :
p_capainfo . hlc = INFO_HLC_NONE ;
break ;
default :
2007-06-27 06:23:50 +00:00
p_capainfo . hlc = hlc_hlc + 0x80 ;
2007-05-06 13:54:52 +00:00
break ;
}
2009-05-11 09:07:58 +00:00
switch ( hlc_exthlc ) {
2007-05-06 13:54:52 +00:00
case - 1 :
p_capainfo . exthlc = INFO_HLC_NONE ;
break ;
default :
2007-06-27 06:23:50 +00:00
p_capainfo . exthlc = hlc_exthlc + 0x80 ;
2007-05-06 13:54:52 +00:00
break ;
}
2008-07-26 15:42:16 +00:00
/* set bchannel mode */
if ( p_capainfo . bearer_capa = = INFO_BC_DATAUNRESTRICTED
| | p_capainfo . bearer_capa = = INFO_BC_DATARESTRICTED
| | p_capainfo . bearer_capa = = INFO_BC_VIDEO )
p_capainfo . source_mode = B_MODE_HDLC ;
else
p_capainfo . source_mode = B_MODE_TRANSPARENT ;
p_m_b_mode = p_capainfo . source_mode ;
2007-06-27 06:23:50 +00:00
/* hunt channel */
ret = channel = hunt_bchannel ( channel , exclusive ) ;
if ( ret < 0 )
2007-05-09 05:39:20 +00:00
goto no_channel ;
2007-05-06 13:54:52 +00:00
/* open channel */
ret = seize_bchannel ( channel , 1 ) ;
2009-05-11 09:07:58 +00:00
if ( ret < 0 ) {
2007-05-06 13:54:52 +00:00
no_channel :
2008-03-24 10:13:44 +00:00
/*
* NOTE : we send MT_RELEASE_COMPLETE to " REJECT " the channel
* in response to the setup
*/
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_RELEASE_COMPLETE_REQ , DIRECTION_OUT ) ;
2008-03-24 10:13:44 +00:00
enc_ie_cause ( l3m , ( p_m_mISDNport - > locally ) ? LOCATION_PRIVATE_LOCAL : LOCATION_PRIVATE_REMOTE , - ret ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_RELEASE_COMPLETE , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
new_state ( PORT_STATE_RELEASE ) ;
2010-01-16 10:20:23 +00:00
trigger_work ( & p_m_d_delete ) ;
2007-05-06 13:54:52 +00:00
return ;
}
2007-08-12 08:16:19 +00:00
bchannel_event ( p_m_mISDNport , p_m_b_index , B_EVENT_USE ) ;
2007-05-09 05:39:20 +00:00
2007-05-06 13:54:52 +00:00
/* create endpoint */
if ( p_epointlist )
2007-07-15 10:01:27 +00:00
FATAL ( " Incoming call but already got an endpoint. \n " ) ;
2007-08-11 13:57:58 +00:00
if ( ! ( epoint = new Endpoint ( p_serial , 0 ) ) )
2007-07-15 10:01:27 +00:00
FATAL ( " No memory for Endpoint instance \n " ) ;
2012-01-16 08:14:22 +00:00
epoint - > ep_app = new_endpointapp ( epoint , 0 , p_m_mISDNport - > ifport - > interface - > app ) ; //incoming
2007-07-15 10:01:27 +00:00
epointlist_new ( epoint - > ep_serial ) ;
2007-05-09 05:39:20 +00:00
/* send setup message to endpoit */
2007-05-06 13:54:52 +00:00
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_SETUP ) ;
message - > param . setup . isdn_port = p_m_portnum ;
message - > param . setup . port_type = p_type ;
2008-06-06 13:18:59 +00:00
// message->param.setup.dtmf = !p_m_mISDNport->ifport->nodtmf;
2007-05-06 13:54:52 +00:00
memcpy ( & message - > param . setup . dialinginfo , & p_dialinginfo , sizeof ( struct dialing_info ) ) ;
memcpy ( & message - > param . setup . callerinfo , & p_callerinfo , sizeof ( struct caller_info ) ) ;
memcpy ( & message - > param . setup . redirinfo , & p_redirinfo , sizeof ( struct redir_info ) ) ;
memcpy ( & message - > param . setup . capainfo , & p_capainfo , sizeof ( struct capa_info ) ) ;
memcpy ( message - > param . setup . useruser . data , & useruser , useruser_len ) ;
message - > param . setup . useruser . len = useruser_len ;
message - > param . setup . useruser . protocol = useruser_protocol ;
message_put ( message ) ;
new_state ( PORT_STATE_IN_SETUP ) ;
}
/* CC_INFORMATION INDICATION */
2008-04-12 16:24:31 +00:00
void Pdss1 : : information_ind ( unsigned int cmd , unsigned int pid , struct l3_msg * l3m )
{
2007-05-06 13:54:52 +00:00
int type , plan ;
2009-10-27 07:02:16 +00:00
unsigned char keypad [ 33 ] = " " , display [ 128 ] = " " ;
2008-04-25 07:06:20 +00:00
struct lcr_msg * message ;
2007-05-06 13:54:52 +00:00
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_INFORMATION_IND , DIRECTION_IN ) ;
2008-04-13 17:52:42 +00:00
dec_ie_called_pn ( l3m , & type , & plan , ( unsigned char * ) p_dialinginfo . id , sizeof ( p_dialinginfo . id ) ) ;
dec_ie_keypad ( l3m , ( unsigned char * ) keypad , sizeof ( keypad ) ) ;
2008-07-03 17:08:37 +00:00
dec_ie_display ( l3m , ( unsigned char * ) display , sizeof ( display ) ) ;
2008-04-13 17:52:42 +00:00
dec_ie_complete ( l3m , & p_dialinginfo . sending_complete ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2007-07-07 15:13:20 +00:00
SCAT ( p_dialinginfo . id , ( char * ) keypad ) ;
2009-05-11 09:07:58 +00:00
switch ( type ) {
2007-05-06 13:54:52 +00:00
case 0x1 :
p_dialinginfo . ntype = INFO_NTYPE_INTERNATIONAL ;
break ;
case 0x2 :
p_dialinginfo . ntype = INFO_NTYPE_NATIONAL ;
break ;
case 0x4 :
p_dialinginfo . ntype = INFO_NTYPE_SUBSCRIBER ;
break ;
default :
p_dialinginfo . ntype = INFO_NTYPE_UNKNOWN ;
break ;
}
2009-08-15 20:13:02 +00:00
SCPY ( p_dialinginfo . display , ( char * ) display ) ;
2007-05-06 13:54:52 +00:00
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_INFORMATION ) ;
memcpy ( & message - > param . information , & p_dialinginfo , sizeof ( struct dialing_info ) ) ;
message_put ( message ) ;
/* reset overlap timeout */
new_state ( p_state ) ;
}
/* CC_SETUP_ACCNOWLEDGE INDICATION */
2008-04-12 16:24:31 +00:00
void Pdss1 : : setup_acknowledge_ind ( unsigned int cmd , unsigned int pid , struct l3_msg * l3m )
{
2007-05-06 13:54:52 +00:00
int exclusive , channel ;
int coding , location , progress ;
int ret ;
2008-04-25 07:06:20 +00:00
struct lcr_msg * message ;
2009-02-15 08:04:14 +00:00
int max = p_m_mISDNport - > ifport - > dialmax ;
char * number ;
l3_msg * nl3m ;
2007-05-06 13:54:52 +00:00
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_SETUP_ACKNOWLEDGE_IND , DIRECTION_IN ) ;
2008-04-13 17:52:42 +00:00
dec_ie_channel_id ( l3m , & exclusive , & channel ) ;
dec_ie_progress ( l3m , & coding , & location , & progress ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2010-05-23 11:46:26 +00:00
if ( progress > = 0 ) {
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_PROGRESS ) ;
message - > param . progressinfo . progress = progress ;
message - > param . progressinfo . location = location ;
message_put ( message ) ;
}
2007-05-27 13:24:02 +00:00
/* process channel */
2008-04-13 17:52:42 +00:00
ret = received_first_reply_to_setup ( cmd , channel , exclusive ) ;
2009-05-11 09:07:58 +00:00
if ( ret < 0 ) {
2007-05-06 13:54:52 +00:00
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_RELEASE ) ;
message - > param . disconnectinfo . cause = - ret ;
message - > param . disconnectinfo . location = LOCATION_PRIVATE_LOCAL ;
message_put ( message ) ;
new_state ( PORT_STATE_RELEASE ) ;
2010-01-16 10:20:23 +00:00
trigger_work ( & p_m_d_delete ) ;
2007-05-06 13:54:52 +00:00
return ;
}
2007-05-27 13:24:02 +00:00
2007-05-06 13:54:52 +00:00
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_OVERLAP ) ;
message_put ( message ) ;
new_state ( PORT_STATE_OUT_OVERLAP ) ;
2009-02-15 08:04:14 +00:00
number = p_m_d_queue ;
2009-05-11 09:07:58 +00:00
while ( number [ 0 ] ) { /* as long we have something to dial */
if ( max > ( int ) strlen ( number ) | | max = = 0 )
max = ( int ) strlen ( number ) ;
2009-02-15 08:04:14 +00:00
nl3m = create_l3msg ( ) ;
l1l2l3_trace_header ( p_m_mISDNport , this , L3_INFORMATION_REQ , DIRECTION_OUT ) ;
enc_ie_called_pn ( nl3m , 0 , 1 , ( unsigned char * ) number , max ) ;
end_trace ( ) ;
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_INFORMATION , p_m_d_l3id , nl3m ) ;
number + = max ;
}
p_m_d_queue [ 0 ] = ' \0 ' ;
2007-05-06 13:54:52 +00:00
}
/* CC_PROCEEDING INDICATION */
2008-04-12 16:24:31 +00:00
void Pdss1 : : proceeding_ind ( unsigned int cmd , unsigned int pid , struct l3_msg * l3m )
{
2007-05-06 13:54:52 +00:00
int exclusive , channel ;
int coding , location , progress ;
int ret ;
2008-04-25 07:06:20 +00:00
struct lcr_msg * message ;
2007-05-06 13:54:52 +00:00
int notify = - 1 , type , plan , present ;
char redir [ 32 ] ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_PROCEEDING_IND , DIRECTION_IN ) ;
2008-04-13 17:52:42 +00:00
dec_ie_channel_id ( l3m , & exclusive , & channel ) ;
dec_ie_progress ( l3m , & coding , & location , & progress ) ;
dec_ie_notify ( l3m , & notify ) ;
dec_ie_redir_dn ( l3m , & type , & plan , & present , ( unsigned char * ) redir , sizeof ( redir ) ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2010-05-23 11:46:26 +00:00
if ( progress > = 0 ) {
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_PROGRESS ) ;
message - > param . progressinfo . progress = progress ;
message - > param . progressinfo . location = location ;
message_put ( message ) ;
}
2008-04-13 17:52:42 +00:00
ret = received_first_reply_to_setup ( cmd , channel , exclusive ) ;
2009-05-11 09:07:58 +00:00
if ( ret < 0 ) {
2007-05-06 13:54:52 +00:00
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_RELEASE ) ;
message - > param . disconnectinfo . cause = - ret ;
message - > param . disconnectinfo . location = LOCATION_PRIVATE_LOCAL ;
message_put ( message ) ;
new_state ( PORT_STATE_RELEASE ) ;
2010-01-16 10:20:23 +00:00
trigger_work ( & p_m_d_delete ) ;
2007-05-06 13:54:52 +00:00
return ;
}
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_PROCEEDING ) ;
message_put ( message ) ;
new_state ( PORT_STATE_OUT_PROCEEDING ) ;
if ( notify > = 0 )
notify | = 0x80 ;
else
notify = 0 ;
2009-05-11 09:07:58 +00:00
if ( type > = 0 | | notify ) {
2007-05-06 13:54:52 +00:00
if ( ! notify & & type > = 0 )
notify = 251 ;
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_NOTIFY ) ;
message - > param . notifyinfo . notify = notify ;
SCPY ( message - > param . notifyinfo . id , redir ) ;
/* redirection number */
2009-05-11 09:07:58 +00:00
switch ( present ) {
2007-05-06 13:54:52 +00:00
case 1 :
message - > param . notifyinfo . present = INFO_PRESENT_RESTRICTED ;
break ;
case 2 :
message - > param . notifyinfo . present = INFO_PRESENT_NOTAVAIL ;
break ;
default :
message - > param . notifyinfo . present = INFO_PRESENT_ALLOWED ;
break ;
}
2009-05-11 09:07:58 +00:00
switch ( type ) {
2007-05-06 13:54:52 +00:00
case - 1 :
2008-11-04 08:31:09 +00:00
message - > param . notifyinfo . ntype = INFO_NTYPE_NOTPRESENT ;
2007-05-06 13:54:52 +00:00
break ;
case 1 :
message - > param . notifyinfo . ntype = INFO_NTYPE_INTERNATIONAL ;
break ;
case 2 :
message - > param . notifyinfo . ntype = INFO_NTYPE_NATIONAL ;
break ;
case 4 :
message - > param . notifyinfo . ntype = INFO_NTYPE_SUBSCRIBER ;
break ;
default :
message - > param . notifyinfo . ntype = INFO_NTYPE_UNKNOWN ;
break ;
}
message - > param . notifyinfo . isdn_port = p_m_portnum ;
message_put ( message ) ;
}
}
/* CC_ALERTING INDICATION */
2008-04-12 16:24:31 +00:00
void Pdss1 : : alerting_ind ( unsigned int cmd , unsigned int pid , struct l3_msg * l3m )
{
2007-05-06 13:54:52 +00:00
int exclusive , channel ;
int coding , location , progress ;
int ret ;
2008-04-25 07:06:20 +00:00
struct lcr_msg * message ;
2007-05-06 13:54:52 +00:00
int notify = - 1 , type , plan , present ;
char redir [ 32 ] ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_ALERTING_IND , DIRECTION_IN ) ;
2008-04-13 17:52:42 +00:00
dec_ie_channel_id ( l3m , & exclusive , & channel ) ;
dec_ie_progress ( l3m , & coding , & location , & progress ) ;
dec_ie_notify ( l3m , & notify ) ;
dec_ie_redir_dn ( l3m , & type , & plan , & present , ( unsigned char * ) redir , sizeof ( redir ) ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2010-05-23 11:46:26 +00:00
if ( progress > = 0 ) {
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_PROGRESS ) ;
message - > param . progressinfo . progress = progress ;
message - > param . progressinfo . location = location ;
message_put ( message ) ;
}
2007-05-27 13:24:02 +00:00
/* process channel */
2008-04-13 17:52:42 +00:00
ret = received_first_reply_to_setup ( cmd , channel , exclusive ) ;
2009-05-11 09:07:58 +00:00
if ( ret < 0 ) {
2007-05-06 13:54:52 +00:00
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_RELEASE ) ;
message - > param . disconnectinfo . cause = - ret ;
message - > param . disconnectinfo . location = LOCATION_PRIVATE_LOCAL ;
message_put ( message ) ;
new_state ( PORT_STATE_RELEASE ) ;
2010-01-16 10:20:23 +00:00
trigger_work ( & p_m_d_delete ) ;
2007-05-06 13:54:52 +00:00
return ;
}
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_ALERTING ) ;
message_put ( message ) ;
new_state ( PORT_STATE_OUT_ALERTING ) ;
if ( notify > = 0 )
notify | = 0x80 ;
else
notify = 0 ;
2009-05-11 09:07:58 +00:00
if ( type > = 0 | | notify ) {
2007-05-06 13:54:52 +00:00
if ( ! notify & & type > = 0 )
notify = 251 ;
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_NOTIFY ) ;
message - > param . notifyinfo . notify = notify ;
SCPY ( message - > param . notifyinfo . id , redir ) ;
2009-05-11 09:07:58 +00:00
switch ( present ) {
2007-05-06 13:54:52 +00:00
case 1 :
message - > param . notifyinfo . present = INFO_PRESENT_RESTRICTED ;
break ;
case 2 :
message - > param . notifyinfo . present = INFO_PRESENT_NOTAVAIL ;
break ;
default :
message - > param . notifyinfo . present = INFO_PRESENT_ALLOWED ;
break ;
}
2009-05-11 09:07:58 +00:00
switch ( type ) {
2007-05-06 13:54:52 +00:00
case - 1 :
2008-11-04 08:31:09 +00:00
message - > param . notifyinfo . ntype = INFO_NTYPE_NOTPRESENT ;
2007-05-06 13:54:52 +00:00
break ;
case 1 :
message - > param . notifyinfo . ntype = INFO_NTYPE_INTERNATIONAL ;
break ;
case 2 :
message - > param . notifyinfo . ntype = INFO_NTYPE_NATIONAL ;
break ;
case 4 :
message - > param . notifyinfo . ntype = INFO_NTYPE_SUBSCRIBER ;
break ;
default :
message - > param . notifyinfo . ntype = INFO_NTYPE_UNKNOWN ;
break ;
}
message - > param . notifyinfo . isdn_port = p_m_portnum ;
message_put ( message ) ;
}
}
/* CC_CONNECT INDICATION */
2008-04-12 16:24:31 +00:00
void Pdss1 : : connect_ind ( unsigned int cmd , unsigned int pid , struct l3_msg * l3m )
{
2007-05-06 13:54:52 +00:00
int exclusive , channel ;
int type , plan , present , screen ;
int ret ;
2008-04-25 07:06:20 +00:00
struct lcr_msg * message ;
2007-05-06 13:54:52 +00:00
int bchannel_before ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_CONNECT_IND , DIRECTION_IN ) ;
2008-04-13 17:52:42 +00:00
dec_ie_channel_id ( l3m , & exclusive , & channel ) ;
dec_ie_connected_pn ( l3m , & type , & plan , & present , & screen , ( unsigned char * ) p_connectinfo . id , sizeof ( p_connectinfo . id ) ) ;
2008-07-03 17:08:37 +00:00
dec_ie_display ( l3m , ( unsigned char * ) p_connectinfo . display , sizeof ( p_connectinfo . display ) ) ;
2008-04-13 17:52:42 +00:00
/* te-mode: CONP (connected name identification presentation) */
2008-09-21 06:57:51 +00:00
dec_facility_centrex ( l3m , ( unsigned char * ) p_connectinfo . name , sizeof ( p_connectinfo . name ) ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
/* select channel */
2007-05-06 13:54:52 +00:00
bchannel_before = p_m_b_channel ;
2008-04-13 17:52:42 +00:00
ret = received_first_reply_to_setup ( cmd , channel , exclusive ) ;
2009-05-11 09:07:58 +00:00
if ( ret < 0 ) {
2007-05-06 13:54:52 +00:00
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_RELEASE ) ;
message - > param . disconnectinfo . cause = - ret ;
message - > param . disconnectinfo . location = LOCATION_PRIVATE_LOCAL ;
message_put ( message ) ;
new_state ( PORT_STATE_RELEASE ) ;
2010-01-16 10:20:23 +00:00
trigger_work ( & p_m_d_delete ) ;
2007-05-06 13:54:52 +00:00
return ;
}
2007-05-27 13:24:02 +00:00
2007-05-06 13:54:52 +00:00
/* connect information */
2009-05-11 09:07:58 +00:00
switch ( present ) {
2007-05-06 13:54:52 +00:00
case 1 :
p_connectinfo . present = INFO_PRESENT_RESTRICTED ;
break ;
case 2 :
p_connectinfo . present = INFO_PRESENT_NOTAVAIL ;
break ;
default :
p_connectinfo . present = INFO_PRESENT_ALLOWED ;
break ;
}
2009-05-11 09:07:58 +00:00
switch ( screen ) {
2007-05-06 13:54:52 +00:00
case 0 :
p_connectinfo . screen = INFO_SCREEN_USER ;
break ;
2009-09-04 08:26:10 +00:00
case 1 :
p_connectinfo . screen = INFO_SCREEN_USER_VERIFIED_PASSED ;
break ;
case 2 :
p_connectinfo . screen = INFO_SCREEN_USER_VERIFIED_FAILED ;
break ;
2007-05-06 13:54:52 +00:00
default :
p_connectinfo . screen = INFO_SCREEN_NETWORK ;
break ;
}
2009-05-11 09:07:58 +00:00
switch ( type ) {
2008-11-04 08:31:09 +00:00
case - 1 :
p_connectinfo . ntype = INFO_NTYPE_NOTPRESENT ;
2007-05-06 13:54:52 +00:00
break ;
case 0x1 :
p_connectinfo . ntype = INFO_NTYPE_INTERNATIONAL ;
break ;
case 0x2 :
p_connectinfo . ntype = INFO_NTYPE_NATIONAL ;
break ;
case 0x4 :
p_connectinfo . ntype = INFO_NTYPE_SUBSCRIBER ;
break ;
default :
p_connectinfo . ntype = INFO_NTYPE_UNKNOWN ;
break ;
}
p_connectinfo . isdn_port = p_m_portnum ;
2007-07-15 10:01:27 +00:00
SCPY ( p_connectinfo . interface , p_m_mISDNport - > ifport - > interface - > name ) ;
2007-05-06 13:54:52 +00:00
2007-07-07 15:13:20 +00:00
/* only in nt-mode we send connect ack. in te-mode it is done by stack itself or optional */
2009-05-11 09:07:58 +00:00
if ( p_m_d_ntmode ) {
2007-07-07 15:13:20 +00:00
/* send connect acknowledge */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_CONNECT_RES , DIRECTION_OUT ) ;
2007-07-07 15:13:20 +00:00
/* if we had no bchannel before, we send it now */
if ( ! bchannel_before & & p_m_b_channel )
2008-03-24 10:13:44 +00:00
enc_ie_channel_id ( l3m , 1 , p_m_b_channel ) ;
2007-07-07 15:13:20 +00:00
end_trace ( ) ;
2008-05-09 19:31:58 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_CONNECT_ACKNOWLEDGE , p_m_d_l3id , l3m ) ;
2007-07-07 15:13:20 +00:00
}
2007-05-06 13:54:52 +00:00
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_CONNECT ) ;
memcpy ( & message - > param . connectinfo , & p_connectinfo , sizeof ( struct connect_info ) ) ;
message_put ( message ) ;
new_state ( PORT_STATE_CONNECT ) ;
}
/* CC_DISCONNECT INDICATION */
2008-04-12 16:24:31 +00:00
void Pdss1 : : disconnect_ind ( unsigned int cmd , unsigned int pid , struct l3_msg * l3m )
{
2007-05-06 13:54:52 +00:00
int location , cause ;
int coding , proglocation , progress ;
2008-04-25 07:06:20 +00:00
struct lcr_msg * message ;
2008-07-03 17:08:37 +00:00
unsigned char display [ 128 ] = " " ;
2007-05-06 13:54:52 +00:00
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_DISCONNECT_IND , DIRECTION_IN ) ;
2008-04-13 17:52:42 +00:00
dec_ie_progress ( l3m , & coding , & proglocation , & progress ) ;
dec_ie_cause ( l3m , & location , & cause ) ;
2008-07-03 17:08:37 +00:00
dec_ie_display ( l3m , ( unsigned char * ) display , sizeof ( display ) ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2009-06-06 21:46:21 +00:00
if ( cause < 0 ) {
2007-05-06 13:54:52 +00:00
cause = 16 ;
2009-06-06 21:46:21 +00:00
location = LOCATION_PRIVATE_LOCAL ;
}
2007-05-06 13:54:52 +00:00
2010-05-23 11:46:26 +00:00
if ( progress > = 0 ) {
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_PROGRESS ) ;
message - > param . progressinfo . progress = progress ;
message - > param . progressinfo . location = proglocation ;
message_put ( message ) ;
}
2007-07-18 09:44:25 +00:00
/* release if remote sends us no tones */
2009-05-11 09:07:58 +00:00
if ( ! p_m_mISDNport - > earlyb ) {
2008-03-24 10:13:44 +00:00
l3_msg * l3m ;
2007-05-06 13:54:52 +00:00
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_RELEASE_REQ , DIRECTION_OUT ) ;
2008-05-18 17:04:35 +00:00
enc_ie_cause ( l3m , location , cause ) ; /* normal */
2007-05-30 04:14:41 +00:00
add_trace ( " reason " , NULL , " no remote patterns " ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_RELEASE , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
/* sending release to endpoint */
2008-05-18 17:04:35 +00:00
if ( location = = LOCATION_PRIVATE_LOCAL )
location = LOCATION_PRIVATE_REMOTE ;
2009-05-11 09:07:58 +00:00
while ( p_epointlist ) {
2007-05-06 13:54:52 +00:00
message = message_create ( p_serial , p_epointlist - > epoint_id , PORT_TO_EPOINT , MESSAGE_RELEASE ) ;
message - > param . disconnectinfo . cause = cause ;
message - > param . disconnectinfo . location = location ;
2008-07-03 17:08:37 +00:00
SCAT ( message - > param . disconnectinfo . display , ( char * ) display ) ;
2007-05-06 13:54:52 +00:00
message_put ( message ) ;
/* remove epoint */
free_epointlist ( p_epointlist ) ;
}
new_state ( PORT_STATE_RELEASE ) ;
2010-01-16 10:20:23 +00:00
trigger_work ( & p_m_d_delete ) ;
2007-05-06 13:54:52 +00:00
return ;
}
/* sending disconnect to active endpoint and release to inactive endpoints */
2008-05-18 17:04:35 +00:00
if ( location = = LOCATION_PRIVATE_LOCAL )
location = LOCATION_PRIVATE_REMOTE ;
2009-05-11 09:07:58 +00:00
if ( ACTIVE_EPOINT ( p_epointlist ) ) {
2007-05-06 13:54:52 +00:00
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_DISCONNECT ) ;
message - > param . disconnectinfo . location = location ;
message - > param . disconnectinfo . cause = cause ;
2008-07-03 17:08:37 +00:00
SCAT ( message - > param . disconnectinfo . display , ( char * ) display ) ;
2007-05-06 13:54:52 +00:00
message_put ( message ) ;
}
2009-05-11 09:07:58 +00:00
while ( INACTIVE_EPOINT ( p_epointlist ) ) {
2007-05-06 13:54:52 +00:00
message = message_create ( p_serial , INACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_RELEASE ) ;
message - > param . disconnectinfo . location = location ;
message - > param . disconnectinfo . cause = cause ;
2008-07-03 17:08:37 +00:00
SCAT ( message - > param . disconnectinfo . display , ( char * ) display ) ;
2007-05-06 13:54:52 +00:00
message_put ( message ) ;
/* remove epoint */
free_epointid ( INACTIVE_EPOINT ( p_epointlist ) ) ;
}
new_state ( PORT_STATE_IN_DISCONNECT ) ;
}
/* CC_DISCONNECT INDICATION */
2008-04-12 16:24:31 +00:00
void Pdss1 : : disconnect_ind_i ( unsigned int cmd , unsigned int pid , struct l3_msg * l3m )
{
2007-05-06 13:54:52 +00:00
int location , cause ;
/* cause */
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_DISCONNECT_IND , DIRECTION_IN ) ;
2009-05-11 09:07:58 +00:00
if ( p_m_d_collect_cause > 0 ) {
2007-05-27 13:24:02 +00:00
add_trace ( " old-cause " , " location " , " %d " , p_m_d_collect_location ) ;
add_trace ( " old-cause " , " value " , " %d " , p_m_d_collect_cause ) ;
}
2008-04-13 17:52:42 +00:00
dec_ie_cause ( l3m , & location , & cause ) ;
2007-07-15 10:01:27 +00:00
if ( location = = LOCATION_PRIVATE_LOCAL )
location = LOCATION_PRIVATE_REMOTE ;
2007-05-06 13:54:52 +00:00
/* collect cause */
2007-07-15 10:01:27 +00:00
collect_cause ( & p_m_d_collect_cause , & p_m_d_collect_location , cause , location ) ;
2007-05-27 13:24:02 +00:00
add_trace ( " new-cause " , " location " , " %d " , p_m_d_collect_location ) ;
add_trace ( " new-cause " , " value " , " %d " , p_m_d_collect_cause ) ;
2007-09-22 07:28:26 +00:00
end_trace ( ) ;
2007-05-06 13:54:52 +00:00
}
/* CC_RELEASE INDICATION */
2008-04-12 16:24:31 +00:00
void Pdss1 : : release_ind ( unsigned int cmd , unsigned int pid , struct l3_msg * l3m )
{
2007-05-06 13:54:52 +00:00
int location , cause ;
2008-04-25 07:06:20 +00:00
struct lcr_msg * message ;
2008-07-03 17:08:37 +00:00
unsigned char display [ 128 ] = " " ;
2007-05-06 13:54:52 +00:00
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_RELEASE_IND , DIRECTION_IN ) ;
2008-04-13 17:52:42 +00:00
dec_ie_cause ( l3m , & location , & cause ) ;
2008-07-03 17:08:37 +00:00
dec_ie_display ( l3m , ( unsigned char * ) display , sizeof ( display ) ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2009-06-06 21:46:21 +00:00
if ( cause < 0 ) {
2007-05-06 13:54:52 +00:00
cause = 16 ;
2009-06-06 21:46:21 +00:00
location = LOCATION_PRIVATE_LOCAL ;
}
2007-05-06 13:54:52 +00:00
2008-05-18 17:04:35 +00:00
/* sending release to endpoint */
if ( location = = LOCATION_PRIVATE_LOCAL )
location = LOCATION_PRIVATE_REMOTE ;
2009-05-11 09:07:58 +00:00
while ( p_epointlist ) {
2008-05-18 17:04:35 +00:00
message = message_create ( p_serial , p_epointlist - > epoint_id , PORT_TO_EPOINT , MESSAGE_RELEASE ) ;
message - > param . disconnectinfo . cause = cause ;
message - > param . disconnectinfo . location = location ;
2008-07-03 17:08:37 +00:00
SCAT ( message - > param . disconnectinfo . display , ( char * ) display ) ;
2008-05-18 17:04:35 +00:00
message_put ( message ) ;
/* remove epoint */
free_epointlist ( p_epointlist ) ;
2007-05-06 13:54:52 +00:00
}
new_state ( PORT_STATE_RELEASE ) ;
2010-01-16 10:20:23 +00:00
trigger_work ( & p_m_d_delete ) ;
2007-05-06 13:54:52 +00:00
}
2008-06-14 06:34:50 +00:00
/* CC_RESTART INDICATION */
void Pdss1 : : restart_ind ( unsigned int cmd , unsigned int pid , struct l3_msg * l3m )
{
l1l2l3_trace_header ( p_m_mISDNport , this , L3_RESTART_IND , DIRECTION_IN ) ;
end_trace ( ) ;
// L3 process is not toucht. (not even by network stack)
}
2007-07-17 17:28:09 +00:00
/* CC_RELEASE_COMPLETE INDICATION (a reject) */
2008-04-12 16:24:31 +00:00
void Pdss1 : : release_complete_ind ( unsigned int cmd , unsigned int pid , struct l3_msg * l3m )
{
2007-05-06 13:54:52 +00:00
int location , cause ;
2008-04-25 07:06:20 +00:00
struct lcr_msg * message ;
2008-05-09 19:31:58 +00:00
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_RELEASE_COMPLETE_IND , DIRECTION_IN ) ;
2008-05-09 19:31:58 +00:00
/* in case layer 2 is down during setup, we send cause 27 loc 5 */
2009-05-11 09:07:58 +00:00
if ( p_state = = PORT_STATE_OUT_SETUP & & p_m_mISDNport - > l1link = = 0 ) {
2008-05-09 19:31:58 +00:00
cause = 27 ;
location = 5 ;
2009-05-11 09:07:58 +00:00
} else {
2008-05-09 19:31:58 +00:00
dec_ie_cause ( l3m , & location , & cause ) ;
2008-07-20 17:33:28 +00:00
if ( p_m_mISDNport - > l1link < 0 )
add_trace ( " layer 1 " , NULL , " unknown " ) ;
else
add_trace ( " layer 1 " , NULL , ( p_m_mISDNport - > l1link ) ? " up " : " down " ) ;
2008-05-09 19:31:58 +00:00
}
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2007-07-15 10:01:27 +00:00
if ( location = = LOCATION_PRIVATE_LOCAL )
location = LOCATION_PRIVATE_REMOTE ;
2007-05-27 13:24:02 +00:00
2009-06-06 21:46:21 +00:00
if ( cause < 0 ) {
2007-05-06 13:54:52 +00:00
cause = 16 ;
2009-06-06 21:46:21 +00:00
location = LOCATION_PRIVATE_LOCAL ;
}
2007-05-06 13:54:52 +00:00
/* sending release to endpoint */
2009-05-11 09:07:58 +00:00
while ( p_epointlist ) {
2007-05-06 13:54:52 +00:00
message = message_create ( p_serial , p_epointlist - > epoint_id , PORT_TO_EPOINT , MESSAGE_RELEASE ) ;
message - > param . disconnectinfo . cause = cause ;
message - > param . disconnectinfo . location = location ;
message_put ( message ) ;
/* remove epoint */
free_epointlist ( p_epointlist ) ;
}
new_state ( PORT_STATE_RELEASE ) ;
2010-01-16 10:20:23 +00:00
trigger_work ( & p_m_d_delete ) ;
2007-05-06 13:54:52 +00:00
}
/* T312 timeout */
2008-04-12 16:24:31 +00:00
void Pdss1 : : t312_timeout_ind ( unsigned int cmd , unsigned int pid , struct l3_msg * l3m )
2007-05-06 13:54:52 +00:00
{
2008-05-09 19:31:58 +00:00
// not required, release is performed with MT_FREE
}
2007-05-06 13:54:52 +00:00
/* CC_NOTIFY INDICATION */
2008-04-12 16:24:31 +00:00
void Pdss1 : : notify_ind ( unsigned int cmd , unsigned int pid , struct l3_msg * l3m )
{
2008-04-25 07:06:20 +00:00
struct lcr_msg * message ;
2007-05-06 13:54:52 +00:00
int notify , type , plan , present ;
2007-07-31 05:34:18 +00:00
unsigned char notifyid [ sizeof ( message - > param . notifyinfo . id ) ] ;
2008-07-03 17:08:37 +00:00
unsigned char display [ 128 ] = " " ;
2007-05-06 13:54:52 +00:00
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_NOTIFY_IND , DIRECTION_IN ) ;
2008-04-13 17:52:42 +00:00
dec_ie_notify ( l3m , & notify ) ;
dec_ie_redir_dn ( l3m , & type , & plan , & present , notifyid , sizeof ( notifyid ) ) ;
2008-07-03 17:08:37 +00:00
dec_ie_display ( l3m , ( unsigned char * ) display , sizeof ( display ) ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2007-05-06 13:54:52 +00:00
if ( ! ACTIVE_EPOINT ( p_epointlist ) )
return ;
/* notification indicator */
if ( notify < 0 )
return ;
notify | = 0x80 ;
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_NOTIFY ) ;
message - > param . notifyinfo . notify = notify ;
2007-07-31 05:34:18 +00:00
SCPY ( message - > param . notifyinfo . id , ( char * ) notifyid ) ;
2007-05-06 13:54:52 +00:00
/* redirection number */
2009-05-11 09:07:58 +00:00
switch ( present ) {
2007-05-06 13:54:52 +00:00
case 1 :
message - > param . notifyinfo . present = INFO_PRESENT_RESTRICTED ;
break ;
case 2 :
message - > param . notifyinfo . present = INFO_PRESENT_NOTAVAIL ;
break ;
default :
message - > param . notifyinfo . present = INFO_PRESENT_ALLOWED ;
break ;
}
2009-05-11 09:07:58 +00:00
switch ( type ) {
2007-05-06 13:54:52 +00:00
case - 1 :
2008-11-04 08:31:09 +00:00
message - > param . notifyinfo . ntype = INFO_NTYPE_NOTPRESENT ;
2007-05-06 13:54:52 +00:00
break ;
case 1 :
message - > param . notifyinfo . ntype = INFO_NTYPE_INTERNATIONAL ;
break ;
case 2 :
message - > param . notifyinfo . ntype = INFO_NTYPE_NATIONAL ;
break ;
case 4 :
message - > param . notifyinfo . ntype = INFO_NTYPE_SUBSCRIBER ;
break ;
default :
message - > param . notifyinfo . ntype = INFO_NTYPE_UNKNOWN ;
break ;
}
2008-07-03 17:08:37 +00:00
SCAT ( message - > param . notifyinfo . display , ( char * ) display ) ;
2007-05-06 13:54:52 +00:00
message - > param . notifyinfo . isdn_port = p_m_portnum ;
message_put ( message ) ;
}
/* CC_HOLD INDICATION */
2008-04-25 07:06:20 +00:00
struct lcr_msg * message ;
2008-04-12 16:24:31 +00:00
void Pdss1 : : hold_ind ( unsigned int cmd , unsigned int pid , struct l3_msg * l3m )
{
2007-05-06 13:54:52 +00:00
// class Endpoint *epoint;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_HOLD_IND , DIRECTION_IN ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2009-05-11 09:07:58 +00:00
if ( ! ACTIVE_EPOINT ( p_epointlist ) | | p_m_hold ) {
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_HOLD_REJECT_REQ , DIRECTION_OUT ) ;
2008-03-24 10:13:44 +00:00
enc_ie_cause ( l3m , ( p_m_mISDNport - > locally ) ? LOCATION_PRIVATE_LOCAL : LOCATION_PRIVATE_REMOTE , p_m_hold ? 101 : 31 ) ; /* normal unspecified / incompatible state */
2007-05-30 04:14:41 +00:00
add_trace ( " reason " , NULL , " no endpoint " ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_HOLD_REJECT , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
return ;
}
/* notify the hold of call */
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_NOTIFY ) ;
message - > param . notifyinfo . notify = INFO_NOTIFY_REMOTE_HOLD ;
message - > param . notifyinfo . local = 1 ; /* call is held by supplementary service */
message_put ( message ) ;
/* deactivate bchannel */
2007-06-27 06:23:50 +00:00
chan_trace_header ( p_m_mISDNport , this , " CHANNEL RELEASE (hold) " , DIRECTION_NONE ) ;
2007-05-27 13:24:02 +00:00
add_trace ( " disconnect " , " channel " , " %d " , p_m_b_channel ) ;
end_trace ( ) ;
2007-06-27 06:23:50 +00:00
drop_bchannel ( ) ;
2007-05-06 13:54:52 +00:00
/* set hold state */
p_m_hold = 1 ;
#if 0
epoint = find_epoint_id ( ACTIVE_EPOINT ( p_epointlist ) ) ;
2009-05-11 09:07:58 +00:00
if ( epoint & & p_m_d_ntmode ) {
2010-01-16 10:20:23 +00:00
if ( p_settings . tout_hold )
schedule_timer ( & p_m_timeout , p_settings . tout_hold , 0 ) ;
2007-05-06 13:54:52 +00:00
}
# endif
/* acknowledge hold */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_HOLD_ACKNOWLEDGE_REQ , DIRECTION_OUT ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_HOLD_ACKNOWLEDGE , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
}
/* CC_RETRIEVE INDICATION */
2008-04-12 16:24:31 +00:00
void Pdss1 : : retrieve_ind ( unsigned int cmd , unsigned int pid , struct l3_msg * l3m )
{
2008-04-25 07:06:20 +00:00
struct lcr_msg * message ;
2007-05-06 13:54:52 +00:00
int channel , exclusive , cause ;
int ret ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_RETRIEVE_IND , DIRECTION_IN ) ;
2008-04-13 17:52:42 +00:00
dec_ie_channel_id ( l3m , & exclusive , & channel ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2009-05-11 09:07:58 +00:00
if ( ! p_m_hold ) {
2007-05-06 13:54:52 +00:00
cause = 101 ; /* incompatible state */
reject :
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_RETRIEVE_REJECT_REQ , DIRECTION_OUT ) ;
2008-03-24 10:13:44 +00:00
enc_ie_cause ( l3m , ( p_m_mISDNport - > locally ) ? LOCATION_PRIVATE_LOCAL : LOCATION_PRIVATE_REMOTE , cause ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_RETRIEVE_REJECT , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
return ;
}
/* notify the retrieve of call */
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_NOTIFY ) ;
message - > param . notifyinfo . notify = INFO_NOTIFY_REMOTE_RETRIEVAL ;
message - > param . notifyinfo . local = 1 ; /* call is retrieved by supplementary service */
message_put ( message ) ;
2007-06-27 06:23:50 +00:00
/* hunt channel */
ret = channel = hunt_bchannel ( channel , exclusive ) ;
if ( ret < 0 )
goto no_channel ;
2007-05-27 13:24:02 +00:00
2007-05-06 13:54:52 +00:00
/* open channel */
2007-06-27 06:23:50 +00:00
ret = seize_bchannel ( channel , 1 ) ;
2009-05-11 09:07:58 +00:00
if ( ret < 0 ) {
2007-06-27 06:23:50 +00:00
no_channel :
2007-05-06 13:54:52 +00:00
cause = - ret ;
goto reject ;
}
2007-08-12 08:16:19 +00:00
bchannel_event ( p_m_mISDNport , p_m_b_index , B_EVENT_USE ) ;
2007-05-06 13:54:52 +00:00
/* set hold state */
p_m_hold = 0 ;
2010-01-16 10:20:23 +00:00
unsched_timer ( & p_m_timeout ) ;
2007-05-06 13:54:52 +00:00
/* acknowledge retrieve */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_RETRIEVE_ACKNOWLEDGE_REQ , DIRECTION_OUT ) ;
2008-03-24 10:13:44 +00:00
enc_ie_channel_id ( l3m , 1 , p_m_b_channel ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_RETRIEVE_ACKNOWLEDGE , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
}
/* CC_SUSPEND INDICATION */
2008-04-12 16:24:31 +00:00
void Pdss1 : : suspend_ind ( unsigned int cmd , unsigned int pid , struct l3_msg * l3m )
{
2008-04-25 07:06:20 +00:00
struct lcr_msg * message ;
2007-05-06 13:54:52 +00:00
class Endpoint * epoint ;
unsigned char callid [ 8 ] ;
int len ;
int ret = - 31 ; /* normal, unspecified */
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_SUSPEND_IND , DIRECTION_IN ) ;
2008-04-13 17:52:42 +00:00
dec_ie_call_id ( l3m , callid , & len ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2009-05-11 09:07:58 +00:00
if ( ! ACTIVE_EPOINT ( p_epointlist ) ) {
2007-05-06 13:54:52 +00:00
reject :
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_SUSPEND_REJECT_REQ , DIRECTION_OUT ) ;
2008-03-24 10:13:44 +00:00
enc_ie_cause ( l3m , ( p_m_mISDNport - > locally ) ? LOCATION_PRIVATE_LOCAL : LOCATION_PRIVATE_REMOTE , - ret ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_SUSPEND_REJECT , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
return ;
}
/* call id */
if ( len < 0 ) len = 0 ;
/* check if call id is in use */
epoint = epoint_first ;
2009-05-11 09:07:58 +00:00
while ( epoint ) {
if ( epoint - > ep_park ) {
2007-05-06 13:54:52 +00:00
if ( epoint - > ep_park_len = = len )
2009-05-11 09:07:58 +00:00
if ( ! memcmp ( epoint - > ep_park_callid , callid , len ) ) {
2007-05-06 13:54:52 +00:00
ret = - 84 ; /* call id in use */
goto reject ;
}
}
epoint = epoint - > next ;
}
/* notify the hold of call */
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_NOTIFY ) ;
message - > param . notifyinfo . notify = INFO_NOTIFY_USER_SUSPENDED ;
message - > param . notifyinfo . local = 1 ; /* call is held by supplementary service */
message_put ( message ) ;
/* deactivate bchannel */
2007-06-27 06:23:50 +00:00
chan_trace_header ( p_m_mISDNport , this , " CHANNEL RELEASE (suspend) " , DIRECTION_NONE ) ;
2007-05-27 13:24:02 +00:00
add_trace ( " disconnect " , " channel " , " %d " , p_m_b_channel ) ;
end_trace ( ) ;
2007-06-27 06:23:50 +00:00
drop_bchannel ( ) ;
2007-05-06 13:54:52 +00:00
/* sending suspend to endpoint */
2009-05-11 09:07:58 +00:00
while ( p_epointlist ) {
2007-05-06 13:54:52 +00:00
message = message_create ( p_serial , p_epointlist - > epoint_id , PORT_TO_EPOINT , MESSAGE_SUSPEND ) ;
memcpy ( message - > param . parkinfo . callid , callid , sizeof ( message - > param . parkinfo . callid ) ) ;
message - > param . parkinfo . len = len ;
message_put ( message ) ;
/* remove epoint */
free_epointlist ( p_epointlist ) ;
}
/* sending SUSPEND_ACKNOWLEDGE */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_SUSPEND_ACKNOWLEDGE_REQ , DIRECTION_OUT ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_SUSPEND_ACKNOWLEDGE , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
new_state ( PORT_STATE_RELEASE ) ;
2010-01-16 10:20:23 +00:00
trigger_work ( & p_m_d_delete ) ;
2007-05-06 13:54:52 +00:00
}
/* CC_RESUME INDICATION */
2008-04-12 16:24:31 +00:00
void Pdss1 : : resume_ind ( unsigned int cmd , unsigned int pid , struct l3_msg * l3m )
{
2007-05-06 13:54:52 +00:00
unsigned char callid [ 8 ] ;
int len ;
int channel , exclusive ;
class Endpoint * epoint ;
2008-04-25 07:06:20 +00:00
struct lcr_msg * message ;
2007-05-06 13:54:52 +00:00
int ret ;
2008-04-13 17:52:42 +00:00
/* process given callref */
l1l2l3_trace_header ( p_m_mISDNport , this , L3_NEW_L3ID_IND , DIRECTION_IN ) ;
add_trace ( " callref " , " new " , " 0x%x " , pid ) ;
2009-05-11 09:07:58 +00:00
if ( p_m_d_l3id ) {
2008-04-13 17:52:42 +00:00
/* release is case the ID is already in use */
add_trace ( " error " , NULL , " callref already in use " ) ;
end_trace ( ) ;
l3m = create_l3msg ( ) ;
l1l2l3_trace_header ( p_m_mISDNport , this , L3_RESUME_REJECT_REQ , DIRECTION_OUT ) ;
enc_ie_cause ( l3m , ( p_m_mISDNport - > locally ) ? LOCATION_PRIVATE_LOCAL : LOCATION_PRIVATE_REMOTE , 47 ) ;
add_trace ( " reason " , NULL , " callref already in use " ) ;
end_trace ( ) ;
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_RESUME_REJECT , pid , l3m ) ;
new_state ( PORT_STATE_RELEASE ) ;
2010-01-16 10:20:23 +00:00
trigger_work ( & p_m_d_delete ) ;
2008-04-13 17:52:42 +00:00
return ;
}
p_m_d_l3id = pid ;
p_m_d_ces = pid > > 16 ;
end_trace ( ) ;
2007-05-27 13:24:02 +00:00
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_RESUME_IND , DIRECTION_IN ) ;
2008-04-13 17:52:42 +00:00
dec_ie_call_id ( l3m , callid , & len ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2007-05-09 05:39:20 +00:00
/* if blocked, release call */
2009-05-11 09:07:58 +00:00
if ( p_m_mISDNport - > ifport - > block ) {
2007-05-09 05:39:20 +00:00
ret = - 27 ;
goto reject ;
}
2007-05-06 13:54:52 +00:00
/* call id */
if ( len < 0 ) len = 0 ;
2007-06-27 06:23:50 +00:00
/* channel_id (no channel is possible in message) */
2007-05-06 13:54:52 +00:00
exclusive = 0 ;
channel = - 1 ; /* any channel */
2007-05-27 13:24:02 +00:00
/* hunt channel */
2007-06-27 06:23:50 +00:00
ret = channel = hunt_bchannel ( channel , exclusive ) ;
if ( ret < 0 )
goto no_channel ;
2008-07-26 15:42:16 +00:00
// mode (if hdlc parked) to be done. never mind, this is almost never requested
2007-06-27 06:23:50 +00:00
/* open channel */
ret = seize_bchannel ( channel , 1 ) ;
2009-05-11 09:07:58 +00:00
if ( ret < 0 ) {
2007-06-27 06:23:50 +00:00
no_channel :
2007-05-06 13:54:52 +00:00
reject :
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_RESUME_REJECT_REQ , DIRECTION_OUT ) ;
2008-03-24 10:13:44 +00:00
enc_ie_cause ( l3m , ( p_m_mISDNport - > locally ) ? LOCATION_PRIVATE_LOCAL : LOCATION_PRIVATE_REMOTE , - ret ) ;
2007-05-27 13:24:02 +00:00
if ( ret = = - 27 )
add_trace ( " reason " , NULL , " port blocked " ) ;
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_RESUME_REJECT , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
new_state ( PORT_STATE_RELEASE ) ;
2010-01-16 10:20:23 +00:00
trigger_work ( & p_m_d_delete ) ;
2007-05-06 13:54:52 +00:00
return ;
}
2007-08-12 08:16:19 +00:00
bchannel_event ( p_m_mISDNport , p_m_b_index , B_EVENT_USE ) ;
2007-05-27 13:24:02 +00:00
2007-05-06 13:54:52 +00:00
/* create endpoint */
if ( p_epointlist )
2007-07-15 10:01:27 +00:00
FATAL ( " Incoming resume but already got an endpoint. \n " ) ;
2007-05-06 13:54:52 +00:00
ret = - 85 ; /* no call suspended */
epoint = epoint_first ;
2009-05-11 09:07:58 +00:00
while ( epoint ) {
if ( epoint - > ep_park ) {
2007-05-06 13:54:52 +00:00
ret = - 83 ; /* suspended call exists, but this not */
if ( epoint - > ep_park_len = = len )
if ( ! memcmp ( epoint - > ep_park_callid , callid , len ) )
break ;
}
epoint = epoint - > next ;
}
if ( ! epoint )
goto reject ;
2007-07-15 10:01:27 +00:00
epointlist_new ( epoint - > ep_serial ) ;
2007-07-07 15:13:20 +00:00
if ( ! ( epoint - > portlist_new ( p_serial , p_type , p_m_mISDNport - > earlyb ) ) )
2007-07-15 10:01:27 +00:00
FATAL ( " No memory for portlist \n " ) ;
2007-05-06 13:54:52 +00:00
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_RESUME ) ;
message_put ( message ) ;
/* notify the resume of call */
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_NOTIFY ) ;
message - > param . notifyinfo . notify = INFO_NOTIFY_USER_RESUMED ;
message - > param . notifyinfo . local = 1 ; /* call is retrieved by supplementary service */
message_put ( message ) ;
/* sending RESUME_ACKNOWLEDGE */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_RESUME_ACKNOWLEDGE_REQ , DIRECTION_OUT ) ;
2008-03-24 10:13:44 +00:00
enc_ie_channel_id ( l3m , 1 , p_m_b_channel ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_RESUME_ACKNOWLEDGE , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
new_state ( PORT_STATE_CONNECT ) ;
}
/* CC_FACILITY INDICATION */
2008-04-12 16:24:31 +00:00
void Pdss1 : : facility_ind ( unsigned int cmd , unsigned int pid , struct l3_msg * l3m )
{
2012-07-28 14:24:06 +00:00
unsigned char fac_ie [ 256 ] ;
struct asn1_parm fac ;
int fac_len ;
2008-04-25 07:06:20 +00:00
struct lcr_msg * message ;
2007-05-06 13:54:52 +00:00
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_FACILITY_IND , DIRECTION_IN ) ;
2012-07-28 14:24:06 +00:00
dec_ie_facility ( l3m , fac_ie + 1 , & fac_len ) ;
fac_ie [ 0 ] = fac_len ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
/* facility */
2012-07-28 14:24:06 +00:00
if ( fac_len < = 0 )
2007-05-06 13:54:52 +00:00
return ;
2012-07-28 14:24:06 +00:00
decodeFac ( fac_ie , & fac ) ;
switch ( fac . comp ) {
case CompInvoke :
switch ( fac . u . inv . operationValue ) {
case Fac_Begin3PTY :
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_3PTY ) ;
message - > param . threepty . begin = 1 ;
message - > param . threepty . invoke = 1 ;
message - > param . threepty . invoke_id = fac . u . inv . invokeId ;
message_put ( message ) ;
return ;
case Fac_End3PTY :
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_3PTY ) ;
message - > param . threepty . end = 1 ;
message - > param . threepty . invoke = 1 ;
message - > param . threepty . invoke_id = fac . u . inv . invokeId ;
message_put ( message ) ;
return ;
default :
;
}
break ;
default :
;
}
2007-05-06 13:54:52 +00:00
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_FACILITY ) ;
2012-07-28 14:24:06 +00:00
message - > param . facilityinfo . len = fac_len ;
memcpy ( message - > param . facilityinfo . data , fac_ie , fac_len ) ;
2007-05-06 13:54:52 +00:00
message_put ( message ) ;
}
2009-03-20 17:47:31 +00:00
/* CC_PROGRESS INDICATION */
void Pdss1 : : progress_ind ( unsigned int cmd , unsigned int pid , struct l3_msg * l3m )
{
int coding , location , progress ;
l1l2l3_trace_header ( p_m_mISDNport , this , L3_PROGRESS_IND , DIRECTION_IN ) ;
dec_ie_progress ( l3m , & coding , & location , & progress ) ;
end_trace ( ) ;
2010-05-23 11:46:26 +00:00
if ( progress > = 0 ) {
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_PROGRESS ) ;
message - > param . progressinfo . progress = progress ;
message - > param . progressinfo . location = location ;
message_put ( message ) ;
}
2009-03-20 17:47:31 +00:00
}
2007-05-06 13:54:52 +00:00
/*
* handler for isdn connections
* incoming information are parsed and sent via message to the endpoint
*/
2008-04-13 17:52:42 +00:00
void Pdss1 : : message_isdn ( unsigned int cmd , unsigned int pid , struct l3_msg * l3m )
{
2008-05-09 19:31:58 +00:00
int timer = 0 ;
2008-04-13 17:52:42 +00:00
2009-05-11 09:07:58 +00:00
switch ( cmd ) {
2008-04-13 17:52:42 +00:00
case MT_TIMEOUT :
2009-05-11 09:07:58 +00:00
if ( ! l3m - > cause ) {
2008-04-24 07:24:04 +00:00
PERROR ( " Pdss1(%s) timeout without cause. \n " , p_name ) ;
break ;
}
2009-05-11 09:07:58 +00:00
if ( l3m - > cause [ 0 ] ! = 5 ) {
2008-05-09 19:31:58 +00:00
PERROR ( " Pdss1(%s) expecting timeout with timer diagnostic. (got len=%d) \n " , p_name , l3m - > cause [ 0 ] ) ;
2008-04-24 07:24:04 +00:00
break ;
}
2008-05-09 19:31:58 +00:00
timer = ( l3m - > cause [ 3 ] - ' 0 ' ) * 100 ;
timer + = ( l3m - > cause [ 4 ] - ' 0 ' ) * 10 ;
timer + = ( l3m - > cause [ 5 ] - ' 0 ' ) ;
l1l2l3_trace_header ( p_m_mISDNport , this , L3_TIMEOUT_IND , DIRECTION_IN ) ;
add_trace ( " timer " , NULL , " %d " , timer ) ;
end_trace ( ) ;
if ( timer = = 312 )
2008-04-13 17:52:42 +00:00
t312_timeout_ind ( cmd , pid , l3m ) ;
break ;
case MT_SETUP :
if ( p_state ! = PORT_STATE_IDLE )
break ;
setup_ind ( cmd , pid , l3m ) ;
break ;
case MT_INFORMATION :
information_ind ( cmd , pid , l3m ) ;
break ;
case MT_SETUP_ACKNOWLEDGE :
2009-05-11 09:07:58 +00:00
if ( p_state ! = PORT_STATE_OUT_SETUP ) {
2008-05-12 11:12:28 +00:00
PDEBUG ( DEBUG_ISDN , " Pdss1(%s) received setup_acknowledge, but we are not in outgoing setup state, IGNORING. \n " , p_name ) ;
2008-04-13 17:52:42 +00:00
break ;
}
setup_acknowledge_ind ( cmd , pid , l3m ) ;
break ;
case MT_CALL_PROCEEDING :
if ( p_state ! = PORT_STATE_OUT_SETUP
2009-05-11 09:07:58 +00:00
& & p_state ! = PORT_STATE_OUT_OVERLAP ) {
2008-05-12 11:12:28 +00:00
PDEBUG ( DEBUG_ISDN , " Pdss1(%s) received proceeding, but we are not in outgoing setup OR overlap state, IGNORING. \n " , p_name ) ;
2008-04-13 17:52:42 +00:00
break ;
}
proceeding_ind ( cmd , pid , l3m ) ;
break ;
case MT_ALERTING :
if ( p_state ! = PORT_STATE_OUT_SETUP
& & p_state ! = PORT_STATE_OUT_OVERLAP
2009-05-11 09:07:58 +00:00
& & p_state ! = PORT_STATE_OUT_PROCEEDING ) {
2008-05-12 11:12:28 +00:00
PDEBUG ( DEBUG_ISDN , " Pdss1(%s) received alerting, but we are not in outgoing setup OR overlap OR proceeding state, IGNORING. \n " , p_name ) ;
2008-04-13 17:52:42 +00:00
break ;
}
alerting_ind ( cmd , pid , l3m ) ;
break ;
case MT_CONNECT :
if ( p_state ! = PORT_STATE_OUT_SETUP
& & p_state ! = PORT_STATE_OUT_OVERLAP
& & p_state ! = PORT_STATE_OUT_PROCEEDING
2009-05-11 09:07:58 +00:00
& & p_state ! = PORT_STATE_OUT_ALERTING ) {
2008-05-12 11:12:28 +00:00
PDEBUG ( DEBUG_ISDN , " Pdss1(%s) received alerting, but we are not in outgoing setup OR overlap OR proceeding OR ALERTING state, IGNORING. \n " , p_name ) ;
2008-04-13 17:52:42 +00:00
break ;
}
connect_ind ( cmd , pid , l3m ) ;
2009-05-11 09:07:58 +00:00
if ( p_m_d_notify_pending ) {
2008-04-13 17:52:42 +00:00
/* send pending notify message during connect */
message_notify ( ACTIVE_EPOINT ( p_epointlist ) , p_m_d_notify_pending - > type , & p_m_d_notify_pending - > param ) ;
message_free ( p_m_d_notify_pending ) ;
p_m_d_notify_pending = NULL ;
}
break ;
case MT_CONNECT_ACKNOWLEDGE :
if ( p_state = = PORT_STATE_CONNECT_WAITING )
new_state ( PORT_STATE_CONNECT ) ;
2009-05-11 09:07:58 +00:00
if ( p_m_d_notify_pending ) {
2008-04-13 17:52:42 +00:00
/* send pending notify message during connect-ack */
message_notify ( ACTIVE_EPOINT ( p_epointlist ) , p_m_d_notify_pending - > type , & p_m_d_notify_pending - > param ) ;
message_free ( p_m_d_notify_pending ) ;
p_m_d_notify_pending = NULL ;
}
break ;
case MT_DISCONNECT :
disconnect_ind ( cmd , pid , l3m ) ;
break ;
case MT_RELEASE :
release_ind ( cmd , pid , l3m ) ;
break ;
case MT_RELEASE_COMPLETE :
release_complete_ind ( cmd , pid , l3m ) ;
break ;
2008-06-14 06:34:50 +00:00
case MT_RESTART :
restart_ind ( cmd , pid , l3m ) ;
break ;
2008-04-13 17:52:42 +00:00
case MT_NOTIFY :
notify_ind ( cmd , pid , l3m ) ;
break ;
case MT_HOLD :
hold_ind ( cmd , pid , l3m ) ;
break ;
case MT_RETRIEVE :
retrieve_ind ( cmd , pid , l3m ) ;
break ;
case MT_SUSPEND :
suspend_ind ( cmd , pid , l3m ) ;
break ;
case MT_RESUME :
resume_ind ( cmd , pid , l3m ) ;
break ;
case MT_FACILITY :
facility_ind ( cmd , pid , l3m ) ;
break ;
2009-03-20 17:47:31 +00:00
case MT_PROGRESS :
progress_ind ( cmd , pid , l3m ) ;
break ;
2008-04-13 17:52:42 +00:00
case MT_FREE :
l1l2l3_trace_header ( p_m_mISDNport , this , L3_RELEASE_L3ID_IND , DIRECTION_IN ) ;
add_trace ( " callref " , NULL , " 0x%x " , p_m_d_l3id ) ;
end_trace ( ) ;
p_m_d_l3id = 0 ;
2010-01-16 10:20:23 +00:00
trigger_work ( & p_m_d_delete ) ;
2008-04-13 17:52:42 +00:00
p_m_d_ces = - 1 ;
/* sending release to endpoint in case we still have an endpoint
* this is because we don ' t get any response if a release_complete is received ( or a release in release state )
*/
2009-05-11 09:07:58 +00:00
while ( p_epointlist ) { // only if not already released
2008-04-25 07:06:20 +00:00
struct lcr_msg * message ;
2008-04-13 17:52:42 +00:00
message = message_create ( p_serial , p_epointlist - > epoint_id , PORT_TO_EPOINT , MESSAGE_RELEASE ) ;
2009-05-11 09:07:58 +00:00
if ( p_m_d_collect_cause ) {
2008-05-09 19:31:58 +00:00
message - > param . disconnectinfo . cause = p_m_d_collect_cause ;
message - > param . disconnectinfo . location = p_m_d_collect_location ;
2009-05-11 09:07:58 +00:00
} else {
2008-05-09 19:31:58 +00:00
message - > param . disconnectinfo . cause = CAUSE_NOUSER ;
message - > param . disconnectinfo . location = LOCATION_PRIVATE_LOCAL ;
}
2008-04-13 17:52:42 +00:00
message_put ( message ) ;
/* remove epoint */
free_epointlist ( p_epointlist ) ;
new_state ( PORT_STATE_RELEASE ) ;
}
break ;
default :
2009-03-20 17:47:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_UNKNOWN_IND , DIRECTION_IN ) ;
2008-04-13 17:52:42 +00:00
add_trace ( " unhandled " , " cmd " , " 0x%x " , cmd ) ;
end_trace ( ) ;
}
}
2008-06-01 16:52:10 +00:00
void Pdss1 : : new_state ( int state )
2007-05-06 13:54:52 +00:00
{
2008-06-01 16:52:10 +00:00
// class Endpoint *epoint;
2007-05-06 13:54:52 +00:00
2008-06-01 16:52:10 +00:00
/* set timeout */
2009-05-11 09:07:58 +00:00
if ( state = = PORT_STATE_IN_OVERLAP ) {
2010-01-16 10:20:23 +00:00
if ( p_m_mISDNport - > ifport - > tout_dialing )
schedule_timer ( & p_m_timeout , p_m_mISDNport - > ifport - > tout_dialing , 0 ) ;
2008-06-01 16:52:10 +00:00
}
2009-05-11 09:07:58 +00:00
if ( state ! = p_state ) {
2010-01-16 10:20:23 +00:00
unsched_timer ( & p_m_timeout ) ;
2008-06-01 16:52:10 +00:00
if ( state = = PORT_STATE_IN_SETUP
| | state = = PORT_STATE_OUT_SETUP
| | state = = PORT_STATE_IN_OVERLAP
2009-05-11 09:07:58 +00:00
| | state = = PORT_STATE_OUT_OVERLAP ) {
2010-01-16 10:20:23 +00:00
if ( p_m_mISDNport - > ifport - > tout_setup )
schedule_timer ( & p_m_timeout , p_m_mISDNport - > ifport - > tout_setup , 0 ) ;
2007-05-06 13:54:52 +00:00
}
2008-06-01 16:52:10 +00:00
if ( state = = PORT_STATE_IN_PROCEEDING
2009-05-11 09:07:58 +00:00
| | state = = PORT_STATE_OUT_PROCEEDING ) {
2010-01-16 10:20:23 +00:00
if ( p_m_mISDNport - > ifport - > tout_proceeding )
schedule_timer ( & p_m_timeout , p_m_mISDNport - > ifport - > tout_proceeding , 0 ) ;
2007-07-07 19:36:16 +00:00
}
2008-06-01 16:52:10 +00:00
if ( state = = PORT_STATE_IN_ALERTING
2009-05-11 09:07:58 +00:00
| | state = = PORT_STATE_OUT_ALERTING ) {
2010-01-16 10:20:23 +00:00
if ( p_m_mISDNport - > ifport - > tout_alerting )
schedule_timer ( & p_m_timeout , p_m_mISDNport - > ifport - > tout_alerting , 0 ) ;
2007-05-06 13:54:52 +00:00
}
2010-01-16 10:20:23 +00:00
#if 0
2008-06-01 16:52:10 +00:00
if ( state = = PORT_STATE_CONNECT
2009-05-11 09:07:58 +00:00
| | state = = PORT_STATE_CONNECT_WAITING ) {
2010-01-16 10:20:23 +00:00
if ( p_m_mISDNport - > ifport - > tout_connect )
schedule_timer ( & p_m_timeout , p_m_mISDNport - > ifport - > tout_connect , 0 ) ;
2007-05-06 13:54:52 +00:00
}
2010-01-16 10:20:23 +00:00
# endif
2008-06-01 16:52:10 +00:00
if ( state = = PORT_STATE_IN_DISCONNECT
2009-05-11 09:07:58 +00:00
| | state = = PORT_STATE_OUT_DISCONNECT ) {
2010-01-16 10:20:23 +00:00
if ( p_m_mISDNport - > ifport - > tout_disconnect )
schedule_timer ( & p_m_timeout , p_m_mISDNport - > ifport - > tout_disconnect , 0 ) ;
2007-05-06 13:54:52 +00:00
}
2008-06-01 16:52:10 +00:00
}
Port : : new_state ( state ) ;
}
2007-05-06 13:54:52 +00:00
2010-01-16 10:20:23 +00:00
/* deletes only if l3id is release, otherwhise it will be triggered then */
static int delete_event ( struct lcr_work * work , void * instance , int index )
2008-06-01 16:52:10 +00:00
{
2010-01-16 10:20:23 +00:00
class Pdss1 * isdnport = ( class Pdss1 * ) instance ;
2007-05-15 20:59:29 +00:00
2010-01-16 10:20:23 +00:00
if ( ! isdnport - > p_m_d_l3id )
delete isdnport ;
2007-05-15 20:59:29 +00:00
2010-01-16 10:20:23 +00:00
return 0 ;
2007-05-06 13:54:52 +00:00
}
/*
* handles all messages from endpoint
*/
/* MESSAGE_INFORMATION */
2008-06-14 06:34:50 +00:00
void Pdss1 : : message_information ( unsigned int epoint_id , int message_id , union parameter * param )
2007-05-06 13:54:52 +00:00
{
2008-03-24 10:13:44 +00:00
l3_msg * l3m ;
2009-02-15 08:04:14 +00:00
char * display = param - > information . display ;
char * number = param - > information . id ;
int max = p_m_mISDNport - > ifport - > dialmax ;
2007-05-06 13:54:52 +00:00
2009-05-11 09:07:58 +00:00
while ( number [ 0 ] ) { /* as long we have something to dial */
if ( max > ( int ) strlen ( number ) | | max = = 0 )
max = ( int ) strlen ( number ) ;
2009-02-15 08:04:14 +00:00
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_INFORMATION_REQ , DIRECTION_OUT ) ;
2009-02-15 08:04:14 +00:00
enc_ie_called_pn ( l3m , 0 , 1 , ( unsigned char * ) number , max ) ;
if ( ( p_m_d_ntmode | | p_m_d_tespecial ) & & display [ 0 ] ) {
enc_ie_display ( l3m , ( unsigned char * ) display ) ;
2009-06-18 08:06:31 +00:00
display = ( char * ) " " ;
2009-02-15 08:04:14 +00:00
}
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_INFORMATION , p_m_d_l3id , l3m ) ;
2009-02-15 08:04:14 +00:00
number + = max ;
2007-05-06 13:54:52 +00:00
}
new_state ( p_state ) ;
}
/* MESSAGE_SETUP */
2008-06-14 06:34:50 +00:00
void Pdss1 : : message_setup ( unsigned int epoint_id , int message_id , union parameter * param )
2007-05-06 13:54:52 +00:00
{
2008-03-24 10:13:44 +00:00
l3_msg * l3m ;
2011-09-28 10:17:00 +00:00
# ifdef OLD_MT_ASSIGN
2008-04-13 17:52:42 +00:00
int ret ;
2011-09-28 10:17:00 +00:00
# endif
2007-05-06 13:54:52 +00:00
int plan , type , screen , present , reason ;
2008-11-04 08:31:09 +00:00
int plan2 , type2 , screen2 , present2 ;
2007-05-06 13:54:52 +00:00
int capability , mode , rate , coding , user , presentation , interpretation , hlc , exthlc ;
int channel , exclusive ;
struct epoint_list * epointlist ;
2009-02-15 08:04:14 +00:00
int max = p_m_mISDNport - > ifport - > dialmax ;
2007-05-06 13:54:52 +00:00
2007-05-09 05:39:20 +00:00
/* release if port is blocked */
2009-05-11 09:07:58 +00:00
if ( p_m_mISDNport - > ifport - > block ) {
2008-04-25 07:06:20 +00:00
struct lcr_msg * message ;
2007-06-27 06:23:50 +00:00
2007-05-09 05:39:20 +00:00
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_RELEASE ) ;
message - > param . disconnectinfo . cause = 27 ; // temp. unavail.
message - > param . disconnectinfo . location = LOCATION_PRIVATE_LOCAL ;
message_put ( message ) ;
new_state ( PORT_STATE_RELEASE ) ;
2010-01-16 10:20:23 +00:00
trigger_work ( & p_m_d_delete ) ;
2007-05-09 05:39:20 +00:00
return ;
}
2007-05-06 13:54:52 +00:00
/* copy setup infos to port */
memcpy ( & p_callerinfo , & param - > setup . callerinfo , sizeof ( p_callerinfo ) ) ;
memcpy ( & p_dialinginfo , & param - > setup . dialinginfo , sizeof ( p_dialinginfo ) ) ;
memcpy ( & p_capainfo , & param - > setup . capainfo , sizeof ( p_capainfo ) ) ;
memcpy ( & p_redirinfo , & param - > setup . redirinfo , sizeof ( p_redirinfo ) ) ;
2008-01-05 21:58:22 +00:00
/* screen outgoing caller id */
2012-01-15 08:42:35 +00:00
do_screen ( 1 , p_callerinfo . id , sizeof ( p_callerinfo . id ) , & p_callerinfo . ntype , & p_callerinfo . present , p_m_mISDNport - > ifport - > interface - > name ) ;
do_screen ( 1 , p_callerinfo . id2 , sizeof ( p_callerinfo . id2 ) , & p_callerinfo . ntype2 , & p_callerinfo . present2 , p_m_mISDNport - > ifport - > interface - > name ) ;
2012-06-16 07:52:48 +00:00
do_screen ( 1 , p_redirinfo . id , sizeof ( p_redirinfo . id ) , & p_redirinfo . ntype , & p_redirinfo . present , p_m_mISDNport - > ifport - > interface - > name ) ;
2007-05-06 13:54:52 +00:00
/* only display at connect state: this case happens if endpoint is in connected mode */
2009-05-11 09:07:58 +00:00
if ( p_state = = PORT_STATE_CONNECT ) {
2007-05-06 13:54:52 +00:00
if ( p_type ! = PORT_TYPE_DSS1_NT_OUT
& & p_type ! = PORT_TYPE_DSS1_NT_IN )
return ;
2009-05-11 09:07:58 +00:00
if ( p_callerinfo . display [ 0 ] ) {
2007-05-06 13:54:52 +00:00
/* sending information */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_INFORMATION_REQ , DIRECTION_OUT ) ;
2008-09-21 06:57:51 +00:00
if ( p_m_d_ntmode | | p_m_d_tespecial )
2008-03-24 10:13:44 +00:00
enc_ie_display ( l3m , ( unsigned char * ) p_callerinfo . display ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_INFORMATION , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
return ;
}
}
/* attach only if not already */
epointlist = p_epointlist ;
2009-05-11 09:07:58 +00:00
while ( epointlist ) {
2007-05-06 13:54:52 +00:00
if ( epointlist - > epoint_id = = epoint_id )
break ;
epointlist = epointlist - > next ;
}
if ( ! epointlist )
2007-07-15 10:01:27 +00:00
epointlist_new ( epoint_id ) ;
2007-05-06 13:54:52 +00:00
/* get channel */
exclusive = 0 ;
2009-05-11 09:07:58 +00:00
if ( p_m_b_channel ) {
2007-05-06 13:54:52 +00:00
channel = p_m_b_channel ;
exclusive = p_m_b_exclusive ;
} else
channel = CHANNEL_ANY ;
/* nt-port with no channel, not reserverd */
if ( ! p_m_b_channel & & ! p_m_b_reserve & & p_type = = PORT_TYPE_DSS1_NT_OUT )
channel = CHANNEL_NO ;
2008-04-13 17:52:42 +00:00
/* creating l3id */
l1l2l3_trace_header ( p_m_mISDNport , this , L3_NEW_L3ID_REQ , DIRECTION_OUT ) ;
2011-09-24 07:29:28 +00:00
# ifdef OLD_MT_ASSIGN
2008-04-13 17:52:42 +00:00
/* see MT_ASSIGN notes at do_layer3() */
mt_assign_pid = 0 ;
ret = p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_ASSIGN , 0 , NULL ) ;
2011-09-24 07:29:28 +00:00
if ( mt_assign_pid = = 0 | | ret < 0 )
p_m_d_l3id = mt_assign_pid ;
mt_assign_pid = ~ 0 ;
# else
p_m_d_l3id = request_new_pid ( p_m_mISDNport - > ml3 ) ;
if ( p_m_d_l3id = = MISDN_PID_NONE )
# endif
{
2008-04-25 07:06:20 +00:00
struct lcr_msg * message ;
2008-04-13 17:52:42 +00:00
add_trace ( " callref " , NULL , " no free id " ) ;
end_trace ( ) ;
message = message_create ( p_serial , ACTIVE_EPOINT ( p_epointlist ) , PORT_TO_EPOINT , MESSAGE_RELEASE ) ;
message - > param . disconnectinfo . cause = 47 ;
message - > param . disconnectinfo . location = LOCATION_PRIVATE_LOCAL ;
message_put ( message ) ;
new_state ( PORT_STATE_RELEASE ) ;
2010-01-16 10:20:23 +00:00
trigger_work ( & p_m_d_delete ) ;
2008-04-13 17:52:42 +00:00
return ;
}
2011-09-24 07:29:28 +00:00
# ifdef OLD_MT_ASSIGN
2008-04-13 17:52:42 +00:00
p_m_d_l3id = mt_assign_pid ;
mt_assign_pid = ~ 0 ;
2011-09-24 07:29:28 +00:00
# endif
2008-05-09 19:31:58 +00:00
add_trace ( " callref " , " new " , " 0x%x " , p_m_d_l3id ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2007-05-06 13:54:52 +00:00
/* preparing setup message */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_SETUP_REQ , DIRECTION_OUT ) ;
2007-05-06 13:54:52 +00:00
/* channel information */
2011-09-03 13:54:37 +00:00
if ( p_m_d_ntmode | | channel ! = CHANNEL_ANY ) /* only omit channel id in te-mode/any channel */
2008-03-24 10:13:44 +00:00
enc_ie_channel_id ( l3m , exclusive , channel ) ;
2007-05-06 13:54:52 +00:00
/* caller information */
plan = 1 ;
2009-05-11 09:07:58 +00:00
switch ( p_callerinfo . ntype ) {
2008-11-04 08:31:09 +00:00
case INFO_NTYPE_UNKNOWN :
type = 0x0 ;
break ;
2007-05-06 13:54:52 +00:00
case INFO_NTYPE_INTERNATIONAL :
type = 0x1 ;
break ;
case INFO_NTYPE_NATIONAL :
type = 0x2 ;
break ;
case INFO_NTYPE_SUBSCRIBER :
type = 0x4 ;
break ;
2008-11-04 08:31:09 +00:00
default : /* INFO_NTYPE_NOTPRESENT */
type = - 1 ;
2007-05-06 13:54:52 +00:00
break ;
}
2009-05-11 09:07:58 +00:00
switch ( p_callerinfo . screen ) {
2007-05-06 13:54:52 +00:00
case INFO_SCREEN_USER :
screen = 0 ;
break ;
2009-09-04 08:26:10 +00:00
case INFO_SCREEN_USER_VERIFIED_PASSED :
screen = 1 ;
break ;
case INFO_SCREEN_USER_VERIFIED_FAILED :
screen = 2 ;
break ;
2007-05-06 13:54:52 +00:00
default : /* INFO_SCREEN_NETWORK */
screen = 3 ;
break ;
}
2009-05-11 09:07:58 +00:00
switch ( p_callerinfo . present ) {
2008-11-04 08:31:09 +00:00
case INFO_PRESENT_ALLOWED :
present = 0 ;
break ;
2007-05-06 13:54:52 +00:00
case INFO_PRESENT_RESTRICTED :
present = 1 ;
break ;
2008-11-04 08:31:09 +00:00
default : /* INFO_PRESENT_NOTAVAIL */
2007-05-06 13:54:52 +00:00
present = 2 ;
break ;
2008-11-04 08:31:09 +00:00
}
/* caller information 2 */
plan2 = 1 ;
2009-05-11 09:07:58 +00:00
switch ( p_callerinfo . ntype2 ) {
2008-11-04 08:31:09 +00:00
case INFO_NTYPE_UNKNOWN :
type2 = 0x0 ;
break ;
case INFO_NTYPE_INTERNATIONAL :
type2 = 0x1 ;
break ;
case INFO_NTYPE_NATIONAL :
type2 = 0x2 ;
break ;
case INFO_NTYPE_SUBSCRIBER :
type2 = 0x4 ;
break ;
default : /* INFO_NTYPE_NOTPRESENT */
type2 = - 1 ;
break ;
}
2009-05-11 09:07:58 +00:00
switch ( p_callerinfo . screen2 ) {
2008-11-04 08:31:09 +00:00
case INFO_SCREEN_USER :
screen2 = 0 ;
break ;
2009-09-04 08:26:10 +00:00
case INFO_SCREEN_USER_VERIFIED_PASSED :
screen2 = 1 ;
break ;
case INFO_SCREEN_USER_VERIFIED_FAILED :
screen2 = 2 ;
break ;
2008-11-04 08:31:09 +00:00
default : /* INFO_SCREEN_NETWORK */
screen2 = 3 ;
break ;
}
2009-05-11 09:07:58 +00:00
switch ( p_callerinfo . present2 ) {
2008-11-04 08:31:09 +00:00
case INFO_PRESENT_ALLOWED :
present2 = 0 ;
break ;
case INFO_PRESENT_RESTRICTED :
present2 = 1 ;
break ;
default : /* INFO_PRESENT_NOTAVAIL */
present2 = 2 ;
2007-05-06 13:54:52 +00:00
break ;
}
if ( type > = 0 )
2008-11-04 08:31:09 +00:00
enc_ie_calling_pn ( l3m , type , plan , present , screen , ( unsigned char * ) p_callerinfo . id , type2 , plan2 , present2 , screen2 , ( unsigned char * ) p_callerinfo . id2 ) ;
2007-05-06 13:54:52 +00:00
/* dialing information */
2009-05-11 09:07:58 +00:00
if ( p_dialinginfo . id [ 0 ] ) { /* only if we have something to dial */
if ( max > ( int ) strlen ( p_dialinginfo . id ) | | max = = 0 )
max = ( int ) strlen ( p_dialinginfo . id ) ;
2009-02-15 08:04:14 +00:00
enc_ie_called_pn ( l3m , 0 , 1 , ( unsigned char * ) p_dialinginfo . id , max ) ;
SCPY ( p_m_d_queue , p_dialinginfo . id + max ) ;
2007-05-06 13:54:52 +00:00
}
2009-10-27 07:02:16 +00:00
/* keypad */
if ( p_dialinginfo . keypad [ 0 ] )
enc_ie_keypad ( l3m , ( unsigned char * ) p_dialinginfo . keypad ) ;
2007-05-06 13:54:52 +00:00
/* sending complete */
if ( p_dialinginfo . sending_complete )
2008-03-24 10:13:44 +00:00
enc_ie_complete ( l3m , 1 ) ;
2007-05-06 13:54:52 +00:00
/* sending user-user */
2009-05-11 09:07:58 +00:00
if ( param - > setup . useruser . len ) {
2008-03-24 10:13:44 +00:00
enc_ie_useruser ( l3m , param - > setup . useruser . protocol , param - > setup . useruser . data , param - > setup . useruser . len ) ;
2007-05-06 13:54:52 +00:00
}
/* redirecting number */
plan = 1 ;
2009-05-11 09:07:58 +00:00
switch ( p_redirinfo . ntype ) {
2008-11-04 08:31:09 +00:00
case INFO_NTYPE_UNKNOWN :
type = 0x0 ;
break ;
2007-05-06 13:54:52 +00:00
case INFO_NTYPE_INTERNATIONAL :
type = 0x1 ;
break ;
case INFO_NTYPE_NATIONAL :
type = 0x2 ;
break ;
case INFO_NTYPE_SUBSCRIBER :
type = 0x4 ;
break ;
2008-11-04 08:31:09 +00:00
default : /* INFO_NTYPE_NOTPRESENT */
type = - 1 ;
2007-05-06 13:54:52 +00:00
break ;
}
2009-05-11 09:07:58 +00:00
switch ( p_redirinfo . screen ) {
2007-05-06 13:54:52 +00:00
case INFO_SCREEN_USER :
screen = 0 ;
break ;
2009-09-04 08:26:10 +00:00
case INFO_SCREEN_USER_VERIFIED_PASSED :
screen = 1 ;
break ;
case INFO_SCREEN_USER_VERIFIED_FAILED :
screen = 2 ;
break ;
2007-05-06 13:54:52 +00:00
default : /* INFO_SCREE_NETWORK */
screen = 3 ;
break ;
}
2009-05-11 09:07:58 +00:00
switch ( p_redirinfo . reason ) {
2007-05-06 13:54:52 +00:00
case INFO_REDIR_BUSY :
reason = 1 ;
break ;
case INFO_REDIR_NORESPONSE :
reason = 2 ;
break ;
case INFO_REDIR_UNCONDITIONAL :
reason = 15 ;
break ;
case INFO_REDIR_CALLDEFLECT :
reason = 10 ;
break ;
case INFO_REDIR_OUTOFORDER :
reason = 9 ;
break ;
default : /* INFO_REDIR_UNKNOWN */
reason = 0 ;
break ;
}
2009-05-11 09:07:58 +00:00
switch ( p_redirinfo . present ) {
2008-11-04 08:31:09 +00:00
case INFO_PRESENT_ALLOWED :
present = 0 ;
2007-05-06 13:54:52 +00:00
break ;
case INFO_PRESENT_RESTRICTED :
present = 1 ;
break ;
2008-11-04 08:31:09 +00:00
default : /* INFO_PRESENT_NOTAVAIL */
2007-05-06 13:54:52 +00:00
present = 2 ;
break ;
}
/* sending redirecting number only in ntmode */
2008-09-21 06:57:51 +00:00
if ( type > = 0 & & ( p_m_d_ntmode | | p_m_d_tespecial ) )
2008-03-24 10:13:44 +00:00
enc_ie_redir_nr ( l3m , type , plan , present , screen , reason , ( unsigned char * ) p_redirinfo . id ) ;
2007-05-06 13:54:52 +00:00
/* bearer capability */
//printf("hlc=%d\n",p_capainfo.hlc);
coding = 0 ;
capability = p_capainfo . bearer_capa ;
mode = p_capainfo . bearer_mode ;
rate = ( mode = = INFO_BMODE_CIRCUIT ) ? 0x10 : 0x00 ;
2009-05-11 09:07:58 +00:00
switch ( p_capainfo . bearer_info1 ) {
2007-05-06 13:54:52 +00:00
case INFO_INFO1_NONE :
user = - 1 ;
break ;
default :
user = p_capainfo . bearer_info1 & 0x7f ;
break ;
}
2008-03-24 10:13:44 +00:00
enc_ie_bearer ( l3m , coding , capability , mode , rate , - 1 , user ) ;
2007-05-06 13:54:52 +00:00
/* hlc */
2009-05-11 09:07:58 +00:00
if ( p_capainfo . hlc ) {
2007-05-06 13:54:52 +00:00
coding = 0 ;
interpretation = 4 ;
presentation = 1 ;
hlc = p_capainfo . hlc & 0x7f ;
exthlc = - 1 ;
if ( p_capainfo . exthlc )
exthlc = p_capainfo . exthlc & 0x7f ;
2008-03-24 10:13:44 +00:00
enc_ie_hlc ( l3m , coding , interpretation , presentation , hlc , exthlc ) ;
2007-05-06 13:54:52 +00:00
}
/* display */
2008-09-21 06:57:51 +00:00
if ( p_callerinfo . display [ 0 ] & & ( p_m_d_ntmode | | p_m_d_tespecial ) )
2008-03-24 10:13:44 +00:00
enc_ie_display ( l3m , ( unsigned char * ) p_callerinfo . display ) ;
2007-05-06 13:54:52 +00:00
/* nt-mode: CNIP (calling name identification presentation) */
2008-09-21 06:57:51 +00:00
// if (p_callerinfo.name[0] && (p_m_d_ntmode || p_m_d_tespecial))
2008-02-03 12:47:33 +00:00
// enc_facility_centrex(&setup->FACILITY, dmsg, (unsigned char *)p_callerinfo.name, 1);
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2007-05-06 13:54:52 +00:00
/* send setup message now */
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_SETUP , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
new_state ( PORT_STATE_OUT_SETUP ) ;
}
/* MESSAGE_FACILITY */
2008-06-14 06:34:50 +00:00
void Pdss1 : : message_facility ( unsigned int epoint_id , int message_id , union parameter * param )
2007-05-06 13:54:52 +00:00
{
2008-03-24 10:13:44 +00:00
l3_msg * l3m ;
2007-05-06 13:54:52 +00:00
/* facility will not be sent to external lines */
2008-09-21 06:57:51 +00:00
if ( ! p_m_d_ntmode & & ! p_m_d_tespecial )
2007-05-06 13:54:52 +00:00
return ;
/* sending facility */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_FACILITY_REQ , DIRECTION_OUT ) ;
2008-03-24 10:13:44 +00:00
enc_ie_facility ( l3m , ( unsigned char * ) param - > facilityinfo . data , param - > facilityinfo . len ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_FACILITY , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
}
2012-07-28 14:24:06 +00:00
/* MESSAGE_3PTY */
void Pdss1 : : message_3pty ( unsigned int epoint_id , int message_id , union parameter * param )
{
l3_msg * l3m ;
unsigned char fac_ie [ 256 ] ;
struct asn1_parm fac ;
/* encode 3PTY facility */
memset ( & fac , 0 , sizeof ( fac ) ) ;
fac . Valid = 1 ;
if ( param - > threepty . result ) {
fac . comp = CompReturnResult ;
fac . u . retResult . invokeId = param - > threepty . invoke_id ;
}
if ( param - > threepty . error ) {
fac . comp = CompReturnError ;
fac . u . retError . invokeId = param - > threepty . invoke_id ;
fac . u . retError . errorValue = FacError_Gen_InvalidCallState ;
}
fac . u . retResult . operationValuePresent = 1 ;
if ( param - > threepty . begin )
fac . u . retResult . operationValue = Fac_Begin3PTY ;
if ( param - > threepty . end )
fac . u . retResult . operationValue = Fac_End3PTY ;
encodeFac ( fac_ie , & fac ) ;
/* sending facility */
l3m = create_l3msg ( ) ;
l1l2l3_trace_header ( p_m_mISDNport , this , L3_FACILITY_REQ , DIRECTION_OUT ) ;
enc_ie_facility ( l3m , fac_ie + 2 , fac_ie [ 1 ] ) ;
end_trace ( ) ;
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_FACILITY , p_m_d_l3id , l3m ) ;
}
2007-05-06 13:54:52 +00:00
/* MESSAGE_NOTIFY */
2008-06-14 06:34:50 +00:00
void Pdss1 : : message_notify ( unsigned int epoint_id , int message_id , union parameter * param )
2007-05-06 13:54:52 +00:00
{
2008-03-24 10:13:44 +00:00
l3_msg * l3m ;
2007-05-06 13:54:52 +00:00
int notify ;
2008-11-04 08:31:09 +00:00
int plan = 0 , type = - 1 , present = 0 ;
2007-05-06 13:54:52 +00:00
2010-01-15 20:55:25 +00:00
if ( p_m_mISDNport - > ifport - > nonotify ) {
l1l2l3_trace_header ( p_m_mISDNport , this , L3_NOTIFY_REQ , DIRECTION_OUT ) ;
add_trace ( " info " , NULL , " blocked by config " ) ;
end_trace ( ) ;
return ;
}
2009-09-06 13:36:36 +00:00
// printf("if = %d\n", param->notifyinfo.notify);
2007-05-06 13:54:52 +00:00
if ( param - > notifyinfo . notify > INFO_NOTIFY_NONE )
notify = param - > notifyinfo . notify & 0x7f ;
else
notify = - 1 ;
2009-05-11 09:07:58 +00:00
if ( notify > = 0 ) {
2007-05-06 13:54:52 +00:00
plan = 1 ;
2009-05-11 09:07:58 +00:00
switch ( param - > notifyinfo . ntype ) {
2008-11-04 08:31:09 +00:00
case INFO_NTYPE_UNKNOWN :
type = 0 ;
break ;
2007-05-06 13:54:52 +00:00
case INFO_NTYPE_INTERNATIONAL :
type = 1 ;
break ;
case INFO_NTYPE_NATIONAL :
type = 2 ;
break ;
case INFO_NTYPE_SUBSCRIBER :
type = 4 ;
break ;
default : /* INFO_NTYPE_UNKNOWN */
2008-11-04 08:31:09 +00:00
type = - 1 ;
2007-05-06 13:54:52 +00:00
break ;
}
2009-05-11 09:07:58 +00:00
switch ( param - > notifyinfo . present ) {
2008-11-04 08:31:09 +00:00
case INFO_PRESENT_ALLOWED :
present = 0 ;
2007-05-06 13:54:52 +00:00
break ;
case INFO_PRESENT_RESTRICTED :
present = 1 ;
break ;
2008-11-04 08:31:09 +00:00
default : /* INFO_PRESENT_NOTAVAIL */
2007-05-06 13:54:52 +00:00
present = 2 ;
break ;
}
}
2009-05-11 09:07:58 +00:00
if ( notify < 0 & & ! param - > notifyinfo . display [ 0 ] ) {
2007-05-30 04:14:41 +00:00
/* nothing to notify, nothing to display */
2007-05-06 13:54:52 +00:00
return ;
}
2009-05-11 09:07:58 +00:00
if ( notify > = 0 ) {
if ( p_state ! = PORT_STATE_CONNECT & & p_state ! = PORT_STATE_IN_PROCEEDING & & p_state ! = PORT_STATE_IN_ALERTING ) {
2007-05-06 13:54:52 +00:00
/* queue notification */
if ( p_m_d_notify_pending )
message_free ( p_m_d_notify_pending ) ;
p_m_d_notify_pending = message_create ( ACTIVE_EPOINT ( p_epointlist ) , p_serial , EPOINT_TO_PORT , message_id ) ;
memcpy ( & p_m_d_notify_pending - > param , param , sizeof ( union parameter ) ) ;
2009-05-11 09:07:58 +00:00
} else {
2007-05-06 13:54:52 +00:00
/* sending notification */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_NOTIFY_REQ , DIRECTION_OUT ) ;
2008-03-24 10:13:44 +00:00
enc_ie_notify ( l3m , notify ) ;
2007-05-06 13:54:52 +00:00
/* sending redirection number only in ntmode */
2008-09-21 06:57:51 +00:00
if ( type > = 0 & & ( p_m_d_ntmode | | p_m_d_tespecial ) )
2008-03-24 10:13:44 +00:00
enc_ie_redir_dn ( l3m , type , plan , present , ( unsigned char * ) param - > notifyinfo . id ) ;
2008-09-21 06:57:51 +00:00
if ( param - > notifyinfo . display [ 0 ] & & ( p_m_d_ntmode | | p_m_d_tespecial ) )
2008-03-24 10:13:44 +00:00
enc_ie_display ( l3m , ( unsigned char * ) param - > notifyinfo . display ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_NOTIFY , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
}
2009-05-11 09:07:58 +00:00
} else if ( p_m_d_ntmode | | p_m_d_tespecial ) {
2007-05-06 13:54:52 +00:00
/* sending information */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_INFORMATION_REQ , DIRECTION_OUT ) ;
2008-03-24 10:13:44 +00:00
enc_ie_display ( l3m , ( unsigned char * ) param - > notifyinfo . display ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_INFORMATION , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
}
}
/* MESSAGE_OVERLAP */
2008-06-14 06:34:50 +00:00
void Pdss1 : : message_overlap ( unsigned int epoint_id , int message_id , union parameter * param )
2007-05-06 13:54:52 +00:00
{
2008-03-24 10:13:44 +00:00
l3_msg * l3m ;
2007-05-06 13:54:52 +00:00
2008-07-08 19:46:35 +00:00
/* in case of sending complete, we proceed */
2009-05-11 09:07:58 +00:00
if ( p_dialinginfo . sending_complete ) {
2008-07-08 19:46:35 +00:00
PDEBUG ( DEBUG_ISDN , " sending proceeding instead of setup_acknowledge, because address is complete. \n " ) ;
message_proceeding ( epoint_id , message_id , param ) ;
return ;
}
2007-05-06 13:54:52 +00:00
/* sending setup_acknowledge */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_SETUP_ACKNOWLEDGE_REQ , DIRECTION_OUT ) ;
2007-05-06 13:54:52 +00:00
/* channel information */
if ( p_state = = PORT_STATE_IN_SETUP )
2008-03-24 10:13:44 +00:00
enc_ie_channel_id ( l3m , 1 , p_m_b_channel ) ;
2007-05-06 13:54:52 +00:00
/* progress information */
if ( p_capainfo . bearer_capa = = INFO_BC_SPEECH
| | p_capainfo . bearer_capa = = INFO_BC_AUDIO
| | p_capainfo . bearer_capa = = INFO_BC_DATAUNRESTRICTED_TONES )
2007-07-07 15:13:20 +00:00
if ( p_m_mISDNport - > tones )
2008-09-21 06:57:51 +00:00
enc_ie_progress ( l3m , 0 , ( p_m_d_ntmode ) ? 1 : 5 , 8 ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_SETUP_ACKNOWLEDGE , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
new_state ( PORT_STATE_IN_OVERLAP ) ;
}
/* MESSAGE_PROCEEDING */
2008-06-14 06:34:50 +00:00
void Pdss1 : : message_proceeding ( unsigned int epoint_id , int message_id , union parameter * param )
2007-05-06 13:54:52 +00:00
{
2008-03-24 10:13:44 +00:00
l3_msg * l3m ;
2007-05-06 13:54:52 +00:00
/* sending proceeding */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_PROCEEDING_REQ , DIRECTION_OUT ) ;
2007-05-06 13:54:52 +00:00
/* channel information */
if ( p_state = = PORT_STATE_IN_SETUP )
2008-03-24 10:13:44 +00:00
enc_ie_channel_id ( l3m , 1 , p_m_b_channel ) ;
2007-05-06 13:54:52 +00:00
/* progress information */
if ( p_capainfo . bearer_capa = = INFO_BC_SPEECH
| | p_capainfo . bearer_capa = = INFO_BC_AUDIO
| | p_capainfo . bearer_capa = = INFO_BC_DATAUNRESTRICTED_TONES )
2007-07-07 15:13:20 +00:00
if ( p_m_mISDNport - > tones )
2008-09-21 06:57:51 +00:00
enc_ie_progress ( l3m , 0 , ( p_m_d_ntmode ) ? 1 : 5 , 8 ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_CALL_PROCEEDING , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
new_state ( PORT_STATE_IN_PROCEEDING ) ;
}
/* MESSAGE_ALERTING */
2008-06-14 06:34:50 +00:00
void Pdss1 : : message_alerting ( unsigned int epoint_id , int message_id , union parameter * param )
2007-05-06 13:54:52 +00:00
{
2008-03-24 10:13:44 +00:00
l3_msg * l3m ;
2007-05-06 13:54:52 +00:00
/* NT-MODE in setup state we must send PROCEEDING first */
2009-05-11 09:07:58 +00:00
if ( p_m_d_ntmode & & p_state = = PORT_STATE_IN_SETUP ) {
2007-05-06 13:54:52 +00:00
/* sending proceeding */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_PROCEEDING_REQ , DIRECTION_OUT ) ;
2007-05-06 13:54:52 +00:00
/* channel information */
2008-03-24 10:13:44 +00:00
enc_ie_channel_id ( l3m , 1 , p_m_b_channel ) ;
2007-05-06 13:54:52 +00:00
/* progress information */
if ( p_capainfo . bearer_capa = = INFO_BC_SPEECH
| | p_capainfo . bearer_capa = = INFO_BC_AUDIO
| | p_capainfo . bearer_capa = = INFO_BC_DATAUNRESTRICTED_TONES )
2008-06-14 06:34:50 +00:00
if ( p_m_mISDNport - > tones )
2008-09-21 06:57:51 +00:00
enc_ie_progress ( l3m , 0 , ( p_m_d_ntmode ) ? 1 : 5 , 8 ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_CALL_PROCEEDING , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
new_state ( PORT_STATE_IN_PROCEEDING ) ;
}
/* sending alerting */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_ALERTING_REQ , DIRECTION_OUT ) ;
2007-05-06 13:54:52 +00:00
/* channel information */
if ( p_state = = PORT_STATE_IN_SETUP )
2008-03-24 10:13:44 +00:00
enc_ie_channel_id ( l3m , 1 , p_m_b_channel ) ;
2007-05-06 13:54:52 +00:00
/* progress information */
if ( p_capainfo . bearer_capa = = INFO_BC_SPEECH
| | p_capainfo . bearer_capa = = INFO_BC_AUDIO
| | p_capainfo . bearer_capa = = INFO_BC_DATAUNRESTRICTED_TONES )
2007-07-07 15:13:20 +00:00
if ( p_m_mISDNport - > tones )
2008-09-21 06:57:51 +00:00
enc_ie_progress ( l3m , 0 , ( p_m_d_ntmode ) ? 1 : 5 , 8 ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_ALERTING , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
new_state ( PORT_STATE_IN_ALERTING ) ;
}
/* MESSAGE_CONNECT */
2008-06-14 06:34:50 +00:00
void Pdss1 : : message_connect ( unsigned int epoint_id , int message_id , union parameter * param )
2007-05-06 13:54:52 +00:00
{
2008-03-24 10:13:44 +00:00
l3_msg * l3m ;
2007-05-06 13:54:52 +00:00
int type , plan , present , screen ;
class Endpoint * epoint ;
2010-01-16 10:20:23 +00:00
time_t current_time ;
2007-05-06 13:54:52 +00:00
/* NT-MODE in setup state we must send PROCEEDING first */
2009-05-11 09:07:58 +00:00
if ( p_m_d_ntmode & & p_state = = PORT_STATE_IN_SETUP ) {
2007-05-06 13:54:52 +00:00
/* sending proceeding */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_PROCEEDING_REQ , DIRECTION_OUT ) ;
2007-05-06 13:54:52 +00:00
/* channel information */
2008-03-24 10:13:44 +00:00
enc_ie_channel_id ( l3m , 1 , p_m_b_channel ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_CALL_PROCEEDING , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
new_state ( PORT_STATE_IN_PROCEEDING ) ;
}
/* copy connected information */
memcpy ( & p_connectinfo , & param - > connectinfo , sizeof ( p_connectinfo ) ) ;
2008-01-05 21:58:22 +00:00
/* screen outgoing caller id */
2012-01-15 08:42:35 +00:00
do_screen ( 1 , p_connectinfo . id , sizeof ( p_connectinfo . id ) , & p_connectinfo . ntype , & p_connectinfo . present , p_m_mISDNport - > ifport - > interface - > name ) ;
2007-05-06 13:54:52 +00:00
/* only display at connect state */
if ( p_state = = PORT_STATE_CONNECT )
2009-05-11 09:07:58 +00:00
if ( p_connectinfo . display [ 0 ] ) {
2007-05-06 13:54:52 +00:00
/* sending information */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_INFORMATION_REQ , DIRECTION_OUT ) ;
2008-09-21 06:57:51 +00:00
if ( p_m_d_ntmode | | p_m_d_tespecial )
2008-03-24 10:13:44 +00:00
enc_ie_display ( l3m , ( unsigned char * ) p_connectinfo . display ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_INFORMATION , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
return ;
}
2009-05-11 09:07:58 +00:00
if ( p_state ! = PORT_STATE_IN_SETUP & & p_state ! = PORT_STATE_IN_OVERLAP & & p_state ! = PORT_STATE_IN_PROCEEDING & & p_state ! = PORT_STATE_IN_ALERTING ) {
2007-05-30 04:14:41 +00:00
/* connect command only possible in setup, proceeding or alerting state */
2007-05-06 13:54:52 +00:00
return ;
}
/* preparing connect message */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_CONNECT_REQ , DIRECTION_OUT ) ;
2007-05-06 13:54:52 +00:00
/* connect information */
plan = 1 ;
2009-05-11 09:07:58 +00:00
switch ( p_connectinfo . ntype ) {
2008-11-04 08:31:09 +00:00
case INFO_NTYPE_UNKNOWN :
type = 0x0 ;
break ;
2007-05-06 13:54:52 +00:00
case INFO_NTYPE_INTERNATIONAL :
type = 0x1 ;
break ;
case INFO_NTYPE_NATIONAL :
type = 0x2 ;
break ;
case INFO_NTYPE_SUBSCRIBER :
type = 0x4 ;
break ;
2008-11-04 08:31:09 +00:00
default : /* INFO_NTYPE_NOTPRESENT */
type = - 1 ;
2007-05-06 13:54:52 +00:00
break ;
}
2009-05-11 09:07:58 +00:00
switch ( param - > connectinfo . screen ) {
2007-05-06 13:54:52 +00:00
case INFO_SCREEN_USER :
screen = 0 ;
break ;
2009-09-04 08:26:10 +00:00
case INFO_SCREEN_USER_VERIFIED_PASSED :
screen = 1 ;
break ;
case INFO_SCREEN_USER_VERIFIED_FAILED :
screen = 2 ;
break ;
2007-05-06 13:54:52 +00:00
default : /* INFO_SCREE_NETWORK */
screen = 3 ;
break ;
}
2009-05-11 09:07:58 +00:00
switch ( p_connectinfo . present ) {
2008-11-04 08:31:09 +00:00
case INFO_PRESENT_ALLOWED :
present = 0 ;
2007-05-06 13:54:52 +00:00
break ;
case INFO_PRESENT_RESTRICTED :
present = 1 ;
break ;
2008-11-04 08:31:09 +00:00
default : /* INFO_PRESENT_NOTAVAIL */
2007-05-06 13:54:52 +00:00
present = 2 ;
break ;
}
if ( type > = 0 )
2008-03-24 10:13:44 +00:00
enc_ie_connected_pn ( l3m , type , plan , present , screen , ( unsigned char * ) p_connectinfo . id ) ;
2007-05-06 13:54:52 +00:00
/* display */
2008-09-21 06:57:51 +00:00
if ( p_connectinfo . display [ 0 ] & & ( p_m_d_ntmode | | p_m_d_tespecial ) )
2008-03-24 10:13:44 +00:00
enc_ie_display ( l3m , ( unsigned char * ) p_connectinfo . display ) ;
2007-05-06 13:54:52 +00:00
/* nt-mode: CONP (connected name identification presentation) */
2008-09-21 06:57:51 +00:00
// if (p_connectinfo.name[0] && (p_m_d_ntmode || p_m_d_tespecial))
2008-02-03 12:47:33 +00:00
// enc_facility_centrex(&connect->FACILITY, dmsg, (unsigned char *)p_connectinfo.name, 0);
2007-05-06 13:54:52 +00:00
/* date & time */
2009-05-11 09:07:58 +00:00
if ( p_m_d_ntmode | | p_m_d_tespecial ) {
2007-05-06 13:54:52 +00:00
epoint = find_epoint_id ( epoint_id ) ;
2010-01-16 10:20:23 +00:00
time ( & current_time ) ;
enc_ie_date ( l3m , current_time , p_settings . no_seconds ) ;
2007-05-06 13:54:52 +00:00
}
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2007-05-06 13:54:52 +00:00
/* finally send message */
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_CONNECT , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
if ( p_m_d_ntmode )
new_state ( PORT_STATE_CONNECT ) ;
else
new_state ( PORT_STATE_CONNECT_WAITING ) ;
set_tone ( " " , NULL ) ;
}
/* MESSAGE_DISCONNECT */
2008-06-14 06:34:50 +00:00
void Pdss1 : : message_disconnect ( unsigned int epoint_id , int message_id , union parameter * param )
2007-05-06 13:54:52 +00:00
{
2008-03-24 10:13:44 +00:00
l3_msg * l3m ;
2008-04-25 07:06:20 +00:00
struct lcr_msg * message ;
2007-05-06 13:54:52 +00:00
char * p = NULL ;
2007-05-09 05:39:20 +00:00
/* we reject during incoming setup when we have no tones. also if we are in outgoing setup state */
2007-07-17 17:28:09 +00:00
// if ((p_state==PORT_STATE_IN_SETUP && !p_m_mISDNport->tones)
2009-05-11 09:07:58 +00:00
if ( /* ||*/ p_state = = PORT_STATE_OUT_SETUP ) {
2007-05-06 13:54:52 +00:00
/* sending release to endpoint */
2009-05-11 09:07:58 +00:00
while ( p_epointlist ) {
2007-05-06 13:54:52 +00:00
message = message_create ( p_serial , p_epointlist - > epoint_id , PORT_TO_EPOINT , MESSAGE_RELEASE ) ;
2008-05-18 17:04:35 +00:00
memcpy ( & message - > param , param , sizeof ( union parameter ) ) ;
2007-05-06 13:54:52 +00:00
message_put ( message ) ;
/* remove epoint */
free_epointlist ( p_epointlist ) ;
}
/* sending release */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_RELEASE_COMPLETE_REQ , DIRECTION_OUT ) ;
2007-05-06 13:54:52 +00:00
/* send cause */
2008-05-18 17:04:35 +00:00
enc_ie_cause ( l3m , ( ! p_m_mISDNport - > locally & & param - > disconnectinfo . location = = LOCATION_PRIVATE_LOCAL ) ? LOCATION_PRIVATE_REMOTE : param - > disconnectinfo . location , param - > disconnectinfo . cause ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_RELEASE_COMPLETE , p_m_d_l3id , l3m ) ;
2007-05-27 13:24:02 +00:00
new_state ( PORT_STATE_RELEASE ) ;
2010-01-16 10:20:23 +00:00
trigger_work ( & p_m_d_delete ) ;
2007-05-06 13:54:52 +00:00
return ;
}
2007-07-17 17:28:09 +00:00
/* workarround: NT-MODE in setup state we must send PROCEEDING first to make it work */
2009-05-11 09:07:58 +00:00
if ( p_state = = PORT_STATE_IN_SETUP ) {
2007-05-06 13:54:52 +00:00
/* sending proceeding */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_PROCEEDING_REQ , DIRECTION_OUT ) ;
2007-05-06 13:54:52 +00:00
/* channel information */
2008-03-24 10:13:44 +00:00
enc_ie_channel_id ( l3m , 1 , p_m_b_channel ) ;
2007-05-06 13:54:52 +00:00
/* progress information */
if ( p_capainfo . bearer_capa = = INFO_BC_SPEECH
| | p_capainfo . bearer_capa = = INFO_BC_AUDIO
| | p_capainfo . bearer_capa = = INFO_BC_DATAUNRESTRICTED_TONES )
2008-06-14 06:34:50 +00:00
if ( p_m_mISDNport - > tones )
2008-09-21 06:57:51 +00:00
enc_ie_progress ( l3m , 0 , ( p_m_d_ntmode ) ? 1 : 5 , 8 ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_CALL_PROCEEDING , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
new_state ( PORT_STATE_IN_PROCEEDING ) ;
}
/* sending disconnect */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_DISCONNECT_REQ , DIRECTION_OUT ) ;
2007-05-06 13:54:52 +00:00
/* progress information */
if ( p_capainfo . bearer_capa = = INFO_BC_SPEECH
| | p_capainfo . bearer_capa = = INFO_BC_AUDIO
| | p_capainfo . bearer_capa = = INFO_BC_DATAUNRESTRICTED_TONES )
2007-07-07 15:13:20 +00:00
if ( p_m_mISDNport - > tones )
2008-09-21 06:57:51 +00:00
enc_ie_progress ( l3m , 0 , ( p_m_d_ntmode ) ? 1 : 5 , 8 ) ;
2007-05-06 13:54:52 +00:00
/* send cause */
2008-05-18 17:04:35 +00:00
enc_ie_cause ( l3m , ( ! p_m_mISDNport - > locally & & param - > disconnectinfo . location = = LOCATION_PRIVATE_LOCAL ) ? LOCATION_PRIVATE_REMOTE : param - > disconnectinfo . location , param - > disconnectinfo . cause ) ;
2007-05-06 13:54:52 +00:00
/* send display */
if ( param - > disconnectinfo . display [ 0 ] )
p = param - > disconnectinfo . display ;
2008-09-21 06:57:51 +00:00
if ( p ) if ( * p & & ( p_m_d_ntmode | | p_m_d_tespecial ) )
2008-03-24 10:13:44 +00:00
enc_ie_display ( l3m , ( unsigned char * ) p ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_DISCONNECT , p_m_d_l3id , l3m ) ;
2007-05-27 13:24:02 +00:00
new_state ( PORT_STATE_OUT_DISCONNECT ) ;
2007-05-06 13:54:52 +00:00
}
/* MESSAGE_RELEASE */
2008-06-14 06:34:50 +00:00
void Pdss1 : : message_release ( unsigned int epoint_id , int message_id , union parameter * param )
2007-05-06 13:54:52 +00:00
{
2008-03-24 10:13:44 +00:00
l3_msg * l3m ;
2007-05-06 13:54:52 +00:00
class Endpoint * epoint ;
char * p = NULL ;
2007-07-17 17:28:09 +00:00
/*
2010-01-16 10:42:46 +00:00
* if we are on incoming call setup , we may reject by sending a release_complete
* also on outgoing call setup , we send a release complete , BUT this is not conform . ( i don ' t know any other way )
2007-07-17 17:28:09 +00:00
*/
2010-01-16 10:42:46 +00:00
if ( p_state = = PORT_STATE_IN_SETUP
| | p_state = = PORT_STATE_OUT_SETUP ) {
//#warning remove me
//PDEBUG(DEBUG_LOG, "JOLLY sending release complete %d\n", p_serial);
/* sending release complete */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_RELEASE_REQ , DIRECTION_OUT ) ;
2007-05-06 13:54:52 +00:00
/* send cause */
2008-03-24 10:13:44 +00:00
enc_ie_cause ( l3m , ( p_m_mISDNport - > locally & & param - > disconnectinfo . location = = LOCATION_PRIVATE_LOCAL ) ? LOCATION_PRIVATE_LOCAL : param - > disconnectinfo . location , param - > disconnectinfo . cause ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2010-01-16 10:42:46 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_RELEASE_COMPLETE , p_m_d_l3id , l3m ) ;
2007-05-27 13:24:02 +00:00
new_state ( PORT_STATE_RELEASE ) ;
2007-07-17 17:28:09 +00:00
/* remove epoint */
free_epointid ( epoint_id ) ;
// wait for callref to be released
2007-05-06 13:54:52 +00:00
return ;
}
2007-07-17 17:28:09 +00:00
/*
2010-01-16 10:42:46 +00:00
* we may only release during incoming disconnect state .
* this means that the endpoint doesnt require audio anymore
2007-07-17 17:28:09 +00:00
*/
2010-01-16 10:42:46 +00:00
if ( p_state = = PORT_STATE_IN_DISCONNECT
| | p_state = = PORT_STATE_OUT_DISCONNECT
| | param - > disconnectinfo . force ) {
/* sending release */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_RELEASE_REQ , DIRECTION_OUT ) ;
2007-05-06 13:54:52 +00:00
/* send cause */
2008-03-24 10:13:44 +00:00
enc_ie_cause ( l3m , ( p_m_mISDNport - > locally & & param - > disconnectinfo . location = = LOCATION_PRIVATE_LOCAL ) ? LOCATION_PRIVATE_LOCAL : param - > disconnectinfo . location , param - > disconnectinfo . cause ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2010-01-16 10:42:46 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_RELEASE , p_m_d_l3id , l3m ) ;
2007-05-27 13:24:02 +00:00
new_state ( PORT_STATE_RELEASE ) ;
2007-07-07 19:36:16 +00:00
/* remove epoint */
free_epointid ( epoint_id ) ;
2007-07-17 17:28:09 +00:00
// wait for callref to be released
2007-07-07 19:36:16 +00:00
return ;
2010-01-16 10:42:46 +00:00
2007-05-06 13:54:52 +00:00
}
2007-07-17 17:28:09 +00:00
#if 0
wirklich erst proceeding ? :
2007-05-06 13:54:52 +00:00
/* NT-MODE in setup state we must send PROCEEDING first */
2009-05-11 09:07:58 +00:00
if ( p_m_d_ntmode & & p_state = = PORT_STATE_IN_SETUP ) {
2007-05-06 13:54:52 +00:00
CALL_PROCEEDING_t * proceeding ;
/* sending proceeding */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_PROCEEDING_REQ , DIRECTION_OUT ) ;
2007-05-06 13:54:52 +00:00
/* channel information */
2008-03-24 10:13:44 +00:00
enc_ie_channel_id ( l3m , 1 , p_m_b_channel ) ;
2007-05-06 13:54:52 +00:00
/* progress information */
if ( p_capainfo . bearer_capa = = INFO_BC_SPEECH
| | p_capainfo . bearer_capa = = INFO_BC_AUDIO
| | p_capainfo . bearer_capa = = INFO_BC_DATAUNRESTRICTED_TONES )
2008-06-14 06:34:50 +00:00
if ( p_m_mISDNport - > tones )
2008-09-21 06:57:51 +00:00
enc_ie_progress ( l3m , 0 , ( p_m_d_ntmode ) ? 1 : 5 , 8 ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_CALL_PROCEEDING , p_m_d_l3id , l3m ) ;
2007-05-06 13:54:52 +00:00
}
2007-07-17 17:28:09 +00:00
# endif
2007-05-06 13:54:52 +00:00
/* sending disconnect */
2008-03-24 10:13:44 +00:00
l3m = create_l3msg ( ) ;
2008-04-12 16:24:31 +00:00
l1l2l3_trace_header ( p_m_mISDNport , this , L3_DISCONNECT_REQ , DIRECTION_OUT ) ;
2007-05-06 13:54:52 +00:00
/* progress information */
if ( p_capainfo . bearer_capa = = INFO_BC_SPEECH
| | p_capainfo . bearer_capa = = INFO_BC_AUDIO
| | p_capainfo . bearer_capa = = INFO_BC_DATAUNRESTRICTED_TONES )
2007-07-07 15:13:20 +00:00
if ( p_m_mISDNport - > tones )
2008-09-21 06:57:51 +00:00
enc_ie_progress ( l3m , 0 , ( p_m_d_ntmode ) ? 1 : 5 , 8 ) ;
2007-05-06 13:54:52 +00:00
/* send cause */
2008-03-24 10:13:44 +00:00
enc_ie_cause ( l3m , ( p_m_mISDNport - > locally & & param - > disconnectinfo . location = = LOCATION_PRIVATE_LOCAL ) ? LOCATION_PRIVATE_LOCAL : param - > disconnectinfo . location , param - > disconnectinfo . cause ) ;
2007-05-06 13:54:52 +00:00
/* send display */
epoint = find_epoint_id ( epoint_id ) ;
if ( param - > disconnectinfo . display [ 0 ] )
p = param - > disconnectinfo . display ;
2008-09-21 06:57:51 +00:00
if ( p ) if ( * p & & ( p_m_d_ntmode | | p_m_d_tespecial ) )
2008-03-24 10:13:44 +00:00
enc_ie_display ( l3m , ( unsigned char * ) p ) ;
2007-05-27 13:24:02 +00:00
end_trace ( ) ;
2008-04-13 17:52:42 +00:00
p_m_mISDNport - > ml3 - > to_layer3 ( p_m_mISDNport - > ml3 , MT_DISCONNECT , p_m_d_l3id , l3m ) ;
2007-07-17 17:28:09 +00:00
new_state ( PORT_STATE_OUT_DISCONNECT ) ;
/* remove epoint */
2007-05-06 13:54:52 +00:00
free_epointid ( epoint_id ) ;
2007-07-17 17:28:09 +00:00
// wait for release and callref to be released
2007-12-22 09:10:18 +00:00
//#warning remove me
//PDEBUG(DEBUG_LOG, "JOLLY sending disconnect %d\n", p_serial);
2007-05-06 13:54:52 +00:00
}
/*
* endpoint sends messages to the port
*/
2008-06-14 06:34:50 +00:00
int Pdss1 : : message_epoint ( unsigned int epoint_id , int message_id , union parameter * param )
2007-05-06 13:54:52 +00:00
{
if ( PmISDN : : message_epoint ( epoint_id , message_id , param ) )
return ( 1 ) ;
2009-05-11 09:07:58 +00:00
switch ( message_id ) {
2007-05-06 13:54:52 +00:00
case MESSAGE_INFORMATION : /* overlap dialing */
if ( p_type = = PORT_TYPE_DSS1_NT_OUT
& & p_state ! = PORT_STATE_OUT_OVERLAP
& & p_state ! = PORT_STATE_CONNECT
& & p_state ! = PORT_STATE_OUT_DISCONNECT
2009-05-11 09:07:58 +00:00
& & p_state ! = PORT_STATE_IN_DISCONNECT ) {
2007-05-06 13:54:52 +00:00
break ;
}
if ( p_type = = PORT_TYPE_DSS1_TE_OUT
& & p_state ! = PORT_STATE_OUT_OVERLAP
& & p_state ! = PORT_STATE_OUT_PROCEEDING
& & p_state ! = PORT_STATE_OUT_ALERTING
& & p_state ! = PORT_STATE_CONNECT
& & p_state ! = PORT_STATE_OUT_DISCONNECT
2009-05-11 09:07:58 +00:00
& & p_state ! = PORT_STATE_IN_DISCONNECT ) {
2007-05-06 13:54:52 +00:00
break ;
}
if ( ( p_type = = PORT_TYPE_DSS1_NT_IN | | p_type = = PORT_TYPE_DSS1_TE_IN )
& & p_state ! = PORT_STATE_IN_OVERLAP
& & p_state ! = PORT_STATE_IN_PROCEEDING
& & p_state ! = PORT_STATE_IN_ALERTING
& & p_state ! = PORT_STATE_CONNECT
& & p_state ! = PORT_STATE_CONNECT_WAITING
& & p_state ! = PORT_STATE_OUT_DISCONNECT
2009-05-11 09:07:58 +00:00
& & p_state ! = PORT_STATE_IN_DISCONNECT ) {
2007-05-06 13:54:52 +00:00
break ;
}
message_information ( epoint_id , message_id , param ) ;
break ;
case MESSAGE_SETUP : /* dial-out command received from epoint */
if ( p_state ! = PORT_STATE_IDLE
2009-05-11 09:07:58 +00:00
& & p_state ! = PORT_STATE_CONNECT ) {
2007-05-06 13:54:52 +00:00
PERROR ( " Pdss1(%s) ignoring setup because isdn port is not in idle state (or connected for sending display info). \n " , p_name ) ;
break ;
}
if ( p_epointlist & & p_state = = PORT_STATE_IDLE )
2007-07-15 10:01:27 +00:00
FATAL ( " Pdss1(%s): epoint pointer is set in idle state, how bad!! \n " , p_name ) ;
2008-04-13 17:52:42 +00:00
message_setup ( epoint_id , message_id , param ) ;
2007-05-06 13:54:52 +00:00
break ;
case MESSAGE_NOTIFY : /* display and notifications */
message_notify ( epoint_id , message_id , param ) ;
break ;
case MESSAGE_FACILITY : /* facility message */
message_facility ( epoint_id , message_id , param ) ;
break ;
2012-07-28 14:24:06 +00:00
case MESSAGE_3PTY : /* begin result message */
message_3pty ( epoint_id , message_id , param ) ;
break ;
2007-05-06 13:54:52 +00:00
case MESSAGE_OVERLAP : /* more information is needed */
2009-05-11 09:07:58 +00:00
if ( p_state ! = PORT_STATE_IN_SETUP ) {
2007-05-06 13:54:52 +00:00
break ;
}
message_overlap ( epoint_id , message_id , param ) ;
break ;
case MESSAGE_PROCEEDING : /* call of endpoint is proceeding */
if ( p_state ! = PORT_STATE_IN_SETUP
2009-05-11 09:07:58 +00:00
& & p_state ! = PORT_STATE_IN_OVERLAP ) {
2007-05-06 13:54:52 +00:00
break ;
}
message_proceeding ( epoint_id , message_id , param ) ;
2009-05-11 09:07:58 +00:00
if ( p_m_d_notify_pending ) {
2009-03-20 17:47:31 +00:00
/* send pending notify message during connect */
message_notify ( ACTIVE_EPOINT ( p_epointlist ) , p_m_d_notify_pending - > type , & p_m_d_notify_pending - > param ) ;
message_free ( p_m_d_notify_pending ) ;
p_m_d_notify_pending = NULL ;
}
2007-05-06 13:54:52 +00:00
break ;
case MESSAGE_ALERTING : /* call of endpoint is ringing */
if ( p_state ! = PORT_STATE_IN_SETUP
& & p_state ! = PORT_STATE_IN_OVERLAP
2009-05-11 09:07:58 +00:00
& & p_state ! = PORT_STATE_IN_PROCEEDING ) {
2007-05-06 13:54:52 +00:00
break ;
}
message_alerting ( epoint_id , message_id , param ) ;
2009-05-11 09:07:58 +00:00
if ( p_m_d_notify_pending ) {
2009-03-20 17:47:31 +00:00
/* send pending notify message during connect */
message_notify ( ACTIVE_EPOINT ( p_epointlist ) , p_m_d_notify_pending - > type , & p_m_d_notify_pending - > param ) ;
message_free ( p_m_d_notify_pending ) ;
p_m_d_notify_pending = NULL ;
}
2007-05-06 13:54:52 +00:00
break ;
case MESSAGE_CONNECT : /* call of endpoint is connected */
if ( p_state ! = PORT_STATE_IN_SETUP
& & p_state ! = PORT_STATE_IN_OVERLAP
& & p_state ! = PORT_STATE_IN_PROCEEDING
& & p_state ! = PORT_STATE_IN_ALERTING
2009-05-11 09:07:58 +00:00
& & ! ( p_state = = PORT_STATE_CONNECT & & p_m_d_ntmode ) ) {
2007-05-06 13:54:52 +00:00
break ;
}
message_connect ( epoint_id , message_id , param ) ;
2009-05-11 09:07:58 +00:00
if ( p_m_d_notify_pending ) {
2009-03-20 17:47:31 +00:00
/* send pending notify message during connect */
message_notify ( ACTIVE_EPOINT ( p_epointlist ) , p_m_d_notify_pending - > type , & p_m_d_notify_pending - > param ) ;
message_free ( p_m_d_notify_pending ) ;
p_m_d_notify_pending = NULL ;
}
2007-05-06 13:54:52 +00:00
break ;
case MESSAGE_DISCONNECT : /* call has been disconnected */
if ( p_state ! = PORT_STATE_IN_SETUP
& & p_state ! = PORT_STATE_IN_OVERLAP
& & p_state ! = PORT_STATE_IN_PROCEEDING
& & p_state ! = PORT_STATE_IN_ALERTING
& & p_state ! = PORT_STATE_OUT_SETUP
& & p_state ! = PORT_STATE_OUT_OVERLAP
& & p_state ! = PORT_STATE_OUT_PROCEEDING
& & p_state ! = PORT_STATE_OUT_ALERTING
& & p_state ! = PORT_STATE_CONNECT
2009-05-11 09:07:58 +00:00
& & p_state ! = PORT_STATE_CONNECT_WAITING ) {
2007-05-06 13:54:52 +00:00
break ;
}
message_disconnect ( epoint_id , message_id , param ) ;
break ;
case MESSAGE_RELEASE : /* release isdn port */
2009-05-11 09:07:58 +00:00
if ( p_state = = PORT_STATE_RELEASE ) {
2007-05-06 13:54:52 +00:00
break ;
}
message_release ( epoint_id , message_id , param ) ;
break ;
default :
2008-11-04 08:31:09 +00:00
PERROR ( " Pdss1(%s) isdn port with (caller id %s) received a wrong message: %d \n " , p_name , p_callerinfo . id , message_id ) ;
2007-05-06 13:54:52 +00:00
}
return ( 1 ) ;
}
/*
* data from isdn - stack ( layer - 3 ) to pbx ( port class )
*/
2008-04-12 16:24:31 +00:00
int stack2manager ( struct mISDNport * mISDNport , unsigned int cmd , unsigned int pid , struct l3_msg * l3m )
{
class Port * port ;
class Pdss1 * pdss1 ;
char name [ 32 ] ;
PDEBUG ( DEBUG_ISDN , " cmd(0x%x) pid(0x%x) \n " , cmd , pid ) ;
2009-05-11 09:07:58 +00:00
if ( pid = = 0 ) {
2008-05-09 19:31:58 +00:00
PDEBUG ( DEBUG_ISDN , " ignoring dummy process from phone. \n " ) ;
return ( 0 ) ;
2008-04-13 17:52:42 +00:00
}
2008-04-12 16:24:31 +00:00
/* find Port object of type ISDN */
port = port_first ;
2009-05-11 09:07:58 +00:00
while ( port ) {
2008-04-12 16:24:31 +00:00
/* are we ISDN ? */
2010-05-31 16:45:02 +00:00
if ( ( port - > p_type & PORT_CLASS_mISDN_MASK ) = = PORT_CLASS_DSS1 ) {
2008-04-12 16:24:31 +00:00
pdss1 = ( class Pdss1 * ) port ;
/* check out correct stack and id */
2009-05-11 09:07:58 +00:00
if ( pdss1 - > p_m_mISDNport = = mISDNport ) {
if ( pdss1 - > p_m_d_l3id & MISDN_PID_CR_FLAG ) {
2008-05-12 09:39:44 +00:00
/* local callref, so match value only */
if ( ( pdss1 - > p_m_d_l3id & MISDN_PID_CRVAL_MASK ) = = ( pid & MISDN_PID_CRVAL_MASK ) )
break ; // found
2009-05-11 09:07:58 +00:00
} else {
2008-05-12 09:39:44 +00:00
/* remote callref, ref + channel id */
if ( pdss1 - > p_m_d_l3id = = pid )
break ; // found
}
2008-04-12 16:24:31 +00:00
}
}
port = port - > next ;
}
/* aktueller prozess */
2009-05-11 09:07:58 +00:00
if ( port ) {
if ( cmd = = MT_ASSIGN ) {
2008-05-09 19:31:58 +00:00
/* stack gives us new layer 3 id (during connect) */
l1l2l3_trace_header ( mISDNport , pdss1 , L3_NEW_L3ID_IND , DIRECTION_IN ) ;
add_trace ( " callref " , " old " , " 0x%x " , pdss1 - > p_m_d_l3id ) ;
/* nt-library now gives us a new id via CC_SETUP_CONFIRM */
if ( ( pdss1 - > p_m_d_l3id & MISDN_PID_CRTYPE_MASK ) ! = MISDN_PID_MASTER )
PERROR ( " strange setup-procid 0x%x \n " , pdss1 - > p_m_d_l3id ) ;
pdss1 - > p_m_d_l3id = pid ;
2008-05-12 16:35:48 +00:00
if ( port - > p_state = = PORT_STATE_CONNECT )
pdss1 - > p_m_d_ces = pid > > 16 ;
2008-05-09 19:31:58 +00:00
add_trace ( " callref " , " new " , " 0x%x " , pdss1 - > p_m_d_l3id ) ;
end_trace ( ) ;
return ( 0 ) ;
}
2008-04-12 16:24:31 +00:00
/* if process id is master process, but a child disconnects */
2008-04-24 07:24:04 +00:00
if ( mISDNport - > ntmode
& & ( pid & MISDN_PID_CRTYPE_MASK ) ! = MISDN_PID_MASTER
2009-05-11 09:07:58 +00:00
& & ( pdss1 - > p_m_d_l3id & MISDN_PID_CRTYPE_MASK ) = = MISDN_PID_MASTER ) {
2008-05-09 19:31:58 +00:00
if ( cmd = = MT_DISCONNECT
2009-05-11 09:07:58 +00:00
| | cmd = = MT_RELEASE ) {
2008-04-12 16:24:31 +00:00
/* send special indication for child disconnect */
pdss1 - > disconnect_ind_i ( cmd , pid , l3m ) ;
return ( 0 ) ;
}
2008-05-09 19:31:58 +00:00
if ( cmd = = MT_RELEASE_COMPLETE )
return ( 0 ) ;
2008-04-12 16:24:31 +00:00
}
2008-05-12 11:12:28 +00:00
/* if we have child pid and got different child pid message, ignore */
if ( mISDNport - > ntmode
& & ( pid & MISDN_PID_CRTYPE_MASK ) ! = MISDN_PID_MASTER
& & ( pdss1 - > p_m_d_l3id & MISDN_PID_CRTYPE_MASK ) ! = MISDN_PID_MASTER
& & pid ! = pdss1 - > p_m_d_l3id )
return ( 0 ) ;
/* process message */
pdss1 - > message_isdn ( cmd , pid , l3m ) ;
2008-04-13 17:52:42 +00:00
return ( 0 ) ;
2008-04-12 16:24:31 +00:00
}
/* d-message */
2009-05-11 09:07:58 +00:00
switch ( cmd ) {
2008-04-12 16:24:31 +00:00
case MT_SETUP :
2008-07-26 15:42:16 +00:00
/* creating port object, transparent until setup with hdlc */
2008-04-12 16:24:31 +00:00
SPRINT ( name , " %s-%d-in " , mISDNport - > ifport - > interface - > name , mISDNport - > portnum ) ;
2008-07-26 15:42:16 +00:00
if ( ! ( pdss1 = new Pdss1 ( PORT_TYPE_DSS1_NT_IN , mISDNport , name , NULL , 0 , 0 , B_MODE_TRANSPARENT ) ) )
2008-04-12 16:24:31 +00:00
FATAL ( " Cannot create Port instance. \n " ) ;
pdss1 - > message_isdn ( cmd , pid , l3m ) ;
break ;
case MT_RESUME :
2008-07-26 15:42:16 +00:00
/* creating port object, transparent until setup with hdlc */
2008-04-12 16:24:31 +00:00
SPRINT ( name , " %s-%d-in " , mISDNport - > ifport - > interface - > name , mISDNport - > portnum ) ;
2008-07-26 15:42:16 +00:00
if ( ! ( pdss1 = new Pdss1 ( PORT_TYPE_DSS1_NT_IN , mISDNport , name , NULL , 0 , 0 , B_MODE_TRANSPARENT ) ) )
2008-04-12 16:24:31 +00:00
FATAL ( " Cannot create Port instance. \n " ) ;
pdss1 - > message_isdn ( cmd , pid , l3m ) ;
break ;
case MT_FREE :
2008-05-09 19:31:58 +00:00
PDEBUG ( DEBUG_ISDN , " unused call ref released (l3id=0x%x) \n " , pid ) ;
2008-04-12 16:24:31 +00:00
break ;
case MT_RELEASE_COMPLETE :
PERROR ( " must be ignored by stack, not sent to app \n " ) ;
break ;
case MT_FACILITY :
// facility als broadcast
break ;
2011-09-28 10:09:54 +00:00
case MT_L2IDLE :
// L2 became idle - we could sent a MT_L2RELEASE if we are the L2 master
PDEBUG ( DEBUG_ISDN , " Got L2 idle \n " ) ;
break ;
2008-04-12 16:24:31 +00:00
default :
PERROR ( " unhandled message: cmd(0x%x) pid(0x%x) \n " , cmd , pid ) ;
port = port_first ;
2009-05-11 09:07:58 +00:00
while ( port ) {
if ( port - > p_type = = PORT_TYPE_DSS1_NT_IN | | port - > p_type = = PORT_TYPE_DSS1_NT_OUT ) {
2008-04-12 16:24:31 +00:00
pdss1 = ( class Pdss1 * ) port ;
/* check out correct stack */
if ( pdss1 - > p_m_mISDNport = = mISDNport )
/* check out correct id */
PERROR ( " unhandled message: pid=%x is not associated with port-dinfo=%x \n " , pid , pdss1 - > p_m_d_l3id ) ;
}
port = port - > next ;
}
return ( - EINVAL ) ;
}
return ( 0 ) ;
}
2007-05-06 13:54:52 +00:00