/***************************************
* sy127_st_mon                         *
*                                      *
* Monitor prot_status and              *
* channel_status of each of the 40 ch  *
*                                      *
***************************************/

#include <stdio.h>
#include <module.h>
#include <errno.h>
#include "../lib/mylib1.h"
#include "a200.h"     /* definitions relative to the CAEN system */
#include "../dbase/hv_dbase.h"

#define SECONDS
#define MINUTES  * 60
#define PAUSE    1001
#define CONTINUE 1002
#define STOP     1003

SY127_MBOX *hv_mod;
PROCS_INFO *hv_procs_mod;
int mev_id, evpro_id;
hv_mod_struct *hv_mid;
int tcp_ip_nr, cpu_nr;
char *hv_config[3];

char *caller;
int tcycle, command;

sighand(signal)
register int signal;
{
   printf(" sy127_st_mon :  signal %d received \n", signal);
   if ( signal == STOP    
        ||  signal == 2 || signal == 3) { /* ^C  ^E */
      A200_end();
      /* put process ID to zero */
      if (tcycle != 0){
      sem_wait(evpro_id, caller);
      hv_procs_mod->sy127_st_mon_id = 0;
      sem_free(evpro_id, caller);
      }
      munlink(hv_mid);
      sem_unl(mev_id, caller);
      sem_unl(evpro_id, caller);
      munlink(hv_mod);
      munlink(hv_procs_mod);
      exit(0);
   }
   else if ( signal == PAUSE )
      sleep(0);
   else if ( signal == CONTINUE )
      ;          /*   do nothing , used to awaike the process  */ 
}

main(argc, argv)
int argc;
char *argv[];
{
   short ndata, data[40], map[40], prot_word;
   int hra[6];
   short i, j, chan, value, code;
   int ntry, rok, nerror;
   int maxtry = 1; 
   short sy127_crate;

   intercept(sighand);

   if (argc < 2)
      usage();
   caller = argv[0];
   tcycle = atoi(argv[1]);  /* sleep time in seconds if tcycle > 0 
                                             in 1/256 s if tcycle < 0
                                ( read once if tcycle = 0 )  */

   mev_id = sem_link("sy127mod", argv[0]);
   evpro_id = sem_link("hv_pr_info", argv[0]);

   if((hv_mod = (SY127_MBOX *)modlink("sy127mod", 0)) == (SY127_MBOX *) -1)
      exit(_errmsg(errno,
      "hv_mod: err. link data module sy127mod, errno %d\n", errno));
     
   if((hv_procs_mod = (PROCS_INFO *)modlink("hv_pr_info", 0)) 
   == (PROCS_INFO *)-1)
      exit(_errmsg(errno,
      "hv_mod: err. link data module hv_procs_info, errno %d\n", errno));

   get_config(&tcp_ip_nr, &cpu_nr, hv_config);

   if ((hv_mid = (hv_mod_struct *)modlink(hv_config[cpu_nr], 0))
   == (hv_mod_struct *)-1)
      if ((hv_mid = (hv_mod_struct *)modload(hv_config[cpu_nr], 0))
      == (hv_mod_struct *)-1)
         exit(_errmsg(errno, " %s: error loading/linking module %s\n",
         argv[0], hv_config[cpu_nr]));

   sy127_crate = hv_mid->hv_crate;   

   A200_init();

   while(1) { 
      ntry = 0;
      rok = 0; 
      while ( rok == 0 && ntry < maxtry ){
         ntry++; 
         if ((code = HV_Read_One(DUMMY, sy127_crate,
         PROT_WORD, &prot_word)) == 0){
            ndata = 40;
            code = HV_Read_Group(STATUS, sy127_crate, GAG_G,
            data, &ndata, map);
            /*         printf(" ndata %d \n", ndata); 
                       for (i = 0; i < ndata ; i++)
                       printf("i = %d   Status= %d \n", i, data[i]); 
            */   
            if ( code != 0)
               printf(" after HV_Read_Group: ndata = %d, code = %d\n",
                      ndata, code);
            if ( code == 0)
               rok = 1;
         }
         else{
            fprintf(stderr,"sy127_st_mon error code %d reading prot_word\n",
                    code);
         }
      }
      if((prot_word & 0xff) == 0xff)
         fprintf(stderr," sy127_st_mon : prot_word 0x%x\n",prot_word);
      if(rok == 1){
         data_ora(&hra[0], &hra[1], &hra[2], &hra[3], &hra[4], &hra[5]); 
         sem_wait(mev_id, argv[0]);
         /*          printf(" vado a scrivere  l'ora nel modulo \n");
         */ 
         for(i=0; i<6; i++)
            hv_mod->sta_tim[i] = hra[i];

         /*         printf(" vado a scrivere  i dati nel modulo \n");
         */    
         j = 0;
         for(i=0; i < 40; i++)
            if ( map[i] ) 
               hv_mod->hv_par[1].status[i] = data[j++];
         hv_mod->hv_par[1].prot_word = prot_word;

         /*        printf(" vado a scrivere nwrite nel modulo \n");
         */    
         hv_mod->nsta++;
         sem_free(mev_id, argv[0]);
      }
      else {
         fprintf(stderr," sy127_st_mon error. code = %d, ndata = %d\n",
                 code, ndata);
         fprintf(stderr,"                     prot_word = 0x%x\n",prot_word);
         sem_wait(mev_id, argv[0]);
         /*          printf(" vado a scrivere  nerrors nel modulo \n");
         */  
         hv_mod->nsta_err++;
         sem_free(mev_id, argv[0]);
      }

      sem_wait(evpro_id, argv[0]);
      if (tcycle != 0) {
         command = hv_procs_mod->sy127_st_mon_com;
         hv_procs_mod->sy127_st_mon_com = 0;  /* reset immediately command */
         tcycle = hv_procs_mod->sy127_st_mon_tcycle;
      }
      else 
         command = 0;
      if (tcycle != 0)
         hv_procs_mod->sy127_st_mon_active = 0;
      sem_free(evpro_id, argv[0]);

      if (!command){
         if (tcycle > 0)
            sleep( (unsigned) tcycle);
         else if(tcycle < 0)
            tsleep(BIT32 | (unsigned) -tcycle);
         else
            break;
      }
      else if(command == PAUSE)
         sleep(0);
      else if(command == STOP)
         break;

      sem_wait(evpro_id, argv[0]);
      hv_procs_mod->sy127_st_mon_active = 1;
      sem_free(evpro_id, argv[0]);
   }
   A200_end();

   if (tcycle != 0){
      sem_wait(evpro_id, argv[0]);
      hv_procs_mod->sy127_st_mon_id = 0;
      sem_free(evpro_id, argv[0]);
   }
   munlink(hv_mid);
   sem_unl(mev_id, caller);
   sem_unl(evpro_id, caller);
   munlink(hv_mod);
   munlink(hv_procs_mod);
   exit(0);
}

usage()
{
   printf(" usage :  sy127_st_mon   <tcycle> \n");
   printf("                            |-> == 0  : read once \n");
   printf("                                >= 0  : cycle in s\n");
   printf("                                <= 0  : cycle in  1/256 s   \n");
   exit(0);
}