/****************************************************************************/ /* */ /* **** COPYRIGHT NOTICE **** */ /* */ /* */ /* Copyright (c) Digital Equipment Corporation, 1992 */ /* */ /* All Rights Reserved. Unpublished rights reserved under the */ /* copyright laws of the United States. */ /* */ /* The software contained on this media is proprietary to and */ /* embodies the confidential technology of Digital Equipment */ /* Corporation. Possession, use, duplication or dissemination */ /* of the software and media is authorized only pursuant to a */ /* valid written license from Digital Equipment Corporation. */ /* */ /* */ /* The information in this software is subject to change without notice */ /* and should not be construed as a commitment by DIGITAL EQUIPMENT */ /* CORPORATION. */ /* */ /* DIGITAL assumes no responsibility for the use or reliability of its */ /* software on equipment which is not supplied by DIGITAL. */ /* */ /* */ /****************************************************************************/ /************************************************************************ ** ** ** FACILITY: DECss7 IVP (Installation Verification Procedure) ** ** ENVIRONMENT: OSF/1 V3.0 ** ** MODULE NAME: ss7_vlr.c ** ** DESCRIPTION: VLR part of the DECss7 IVP. ** Mono-thread version. ** ** AUTHORS: Marc Beatini ** ** CREATION DATE: 17 February 1995 ** ** MODIFICATION HISTORY: ** Name (UserID) Date Comments ** ** Pierre Garnero 07-May-1996 Port on VMS ** ** Yves Schneider 11-Sep-1997 Add TCAP on TCPIP ** ** Yves Schneider 30-Dec-1997 Add signals handler. ** ** Pascal Gauthier 21-Jan-1998 Set On/Off the GT Translation ** at startup pass ** ** Yves Schneider 03-Jun-1998 Use the TCAP 96 API. ** ************************************************************************/ /* ** ** INCLUDE FILES ** */ /*************/ /* Libraries */ /*************/ #include #ifndef SS7_TCAP_96_API #define SS7_TCAP_96_API #endif #ifdef VMS #include #include #include #include #include #include #elif __unix__ #include #include #include #include #include #include #include #include #else /* WIN32 */ #include #include "ss7api.h" #include "ss7_cond_codes.h" #include "ss7_tcap_k_common.h" #endif /***************/ /* Local files */ /***************/ #include "ss7_ivp_defines.h" #include "ss7_ivp_typedefs.h" /* ** ** Table of contents ** */ static int msc_invoke_tcap (int); static int msc_cancel_ass (to_process_t *); static int msc_read_new_cell_coords(int *); static int examine_response(); static void PR_wait_indic_or_cell(); static int FB_cell_entered(); static int FB_ss7_indication(); typedef enum { NOGT , GT , NEVERGT } TRANSLATION ; TRANSLATION translate = NOGT ; /* ** ** MACRO DEFINITIONS ** */ #ifdef TCAPIP #define HLR_SITE '1' #define HLR_HOST '1' #define HLR_APPLI '9' #else #define HLR_PC 1 #define MSC_PC 2 #endif /* ** ** External References ** */ #include "ss7_ivp_tools.h" /* ** ** Data structure definitions ** */ #ifdef TCAPIP char dest_addr_string_nogt[]= {HLR_SITE,'.',HLR_HOST,':',HLR_APPLI}; char dest_addr_string_gt[] = {HLR_SITE,'.',HLR_HOST,':',HLR_APPLI}; char orig_addr_string[]=""; #elif CCITT char dest_addr_string_nogt[] = { (char)0xc3, (char)HLR_PC, (char)0, (char)0x09 }; char dest_addr_string_gt[] = { (char)0x88, (char)0x18, (char)0x80, (char)0 }; char orig_addr_string[] = { (char)0xc3, (char)MSC_PC, (char)0, (char)0x08 }; #define PC_POS 1 #elif ANSI char dest_addr_string_nogt[] = { (char)0xc3, (char)0x09, (char)HLR_PC, (char)0, (char)0 }; char dest_addr_string_gt[] = { (char)0x88, (char)0x18, (char)0x80, (char)0 }; char orig_addr_string[] = { (char)0xc3, (char)0x08, (char)MSC_PC, (char)0, (char)0 }; #define PC_POS 2 #elif TTC char dest_addr_string_nogt[] = { (char)0xc3, (char)HLR_PC, (char)0, (char)0x09 }; char orig_addr_string[] = { (char)0xc3, (char)MSC_PC, (char)0, (char)0x08 }; #define PC_POS 1 #elif CCI24 char dest_addr_string_nogt[] = { (char)0xc3, (char)HLR_PC, (char)0, (char)0, (char)0x09 }; char dest_addr_string_gt[] = { (char)0x88, (char)0x18, (char)0x80, (char)0 }; char orig_addr_string[] = { (char)0xc3, (char)MSC_PC, (char)0, (char)0, (char)0x08 }; #define PC_POS 1 #else PROTOCOL NOT SUPPORTED #endif #ifdef VMS /* ** array where input corresponding to the cell entered by the user ** is stored */ #define CI_INPUT_MAX_SIZE 80 char VA_input[CI_INPUT_MAX_SIZE]; /* ** control block used for reading the cell input */ struct TR_ioblock { short FI_status; short FI_offset; short FI_terminator; short FI_terminator_size; } VR_iosb; #endif #ifdef VMS long VI_event_flag; /* event flag for cell input */ #elif __unix__ fd_set fds; /* File descriptor set used for the select function */ #else /* WIN32 */ HANDLE VA_multi_input[2] ; DWORD VI_object_ready ; #ifdef CCITT extern void init_tcapport_ccitt(); #endif #ifdef ANSI extern void init_tcapport_ansi(); #endif #endif ss7_synch_var_t ss7_synch; /* ss7 synchronisation variable */ unsigned long user_info=0; int opc=BAD_VALUE; int dpc=BAD_VALUE; /* **++ ** FUNCTIONAL DESCRIPTION: ** ** Main line of VLR: ** Declare ourselves to SS7. ** Read and wait for new cell coords. ** Send them over SS7 to ss7_hlr_main. ** ** FORMAL PARAMETERS: ** ** None. ** ** RETURN VALUE: ** ** None. ** ** SIDE EFFECTS: ** ** None ** ** **-- */ void main(int argc, char *argv[]) { unsigned int status; int cell_id; /*Co-ordinates for the cell update. */ int exit_program = SS7_K_FALSE; /* Used to work out when to exit */ ss7_tcap_vector_t indications = { begin_ind_mess, continue_ind_mess, end_ind_mess, abort_ind_mess, invoke_ind_mess, result_ind_mess, error_ind_mess, reject_ind_mess, cancel_ind_mess, 0, /* unidirectional */ 0, /* notice */ 0 /* user_distrib */ }; void *evp; /* ss7 event context block pointer */ #ifdef VMS float delay = 10.0; /* Before "real" start */ float delay_exit = 2.0; /* Before exiting */ #elif __unix__ int delay = 10; /* Before "real" start */ int delay_exit = 2; /* Before exiting */ /* ADD SIGNALS HANDLER. */ sigset_t sig_set; sigemptyset(&sig_set); sigaddset(&sig_set, SIGXCPU); sigaddset(&sig_set, SIGABRT); sigaddset(&sig_set, SIGTERM); sigaddset(&sig_set, SIGURG); #ifdef V3.2 sigprocmask( SIG_BLOCK, &sig_set, 0 ); #else pthread_sigmask( SIG_BLOCK, &sig_set, 0 ); #endif #else /* WIN32 */ int delay = 10000; /* Before "real" start */ int delay_exit = 3000; /* Before exiting */ #ifdef CCITT init_tcapport_ccitt(); #endif #ifdef ANSI init_tcapport_ansi(); #endif #endif /* VMS */ /* Check the values (if any) */ #ifdef TCAPIP if ((argc != 1) && (argc != 2)) { printf("Usage: %s [site1.host1:appid1]\n",argv[0]); exit(-1); } if (argc == 2) { strcpy(dest_addr_string_nogt,argv[1]); } printf("\nDest=%s\n",dest_addr_string_nogt,orig_addr_string); #else if ((argc != 1) && (argc != 4)) { printf("Usage: %s [opc dpc (gtt_on|gtt_off)]\n",argv[0]); exit(-1); } if (argc == 1) { dpc=HLR_PC; opc=MSC_PC; } else { unsigned int i; opc=atoi(argv[1]); if ((opc < 0) || (opc > MAX_VALUE)) { printf("Bad opc value (%s). Range is 0 to %d.\n",argv[1],MAX_VALUE); exit(-1); } dpc=atoi(argv[2]); if ((dpc < 0 ) || (dpc > MAX_VALUE)) { printf("Bad dpc value (%s). Range is 0 to %d.\n",argv[2],MAX_VALUE); exit(-1); } for (i=0; i Invalid cell_id.\n"); VI_status = 0; } else { *cell_id = strtol(read_c,&e,10); if ((int)e < (int)read_c+strlen(read_c)) { printf("> Invalid cell_id.\n"); VI_status = 0; } } /* ** check that status that must be returned ** if equal to 0, fill cell_id with something different from 0 */ if (VI_status == 0) { *cell_id = 1; } return VI_status; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** Examine and process the response received from the HLR. ** ** FORMAL PARAMETERS: ** ** None. ** ** RETURN VALUE: ** ** Q_SUCCESS ** Q_WAS_EMPTY ** Q_FAIL ** ** SIDE EFFECTS: ** ** None **-- */ int examine_response() { unsigned int status; struct queue *queue_elem; to_process_t *to_process; status = rem_from_busy( &queue_elem, &to_process); /* get a buffer from busy queue */ if (status != Q_SUCCESS ) { return (Q_WAS_EMPTY); } /* busy queue empty */ if (to_process != NULL) { switch ((*to_process).ind_type) { case WRITE_RESULT_C: write_result_ass_mess( to_process); break; case WRITE_CANCEL_C: msc_cancel_ass(to_process); break; case WRITE_BEGIN_C: write_begin_ass_mess(to_process); break; case WRITE_CONTINUE_C: write_continue_ass_mess(to_process); break; case WRITE_ABORT_C: write_abort_ass_mess(to_process); break; case WRITE_ERROR_C: write_error_ass_mess(to_process); break; case WRITE_REJECT_C: write_reject_ass_mess(to_process); break; case WRITE_END_C: write_end_ass_mess(to_process); break; } /* switch */ (*to_process).ind_type = 0; /* record free */ status = put_at_free( queue_elem); /* reput elem in free queue */ if (status != Q_SUCCESS) { fprintf(stderr,"error reputing a buffer in free queue\n"); } } else { fprintf(stderr,"busy queue object pointer NULL, abnormal problem"); return (Q_FAIL); } return(status); } /* * Synchronization management */ void PR_wait_indic_or_cell() { #ifdef VMS /* ** ASCII values for the characters which are to terminate the read */ #define CR 13 #define HT 9 $DESCRIPTOR (DEVICE,"TT:"); static struct TR_short_mask { unsigned long FI_zero; unsigned long FI_mask; } VR_mask; static int VB_first = 1; static short VI_chan; static long VI_event_mask; unsigned long VI_cr_v = 0; unsigned long VI_ht_v = 0; unsigned long VI_event_1 = 0; unsigned long VI_event_2 = 0; if ( VB_first ) { /* ** set up the mask */ VR_mask.FI_zero = 0; VR_mask.FI_mask = 0; VI_cr_v = 1 << CR; VI_ht_v = 1 << HT; VR_mask.FI_mask = VI_cr_v | VI_ht_v ; /* ** get a free event flag */ lib$get_ef(&VI_event_flag); sys$assign(&DEVICE,&VI_chan,0,0); /* ** compute the mask corresponsing to the 2 event flags ** on which we must wait => substract 32 because ef are ** in the range 32..63 */ VI_event_1 = 1 << ( VI_event_flag - 32 ); VI_event_2 = 1 << ( ss7_synch - 32 ); VI_event_mask = VI_event_1 | VI_event_2; /* ** do this part of code only 1 time */ VB_first = 0; } /* ** Post a QIO to read cell */ sys$qio(VI_event_flag,VI_chan,IO$_READVBLK | IO$M_NOECHO ,&VR_iosb,0,0,VA_input,CI_INPUT_MAX_SIZE,0,&VR_mask,0,0); /* ** wait on the 2 event flags */ sys$wflor(ss7_synch,VI_event_mask); #elif __unix__ int selstat; /* Return code of the select function */ /* Declaration of file descr. we'll wait on: stdin and ss7 */ FD_ZERO(&fds); /* Reset file descriptor set */ FD_SET(STDIN_FILENO,&fds); /* Add stdin file descriptor */ FD_SET(ss7_synch,&fds); /* Add ss7 file descriptor */ selstat = select(ss7_synch+1,&fds,0,0,0); #else /* WIN32 */ static int VI_first = 1 ; HANDLE VV_console_handle ; if ( VI_first ) { /* the first time we enter in this function : perform some initializations */ VI_first = 0 ; /* get an handle on the current input console */ VV_console_handle = GetStdHandle(STD_INPUT_HANDLE) ; /* fill array of objetcs on which we are waiting */ VA_multi_input[0] = VV_console_handle ; VA_multi_input[1] = (HANDLE) ss7_synch ; } VI_object_ready = WaitForMultipleObjects( 2 , VA_multi_input, FALSE, /* only 1 object signalled is OK */ INFINITE ) ; #endif } /* end of PR_wait_indic_or_cell */ int FB_cell_entered() { #ifdef VMS unsigned long VI_state; int VI_return = 0; /* ** check if the event flag corresponding to the cell input ** is set */ if ( sys$readef(VI_event_flag,&VI_state) == SS$_WASSET ) { /* ** clear the event flag associated to the cell input */ sys$clref(VI_event_flag); VI_return = 1; } return VI_return; #elif __unix__ return FD_ISSET(STDIN_FILENO,&fds); #else /* WIN32 */ if ( VI_object_ready == WAIT_OBJECT_0 ) { return 1; } else { return 0; } #endif } /* end of FB_cell_entered */ int FB_ss7_indication() { #ifdef VMS unsigned long VI_state; int VI_return = 0; /* ** check if the event flag corresponding to the cell input ** is set */ if ( sys$readef(ss7_synch,&VI_state) == SS$_WASSET ) { VI_return = 1; } return VI_return; #elif __unix__ return FD_ISSET(ss7_synch,&fds); #else /* WIN32 */ if ( VI_object_ready == WAIT_OBJECT_0+1 ) { return 1; } else { return 0; } #endif } /* end of FB_ss7_indication */