#define ident "1A05" /*---------------------------------------------------------------------------*/ #ifdef __DECC #pragma module SINQHM_CTRL ident #endif /* ** Link_options - Here is the Linker Option File **! sinqhm_ctrl **! sinq_olb/lib/inc=deltat_messages **!! **!! To build SINQHM_CTRL on LNSA09 **!! **!! $ import tasmad **!! $ define/job deltat_c_tlb sinq_c_tlb **!! $ sss := ud0:[maden.pss123.wind.sinqhm] **!! $ bui 'sss'sinqhm_ctrl debug ** Link_options_end ** ** Building on Alpha OSF/1: ** cc -std1 -g -o ~/bin/sinqhm_ctrl -I/public/lib/include \ -transitive_link -L/public/lib -lsinq -lrt \ ~/SinqHM/sinqhm_ctrl.c ** ** +--------------------------------------------------------------+ ** | Paul Scherrer Institute | ** | Computing Section | ** | | ** | This software may be used freely by non-profit organizations.| ** | It may be copied provided that the name of P.S.I. and of the | ** | author is included. Neither P.S.I. nor the author assume any | ** | responsibility for the use of this software outside of P.S.I.| ** +--------------------------------------------------------------+ ** ** Module Name . . . . . . . . : [...HMSR]SINQHM_CTRL.C ** ** Author . . . . . . . . . . : D. Maden ** Date of creation . . . . . . : Dec 1996 ** ** Purpose ** ======= ** SINQHM_CTRL.C is an Internet Client which can be used to send control ** messages to a front-end processor running the SINQHM histogram ** memory server process. Control messages may be sent to configure, ** de-configure, rundown, set the level of debug printing, start data ** acquisition, stop data acquisition, show the status of SINQHM_SRV, or ** zero the histogram memory. ** ** 1) Configure: ** ========= ** The configuration information is obtained from the logical name ** table. The following logical name definitions are used ... ** ** SINQHM_FRONTEND " " ** is the node where SINQHM_SRV is running, ** is SINQHM_SRV's TCP/IP port number (dflt=2400), ** is max packet size for send/rcve (dflt = 8192). ** SINQHM_NHISTS The number of histograms (dflt = 1). ** SINQHM_NBINS The number of bins per histogram (no dflt). ** SINQHM_BINWID The number of bytes per bin (dflt = 4). ** ** Once the configuration information has been obtained from the logical ** names, a connection is made to the SINQHM_SRV root process on the ** front-end and a configure message is sent. SINQHM_SRV will check the ** information, start up a child process, FILLER, which will do the work of ** filling histograms, and then send a reply. ** ** Note: If SINQHM_SRV has already been successfully configured, i.e. it ** already has an active FILLER child process, it must be ** de-configured first. ** ** 2) Debug: ** ====== ** The level of debug printing in the SINQHM_SRV root process can be set. The ** higher the level, the more print-out on the front-end processor's console ** occurs. The debug level is inherited by any server children (or FILLER) ** which subsequently get started. ** ** 3) De-configure: ** ============ ** "De-configuration" involves terminating any child processes of the ** SINQHM_SRV root process. Normally, it is expected that the server children ** will have been terminated via the protocol between the servers and their ** clients so that a de-configure involves simply the termination of FILLER. ** This is a so-called "gentle" de-configure. However, in order to facilitate ** the recovery from error situations, it is possible to specify a "harsh" ** de-configure in which any active server children will also be terminated. ** A gentle de-configure will fail if there are active children. ** ** 4) Rundown: ** ======= ** "Rundown" implies the termination not only of the SINQHM_SRV children but ** also of the root process itself. Once a rundown has been performed, ** intervention will be required on the front-end (e.g. reboot or creation ** of a new SINQHM_SRV root job from the front-end console) before SINQHM_SRV ** can be used again. ** ** 5) Show-Status: ** =========== ** The status of SINQHM_SRV is illicited and printed out. ** ** 6) Start-Data-Acquisition ** ====================== ** The SinqHM-Filler process in the HM is instructed to start data-acq. ** ** 7) Stop-Data-Acquisition ** ===================== ** The SinqHM-Filler process in the HM is instructed to stop data-acq. ** ** 8) Zero: ** ==== ** The complete histogram area is set to zero. ** ** Use: ** === ** Define the foreign command: ** ** $ sinqhm_ctrl :== $mad_exe:sinqhm_ctrl ** ** Then issue the command: ** ** $ sinqhm_ctrl ** ** where may be "CONFIG", "DEBUG", "DECONFIG", "GO", "HELP", ** "RUNDOWN", "SHOW", "STOP" or "ZERO". If is omitted or none of ** the above or if any error occurs obtaining the configuration ** information for the "CONFIG" command, a "HELP" command will be assumed. ** ** For the "CONFIG" command, may be specified as "SUSPEND". ** If so, the filler task in the front-end will suspend as soon as it ** starts so that it can be debugged. ** ** For the "DEBUG" command, is an integer specifying the debug ** level. may also be specified as "ON" or "OFF", corresponding ** to levels 1 and 0 respectively. If is anything else (or ** absent), "ON" is assumed. ** ** For the "DECONFIG" command, is used to specify the ** "harshness" of the de-configure. If is specified as ** "HARSH", the de-configure will be "harsh". If is anything ** else (or absent) the de-configure will be gentle. ** ** Communication between SINQHM_CTRL and the server is via TCP/IP protocol. ** ** Updates: ** 1A01 18-Dec-1996 DM. Initial version. **==================================================================== */ #include #include #include #include #include #include #include #include #include #include #include #include /* **==================== Global Definitions ===================================== */ #include "sinq_prototypes.h" #include "sinqhm_def.h" #define SUCCESS 1 #define ERROR 0 #define NIL '\0' #define HM_SIZE 65536 /* Number of Bins in Hist Mem */ /* **==================== Some functions and structures ===================== ** ** Fixed-Length Descriptor: */ struct dsc__descriptor_s { unsigned short dsc__w_length; /* length of data item in bytes */ unsigned char dsc__b_dtype; /* data type code */ unsigned char dsc__b_class; /* descriptor class code */ char *dsc__a_pointer; /* address of data storage */ }; /* **==================== Global Variables ====================================== */ int My_errno, My_vaxc_errno; struct req_buff_struct Req_buff; struct rply_buff_struct Rply_buff; char Rmt_node[10]; int Rmt_port; int Pkt_size; int Hm_mode; /* The histogramming mode */ int Nhists; /* The number of histograms to fill */ int Lo_bin; /* The first bin */ int Nbins; /* The number of bins to fill */ int Binwid; /* The number of bytes per bin */ int Compress; /* The bin compression factor */ struct dsc__descriptor_s Name_desc; extern int C_gbl_status; /* Return status from C_... routines */ /* **============================================================================= ** Local routines. ** ** get_SINQHM_FRONTEND : Extract info from SINQHM_FRONTEND environment variable ** show_help : Display the help text. ** strMatch : Match 2 strings. **---------------------------------------------------------------------------- ** Prototypes */ int getenv_integer (char *name, int *value, int dflt_value); void get_SINQHM_FRONTEND (char *node, int node_l, char *node_dflt, int *port, int port_dflt, int *pktlen, int pktlen_dflt); void show_help (char *modifier); int strMatch (char *str1, char *str2); /* **--------------------------------------------------------------------------*/ int getCheckStatusResponse ( /* ====================== ** Wait for the status response from SinqHM and ** check it for errors. ** */ int skt, /* The socket for recv */ struct rply_buff_struct *reply, /* The buffer to use */ int rlen) { /* Size of buffer */ int status; status = recv (skt, (char *) reply, rlen, 0); if (status == -1) { FailInet ("\n\007SINQHM_CTRL -- recv error"); return ERROR; } else if (status != rlen) { printf ("\007" "SINQHM_CTRL -- recv error - unexpected byte count: %d/%d\n", rlen, status); return ERROR; } if (ntohl (reply->bigend) != 0x12345678) { printf ("\007" "SINQHM_CTRL -- big-endian/little-endian problem!\n" " Buffer received in non-network byte order!\n"); return ERROR; } status = ntohl (reply->status); if (status == KER__SUCCESS) { return SUCCESS; }else if (status == KER__BAD_CREATE) { printf ("\007 Status response is KER__BAD_CREATE\n"); printf (" Sub-status = %d\n", ntohl (reply->sub_status)); }else if (status == KER__BAD_STATE) { printf ("\007 Status response is KER__BAD_STATE\n"); }else if (status == KER__BAD_VALUE) { printf ("\007 Status response is KER__BAD_VALUE\n"); }else if (status == KER__BAD_RECV) { printf ("\007 Status response is KER__BAD_RECV\n"); }else if (status == KER__BAD_ALLOC) { printf ("\007 Status response is KER__BAD_ALLOC\n"); }else { printf ("\007 Bad and unrecognised status response: 0x%x\n", status); } if (reply->u.message[0] != NIL) { printf (" Message = \"%s\"\n", &reply->u.message[0]); } return ERROR; } /* **--------------------------------------------------------------------------*/ int getenv_integer (char *name, int *value, int dflt_value) { /* ============== ** Extract an integer from an ** environment variable. */ char *p_env; p_env = getenv (name); /* Get pointer to env var */ if (p_env == NULL) { /* Env. var. not found, return default */ *value = dflt_value; return EXIT_FAILURE; }else { /* Convert it to binary */ if (sscanf (p_env, "%d", value) != 1) { *value = dflt_value; /* Value is not integer, return default */ return EXIT_FAILURE; }else { return EXIT_SUCCESS; } } } /* **--------------------------------------------------------------------------*/ void get_SINQHM_FRONTEND ( /* =================== ** Extract info from the SINQHM_FRONTEND ** environment variable. ** */ char *node, int node_l, char *node_dflt, int *port, int port_dflt, int *pktlen, int pktlen_dflt) { int env_len; char *p_env, *token; char my_env[100]; p_env = getenv ("SINQHM_FRONTEND"); /* Get pointer to env var */ if (p_env == NULL) { /* Env. var. not found, return defaults */ StrJoin (node, node_l, node_dflt, ""); *port = port_dflt; *pktlen = pktlen_dflt; }else { /* Make a local copy of it in case the original is in .. ** .. read-protected memory (strtok needs to be able to .. ** .. modify it */ env_len = sizeof (my_env); StrEdit (my_env, p_env, "uncomment compress trim", &env_len); token = (env_len == 0) ? NULL : strtok (my_env, " ,"); /* Get node token */ if ((token == NULL) || (token[0] == ' ')) { /* Node token not found, return defaults */ StrJoin (node, node_l, node_dflt, ""); *port = port_dflt; *pktlen = pktlen_dflt; }else { StrJoin (node, node_l, token, ""); token = strtok (NULL, " ,"); /* Get port token */ if (token == NULL) { *port = port_dflt; /* Port token not found, return defaults */ *pktlen = pktlen_dflt; }else { if (sscanf (token, "%d", port) != 1) { *port = port_dflt; /* Port token illegal, return defaults */ *pktlen = pktlen_dflt; }else { token = strtok (NULL, " ,"); /* Get packet-size token */ if (token == NULL) { *pktlen = pktlen_dflt; /* Packet-size token not found, use dflt */ }else { if (sscanf (token, "%d", pktlen) != 1) { *pktlen = pktlen_dflt; /* Packet-size token illegal, use dflt */ } } } } } } } /* **--------------------------------------------------------------------------*/ void show_help (char *modifier) { /* ========= */ int len; len = strlen (modifier); if (len == 0) goto sh_basic; if (strMatch (modifier, "CONFIG") >= 1) goto sh_config; if (strMatch (modifier, "DEBUG") >= 3) goto sh_debug; if (strMatch (modifier, "DECONFIG") >= 3) goto sh_deconfig; if (strMatch (modifier, "GO") >= 1) goto sh_go; if (strMatch (modifier, "RUNDOWN") >= 1) goto sh_rundown; if (strMatch (modifier, "SETUP") >= 2) goto sh_setup; if (strMatch (modifier, "SHOW") >= 1) goto sh_show; if (strMatch (modifier, "STOP") >= 2) goto sh_stop; if (strMatch (modifier, "ZERO") >= 1) goto sh_zero; sh_basic: printf ("\n" " The following commands are recognised by SINQHM_CTRL:\n" " CONFIG - configure the hist memory.\n" " DEBUG - sets the debug level.\n" " DECONFIG - de-configure the hist memory.\n" " GO - start data acquisition.\n" " HELP - generate help text.\n" " RUNDOWN - run down SinqHM server.\n" " SHOW - get status of hist memory.\n" " STOP - stop data acquisition.\n" " ZERO - zero the HM buffer.\n" "\n" " In order to use SINQHM_CTRL on a VMS system, a \"foreign command\" must\n" " be defined, e.g:\n" " $ ctrl :== $mad_exe:sinqhm_ctrl\n" "\n" " To get more help, issue the command: ctrl help \n" "\n" " where may be any of\n" "\n" " CONFIG DEBUG DECONFIG GO RUNDOWN\n" " Setup SHOW STOP ZERO\n" "\n"); return; sh_setup: printf ("\nSetup:\n" "\n" " The histogram memory with which SINQHM_CTRL is to communicate is\n" " specified on Unix systems via an environment variable, thus:\n" "\n" " setenv SINQHM_FRONTEND \" \"\n" "\n" " In addition, the following environment variables are used by CONFIG\n" "\n" " setenv SINQHM_HM_MODE (Dflt = SQHM__HM_DIG)\n" " setenv SINQHM_NHISTS (Dflt = 1)\n" " setenv SINQHM_LOW_BIN (Dflt = 0)\n" " setenv SINQHM_NBINS (Dflt = none)\n" " setenv SINQHM_BINWID (Dflt = 4)\n" " setenv SINQHM_COMPRESS (Dflt = 0)\n" "\n" " On VMS systems, logical names are used instead, e.g.\n" "\n" " define/group sinqhm_frontend \" \"\n" " define/group sinqhm_hm_mode \n" "\n" " Defaults: = None = 2400 = 8192\n" "\n"); return; sh_config: printf ("\n" " CONFIG - configure the hist memory.\n" "\n" " See \"help setup\" for a list of the environment variables which may be\n" " used for specifying the configuration parameters.\n" "\n" " The filler process in the hist memory will be started.\n" "\n" " If is specified as \"SUSPEND\", the filler process will\n" " immediately enter a suspended state so that it can be debugged.\n" "\n"); return; sh_debug: printf ("\n" " Debug:\n" "\n" " DEBUG - sets the level of debug messages to the\n" " hist memory console.\n" "\n" " may be \"OFF\", \"ON\", 0, 1, 2 or 3.\n" "\n" " \"OFF\" is equivalent to 0\n" " \"ON\" is equivalent to 1\n" " The default is \"ON\".\n" "\n"); return; sh_deconfig: printf ("\n" " Deconfig:\n" "\n" " DECONFIG - de-configure the hist memory.\n" "\n" " If is not specified, there must be no active clients\n" " for the command to be accepted.\n" "\n" " If is specified as \"HARSH\", any active clients will\n" " be killed.\n" "\n" " The filler task is also terminated.\n" "\n"); return; sh_go: printf ("\n" " Go:\n" "\n" " GO - start data acquisition by SinqHM-filler\n" "\n" " An SQHM_DAQ/DAQ__GO command will be sent to SinqHM-master to cause\n" " SinqHM-filler to start data acquisition.\n" "\n"); return; sh_rundown: printf ("\n" " Rundown:\n" "\n" " USE WITH CAUTION\n" " ================\n" "\n" " RUNDOWN - runs down SinqHM\n" "\n" " SinqHM-master, SinqHM-filler and all SinqHM-servers will\n" " be terminated.\n" "\n" " After issuing this command, manual intervention on the\n" " histogram memory will be necessary in order to restart\n" " SinqHM.\n" "\n"); return; sh_show: printf ("\n" " Show:\n" "\n" " SHOW - get and display the status of the hist memory.\n" "\n"); return; sh_stop: printf ("\n" " Stop:\n" "\n" " STOP - stop data acquisition by SinqHM-filler\n" "\n" " An SQHM_DAQ/DAQ__STOP command will be sent to SinqHM-master to cause\n" " SinqHM-filler to stop data acquisition.\n" "\n"); return; sh_zero: printf ("\n" " Zero:\n" "\n" " ZERO - zero the histogram memory buffer\n" "\n" " An SQHM_ZERO command will be sent to SinqHM-master. The values of\n" " hist_no, first_bin and n_bins will be set to -1 so that the entire\n" " histogram memory buffer will be set to zero.\n" "\n"); return; } /* **--------------------------------------------------------------------------*/ int strMatch (char *str1, char *str2) { /* ======== ** See if str1 matches str2. Case is ignored. ** The length of str1 must be less than or equal to the ** length of str2. ** Return zero if no match, otherwise the length of str1. */ int i = 0; while ((tolower (str1[i]) == tolower (str2[i])) && (str1[i] != '\0')) i++; if (str1[i] != '\0') i = 0; return i; } /* **========================================================================== ** ** Main line program ** ------------------ **==========================================================================*/ main (int argc, char *argv[]) { /*==========================================================================*/ int i, j, k, status; int is1, is2; char *p_addr, tmp_ch; char *cmnd, *modifier, buff[8]; unsigned int daq_state_now; unsigned int daq_state_was; unsigned int filler_mask; int cnct_skt; /* Connect socket */ int rw_skt; /* Read/write socket */ struct sockaddr_in lcl_sockname; struct sockaddr_in rmt_sockname; int rmt_inet_addr; struct in_addr *rmt_inet_addr_pntr; struct hostent *rmt_hostent; int rmt_sockname_len; /*============================================================================*/ printf ("\n SinqHM_Ctrl Ident %s.", ident); /*============================================================================ ** Analyse the arguments to see what has to be done. */ if (argc > 1) { /* First arg is */ cmnd = argv[1]; for (i = 0; i < strlen (cmnd); i++) { /* Convert to upper case */ cmnd[i] = toupper (cmnd[i]); } if (cmnd[0] == '-') cmnd++; /* Ignore a leading "-" (i.e. get .. */ /* .. ready for porting to UNIX */ }else { cmnd = "?"; } if ((strMatch (cmnd, "CONFIG") == 0) && (strMatch (cmnd, "DEBUG") < 3) && (strMatch (cmnd, "DECONFIG") < 3) && (strMatch (cmnd, "GO") == 0) && (strMatch (cmnd, "RUNDOWN") < 7) && (strMatch (cmnd, "HELP") == 0) && (strMatch (cmnd, "?") == 0) && (strMatch (cmnd, "SHOW") == 0) && (strMatch (cmnd, "STOP") < 2) && (strMatch (cmnd, "ZERO") == 0)) cmnd = "HELP"; if (argc > 2) { /* Second arg is */ modifier = argv[2]; for (i = 0; i < strlen (modifier); i++) { /* Convert to upper case */ modifier[i] = toupper (modifier[i]); } }else { modifier = ""; } if (strMatch (cmnd, "HELP") != 0) goto help; if (strMatch (cmnd, "?") != 0) goto help; /*============================================================================ ** Start out by finding the TCP/IP location of SINQHM_SRV and making ** a connection to it. Any errors during this phase cause the program ** to exit with an error status. */ get_SINQHM_FRONTEND (Rmt_node, sizeof (Rmt_node), "", &Rmt_port, PORT_BASE, &Pkt_size, 8192); if (Rmt_node[0] == NIL) { printf ("\n"); modifier = "SETUP"; show_help (modifier); printf ("\007\n" " The histogram memory is not defined correctly.\n" "\n" " If this is a UNIX system, check that the environment variable\n" " \"SINQHM_FRONTEND\" is defined correctly.\n" "\n" " If this is a VMS system, check that the logical name " "\"SINQHM_FRONTEND\" is\n" " defined correctly.\n" "\n"); return EXIT_FAILURE; } /* ** Get Internet address of the front-end. */ rmt_hostent = gethostbyname (Rmt_node); if (rmt_hostent == NULL) { for (i = 0; i < strlen (Rmt_node); i++) Rmt_node[i] = toupper (Rmt_node[i]); if (strcmp (Rmt_node, "SQFE01") == 0) { rmt_inet_addr_pntr = (struct in_addr *) &rmt_inet_addr; rmt_inet_addr = inet_addr ("129.129.56.181"); } else { printf ("Server Node is %s.\n", Rmt_node); FailInet ("\nGethostbyname error."); } } else { rmt_inet_addr_pntr = (struct in_addr *) rmt_hostent->h_addr_list[0]; } printf (" Server is %s ", Rmt_node); printf ("(%s),", inet_ntoa (*rmt_inet_addr_pntr)); printf (" Port %d.\n", Rmt_port); /* ** Create a TCP/IP socket for connecting to SINQHM_SRV root and bind it. */ cnct_skt = socket (AF_INET, SOCK_STREAM, 0); if (cnct_skt == -1) FailInet ("\nSocket error."); lcl_sockname.sin_family = AF_INET; lcl_sockname.sin_port = htons (0); lcl_sockname.sin_addr.s_addr = 0; status = bind (cnct_skt, (struct sockaddr *) &lcl_sockname, sizeof (lcl_sockname)); if (status == -1) FailInet ("\nBind error."); /* ** Connect to SINQHM_SRV root. */ rmt_sockname_len = sizeof (rmt_sockname); rmt_sockname.sin_family = AF_INET; rmt_sockname.sin_port = htons (Rmt_port); rmt_sockname.sin_addr.s_addr = rmt_inet_addr_pntr->s_addr; status = connect (cnct_skt, (struct sockaddr *) &rmt_sockname, sizeof (rmt_sockname)); if (status == -1) { GetErrno (&My_errno, &My_vaxc_errno); FailInet ("\nConnect error"); } /*============================================================================ ** Switch according to value of */ if (strMatch (cmnd, "CONFIG") > 0) goto config; if (strMatch (cmnd, "DEBUG") >= 3) goto debug; if (strMatch (cmnd, "DECONFIG") >= 3) goto deconfig; if (strMatch (cmnd, "GO") > 0) goto go; if (strMatch (cmnd, "RUNDOWN") == 7) goto rundown; if (strMatch (cmnd, "STOP") >= 2) goto stop; if (strMatch (cmnd, "ZERO") > 0) goto zero; goto show; /*============================================================================*/ config: /*====== Configure - Extract values from the logical names. */ getenv_integer ("SINQHM_HM_MODE", &Hm_mode, SQHM__HM_DIG); getenv_integer ("SINQHM_NHISTS", &Nhists, 1); getenv_integer ("SINQHM_LOW_BIN", &Lo_bin, 0); is1 = getenv_integer ("SINQHM_NBINS", &Nbins, 0); getenv_integer ("SINQHM_BINWID", &Binwid, 4); getenv_integer ("SINQHM_COMPRESS", &Compress, 0); if (is1 != EXIT_SUCCESS) { printf ("\n\007 SINQHM setup is not defined or not complete.\n"); printf (" Here is some help ...\n"); show_help ("SETUP"); if (is1 != EXIT_SUCCESS) { printf (" The problem is with SINQHM_NBINS\n"); } printf ("\n"); close (cnct_skt); return EXIT_FAILURE; } /* ** Set up and send the configure message. */ if (strMatch (modifier, "SUSPEND") >= 3) { Hm_mode |= SQHM__DEBUG; } Req_buff.bigend = htonl (0x12345678); Req_buff.cmnd = htonl (SQHM_CONFIG); Req_buff.u.cnfg.mode = htonl (Hm_mode); Req_buff.u.cnfg.n_hists = htonl (Nhists); Req_buff.u.cnfg.lo_bin = htonl (Lo_bin); Req_buff.u.cnfg.num_bins = htonl (Nbins); Req_buff.u.cnfg.binwid = htonl (Binwid); Req_buff.u.cnfg.compress = htonl (Compress); printf (" Configuration:\n" " Histogramming mode is 0x%08x\n", Hm_mode); printf (" Number of histograms = %5d\n" " Index of first bin = %5d\n" " Number of bins per histogram = %5d\n" " Number of bytes per bin = %5d\n" " Bin compression factor = %5d\n", Nhists, Lo_bin, Nbins, Binwid, Compress); if ((Hm_mode & SQHM__DEBUG) != 0) printf ("\007\n Warning -- SQHM__DEBUG suspend flag is set!\n\n"); printf (" Configuring ..."); status = send (cnct_skt, (char *) &Req_buff, sizeof (Req_buff), 0); if (status == -1) FailInet ("\nSINQHM_CTRL -- send error"); if (status != sizeof (Req_buff)) { printf ("\nSINQHM_CTRL -- wrong number of bytes sent: %d", status); return EXIT_FAILURE; } /* ** Wait for the status response. */ status = getCheckStatusResponse (cnct_skt, &Rply_buff, sizeof (Rply_buff)); if (status == SUCCESS) { printf (" done.\n"); } /* ** Close the connection. */ status = close (cnct_skt); if ((status != 0) && (errno != ECONNRESET)) FailInet ("\nSINQHM_CTRL -- close error"); return EXIT_SUCCESS; /*============================================================================*/ debug: /*===== Debug. Set up the debug level of the front-end.. */ Req_buff.bigend = htonl (0x12345678); Req_buff.cmnd = htonl (SQHM_DBG); if (strcmp (modifier, "ON") == 0) { /* "modifier" may be "ON", "OFF" .. ** .. or an integer. */ Req_buff.u.dbg.level = htonl (1); /* Turn on, level 1 */ printf (" Setting SinqHM debug level on (1) ..."); }else if (strcmp (modifier, "OFF") == 0) { Req_buff.u.dbg.level = 0; /* Turn off, level 0 */ printf (" Setting SinqHM debug level off (0) ..."); }else if (strcmp (modifier, "") == 0) { Req_buff.u.dbg.level = htonl (1); /* Turn on, level 1 */ printf (" \"DEBUG ON\" assumed ..." " setting SinqHM debug level = 1 ..."); }else { status = sscanf (modifier, "%i", &i); status = sscanf (modifier, "%i", &Req_buff.u.dbg.level); if (status == 1) { Req_buff.u.dbg.level = htonl (i); printf (" Setting SinqHM debug level = %d ...", i); }else { Req_buff.u.dbg.level = htonl (1); /* Turn on, if error */ printf (" Invalid DEBUG command. \"DEBUG ON\" assumed ..."); } } status = send (cnct_skt, (char *) &Req_buff, sizeof (Req_buff), 0); if (status == -1) FailInet ("\nSINQHM_CTRL -- send error"); if (status != sizeof (Req_buff)) { printf ("SINQHM_CTRL -- wrong number of bytes sent: %d", status); return EXIT_FAILURE; } /* ** Wait for the status response. */ status = getCheckStatusResponse (cnct_skt, &Rply_buff, sizeof (Rply_buff)); if (status == SUCCESS) { printf (" done.\n"); } /* ** Close the connection. */ status = close (cnct_skt); if ((status != 0) && (errno != ECONNRESET)) FailInet ("\nSINQHM_CTRL -- close error"); return EXIT_SUCCESS; /*============================================================================*/ deconfig: /*======== De-configure. Set up and send the deconfig message. */ Req_buff.bigend = htonl (0x12345678); Req_buff.cmnd = htonl (SQHM_DECONFIG); Req_buff.u.decnfg.sub_code = 0; /* Be gentle, by default */ if (strcmp (modifier, "HARSH") == 0) { Req_buff.u.decnfg.sub_code = htonl (1); /* But be harsh, if ordered */ printf (" Deconfiguring (mit Gewalt!) ..."); }else { printf (" Deconfiguring ..."); } status = send (cnct_skt, (char *) &Req_buff, sizeof (Req_buff), 0); if (status == -1) FailInet ("\nSINQHM_CTRL -- send error"); if (status != sizeof (Req_buff)) { printf ("SINQHM_CTRL -- wrong number of bytes sent: %d", status); return EXIT_FAILURE; } /* ** Wait for the status response. */ status = getCheckStatusResponse (cnct_skt, &Rply_buff, sizeof (Rply_buff)); if (status == SUCCESS) { printf (" done.\n"); } /* ** Close the connection. */ status = close (cnct_skt); if ((status != 0) && (errno != ECONNRESET)) FailInet ("\nSINQHM_CTRL -- close error"); return EXIT_SUCCESS; /*============================================================================*/ go: /*== Go. Get SinqHM-filler to start taking data. */ printf (" Starting data acquisition ..."); Req_buff.bigend = htonl (0x12345678); Req_buff.cmnd = htonl (SQHM_DAQ); Req_buff.u.daq.sub_cmnd = htonl (DAQ__GO); status = send (cnct_skt, (char *) &Req_buff, sizeof (Req_buff), 0); if (status == -1) FailInet ("\nSINQHM_CTRL -- send error"); if (status != sizeof (Req_buff)) { printf ("SINQHM_CTRL -- wrong number of bytes sent: %d", status); return EXIT_FAILURE; } /* ** Wait for the status response. */ status = getCheckStatusResponse (cnct_skt, &Rply_buff, sizeof (Rply_buff)); if (status == SUCCESS) { daq_state_now = ntohl (Rply_buff.u.daq.daq_now); daq_state_was = ntohl (Rply_buff.u.daq.daq_was); filler_mask = ntohl (Rply_buff.u.daq.filler_mask); if (daq_state_now == 0) { if (daq_state_was == 0) { printf (" done. It was already active!\n"); }else { printf (" done.\n"); } }else { printf ("\n\007 Data acquisition is still disabled.\n" " Dsbl_Mask is 0x%08x\n" " Filler_Mask is 0x%08x\n", daq_state_now, filler_mask); } } /* ** Close the connection. */ status = close (cnct_skt); if ((status != 0) && (errno != ECONNRESET)) FailInet ("\nSINQHM_CTRL -- close error"); return EXIT_SUCCESS; /*============================================================================*/ rundown: /*======= Rundown. Set up and send the rundown message. */ printf (" Sending SQHM_EXIT command to SinqHM ..."); Req_buff.bigend = htonl (0x12345678); Req_buff.cmnd = htonl (SQHM_EXIT); status = send (cnct_skt, (char *) &Req_buff, sizeof (Req_buff), 0); if (status == -1) FailInet ("\nSINQHM_CTRL -- send error"); if (status != sizeof (Req_buff)) { printf ("SINQHM_CTRL -- wrong number of bytes sent: %d", status); return EXIT_FAILURE; } /* ** Wait for the status response. */ status = getCheckStatusResponse (cnct_skt, &Rply_buff, sizeof (Rply_buff)); if (status == SUCCESS) { printf (" done.\n"); } /* ** Close the connection. */ status = close (cnct_skt); if ((status != 0) && (errno != ECONNRESET)) FailInet ("\nSINQHM_CTRL -- close error"); return EXIT_SUCCESS; /*============================================================================*/ show: /*==== Show-status. Set up and send the status message. */ printf (" Getting status of SinqHM ..."); Req_buff.bigend = htonl (0x12345678); Req_buff.cmnd = htonl (SQHM_STATUS); status = send (cnct_skt, (char *) &Req_buff, sizeof (Req_buff), 0); if (status == -1) FailInet ("\nSINQHM_CTRL -- send error"); if (status != sizeof (Req_buff)) { printf ("SINQHM_CTRL -- wrong number of bytes sent: %d", status); return EXIT_FAILURE; } /* ** Wait for the status response. */ status = getCheckStatusResponse (cnct_skt, &Rply_buff, sizeof (Rply_buff)); if (status == SUCCESS) { /* ** Display the status obtained. */ memcpy (buff, (char *) &Rply_buff.sub_status, 4); /* Get SinqHM Ident */ buff[4] = '\0'; if (Rply_buff.u.status.cfg_state == 0) { printf ("\n SINQHM has not yet been configured.\n"); printf (" SinqHM Identifier is \"%s\"\n", buff); printf (" Maximum number of histograms = %d\n", ntohl (Rply_buff.u.status.max_n_hists)); printf (" Maximum number of bins per histogram = %d\n", ntohl (Rply_buff.u.status.max_num_bins)); printf (" Maximum number of active connections supported = %d\n", Rply_buff.u.status.max_srvrs); printf (" Maximum space available for histograms = %d bytes\n", ntohl (Rply_buff.u.status.max_block)); }else { printf ("\n SinqHM Identifier is \"%s\"\n", buff); printf (" Histogramming Mode = 0x%x\n", ntohl (Rply_buff.u.status.cfg_state)); printf (" Number of histograms/Current histogram = %d/%d\n", ntohs (Rply_buff.u.status.n_hists), ntohs (Rply_buff.u.status.curr_hist)); printf (" Number of bins per histogram = %d\n", ntohl (Rply_buff.u.status.num_bins)); printf (" Number of bytes per bin = %d\n", Rply_buff.u.status.binwid); printf (" Maximum number of active connections supported = %d\n", Rply_buff.u.status.max_srvrs); printf (" Current number of active connections = %d\n", Rply_buff.u.status.act_srvrs); printf (" Maximum block of free memory = %d bytes\n", ntohl (Rply_buff.u.status.max_block)); if (Rply_buff.u.status.daq_now == 0) { printf (" Data acquisition is active\n"); }else { printf (" Data acquisition is not active\n"); } } } /* ** Close the connection. */ status = close (cnct_skt); if ((status != 0) && (errno != ECONNRESET)) FailInet ("\nSINQHM_CTRL -- close error"); return EXIT_SUCCESS; /*============================================================================*/ stop: /*==== Stop. Get SinqHM-filler to stop taking data. */ printf (" Stopping data acquisition ..."); Req_buff.bigend = htonl (0x12345678); Req_buff.cmnd = htonl (SQHM_DAQ); Req_buff.u.daq.sub_cmnd = htonl (DAQ__STOP); status = send (cnct_skt, (char *) &Req_buff, sizeof (Req_buff), 0); if (status == -1) FailInet ("\nSINQHM_CTRL -- send error"); if (status != sizeof (Req_buff)) { printf ("SINQHM_CTRL -- wrong number of bytes sent: %d", status); return EXIT_FAILURE; } /* ** Wait for the status response. */ status = getCheckStatusResponse (cnct_skt, &Rply_buff, sizeof (Rply_buff)); if (status == SUCCESS) { daq_state_now = ntohl (Rply_buff.u.daq.daq_now); daq_state_was = ntohl (Rply_buff.u.daq.daq_was); filler_mask = ntohl (Rply_buff.u.daq.filler_mask); if (daq_state_now != 0) { if (daq_state_was == 0) { printf (" done.\n"); }else { printf (" done. It was already stopped!\n"); } }else { printf ("\n\007 Data acquisition is still enabled!\n" " Dsbl_Mask is 0x%08x\n" " Filler_Mask is 0x%08x\n", daq_state_now, filler_mask); } } /* ** Close the connection. */ status = close (cnct_skt); if ((status != 0) && (errno != ECONNRESET)) FailInet ("\nSINQHM_CTRL -- close error"); return EXIT_SUCCESS; /*============================================================================*/ zero: /*==== Zero. Zero the complete histogram buffer */ Req_buff.bigend = htonl (0x12345678); Req_buff.cmnd = htonl (SQHM_ZERO); Req_buff.u.zero.hist_no = htonl (-1); Req_buff.u.zero.first_bin = htonl (-1); Req_buff.u.zero.n_bins = htonl (-1); printf (" Zeroing the histogram memory buffer ..."); status = send (cnct_skt, (char *) &Req_buff, sizeof (Req_buff), 0); if (status == -1) FailInet ("\nSINQHM_CTRL -- send error"); if (status != sizeof (Req_buff)) { printf ("\nSINQHM_CTRL -- wrong number of bytes sent: %d", status); return EXIT_FAILURE; } /* ** Wait for the status response. */ status = getCheckStatusResponse (cnct_skt, &Rply_buff, sizeof (Rply_buff)); if (status == SUCCESS) { printf (" done.\n"); } /* ** Close the connection. */ status = close (cnct_skt); if ((status != 0) && (errno != ECONNRESET)) FailInet ("\nSINQHM_CTRL -- close error"); return EXIT_SUCCESS; /*============================================================================*/ help: /*==== Help - give some help. */ show_help (modifier); return EXIT_SUCCESS; } /*================================================ End of SINQHM_CTRL.C =====*/