2007-05-06 13:54:52 +00:00
/*****************************************************************************\
* * * *
2007-07-17 17:28:09 +00:00
* * Linux Call Router * *
2007-05-06 13:54:52 +00:00
* * * *
* * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *
* * Copyright : Andreas Eversberg * *
* * * *
2007-07-17 17:28:09 +00:00
* * Socket link server * *
2007-05-06 13:54:52 +00:00
* * * *
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-05-01 08:35:20 +00:00
# include "main.h"
2007-05-06 13:54:52 +00:00
# include <sys/socket.h>
# include <sys/un.h>
# include <curses.h>
2008-08-30 06:24:52 +00:00
char socket_name [ 128 ] ;
2007-05-06 13:54:52 +00:00
int sock = - 1 ;
struct sockaddr_un sock_address ;
2007-07-26 12:23:56 +00:00
struct admin_list * admin_first = NULL ;
2010-01-16 10:20:23 +00:00
static struct lcr_fd admin_fd ;
int admin_handle ( struct lcr_fd * fd , unsigned int what , void * instance , int index ) ;
2007-05-06 13:54:52 +00:00
/*
* initialize admin socket
*/
int admin_init ( void )
{
/* open and bind socket */
2009-07-05 20:14:21 +00:00
if ( ( sock = socket ( PF_UNIX , SOCK_STREAM , 0 ) ) < 0 ) {
2007-05-06 13:54:52 +00:00
PERROR ( " Failed to create admin socket. (errno=%d) \n " , errno ) ;
return ( - 1 ) ;
}
fhuse + + ;
memset ( & sock_address , 0 , sizeof ( sock_address ) ) ;
2008-08-30 06:24:52 +00:00
SPRINT ( socket_name , SOCKET_NAME , options . lock ) ;
2007-05-06 13:54:52 +00:00
sock_address . sun_family = AF_UNIX ;
UCPY ( sock_address . sun_path , socket_name ) ;
unlink ( socket_name ) ;
2009-07-05 20:14:21 +00:00
if ( bind ( sock , ( struct sockaddr * ) ( & sock_address ) , SUN_LEN ( & sock_address ) ) < 0 ) {
2007-05-06 13:54:52 +00:00
close ( sock ) ;
unlink ( socket_name ) ;
fhuse - - ;
sock = - 1 ;
PERROR ( " Failed to bind admin socket to \" %s \" . (errno=%d) \n " , sock_address . sun_path , errno ) ;
return ( - 1 ) ;
}
2009-07-05 20:14:21 +00:00
if ( listen ( sock , 5 ) < 0 ) {
2007-05-06 13:54:52 +00:00
close ( sock ) ;
unlink ( socket_name ) ;
fhuse - - ;
sock = - 1 ;
PERROR ( " Failed to listen to socket \" %s \" . (errno=%d) \n " , sock_address . sun_path , errno ) ;
return ( - 1 ) ;
}
2010-01-16 10:20:23 +00:00
memset ( & admin_fd , 0 , sizeof ( admin_fd ) ) ;
admin_fd . fd = sock ;
register_fd ( & admin_fd , LCR_FD_READ | LCR_FD_EXCEPT , admin_handle , NULL , 0 ) ;
2009-07-05 20:14:21 +00:00
if ( chmod ( socket_name , options . socketrights ) < 0 ) {
2009-10-08 08:36:06 +00:00
PERROR ( " Failed to change socket rights to %d. (errno=%d) \n " , options . socketrights , errno ) ;
2008-08-30 06:24:52 +00:00
}
2009-10-08 08:36:06 +00:00
if ( chown ( socket_name , options . socketuser , options . socketgroup ) < 0 ) {
PERROR ( " Failed to change socket user/group to %d/%d. (errno=%d) \n " , options . socketuser , options . socketgroup , errno ) ;
}
2007-05-06 13:54:52 +00:00
return ( 0 ) ;
}
/*
* free connection
2007-07-26 12:23:56 +00:00
* also releases all remote joins
2007-05-06 13:54:52 +00:00
*/
void free_connection ( struct admin_list * admin )
{
struct admin_queue * response ;
void * temp ;
2007-07-15 10:01:27 +00:00
union parameter param ;
2007-07-17 17:28:09 +00:00
class Join * join , * joinnext ;
2008-06-06 17:15:14 +00:00
struct mISDNport * mISDNport ;
int i , ii ;
2010-01-16 10:20:23 +00:00
struct admin_list * * adminp ;
2007-07-15 10:01:27 +00:00
2007-07-26 12:23:56 +00:00
/* free remote joins */
2009-07-05 20:14:21 +00:00
if ( admin - > remote_name [ 0 ] ) {
2008-09-14 10:27:11 +00:00
start_trace ( - 1 ,
2008-06-01 16:52:10 +00:00
NULL ,
NULL ,
NULL ,
DIRECTION_NONE ,
0 ,
0 ,
" REMOTE APP release " ) ;
add_trace ( " app " , " name " , " %s " , admin - > remote_name ) ;
end_trace ( ) ;
2008-06-06 17:15:14 +00:00
/* release all exported channels */
mISDNport = mISDNport_first ;
2009-07-05 20:14:21 +00:00
while ( mISDNport ) {
2008-06-06 17:15:14 +00:00
i = 0 ;
ii = mISDNport - > b_num ;
2009-07-05 20:14:21 +00:00
while ( i < ii ) {
if ( mISDNport - > b_remote_id [ i ] = = admin - > sock ) {
2008-06-06 17:15:14 +00:00
mISDNport - > b_state [ i ] = B_STATE_IDLE ;
2010-01-16 10:20:23 +00:00
unsched_timer ( & mISDNport - > b_timer [ i ] ) ;
2008-06-06 17:15:14 +00:00
mISDNport - > b_remote_id [ i ] = 0 ;
mISDNport - > b_remote_ref [ i ] = 0 ;
}
i + + ;
}
mISDNport = mISDNport - > next ;
}
/* release join */
2007-07-17 17:28:09 +00:00
join = join_first ;
2009-07-05 20:14:21 +00:00
while ( join ) {
2007-07-17 17:28:09 +00:00
joinnext = join - > next ;
2009-07-05 20:14:21 +00:00
if ( join - > j_type = = JOIN_TYPE_REMOTE ) if ( ( ( class JoinRemote * ) join ) - > j_remote_id = = admin - > sock ) {
2007-07-15 10:01:27 +00:00
memset ( & param , 0 , sizeof ( param ) ) ;
param . disconnectinfo . cause = CAUSE_OUTOFORDER ;
param . disconnectinfo . location = LOCATION_PRIVATE_LOCAL ;
2007-08-11 13:57:58 +00:00
( ( class JoinRemote * ) join ) - > message_remote ( MESSAGE_RELEASE , & param ) ;
2007-07-17 17:28:09 +00:00
/* join is now destroyed, so we go to next join */
2007-07-15 10:01:27 +00:00
}
2007-07-17 17:28:09 +00:00
join = joinnext ;
2007-07-15 10:01:27 +00:00
}
}
2007-05-06 13:54:52 +00:00
2009-07-05 20:14:21 +00:00
if ( admin - > sock > = 0 ) {
2010-01-16 10:20:23 +00:00
unregister_fd ( & admin - > fd ) ;
2007-05-06 13:54:52 +00:00
close ( admin - > sock ) ;
fhuse - - ;
}
response = admin - > response ;
2009-07-05 20:14:21 +00:00
while ( response ) {
2007-05-06 13:54:52 +00:00
temp = response - > next ;
2007-07-15 10:01:27 +00:00
FREE ( response , 0 ) ;
2007-05-06 13:54:52 +00:00
memuse - - ;
response = ( struct admin_queue * ) temp ;
}
2010-01-16 10:20:23 +00:00
adminp = & admin_first ;
while ( * adminp ) {
if ( * adminp = = admin )
break ;
adminp = & ( ( * adminp ) - > next ) ;
}
if ( * adminp )
* adminp = ( * adminp ) - > next ;
2007-07-15 10:01:27 +00:00
FREE ( admin , 0 ) ;
2007-05-06 13:54:52 +00:00
memuse - - ;
}
/*
* cleanup admin socket
*/
void admin_cleanup ( void )
{
struct admin_list * admin , * next ; ;
2007-07-26 12:23:56 +00:00
admin = admin_first ;
2009-07-05 20:14:21 +00:00
while ( admin ) {
2007-05-06 13:54:52 +00:00
next = admin - > next ;
free_connection ( admin ) ;
admin = next ;
}
2009-07-05 20:14:21 +00:00
if ( sock > = 0 ) {
2010-01-16 10:20:23 +00:00
unregister_fd ( & admin_fd ) ;
2007-05-06 13:54:52 +00:00
close ( sock ) ;
fhuse - - ;
}
2008-08-30 06:24:52 +00:00
unlink ( socket_name ) ;
2007-05-06 13:54:52 +00:00
}
/*
* do interface reload
*/
int admin_interface ( struct admin_queue * * responsep )
{
struct admin_queue * response ; /* response pointer */
2008-09-02 00:02:11 +00:00
const char * err_txt = " " ;
2007-05-06 13:54:52 +00:00
int err = 0 ;
2009-07-05 20:14:21 +00:00
if ( read_interfaces ( ) ) {
2007-05-06 13:54:52 +00:00
relink_interfaces ( ) ;
free_interfaces ( interface_first ) ;
interface_first = interface_newlist ;
interface_newlist = NULL ;
2009-07-05 20:14:21 +00:00
} else {
2007-05-06 13:54:52 +00:00
err_txt = interface_error ;
err = - 1 ;
}
/* create state response */
2007-07-15 10:01:27 +00:00
response = ( struct admin_queue * ) MALLOC ( sizeof ( struct admin_queue ) + sizeof ( admin_message ) ) ;
2007-05-06 13:54:52 +00:00
memuse + + ;
response - > num = 1 ;
/* message */
response - > am [ 0 ] . message = ADMIN_RESPONSE_CMD_INTERFACE ;
/* error */
response - > am [ 0 ] . u . x . error = err ;
/* message */
SCPY ( response - > am [ 0 ] . u . x . message , err_txt ) ;
/* attach to response chain */
* responsep = response ;
responsep = & response - > next ;
return ( 0 ) ;
}
/*
* do route reload
*/
int admin_route ( struct admin_queue * * responsep )
{
struct route_ruleset * ruleset_new ;
struct admin_queue * response ; /* response pointer */
char err_txt [ 256 ] = " " ;
int err = 0 ;
#if 0
int n ;
# endif
class EndpointAppPBX * apppbx ;
#if 0
n = 0 ;
apppbx = apppbx_first ;
2009-07-05 20:14:21 +00:00
while ( apppbx ) {
2007-05-06 13:54:52 +00:00
n + + ;
apppbx = apppbx - > next ;
}
2009-07-05 20:14:21 +00:00
if ( apppbx_first ) {
2007-05-06 13:54:52 +00:00
SPRINT ( err_txt , " Cannot reload routing, because %d endpoints active \n " , n ) ;
err = - 1 ;
goto response ;
}
# endif
2009-07-05 20:14:21 +00:00
if ( ! ( ruleset_new = ruleset_parse ( ) ) ) {
2007-05-06 13:54:52 +00:00
SPRINT ( err_txt , ruleset_error ) ;
err = - 1 ;
goto response ;
}
ruleset_free ( ruleset_first ) ;
ruleset_first = ruleset_new ;
ruleset_main = getrulesetbyname ( " main " ) ;
2009-07-05 20:14:21 +00:00
if ( ! ruleset_main ) {
2007-05-06 13:54:52 +00:00
SPRINT ( err_txt , " Ruleset reloaded, but rule 'main' not found. \n " ) ;
err = - 1 ;
}
apppbx = apppbx_first ;
2009-07-05 20:14:21 +00:00
while ( apppbx ) {
if ( apppbx - > e_action ) {
switch ( apppbx - > e_action - > index ) {
2007-05-06 13:54:52 +00:00
case ACTION_INTERNAL :
apppbx - > e_action = & action_internal ;
break ;
case ACTION_EXTERNAL :
apppbx - > e_action = & action_external ;
break ;
2007-07-26 12:23:56 +00:00
case ACTION_REMOTE :
apppbx - > e_action = & action_remote ;
2007-05-06 13:54:52 +00:00
break ;
case ACTION_VBOX_RECORD :
apppbx - > e_action = & action_vbox ;
break ;
case ACTION_PARTYLINE :
apppbx - > e_action = & action_partyline ;
break ;
default :
goto release ;
}
2009-07-05 20:14:21 +00:00
} else if ( apppbx - > e_state ! = EPOINT_STATE_CONNECT ) {
2007-05-06 13:54:52 +00:00
release :
2010-01-16 10:20:23 +00:00
unsched_timer ( & apppbx - > e_callback_timeout ) ;
2007-05-06 13:54:52 +00:00
apppbx - > e_action = NULL ;
2010-01-16 10:42:46 +00:00
apppbx - > release ( RELEASE_ALL , LOCATION_PRIVATE_LOCAL , CAUSE_NORMAL , LOCATION_PRIVATE_LOCAL , CAUSE_NORMAL , 0 ) ;
2008-09-14 10:27:11 +00:00
start_trace ( - 1 ,
2007-06-27 06:23:50 +00:00
NULL ,
2008-05-01 08:35:20 +00:00
numberrize_callerinfo ( apppbx - > e_callerinfo . id , apppbx - > e_callerinfo . ntype , options . national , options . international ) ,
2007-07-07 15:13:20 +00:00
apppbx - > e_dialinginfo . id ,
2007-06-27 06:23:50 +00:00
DIRECTION_NONE ,
CATEGORY_EP ,
2007-07-07 15:13:20 +00:00
apppbx - > ea_endpoint - > ep_serial ,
2007-06-27 06:23:50 +00:00
" KICK (reload routing) " ) ;
2007-07-08 09:24:26 +00:00
end_trace ( ) ;
2007-05-06 13:54:52 +00:00
}
2010-01-16 10:20:23 +00:00
unsched_timer ( & apppbx - > e_action_timeout ) ;
2007-05-06 13:54:52 +00:00
apppbx - > e_rule = NULL ;
apppbx - > e_ruleset = NULL ;
apppbx = apppbx - > next ;
}
response :
/* create state response */
2007-07-15 10:01:27 +00:00
response = ( struct admin_queue * ) MALLOC ( sizeof ( struct admin_queue ) + sizeof ( admin_message ) ) ;
2007-05-06 13:54:52 +00:00
memuse + + ;
response - > num = 1 ;
/* message */
response - > am [ 0 ] . message = ADMIN_RESPONSE_CMD_ROUTE ;
/* error */
response - > am [ 0 ] . u . x . error = err ;
/* message */
SCPY ( response - > am [ 0 ] . u . x . message , err_txt ) ;
/* attach to response chain */
* responsep = response ;
responsep = & response - > next ;
return ( 0 ) ;
}
/*
* do dialing
*/
int admin_dial ( struct admin_queue * * responsep , char * message )
{
struct extension ext ; /* temporary extension's settings */
struct admin_queue * response ; /* response pointer */
char * p ; /* pointer to dialing digits */
/* create state response */
2007-07-15 10:01:27 +00:00
response = ( struct admin_queue * ) MALLOC ( sizeof ( struct admin_queue ) + sizeof ( admin_message ) ) ;
2007-05-06 13:54:52 +00:00
memuse + + ;
response - > num = 1 ;
/* message */
response - > am [ 0 ] . message = ADMIN_RESPONSE_CMD_DIAL ;
/* process request */
2009-07-05 20:14:21 +00:00
if ( ! ( p = strchr ( message , ' : ' ) ) ) {
2007-05-06 13:54:52 +00:00
response - > am [ 0 ] . u . x . error = - EINVAL ;
SPRINT ( response - > am [ 0 ] . u . x . message , " no seperator ':' in message to seperate number from extension " ) ;
goto out ;
}
* p + + = 0 ;
/* modify extension */
2009-07-05 20:14:21 +00:00
if ( ! read_extension ( & ext , message ) ) {
2007-05-06 13:54:52 +00:00
response - > am [ 0 ] . u . x . error = - EINVAL ;
SPRINT ( response - > am [ 0 ] . u . x . message , " extension doesn't exist " ) ;
goto out ;
}
SCPY ( ext . next , p ) ;
write_extension ( & ext , message ) ;
out :
/* attach to response chain */
* responsep = response ;
responsep = & response - > next ;
return ( 0 ) ;
}
2007-07-08 09:24:26 +00:00
/*
* do tracing
*/
int admin_trace ( struct admin_list * admin , struct admin_trace_req * trace )
{
memcpy ( & admin - > trace , trace , sizeof ( struct admin_trace_req ) ) ;
return ( 0 ) ;
}
2007-07-07 15:13:20 +00:00
/*
* do blocking
*
* 0 = make port available
* 1 = make port administratively blocked
* 2 = unload port
* the result is returned :
* 0 = port is now available
* 1 = port is now blocked
* 2 = port cannot be loaded or has been unloaded
* - 1 = port doesn ' t exist
*/
int admin_block ( struct admin_queue * * responsep , int portnum , int block )
{
struct admin_queue * response ; /* response pointer */
struct interface * interface ;
struct interface_port * ifport ;
/* create block response */
2007-07-15 10:01:27 +00:00
response = ( struct admin_queue * ) MALLOC ( sizeof ( struct admin_queue ) + sizeof ( admin_message ) ) ;
2007-07-07 15:13:20 +00:00
memuse + + ;
response - > num = 1 ;
/* message */
response - > am [ 0 ] . message = ADMIN_RESPONSE_CMD_BLOCK ;
response - > am [ 0 ] . u . x . portnum = portnum ;
/* search for port */
2008-11-04 08:31:09 +00:00
ifport = NULL ;
2007-07-07 15:13:20 +00:00
interface = interface_first ;
2009-07-05 20:14:21 +00:00
while ( interface ) {
2007-07-07 15:13:20 +00:00
ifport = interface - > ifport ;
2009-07-05 20:14:21 +00:00
while ( ifport ) {
2007-07-07 15:13:20 +00:00
if ( ifport - > portnum = = portnum )
break ;
ifport = ifport - > next ;
}
if ( ifport )
break ;
interface = interface - > next ;
}
/* not found, we return -1 */
2009-07-05 20:14:21 +00:00
if ( ! ifport ) {
2007-07-07 15:13:20 +00:00
response - > am [ 0 ] . u . x . block = - 1 ;
response - > am [ 0 ] . u . x . error = 1 ;
SPRINT ( response - > am [ 0 ] . u . x . message , " Port %d does not exist. " , portnum ) ;
goto out ;
}
/* no interface */
2009-07-05 20:14:21 +00:00
if ( ! ifport - > mISDNport ) {
2007-07-07 15:13:20 +00:00
/* not loaded anyway */
2009-07-05 20:14:21 +00:00
if ( block > = 2 ) {
2007-07-07 15:13:20 +00:00
response - > am [ 0 ] . u . x . block = 2 ;
goto out ;
}
/* try loading interface */
ifport - > block = block ;
load_port ( ifport ) ;
/* port cannot load */
2009-07-05 20:14:21 +00:00
if ( ifport - > block > = 2 ) {
2007-07-07 15:13:20 +00:00
response - > am [ 0 ] . u . x . block = 2 ;
response - > am [ 0 ] . u . x . error = 1 ;
SPRINT ( response - > am [ 0 ] . u . x . message , " Port %d will not load. " , portnum ) ;
goto out ;
}
/* port loaded */
response - > am [ 0 ] . u . x . block = ifport - > block ;
goto out ;
}
/* if we shall unload interface */
2009-07-05 20:14:21 +00:00
if ( block > = 2 ) {
2007-07-07 15:13:20 +00:00
mISDNport_close ( ifport - > mISDNport ) ;
ifport - > mISDNport = 0 ;
ifport - > block = 2 ;
goto out ;
}
/* port new blocking state */
ifport - > block = response - > am [ 0 ] . u . x . block = block ;
out :
/* attach to response chain */
* responsep = response ;
responsep = & response - > next ;
return ( 0 ) ;
}
2007-05-06 13:54:52 +00:00
/*
* do release
*/
int admin_release ( struct admin_queue * * responsep , char * message )
{
2008-06-14 06:34:50 +00:00
unsigned int id ;
2007-05-06 13:54:52 +00:00
struct admin_queue * response ; /* response pointer */
class EndpointAppPBX * apppbx ;
/* create state response */
2007-07-15 10:01:27 +00:00
response = ( struct admin_queue * ) MALLOC ( sizeof ( struct admin_queue ) + sizeof ( admin_message ) ) ;
2007-05-06 13:54:52 +00:00
memuse + + ;
response - > num = 1 ;
/* message */
response - > am [ 0 ] . message = ADMIN_RESPONSE_CMD_RELEASE ;
id = atoi ( message ) ;
apppbx = apppbx_first ;
2009-07-05 20:14:21 +00:00
while ( apppbx ) {
2007-05-06 13:54:52 +00:00
if ( apppbx - > ea_endpoint - > ep_serial = = id )
break ;
apppbx = apppbx - > next ;
}
2009-07-05 20:14:21 +00:00
if ( ! apppbx ) {
2007-05-06 13:54:52 +00:00
response - > am [ 0 ] . u . x . error = - EINVAL ;
SPRINT ( response - > am [ 0 ] . u . x . message , " Given endpoint %d doesn't exist. " , id ) ;
goto out ;
}
2010-01-16 10:20:23 +00:00
unsched_timer ( & apppbx - > e_callback_timeout ) ;
2010-01-16 10:42:46 +00:00
apppbx - > release ( RELEASE_ALL , LOCATION_PRIVATE_LOCAL , CAUSE_NORMAL , LOCATION_PRIVATE_LOCAL , CAUSE_NORMAL , 0 ) ;
2007-05-06 13:54:52 +00:00
out :
/* attach to response chain */
* responsep = response ;
responsep = & response - > next ;
return ( 0 ) ;
}
/*
* do call
*/
int admin_call ( struct admin_list * admin , struct admin_message * msg )
{
class Endpoint * epoint ;
class EndpointAppPBX * apppbx ;
2007-08-11 13:57:58 +00:00
if ( ! ( epoint = new Endpoint ( 0 , 0 ) ) )
2007-07-15 10:01:27 +00:00
FATAL ( " No memory for Endpoint instance \n " ) ;
2007-12-22 09:10:18 +00:00
if ( ! ( epoint - > ep_app = apppbx = new DEFAULT_ENDPOINT_APP ( epoint , 1 ) ) ) // outgoing
2007-07-15 10:01:27 +00:00
FATAL ( " No memory for Endpoint Application instance \n " ) ;
2007-05-06 13:54:52 +00:00
apppbx - > e_adminid = admin - > sockserial ;
admin - > epointid = epoint - > ep_serial ;
2008-05-01 08:35:20 +00:00
SCPY ( apppbx - > e_callerinfo . id , nationalize_callerinfo ( msg - > u . call . callerid , & apppbx - > e_callerinfo . ntype , options . national , options . international ) ) ;
2007-05-06 13:54:52 +00:00
if ( msg - > u . call . present )
apppbx - > e_callerinfo . present = INFO_PRESENT_ALLOWED ;
else
apppbx - > e_callerinfo . present = INFO_PRESENT_RESTRICTED ;
apppbx - > e_callerinfo . screen = INFO_SCREEN_NETWORK ;
apppbx - > e_capainfo . bearer_capa = msg - > u . call . bc_capa ;
apppbx - > e_capainfo . bearer_mode = msg - > u . call . bc_mode ;
apppbx - > e_capainfo . bearer_info1 = msg - > u . call . bc_info1 ;
apppbx - > e_capainfo . hlc = msg - > u . call . hlc ;
apppbx - > e_capainfo . exthlc = msg - > u . call . exthlc ;
2007-07-07 15:13:20 +00:00
SCPY ( apppbx - > e_dialinginfo . id , msg - > u . call . dialing ) ;
2007-05-06 13:54:52 +00:00
SCPY ( apppbx - > e_dialinginfo . interfaces , msg - > u . call . interface ) ;
apppbx - > e_dialinginfo . sending_complete = 1 ;
apppbx - > new_state ( PORT_STATE_OUT_SETUP ) ;
2010-06-14 16:32:15 +00:00
apppbx - > out_setup ( 0 ) ;
2007-05-06 13:54:52 +00:00
return ( 0 ) ;
}
/*
* this function is called for response whenever a call state changes .
*/
2010-05-23 11:46:26 +00:00
void admin_call_response ( int adminid , int message , const char * connected , int cause , int location , int notify_progress )
2007-05-06 13:54:52 +00:00
{
struct admin_list * admin ;
struct admin_queue * response , * * responsep ; /* response pointer */
/* searching for admin id
* maybe there is no admin instance , because the calling port was not
* initiated by admin_call */
2007-07-26 12:23:56 +00:00
admin = admin_first ;
2009-07-05 20:14:21 +00:00
while ( admin ) {
2007-05-06 13:54:52 +00:00
if ( adminid = = admin - > sockserial )
break ;
admin = admin - > next ;
}
if ( ! admin )
return ;
/* seek to end of response list */
response = admin - > response ;
responsep = & admin - > response ;
2009-07-05 20:14:21 +00:00
while ( response ) {
2007-05-06 13:54:52 +00:00
responsep = & response - > next ;
response = response - > next ;
}
/* create state response */
2007-07-15 10:01:27 +00:00
response = ( struct admin_queue * ) MALLOC ( sizeof ( struct admin_queue ) + sizeof ( admin_message ) ) ;
2007-05-06 13:54:52 +00:00
memuse + + ;
response - > num = 1 ;
/* message */
response - > am [ 0 ] . message = message ;
SCPY ( response - > am [ 0 ] . u . call . callerid , connected ) ;
response - > am [ 0 ] . u . call . cause = cause ;
response - > am [ 0 ] . u . call . location = location ;
2010-05-23 11:46:26 +00:00
response - > am [ 0 ] . u . call . notify_progress = notify_progress ;
2007-05-06 13:54:52 +00:00
/* attach to response chain */
* responsep = response ;
responsep = & response - > next ;
2010-01-16 10:20:23 +00:00
admin - > fd . when | = LCR_FD_WRITE ;
2007-05-06 13:54:52 +00:00
}
2007-07-15 10:01:27 +00:00
/*
2007-07-26 12:23:56 +00:00
* send data to the remote socket join instance
2007-07-15 10:01:27 +00:00
*/
2008-06-01 16:52:10 +00:00
int admin_message_to_join ( struct admin_msg * msg , struct admin_list * admin )
2007-07-15 10:01:27 +00:00
{
2007-07-17 17:28:09 +00:00
class Join * join ;
2008-06-01 16:52:10 +00:00
struct admin_list * temp ;
2007-07-15 10:01:27 +00:00
2007-07-26 12:23:56 +00:00
/* hello message */
2009-07-05 20:14:21 +00:00
if ( msg - > type = = MESSAGE_HELLO ) {
if ( admin - > remote_name [ 0 ] ) {
2007-07-26 12:23:56 +00:00
PERROR ( " Remote application repeats hello message. \n " ) ;
return ( - 1 ) ;
}
/* look for second application */
2008-06-01 16:52:10 +00:00
temp = admin_first ;
2009-07-05 20:14:21 +00:00
while ( temp ) {
2008-06-01 16:52:10 +00:00
if ( ! strcmp ( temp - > remote_name , msg - > param . hello . application ) )
2007-07-15 10:01:27 +00:00
break ;
2008-06-01 16:52:10 +00:00
temp = temp - > next ;
2007-07-15 10:01:27 +00:00
}
2009-07-05 20:14:21 +00:00
if ( temp ) {
2007-07-26 12:23:56 +00:00
PERROR ( " Remote application connects twice??? (ignoring) \n " ) ;
2007-07-15 10:01:27 +00:00
return ( - 1 ) ;
}
2007-07-27 18:07:22 +00:00
/* set remote socket instance */
2008-06-01 16:52:10 +00:00
SCPY ( admin - > remote_name , msg - > param . hello . application ) ;
2008-09-14 10:27:11 +00:00
start_trace ( - 1 ,
2008-06-01 16:52:10 +00:00
NULL ,
NULL ,
NULL ,
DIRECTION_NONE ,
0 ,
0 ,
" REMOTE APP registers " ) ;
add_trace ( " app " , " name " , " %s " , admin - > remote_name ) ;
end_trace ( ) ;
2007-07-26 12:23:56 +00:00
return ( 0 ) ;
}
2007-07-27 18:07:22 +00:00
/* check we have no application name */
2009-07-05 20:14:21 +00:00
if ( ! admin - > remote_name [ 0 ] ) {
2007-07-26 12:23:56 +00:00
PERROR ( " Remote application did not send us a hello message. \n " ) ;
return ( - 1 ) ;
}
/* new join */
2009-07-05 20:14:21 +00:00
if ( msg - > type = = MESSAGE_NEWREF ) {
2007-07-26 12:23:56 +00:00
/* create new join instance */
2008-06-01 16:52:10 +00:00
join = new JoinRemote ( 0 , admin - > remote_name , admin - > sock ) ; // must have no serial, because no endpoint is connected
2009-07-05 20:14:21 +00:00
if ( ! join ) {
2007-07-26 12:23:56 +00:00
FATAL ( " No memory for remote join instance \n " ) ;
2008-06-01 16:52:10 +00:00
return ( - 1 ) ;
}
2007-07-26 12:23:56 +00:00
return ( 0 ) ;
}
2007-08-11 13:57:58 +00:00
/* bchannel message
* no ref given for * _ack */
if ( msg - > type = = MESSAGE_BCHANNEL )
if ( msg - > param . bchannel . type = = BCHANNEL_ASSIGN_ACK
2008-06-06 13:18:59 +00:00
| | msg - > param . bchannel . type = = BCHANNEL_REMOVE_ACK
2009-07-05 20:14:21 +00:00
| | msg - > param . bchannel . type = = BCHANNEL_RELEASE ) {
2007-08-11 13:57:58 +00:00
/* no ref, but address */
2008-06-06 13:18:59 +00:00
message_bchannel_from_remote ( NULL , msg - > param . bchannel . type , msg - > param . bchannel . handle ) ;
2007-08-11 13:57:58 +00:00
return ( 0 ) ;
}
2007-07-26 12:23:56 +00:00
/* check for ref */
2009-07-05 20:14:21 +00:00
if ( ! msg - > ref ) {
2007-07-26 12:23:56 +00:00
PERROR ( " Remote application did not send us a valid ref with a message. \n " ) ;
return ( - 1 ) ;
2007-07-15 10:01:27 +00:00
}
2007-07-17 17:28:09 +00:00
/* find join instance */
join = join_first ;
2009-07-05 20:14:21 +00:00
while ( join ) {
2007-07-26 12:23:56 +00:00
if ( join - > j_serial = = msg - > ref )
2007-07-15 10:01:27 +00:00
break ;
2007-07-17 17:28:09 +00:00
join = join - > next ;
2007-07-15 10:01:27 +00:00
}
2009-07-05 20:14:21 +00:00
if ( ! join ) {
2008-06-23 17:50:46 +00:00
PDEBUG ( DEBUG_LOG , " No join found with serial %d. (May have been already released.) \n " , msg - > ref ) ;
return ( 0 ) ;
2007-07-27 18:07:22 +00:00
}
2007-07-15 10:01:27 +00:00
2007-07-26 12:23:56 +00:00
/* check application */
2009-07-05 20:14:21 +00:00
if ( join - > j_type ! = JOIN_TYPE_REMOTE ) {
2007-07-26 12:23:56 +00:00
PERROR ( " Ref %d does not belong to a remote join instance. \n " , msg - > ref ) ;
return ( - 1 ) ;
}
2009-07-05 20:14:21 +00:00
if ( admin - > sock ! = ( ( class JoinRemote * ) join ) - > j_remote_id ) {
2008-06-01 16:52:10 +00:00
PERROR ( " Ref %d belongs to remote application %s, but not to sending application %s. \n " , msg - > ref , ( ( class JoinRemote * ) join ) - > j_remote_name , admin - > remote_name ) ;
2007-07-26 12:23:56 +00:00
return ( - 1 ) ;
2007-07-15 10:01:27 +00:00
}
/* send message */
2007-08-11 13:57:58 +00:00
( ( class JoinRemote * ) join ) - > message_remote ( msg - > type , & msg - > param ) ;
2007-07-15 10:01:27 +00:00
return ( 0 ) ;
}
/*
2007-07-26 12:23:56 +00:00
* this function is called for every message to remote socket
2007-07-15 10:01:27 +00:00
*/
2008-06-14 06:34:50 +00:00
int admin_message_from_join ( int remote_id , unsigned int ref , int message_type , union parameter * param )
2007-07-15 10:01:27 +00:00
{
struct admin_list * admin ;
2008-06-01 16:52:10 +00:00
struct admin_queue * * responsep ; /* response pointer */
2007-07-15 10:01:27 +00:00
/* searching for admin id
2007-07-26 12:23:56 +00:00
* maybe there is no given remote application
2007-07-15 10:01:27 +00:00
*/
2007-07-26 12:23:56 +00:00
admin = admin_first ;
2009-07-05 20:14:21 +00:00
while ( admin ) {
2007-07-27 18:07:22 +00:00
if ( admin - > remote_name [ 0 ] & & admin - > sock = = remote_id )
2007-07-15 10:01:27 +00:00
break ;
admin = admin - > next ;
}
2007-07-26 12:23:56 +00:00
/* no given remote application connected */
2007-07-15 10:01:27 +00:00
if ( ! admin )
return ( - 1 ) ;
/* seek to end of response list */
responsep = & admin - > response ;
2009-07-05 20:14:21 +00:00
while ( * responsep ) {
2008-06-01 16:52:10 +00:00
responsep = & ( * responsep ) - > next ;
2007-07-15 10:01:27 +00:00
}
/* create state response */
2008-06-01 16:52:10 +00:00
* responsep = ( struct admin_queue * ) MALLOC ( sizeof ( struct admin_queue ) + sizeof ( admin_message ) ) ;
2007-07-15 10:01:27 +00:00
memuse + + ;
2008-06-01 16:52:10 +00:00
( * responsep ) - > num = 1 ;
2007-07-15 10:01:27 +00:00
/* message */
2008-06-01 16:52:10 +00:00
( * responsep ) - > am [ 0 ] . message = ADMIN_MESSAGE ;
( * responsep ) - > am [ 0 ] . u . msg . type = message_type ;
( * responsep ) - > am [ 0 ] . u . msg . ref = ref ;
memcpy ( & ( * responsep ) - > am [ 0 ] . u . msg . param , param , sizeof ( union parameter ) ) ;
2010-01-16 10:20:23 +00:00
admin - > fd . when | = LCR_FD_WRITE ;
2007-07-15 10:01:27 +00:00
return ( 0 ) ;
}
2007-05-06 13:54:52 +00:00
/*
* do state debugging
*/
int admin_state ( struct admin_queue * * responsep )
{
class Port * port ;
class EndpointAppPBX * apppbx ;
2007-07-17 17:28:09 +00:00
class Join * join ;
2007-05-06 13:54:52 +00:00
class Pdss1 * pdss1 ;
2007-07-07 15:13:20 +00:00
struct interface * interface ;
struct interface_port * ifport ;
2007-05-06 13:54:52 +00:00
struct mISDNport * mISDNport ;
int i ;
int num ;
int anybusy ;
struct admin_queue * response ;
2007-07-26 12:23:56 +00:00
struct admin_list * admin ;
2010-01-16 10:20:23 +00:00
struct tm * now_tm ;
time_t now ;
2007-05-06 13:54:52 +00:00
/* create state response */
2007-07-15 10:01:27 +00:00
response = ( struct admin_queue * ) MALLOC ( sizeof ( struct admin_queue ) + sizeof ( admin_message ) ) ;
2007-05-06 13:54:52 +00:00
memuse + + ;
response - > num = 1 ;
/* message */
response - > am [ 0 ] . message = ADMIN_RESPONSE_STATE ;
/* version */
SCPY ( response - > am [ 0 ] . u . s . version_string , VERSION_STRING ) ;
/* time */
2010-01-16 10:20:23 +00:00
time ( & now ) ;
now_tm = localtime ( & now ) ;
2007-05-06 13:54:52 +00:00
memcpy ( & response - > am [ 0 ] . u . s . tm , now_tm , sizeof ( struct tm ) ) ;
/* log file */
SCPY ( response - > am [ 0 ] . u . s . logfile , options . log ) ;
/* interface count */
i = 0 ;
2007-07-07 15:13:20 +00:00
interface = interface_first ;
2009-07-05 20:14:21 +00:00
while ( interface ) {
2007-07-07 15:13:20 +00:00
ifport = interface - > ifport ;
2009-07-05 20:14:21 +00:00
while ( ifport ) {
2007-07-07 15:13:20 +00:00
i + + ;
ifport = ifport - > next ;
}
interface = interface - > next ;
2007-05-06 13:54:52 +00:00
}
response - > am [ 0 ] . u . s . interfaces = i ;
2007-07-26 12:23:56 +00:00
/* remote connection count */
i = 0 ;
admin = admin_first ;
2009-07-05 20:14:21 +00:00
while ( admin ) {
2007-07-27 18:07:22 +00:00
if ( admin - > remote_name [ 0 ] )
2007-07-26 12:23:56 +00:00
i + + ;
admin = admin - > next ;
}
response - > am [ 0 ] . u . s . remotes = i ;
2007-07-17 17:28:09 +00:00
/* join count */
join = join_first ;
2007-05-06 13:54:52 +00:00
i = 0 ;
2009-07-05 20:14:21 +00:00
while ( join ) {
2007-05-06 13:54:52 +00:00
i + + ;
2007-07-17 17:28:09 +00:00
join = join - > next ;
2007-05-06 13:54:52 +00:00
}
2007-07-17 17:28:09 +00:00
response - > am [ 0 ] . u . s . joins = i ;
2007-05-06 13:54:52 +00:00
/* apppbx count */
apppbx = apppbx_first ;
i = 0 ;
2009-07-05 20:14:21 +00:00
while ( apppbx ) {
2007-05-06 13:54:52 +00:00
i + + ;
apppbx = apppbx - > next ;
}
response - > am [ 0 ] . u . s . epoints = i ;
/* port count */
i = 0 ;
2007-07-07 15:13:20 +00:00
port = port_first ;
2009-07-05 20:14:21 +00:00
while ( port ) {
2007-05-06 13:54:52 +00:00
i + + ;
port = port - > next ;
}
response - > am [ 0 ] . u . s . ports = i ;
/* attach to response chain */
* responsep = response ;
responsep = & response - > next ;
2008-06-01 16:52:10 +00:00
/* create response for all instances */
num = ( response - > am [ 0 ] . u . s . interfaces )
+ ( response - > am [ 0 ] . u . s . remotes )
+ ( response - > am [ 0 ] . u . s . joins )
+ ( response - > am [ 0 ] . u . s . epoints )
+ ( response - > am [ 0 ] . u . s . ports ) ;
2007-07-07 15:13:20 +00:00
if ( num = = 0 )
return ( 0 ) ;
2007-07-15 10:01:27 +00:00
response = ( struct admin_queue * ) MALLOC ( sizeof ( admin_queue ) + ( num * sizeof ( admin_message ) ) ) ;
2007-05-06 13:54:52 +00:00
memuse + + ;
response - > num = num ;
* responsep = response ;
responsep = & response - > next ;
2007-07-07 15:13:20 +00:00
interface = interface_first ;
2007-05-06 13:54:52 +00:00
num = 0 ;
2009-07-05 20:14:21 +00:00
while ( interface ) {
2007-07-07 15:13:20 +00:00
ifport = interface - > ifport ;
2009-07-05 20:14:21 +00:00
while ( ifport ) {
2007-07-07 15:13:20 +00:00
/* message */
response - > am [ num ] . message = ADMIN_RESPONSE_S_INTERFACE ;
/* interface */
SCPY ( response - > am [ num ] . u . i . interface_name , interface - > name ) ;
/* portnum */
response - > am [ num ] . u . i . portnum = ifport - > portnum ;
2008-09-07 08:31:58 +00:00
/* portname */
SCPY ( response - > am [ num ] . u . i . portname , ifport - > portname ) ;
2007-07-07 15:13:20 +00:00
/* iftype */
response - > am [ num ] . u . i . extension = interface - > extension ;
/* block */
response - > am [ num ] . u . i . block = ifport - > block ;
2009-07-05 20:14:21 +00:00
if ( ifport - > mISDNport ) {
2007-07-07 15:13:20 +00:00
mISDNport = ifport - > mISDNport ;
/* ptp */
response - > am [ num ] . u . i . ptp = mISDNport - > ptp ;
2009-03-20 19:46:25 +00:00
/* l1hold */
response - > am [ num ] . u . i . l1hold = mISDNport - > l1hold ;
/* l2hold */
response - > am [ num ] . u . i . l2hold = mISDNport - > l2hold ;
2007-07-07 15:13:20 +00:00
/* ntmode */
response - > am [ num ] . u . i . ntmode = mISDNport - > ntmode ;
/* pri */
response - > am [ num ] . u . i . pri = mISDNport - > pri ;
/* use */
response - > am [ num ] . u . i . use = mISDNport - > use ;
/* l1link */
response - > am [ num ] . u . i . l1link = mISDNport - > l1link ;
/* l2link */
response - > am [ num ] . u . i . l2link = mISDNport - > l2link ;
2009-04-05 10:52:24 +00:00
memcpy ( response - > am [ num ] . u . i . l2mask , mISDNport - > l2mask , 16 ) ;
2008-05-02 19:19:06 +00:00
/* los */
response - > am [ num ] . u . i . los = mISDNport - > los ;
/* ais */
response - > am [ num ] . u . i . ais = mISDNport - > ais ;
/* rdi */
response - > am [ num ] . u . i . rdi = mISDNport - > rdi ;
/* slip */
response - > am [ num ] . u . i . slip_tx = mISDNport - > slip_tx ;
response - > am [ num ] . u . i . slip_rx = mISDNport - > slip_rx ;
2007-07-07 15:13:20 +00:00
/* channels */
response - > am [ num ] . u . i . channels = mISDNport - > b_num ;
/* channel info */
i = 0 ;
anybusy = 0 ;
2009-07-05 20:14:21 +00:00
while ( i < mISDNport - > b_num ) {
2007-07-07 15:13:20 +00:00
response - > am [ num ] . u . i . busy [ i ] = mISDNport - > b_state [ i ] ;
if ( mISDNport - > b_port [ i ] )
response - > am [ num ] . u . i . port [ i ] = mISDNport - > b_port [ i ] - > p_serial ;
2008-07-26 15:42:16 +00:00
response - > am [ num ] . u . i . mode [ i ] = mISDNport - > b_mode [ i ] ;
2007-07-07 15:13:20 +00:00
i + + ;
}
}
num + + ;
ifport = ifport - > next ;
2007-05-06 13:54:52 +00:00
}
2007-07-07 15:13:20 +00:00
interface = interface - > next ;
2007-05-06 13:54:52 +00:00
}
2007-07-26 12:23:56 +00:00
/* create response for all remotes */
admin = admin_first ;
2009-07-05 20:14:21 +00:00
while ( admin ) {
if ( admin - > remote_name [ 0 ] ) {
2007-07-26 12:23:56 +00:00
/* message */
response - > am [ num ] . message = ADMIN_RESPONSE_S_REMOTE ;
/* name */
2007-07-27 18:07:22 +00:00
SCPY ( response - > am [ num ] . u . r . name , admin - > remote_name ) ;
2007-07-26 12:23:56 +00:00
/* */
num + + ;
}
admin = admin - > next ;
}
2007-07-17 17:28:09 +00:00
/* create response for all joins */
join = join_first ;
2009-07-05 20:14:21 +00:00
while ( join ) {
2007-05-06 13:54:52 +00:00
/* message */
2007-07-17 17:28:09 +00:00
response - > am [ num ] . message = ADMIN_RESPONSE_S_JOIN ;
2007-05-06 13:54:52 +00:00
/* serial */
2007-07-26 12:23:56 +00:00
response - > am [ num ] . u . j . serial = join - > j_serial ;
2007-05-06 13:54:52 +00:00
/* partyline */
2007-07-26 12:23:56 +00:00
if ( join - > j_type = = JOIN_TYPE_PBX )
response - > am [ num ] . u . j . partyline = ( ( class JoinPBX * ) join ) - > j_partyline ;
/* remote application */
if ( join - > j_type = = JOIN_TYPE_REMOTE )
2007-07-27 18:07:22 +00:00
SCPY ( response - > am [ num ] . u . j . remote , ( ( class JoinRemote * ) join ) - > j_remote_name ) ;
2007-05-06 13:54:52 +00:00
/* */
2007-07-17 17:28:09 +00:00
join = join - > next ;
2007-05-06 13:54:52 +00:00
num + + ;
}
/* create response for all endpoint */
apppbx = apppbx_first ;
2009-07-05 20:14:21 +00:00
while ( apppbx ) {
2007-05-06 13:54:52 +00:00
/* message */
response - > am [ num ] . message = ADMIN_RESPONSE_S_EPOINT ;
/* serial */
response - > am [ num ] . u . e . serial = apppbx - > ea_endpoint - > ep_serial ;
2007-07-17 17:28:09 +00:00
/* join */
response - > am [ num ] . u . e . join = apppbx - > ea_endpoint - > ep_join_id ;
2007-05-06 13:54:52 +00:00
/* rx notification */
response - > am [ num ] . u . e . rx_state = apppbx - > e_rx_state ;
/* tx notification */
response - > am [ num ] . u . e . tx_state = apppbx - > e_tx_state ;
/* state */
2009-07-05 20:14:21 +00:00
switch ( apppbx - > e_state ) {
2007-05-06 13:54:52 +00:00
case EPOINT_STATE_IN_SETUP :
response - > am [ num ] . u . e . state = ADMIN_STATE_IN_SETUP ;
break ;
case EPOINT_STATE_OUT_SETUP :
response - > am [ num ] . u . e . state = ADMIN_STATE_OUT_SETUP ;
break ;
case EPOINT_STATE_IN_OVERLAP :
response - > am [ num ] . u . e . state = ADMIN_STATE_IN_OVERLAP ;
break ;
case EPOINT_STATE_OUT_OVERLAP :
response - > am [ num ] . u . e . state = ADMIN_STATE_OUT_OVERLAP ;
break ;
case EPOINT_STATE_IN_PROCEEDING :
response - > am [ num ] . u . e . state = ADMIN_STATE_IN_PROCEEDING ;
break ;
case EPOINT_STATE_OUT_PROCEEDING :
response - > am [ num ] . u . e . state = ADMIN_STATE_OUT_PROCEEDING ;
break ;
case EPOINT_STATE_IN_ALERTING :
response - > am [ num ] . u . e . state = ADMIN_STATE_IN_ALERTING ;
break ;
case EPOINT_STATE_OUT_ALERTING :
response - > am [ num ] . u . e . state = ADMIN_STATE_OUT_ALERTING ;
break ;
case EPOINT_STATE_CONNECT :
response - > am [ num ] . u . e . state = ADMIN_STATE_CONNECT ;
break ;
case EPOINT_STATE_IN_DISCONNECT :
response - > am [ num ] . u . e . state = ADMIN_STATE_IN_DISCONNECT ;
break ;
case EPOINT_STATE_OUT_DISCONNECT :
response - > am [ num ] . u . e . state = ADMIN_STATE_OUT_DISCONNECT ;
break ;
default :
response - > am [ num ] . u . e . state = ADMIN_STATE_IDLE ;
}
/* terminal */
2007-05-23 09:19:25 +00:00
SCPY ( response - > am [ num ] . u . e . terminal , apppbx - > e_ext . number ) ;
2007-05-06 13:54:52 +00:00
/* callerid */
SCPY ( response - > am [ num ] . u . e . callerid , apppbx - > e_callerinfo . id ) ;
/* dialing */
2007-07-07 15:13:20 +00:00
SCPY ( response - > am [ num ] . u . e . dialing , apppbx - > e_dialinginfo . id ) ;
2007-05-06 13:54:52 +00:00
/* action string */
if ( apppbx - > e_action )
SCPY ( response - > am [ num ] . u . e . action , action_defs [ apppbx - > e_action - > index ] . name ) ;
// if (apppbx->e_action)
// printf("action=%s\n",action_defs[apppbx->e_action->index].name);
/* park */
response - > am [ num ] . u . e . park = apppbx - > ea_endpoint - > ep_park ;
if ( apppbx - > ea_endpoint - > ep_park & & apppbx - > ea_endpoint - > ep_park_len & & apppbx - > ea_endpoint - > ep_park_len < = ( int ) sizeof ( response - > am [ num ] . u . e . park_callid ) )
memcpy ( response - > am [ num ] . u . e . park_callid , apppbx - > ea_endpoint - > ep_park_callid , apppbx - > ea_endpoint - > ep_park_len ) ;
response - > am [ num ] . u . e . park_len = apppbx - > ea_endpoint - > ep_park_len ;
/* crypt */
if ( apppbx - > e_crypt = = CRYPT_ON )
response - > am [ num ] . u . e . crypt = 1 ;
/* */
apppbx = apppbx - > next ;
num + + ;
}
/* create response for all ports */
port = port_first ;
2009-07-05 20:14:21 +00:00
while ( port ) {
2007-05-06 13:54:52 +00:00
/* message */
response - > am [ num ] . message = ADMIN_RESPONSE_S_PORT ;
/* serial */
response - > am [ num ] . u . p . serial = port - > p_serial ;
/* name */
SCPY ( response - > am [ num ] . u . p . name , port - > p_name ) ;
/* epoint */
response - > am [ num ] . u . p . epoint = ACTIVE_EPOINT ( port - > p_epointlist ) ;
/* state */
2009-07-05 20:14:21 +00:00
switch ( port - > p_state ) {
2007-05-06 13:54:52 +00:00
case PORT_STATE_IN_SETUP :
response - > am [ num ] . u . p . state = ADMIN_STATE_IN_SETUP ;
break ;
case PORT_STATE_OUT_SETUP :
response - > am [ num ] . u . p . state = ADMIN_STATE_OUT_SETUP ;
break ;
case PORT_STATE_IN_OVERLAP :
response - > am [ num ] . u . p . state = ADMIN_STATE_IN_OVERLAP ;
break ;
case PORT_STATE_OUT_OVERLAP :
response - > am [ num ] . u . p . state = ADMIN_STATE_OUT_OVERLAP ;
break ;
case PORT_STATE_IN_PROCEEDING :
response - > am [ num ] . u . p . state = ADMIN_STATE_IN_PROCEEDING ;
break ;
case PORT_STATE_OUT_PROCEEDING :
response - > am [ num ] . u . p . state = ADMIN_STATE_OUT_PROCEEDING ;
break ;
case PORT_STATE_IN_ALERTING :
response - > am [ num ] . u . p . state = ADMIN_STATE_IN_ALERTING ;
break ;
case PORT_STATE_OUT_ALERTING :
response - > am [ num ] . u . p . state = ADMIN_STATE_OUT_ALERTING ;
break ;
case PORT_STATE_CONNECT :
response - > am [ num ] . u . p . state = ADMIN_STATE_CONNECT ;
break ;
case PORT_STATE_IN_DISCONNECT :
response - > am [ num ] . u . p . state = ADMIN_STATE_IN_DISCONNECT ;
break ;
case PORT_STATE_OUT_DISCONNECT :
response - > am [ num ] . u . p . state = ADMIN_STATE_OUT_DISCONNECT ;
break ;
2009-09-26 11:20:29 +00:00
case PORT_STATE_RELEASE :
response - > am [ num ] . u . p . state = ADMIN_STATE_RELEASE ;
break ;
2007-05-06 13:54:52 +00:00
default :
response - > am [ num ] . u . p . state = ADMIN_STATE_IDLE ;
}
/* isdn */
2010-05-31 16:45:02 +00:00
if ( ( port - > p_type & PORT_CLASS_mISDN_MASK ) = = PORT_CLASS_DSS1 ) {
2007-05-06 13:54:52 +00:00
response - > am [ num ] . u . p . isdn = 1 ;
pdss1 = ( class Pdss1 * ) port ;
response - > am [ num ] . u . p . isdn_chan = pdss1 - > p_m_b_channel ;
response - > am [ num ] . u . p . isdn_hold = pdss1 - > p_m_hold ;
response - > am [ num ] . u . p . isdn_ces = pdss1 - > p_m_d_ces ;
}
/* */
port = port - > next ;
num + + ;
}
return ( 0 ) ;
}
int sockserial = 1 ; // must start with 1, because 0 is used if no serial is set
/*
* handle admin socket ( non blocking )
*/
2010-01-16 10:20:23 +00:00
int admin_handle_con ( struct lcr_fd * fd , unsigned int what , void * instance , int index ) ;
int admin_handle ( struct lcr_fd * fd , unsigned int what , void * instance , int index )
2007-05-06 13:54:52 +00:00
{
int new_sock ;
socklen_t sock_len = sizeof ( sock_address ) ;
2010-01-16 10:20:23 +00:00
struct admin_list * admin ;
2007-05-06 13:54:52 +00:00
2008-01-19 17:10:46 +00:00
/* check for new incoming connections */
2009-07-05 20:14:21 +00:00
if ( ( new_sock = accept ( sock , ( struct sockaddr * ) & sock_address , & sock_len ) ) > = 0 ) {
2007-05-06 13:54:52 +00:00
/* insert new socket */
2007-07-15 10:01:27 +00:00
admin = ( struct admin_list * ) MALLOC ( sizeof ( struct admin_list ) ) ;
2010-01-16 10:20:23 +00:00
memuse + + ;
fhuse + + ;
admin - > sockserial = sockserial + + ;
admin - > next = admin_first ;
admin_first = admin ;
admin - > sock = new_sock ;
admin - > fd . fd = new_sock ;
register_fd ( & admin - > fd , LCR_FD_READ | LCR_FD_EXCEPT , admin_handle_con , admin , 0 ) ;
2009-07-05 20:14:21 +00:00
} else {
if ( errno ! = EWOULDBLOCK ) {
2007-05-06 13:54:52 +00:00
PERROR ( " Failed to accept connection from socket \" %s \" . (errno=%d) Closing socket. \n " , sock_address . sun_path , errno ) ;
admin_cleanup ( ) ;
2010-01-16 10:20:23 +00:00
return 0 ;
2007-05-06 13:54:52 +00:00
}
}
2010-01-16 10:20:23 +00:00
return 0 ;
}
int admin_handle_con ( struct lcr_fd * fd , unsigned int what , void * instance , int index )
{
struct admin_list * admin = ( struct admin_list * ) instance ;
void * temp ;
struct admin_message msg ;
int len ;
struct Endpoint * epoint ;
if ( ( what & LCR_FD_READ ) ) {
2007-05-06 13:54:52 +00:00
/* read command */
len = read ( admin - > sock , & msg , sizeof ( msg ) ) ;
2009-07-05 20:14:21 +00:00
if ( len < 0 ) {
2010-01-16 10:20:23 +00:00
brokenpipe :
PDEBUG ( DEBUG_LOG , " Broken pipe on socket %d. (errno=%d). \n " , admin - > sock , errno ) ;
free_connection ( admin ) ;
return 0 ;
2007-05-06 13:54:52 +00:00
}
2009-07-05 20:14:21 +00:00
if ( len = = 0 ) {
2007-05-06 13:54:52 +00:00
end :
/*release endpoint if exists */
2009-07-05 20:14:21 +00:00
if ( admin - > epointid ) {
2007-05-06 13:54:52 +00:00
epoint = find_epoint_id ( admin - > epointid ) ;
2009-07-05 20:14:21 +00:00
if ( epoint ) {
2007-05-06 13:54:52 +00:00
( ( class DEFAULT_ENDPOINT_APP * ) epoint - > ep_app ) - >
2010-01-16 10:42:46 +00:00
release ( RELEASE_ALL , LOCATION_PRIVATE_LOCAL , CAUSE_NORMAL , LOCATION_PRIVATE_LOCAL , CAUSE_NORMAL , 0 ) ;
2007-05-06 13:54:52 +00:00
}
}
free_connection ( admin ) ;
2010-01-16 10:20:23 +00:00
return 0 ;
2007-05-06 13:54:52 +00:00
}
2009-07-05 20:14:21 +00:00
if ( len ! = sizeof ( msg ) ) {
2007-05-06 13:54:52 +00:00
PERROR ( " Short/long read on socket %d. (len=%d != size=%d). \n " , admin - > sock , len , sizeof ( msg ) ) ;
free_connection ( admin ) ;
2010-01-16 10:20:23 +00:00
return 0 ;
2007-05-06 13:54:52 +00:00
}
/* process socket command */
2009-07-05 20:14:21 +00:00
if ( admin - > response & & msg . message ! = ADMIN_MESSAGE ) {
2007-05-06 13:54:52 +00:00
PERROR ( " Data from socket %d while sending response. \n " , admin - > sock ) ;
free_connection ( admin ) ;
2010-01-16 10:20:23 +00:00
return 0 ;
2007-05-06 13:54:52 +00:00
}
2009-07-05 20:14:21 +00:00
switch ( msg . message ) {
2007-05-06 13:54:52 +00:00
case ADMIN_REQUEST_CMD_INTERFACE :
2009-07-05 20:14:21 +00:00
if ( admin_interface ( & admin - > response ) < 0 ) {
2007-05-06 13:54:52 +00:00
PERROR ( " Failed to create dial response for socket %d. \n " , admin - > sock ) ;
goto response_error ;
}
2010-01-16 10:20:23 +00:00
admin - > fd . when | = LCR_FD_WRITE ;
2007-05-06 13:54:52 +00:00
break ;
case ADMIN_REQUEST_CMD_ROUTE :
2009-07-05 20:14:21 +00:00
if ( admin_route ( & admin - > response ) < 0 ) {
2007-05-06 13:54:52 +00:00
PERROR ( " Failed to create dial response for socket %d. \n " , admin - > sock ) ;
goto response_error ;
}
2010-01-16 10:20:23 +00:00
admin - > fd . when | = LCR_FD_WRITE ;
2007-05-06 13:54:52 +00:00
break ;
case ADMIN_REQUEST_CMD_DIAL :
2009-07-05 20:14:21 +00:00
if ( admin_dial ( & admin - > response , msg . u . x . message ) < 0 ) {
2007-05-06 13:54:52 +00:00
PERROR ( " Failed to create dial response for socket %d. \n " , admin - > sock ) ;
goto response_error ;
}
2010-01-16 10:20:23 +00:00
admin - > fd . when | = LCR_FD_WRITE ;
2007-05-06 13:54:52 +00:00
break ;
case ADMIN_REQUEST_CMD_RELEASE :
2009-07-05 20:14:21 +00:00
if ( admin_release ( & admin - > response , msg . u . x . message ) < 0 ) {
2007-05-06 13:54:52 +00:00
PERROR ( " Failed to create release response for socket %d. \n " , admin - > sock ) ;
goto response_error ;
}
2010-01-16 10:20:23 +00:00
admin - > fd . when | = LCR_FD_WRITE ;
2007-05-06 13:54:52 +00:00
break ;
case ADMIN_REQUEST_STATE :
2009-07-05 20:14:21 +00:00
if ( admin_state ( & admin - > response ) < 0 ) {
2007-05-06 13:54:52 +00:00
PERROR ( " Failed to create state response for socket %d. \n " , admin - > sock ) ;
2007-05-09 05:39:20 +00:00
goto response_error ;
}
2010-01-16 10:20:23 +00:00
admin - > fd . when | = LCR_FD_WRITE ;
2007-07-07 15:13:20 +00:00
break ;
2007-07-08 09:24:26 +00:00
case ADMIN_TRACE_REQUEST :
2009-07-05 20:14:21 +00:00
if ( admin_trace ( admin , & msg . u . trace_req ) < 0 ) {
2007-07-08 09:24:26 +00:00
PERROR ( " Failed to create trace response for socket %d. \n " , admin - > sock ) ;
goto response_error ;
}
2010-01-16 10:20:23 +00:00
admin - > fd . when | = LCR_FD_WRITE ;
2007-07-08 09:24:26 +00:00
break ;
2007-07-07 15:13:20 +00:00
case ADMIN_REQUEST_CMD_BLOCK :
2009-07-05 20:14:21 +00:00
if ( admin_block ( & admin - > response , msg . u . x . portnum , msg . u . x . block ) < 0 ) {
2007-07-07 15:13:20 +00:00
PERROR ( " Failed to create block response for socket %d. \n " , admin - > sock ) ;
goto response_error ;
}
2010-01-16 10:20:23 +00:00
admin - > fd . when | = LCR_FD_WRITE ;
2007-07-07 15:13:20 +00:00
break ;
case ADMIN_MESSAGE :
2009-07-05 20:14:21 +00:00
if ( admin_message_to_join ( & msg . u . msg , admin ) < 0 ) {
2007-07-15 10:01:27 +00:00
PERROR ( " Failed to deliver message for socket %d. \n " , admin - > sock ) ;
2007-07-07 15:13:20 +00:00
goto response_error ;
2007-05-06 13:54:52 +00:00
}
break ;
case ADMIN_CALL_SETUP :
2009-07-05 20:14:21 +00:00
if ( admin_call ( admin , & msg ) < 0 ) {
2007-05-06 13:54:52 +00:00
PERROR ( " Failed to create call for socket %d. \n " , admin - > sock ) ;
2007-07-07 15:13:20 +00:00
response_error :
free_connection ( admin ) ;
2010-01-16 10:20:23 +00:00
return 0 ;
2007-05-06 13:54:52 +00:00
}
break ;
default :
PERROR ( " Invalid message %d from socket %d. \n " , msg . message , admin - > sock ) ;
free_connection ( admin ) ;
2010-01-16 10:20:23 +00:00
return 0 ;
2007-05-06 13:54:52 +00:00
}
2010-01-16 10:20:23 +00:00
}
if ( ( what & LCR_FD_WRITE ) ) {
2007-05-06 13:54:52 +00:00
/* write queue */
2009-07-05 20:14:21 +00:00
if ( admin - > response ) {
2007-05-06 13:54:52 +00:00
len = write ( admin - > sock , ( ( unsigned char * ) ( admin - > response - > am ) ) + admin - > response - > offset , sizeof ( struct admin_message ) * ( admin - > response - > num ) - admin - > response - > offset ) ;
2009-07-05 20:14:21 +00:00
if ( len < 0 ) {
2010-01-16 10:20:23 +00:00
goto brokenpipe ;
2007-05-06 13:54:52 +00:00
}
if ( len = = 0 )
goto end ;
2009-07-05 20:14:21 +00:00
if ( len < ( int ) ( sizeof ( struct admin_message ) * ( admin - > response - > num ) - admin - > response - > offset ) ) {
2007-05-06 13:54:52 +00:00
admin - > response - > offset + = len ;
2010-01-16 10:20:23 +00:00
return 0 ;
2009-07-05 20:14:21 +00:00
} else {
2007-05-06 13:54:52 +00:00
temp = admin - > response ;
admin - > response = admin - > response - > next ;
2007-07-15 10:01:27 +00:00
FREE ( temp , 0 ) ;
2007-05-06 13:54:52 +00:00
memuse - - ;
}
2010-01-16 10:20:23 +00:00
} else
admin - > fd . when & = ~ LCR_FD_WRITE ;
2007-05-06 13:54:52 +00:00
}
2010-01-16 10:20:23 +00:00
return 0 ;
2007-05-06 13:54:52 +00:00
}