/**************************************************************************** * * * a l m _ l i n e * * * * by Kevin Millar * * * * Display latest alarm message on DM message line * * * * Usage * * * * alm_line NAME DM_LIST [-d] * * * * where * * NAME is the name the task will use register with on the IPC * * DM_LIST is the name of a file containing a list of Display * * Managers the alarm messages are to be displayed on. * * -d is an optional flag to activate the debug output * * * * W A R N I N G !!! * * * * If a DM is not responding, the program will be very slow to respond, and * * alarm messages may be lost. * * * ****************************************************************************/ #include #include #include #include #include #include #include #include #define MAX_DM 50 /* maximum number of DMs allowed */ #define RCV_FLAG 1 /* IPC flag */ char task_name[14]; /* name of task object */ char rcv_buf[1024]; /* IPC receive buffer */ struct chk_clinfo info; /* IPC connectionless data structure */ struct event_spec event; /* IPC event data structure */ int debug_flag = FALSE; /* debug flag */ int num_dms; /* number of DMs in DM_FILE */ char dm_list[128]; /* DM_List file name */ char var_name[MAX_DM][14]; /* list of DM command variables */ char command[160]; /* DMCMD to be executed */ struct ALARM { short messg_type; char date_time[DATE_TIME_LENGTH]; char letterbug[LETTERBUG_LENGTH]; char compound_name[COMPOUND_NAME_LENGTH]; char block_name[BLOCK_NAME_LENGTH]; char point_name[POINT_NAME_LENGTH]; char alarm_type_msg[ALARM_TYPE_MSG_LENGTH]; short pnt_no; short sct_no; short opr_err; char parameter_name[PARAMETER_NAME_LENGTH]; char tenths; char inhprt; char dummy[DUMMY_LENGTH]; char ack_state; short monotonic_time; short valid_time; short priority; short stepno; char subrno; char sbxno; char alarm_limit[4]; char real_value[4]; short block_dscrp_length; short msg__text_length; short in_out_length; short units_length; short state_text_length; char text_buffer[LENGTH_LEFT]; } alarm_msg; /* local copy of alarm message structure */ /* if the alarm message structure in the Foxboro include files is used, the size of the elements varies depending on the platform used. There is probably a better way of doing this but it was easy and it worked */ /* declaration of local functions */ void cleanup(); int swap_bytes( short *src, int num ); int process_message( char *buf_ptr, int *size ); int dump_data( char *addr, int size ); /**************************************************************************** * * * Function : main * * * * Purpose : process command line * * read display manager list file * * register task for connectionless IPC * * main loop * * wait for IPC message * * process IPC message(s) * * next IPC message * * * ****************************************************************************/ main( argc, argv) int argc; char *argv[]; { int result; int msg_id; int i, offset, size; char c; FILE *dm_file; /* display banner */ printf("\n"); printf(" Display alarms on message line (Ver 1.2) - Kevin Millar\n"); printf(" =========================================================\n"); printf("\n"); /* process command line arguments */ /* check number of arguments */ if ( argc<3 || argc>4 ) { printf("Usage : %s NAME DM_LIST [-d]\n",argv[0]); printf("\n"); printf("Alarm messages send to NAME will output to the message line\n"); printf("of the DMs listed in the file DM_LIST\n"); printf("\n"); printf(" W A R N I N G !!!\n"); printf("\n"); printf("If a DM is not responding, the program will be very slow to\n"); printf("respond, and alarm messages may be lost.\n"); printf("\n"); exit(0); } /* check for debug option */ if ( argc==4 ) { if ( strcmp( argv[3], "-d" ) == 0 ) { printf("Debug output active\n\n"); debug_flag = TRUE; } } /* process task name argument */ if ( (int)strlen(argv[1]) > 12 ) { printf("ERROR : task name too long\n"); exit(-1); } strcpy( task_name, argv[1] ); for (i=0; i<(int)strlen(task_name); i++) task_name[i] = toupper( task_name[i] ); /* open the DM list file */ dm_file = fopen( argv[2], "r" ); if (dm_file==NULL) { printf("ERROR : unable to open DM list file \" %s \"\n", argv[2]); exit(-1); } if (debug_flag) printf("Message will be sent to the following DMs\n"); /* loop thru contents of dm list file */ num_dms = 0; fgets( var_name[num_dms], 8, dm_file ); while ( !feof(dm_file) && num_dms 0 ) { /* exit parent task */ if ( debug_flag ) printf("%s child PID = %d\n", argv[0], i ); exit(0); } /* child task to continue - effect is task running in the background */ if ( ! debug_flag ) { for (i=0; i 141 ) { /* skip first 10 bytes */ offset = 10; /* loop through messages in buffer */ while ( offset < info.r_size - 132 ) { process_message( &rcv_buf[offset], &size ); offset += size; } } else { /* message too small to be an alarm message */ if (debug_flag) printf("Message too small to be alarm message - ignoring\n"); } /* repeat forever */ } } /**************************************************************************** * * * Function : cleanup * * * * Purpose : unregister task * * umimport command variables * * * ****************************************************************************/ void cleanup() { int i; printf("\nExiting...\n\n"); cl_cancel( task_name ); cs_unregister( task_name, CDT ); obj_delete( task_name, PROCESS ); for (i=0; i 28 || alarm_msg.messg_type == 22 ) return; /* build C:B.P */ sprintf( cbp_name, "%s:%s.%s", alarm_msg.compound_name, alarm_msg.block_name, alarm_msg.point_name ); /* build message to display on DM message line */ sprintf( message ," %s.%s %s", alarm_msg.block_name, alarm_msg.alarm_type_msg, alarm_msg.text_buffer ); /* build DM command string */ sprintf( command, "msglin \"%s\"", message ); if (debug_flag) printf("%s\n", command ); /* write DM command to command variables */ /* This section needs some work. If the station is offline then setval() call will timeout after 12 seconds. If there is a burst of alarms then the delays could cause problems. It needs to check the status of of the stations, and only write to ones that are OK, and periodically check the bad ones so it will detect when they come back online. */ for ( dm=0; dm' ' && c<127) printf("%c",c); else printf("."); } } printf("\n"); }