diff --git a/sinqhm/sinqhm_ctrl.c b/sinqhm/sinqhm_ctrl.c new file mode 100755 index 00000000..23d485cb --- /dev/null +++ b/sinqhm/sinqhm_ctrl.c @@ -0,0 +1,1903 @@ +#define IDENT "1A14" +/*---------------------------------------------------------------------------*/ +#ifdef __DECC +#pragma module sinqhm_ctrl IDENT +#endif +/* +** Link_options - Here is the Linker Option File +**! sinqhm_ctrl +**! tas_src:[lib]sinq/lib +**! sys$share:decw$xlibshr/share +**!! +**!! To build sinqhm_ctrl on LNSA09 +**!! +**!! $ import tasmad +**!! $ define/job deltat_c_tlb sinq_c_tlb +**!! $ sss := tas_src:[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 . . . . . . . . : TAS_SRC:[SINQHM]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 options on the command +** line. Use the "-help config" option for details. +** +** Once the configuration information has been checked, 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", "STATUS", "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. Note that the same action can be +** achieved by specifying "DEBUG" as a token in SINQHM_MODE. +** +** 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 + +#ifdef __VMS +#include +#else +#include +#endif +#include +#include + +#include +#include +#include +#include +#include +#include + +/* +**==================== Global Definitions ===================================== +*/ +#include +#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; + + int Verbose; + char Rmt_host[32]; + int Rmt_port; + int Pkt_size; + + int Do_config; + int Do_debug; + int Do_deconfig; + int Do_go; + int Do_rundown; + int Do_status; + int Do_stop; + int Do_zero; + + int Dbg_level; + int Be_harsh; /* Set to True if -harsh option specified */ + char Mode[64]; /* The "-mode" option */ + int Hm_mode; /* The histogramming mode */ + int Nhist; /* The number of histograms to fill */ + int Nbins; /* The number of bins to fill */ + int Lo_bin; /* The first bin */ + int Compress; /* The bin compression factor */ + int Bytes_per_bin; /* The number of bytes per bin */ + int Ncntrs; /* The number of counters (TOF mode) */ + int Lo_cntr; /* The first counter */ + int Span; /* The time span per bin */ + int Delay_time_to_start; /* The DTS for the MDI in TOF mode */ + int Nbuff; /* The # buffers in TRANS mode */ + int Buff_size; /* The buffer size in TRANS mode */ + + struct dsc__descriptor_s Name_desc; + + static XrmOptionDescRec OpTable_0[] = { + {"-name", ".name", XrmoptionSepArg, (XPointer) NULL}, + {"-h", ".sqhmHelp", XrmoptionNoArg, (XPointer) "1"}, + {"-he", ".sqhmHelp", XrmoptionNoArg, (XPointer) "1"}, + {"-hel", ".sqhmHelp", XrmoptionNoArg, (XPointer) "1"}, + {"-help", ".sqhmHelp", XrmoptionNoArg, (XPointer) "1"}, + {"-?", ".sqhmHelp", XrmoptionNoArg, (XPointer) "1"}, + {"-ho", ".sqhmHost", XrmoptionSepArg, (XPointer) NULL}, + {"-hos", ".sqhmHost", XrmoptionSepArg, (XPointer) NULL}, + {"-host", ".sqhmHost", XrmoptionSepArg, (XPointer) NULL}, + {"-port", ".sqhmPort", XrmoptionSepArg, (XPointer) NULL}, + {"-size", ".sqhmPktSize", XrmoptionSepArg, (XPointer) NULL}, + {"-v", ".sqhmVerbose", XrmoptionNoArg, (XPointer) "1"}, + {"-config", ".sqhmConfig", XrmoptionNoArg, (XPointer) "1"}, + {"-debug", ".sqhmDebug", XrmoptionSepArg, (XPointer) NULL}, + {"-deconfig", ".sqhmDeconfig", XrmoptionNoArg, (XPointer) "1"}, + {"-go", ".sqhmGo", XrmoptionNoArg, (XPointer) "1"}, + {"-rundown", ".sqhmRundown", XrmoptionNoArg, (XPointer) "1"}, + {"-show", ".sqhmStatus", XrmoptionNoArg, (XPointer) "1"}, + {"-status", ".sqhmStatus", XrmoptionNoArg, (XPointer) "1"}, + {"-stop", ".sqhmStop", XrmoptionNoArg, (XPointer) "1"}, + {"-zero", ".sqhmZero", XrmoptionNoArg, (XPointer) "1"}, + {"-mode", ".sqhmMode", XrmoptionSepArg, (XPointer) NULL}, + {"-nhist", ".sqhmNhist", XrmoptionSepArg, (XPointer) NULL}, + {"-nbins", ".sqhmNbins", XrmoptionSepArg, (XPointer) NULL}, + {"-lo_bin", ".sqhmLoBin", XrmoptionSepArg, (XPointer) NULL}, + {"-compress", ".sqhmCompress", XrmoptionSepArg, (XPointer) NULL}, + {"-bpb", ".sqhmBpb", XrmoptionSepArg, (XPointer) NULL}, + {"-ncntr", ".sqhmNcntr", XrmoptionSepArg, (XPointer) NULL}, + {"-lo_cntr", ".sqhmLoCntr", XrmoptionSepArg, (XPointer) NULL}, + {"-span", ".sqhmSpan", XrmoptionSepArg, (XPointer) NULL}, + {"-delay", ".sqhmDelay", XrmoptionSepArg, (XPointer) NULL}, + {"-nbuff", ".sqhmNbuff", XrmoptionSepArg, (XPointer) NULL}, + {"-buff_size",".sqhmBuffSize", XrmoptionSepArg, (XPointer) NULL}, + {"-harsh", ".sqhmHarsh", XrmoptionNoArg, (XPointer) "1"}, + }; + + extern int C_gbl_status; /* Return status from C_... routines */ +/* +**============================================================================= +** Local routines. +** +** show_help : Display the help text. +**---------------------------------------------------------------------------- +** Prototypes +*/ + int getCheckStatusResponse ( + int skt, + struct rply_buff_struct *reply, + int rlen); + int get_check_resources ( + XrmDatabase *db, + char *appName, + int *argc, + char *argv[], + int verbose); + int get_no_arg_resource ( + XrmDatabase *db, + char *appName, + int *argc, + char *argv[], + char *resource, + char *cmnd, + int min_len); + int open_socket ( + char *host, + int port); + void print_HM_mode (uint mode); + void print_uptime (FILE *lun, char *prefix, int secs, char *suffix); + int setup_xrm_database (XrmDatabase *db, + char *name[], + int *argc, + char *argv[], + int verbose); + void show_help (char *mod0, char *mod1); +/* +**--------------------------------------------------------------------------*/ + 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; + } +/* +**--------------------------------------------------------------------------- +** get_check_resources - get and check our resources +*/ + int get_check_resources ( +/* =================== +*/ XrmDatabase *db, + char *appName, + int *argc, + char *argv[], + int verbose) { + + int i, status, len; + char buff[80]; + char *type; + XrmValue value; + time_t time_now; + float tmp_secs; +/*---------------------------------------------------------- -help */ + status = get_no_arg_resource (db, appName, argc, argv, + ".sqhmHelp", "help", 1); + if (status) { + if (*argc <= 1) { + show_help (NULL, NULL); + }else if (*argc <= 2) { + show_help (argv[1], NULL); + }else { + show_help (argv[1], argv[2]); + } + exit (EXIT_SUCCESS); + } +/*---------------------------------------------------------- -v */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmVerbose"), + "ProgramName.Values", + &type, &value); + Verbose = verbose = (status) ? True : False; +/*---------------------------------------------------------- -host */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmHost"), + "ProgramName.Values", + &type, &value); + if (status) { + StrJoin (Rmt_host, sizeof (Rmt_host), value.addr, ""); + }else { + if (*argc >= 2) { + StrJoin (Rmt_host, sizeof (Rmt_host), argv[1], ""); + (*argc)--; + for (i = 1; i < *argc; i++) argv[i] = argv[i+1]; + }else { + printf ("\n" + " Target host not specified, there is no default!\n"); + show_help (NULL, NULL); + exit (EXIT_FAILURE); + } + } + if (verbose) printf ("Target host is \"%s\".\n", Rmt_host); +/*---------------------------------------------------------- -port */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmPort"), + "ProgramName.Values", + &type, &value); + if (!status || (sscanf (value.addr, "%d", &Rmt_port) != 1)) { + Rmt_port = 2400; + if (verbose) printf ("Using the default TCP/IP port number of "); + }else { + if (verbose) printf ("TCP/IP port number = "); + } + if (verbose) printf ("%d\n", Rmt_port); +/*---------------------------------------------------------- -size */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmPktSize"), + "ProgramName.Values", + &type, &value); + if (!status || (sscanf (value.addr, "%d", &Pkt_size) != 1)) { + Pkt_size = 8192; + if (verbose) printf ("Using the default packet size of "); + }else { + if (verbose) printf ("Packet size = "); + } + if (verbose) printf ("%d\n", Pkt_size); +/*----------------------------------------------------------*/ + Do_config = get_no_arg_resource (db, appName, argc, argv, + ".sqhmConfig", "config", 1); + Do_deconfig = get_no_arg_resource (db, appName, argc, argv, + ".sqhmDeconfig", "deconfig", 8); + Do_go = get_no_arg_resource (db, appName, argc, argv, + ".sqhmGo", "go", 2); + Do_rundown = get_no_arg_resource (db, appName, argc, argv, + ".sqhmRundown", "rundown", 7); + Do_status = get_no_arg_resource (db, appName, argc, argv, + ".sqhmStatus", "status", 1); + if (!Do_status) Do_status = get_no_arg_resource (db, appName, argc, argv, + ".sqhmStatus", "show", 1); + Do_stop = get_no_arg_resource (db, appName, argc, argv, + ".sqhmStop", "stop", 4); + Do_zero = get_no_arg_resource (db, appName, argc, argv, + ".sqhmZero", "zero", 4); + Be_harsh = get_no_arg_resource (db, appName, argc, argv, + ".sqhmHarsh", "harsh", 5); +/*---------------------------------------------------------- -debug */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmDebug"), + "ProgramName.Values", + &type, &value); + if (!status) { + Do_debug = False; + }else { + if (StrMatch (value.addr, "ON", 2)) { + Dbg_level = 0x0001; + }else if (StrMatch (value.addr, "OFF", 2)) { + Dbg_level = 0x0000; + }else if ((sscanf (value.addr, "%i", &Dbg_level) != 1) || + (Dbg_level < 0) || + (Dbg_level > 0x0ff)) { + printf ("\n" + " \"-debug %s\" is invalid!\n" + "\n", value.addr); + show_help ("debug", NULL); + exit (EXIT_FAILURE); + } + Do_debug = True; + } +/*---------------------------------------------------------- -mode */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmMode"), + "ProgramName.Values", + &type, &value); + if (status) { + StrJoin (Mode, sizeof (Rmt_host), value.addr, ""); + if (verbose) printf ("-mode is \"%s\"\n", Mode); + }else { + StrJoin (Mode, sizeof (Rmt_host), "", ""); + } +/*---------------------------------------------------------- -nhist */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmNhist"), + "ProgramName.Values", + &type, &value); + if (!status) { + Nhist = 1; + }else if (sscanf (value.addr, "%d", &Nhist) != 1) { + printf (" \"-nhist %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + }else if (Nhist <= 0) { + printf (" \"-nhist %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + } +/*---------------------------------------------------------- -nbins */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmNbins"), + "ProgramName.Values", + &type, &value); + if (!status) { + Nbins = 0; + }else if (sscanf (value.addr, "%d", &Nbins) != 1) { + printf (" \"-nbins %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + }else if (Nbins <= 0) { + printf (" \"-nbins %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + } +/*---------------------------------------------------------- -lo_bin */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmLoBin"), + "ProgramName.Values", + &type, &value); + if (!status) { + Lo_bin = 0; + }else if (sscanf (value.addr, "%d", &Lo_bin) != 1) { + printf ("\"-lo_bin %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + }else if (Lo_bin < 0) { + printf ("\"-lo_bin %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + } +/*---------------------------------------------------------- -compress */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmCompress"), + "ProgramName.Values", + &type, &value); + if (!status) { + Compress = 1; + }else if (sscanf (value.addr, "%d", &Compress) != 1) { + printf (" \"-compress %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + }else if (Compress <= 0) { + printf (" \"-compress %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + } +/*---------------------------------------------------------- -bpb */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmBpb"), + "ProgramName.Values", + &type, &value); + if (!status) { + Bytes_per_bin = 4; + }else if (sscanf (value.addr, "%d", &Bytes_per_bin) != 1) { + printf (" \"-bpb %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + }else if ((Bytes_per_bin != 1) || + (Bytes_per_bin != 2) || + (Bytes_per_bin != 4)) { + printf (" \"-bpb %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + } +/*---------------------------------------------------------- -ncntr */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmNcntr"), + "ProgramName.Values", + &type, &value); + if (!status) { + Ncntrs = 0; + }else if (sscanf (value.addr, "%d", &Ncntrs) != 1) { + printf (" \"-ncntr %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + }else if (Ncntrs <= 0) { + printf (" \"-ncntr %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + } +/*---------------------------------------------------------- -lo_cntr */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmLoCntr"), + "ProgramName.Values", + &type, &value); + if (!status) { + Lo_cntr = 0; + }else if (sscanf (value.addr, "%d", &Lo_cntr) != 1) { + printf (" \"-lo_cntr %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + }else if (Lo_cntr < 0) { + printf (" \"-lo_cntr %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + } +/*---------------------------------------------------------- -span */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmSpan"), + "ProgramName.Values", + &type, &value); + if (!status) { + Span = -1; + }else if (sscanf (value.addr, "%d", &Span) != 1) { + printf (" \"-span %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + }else if (Span <= 0) { + printf (" \"-span %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + } +/*---------------------------------------------------------- -delay */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmDelay"), + "ProgramName.Values", + &type, &value); + if (!status) { + Delay_time_to_start = 0; + }else if (sscanf (value.addr, "%d", &Delay_time_to_start) != 1) { + printf (" \"-delay %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + }else if (Delay_time_to_start <= 0) { + printf (" \"-delay %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + } +/*---------------------------------------------------------- -nbuff */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmNbuff"), + "ProgramName.Values", + &type, &value); + if (!status) { + Nbuff = 5; + }else if (sscanf (value.addr, "%d", &Nbuff) != 1) { + printf (" \"-nbuff %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + }else if (Nbuff <= 0) { + printf (" \"-nbuff %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + } +/*---------------------------------------------------------- -buff_size */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmBuffSize"), + "ProgramName.Values", + &type, &value); + if (!status) { + Buff_size = 8192; + }else if (sscanf (value.addr, "%d", &Buff_size) != 1) { + printf (" \"-buff_size %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + }else if (Buff_size <= 0) { + printf (" \"-buff_size %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + } +/*----------------------------------------------------------*/ + return True; + } +/* +**--------------------------------------------------------------------------- +** get_no_arg_resource - get a resource with no args +*/ + int get_no_arg_resource ( +/* =================== +*/ XrmDatabase *db, + char *appName, + int *argc, + char *argv[], + char *resource, + char *cmnd, + int min_len) { + + int i, status; + char buff[80]; + char *type; + XrmValue value; + + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), appName, resource), + "ProgramName.Values", + &type, &value); + if (status) { + return True; + }else { + if ((*argc >= 2) && StrMatch (argv[1], cmnd, min_len)) { + (*argc)--; + for (i = 1; i < *argc; i++) argv[i] = argv[i+1]; + return True; + } + } + return False; + } +/* +**--------------------------------------------------------------------------- +** Function: open_socket () +** +** Description: +** Create a "stream" socket and connect to a given Host/Port combination. +** +** Return value is socket. +** If an error is detected, a message will be printed and return value = 0. +*/ + int open_socket ( +/* =========== +*/ + char *host, /* The host's name */ + int port) { /* The port on the host to connect to */ + + int status, my_skt, my_port; + char old_time_out[4]; + union { + char chars[4]; + int val; + } time_out; + unsigned int oto_status; + struct sockaddr_in lcl_sockname; + struct sockaddr_in rmt_sockname; + struct in_addr rmt_inet_addr; + struct in_addr *rmt_inet_addr_pntr; + struct hostent *rmt_hostent; + int rmt_sockname_len; +#ifdef __VMS + unsigned int oto_len; + int tcp_option = UCX$C_TCP_PROBE_IDLE; +#else + int oto_len; + #ifdef LINUX + int tcp_option = 0; + #else + int tcp_option = TCP_KEEPINIT; + #endif +#endif +/*------------------------------------------------------------------*/ + /* + ** Get the Internet address of the Host + */ + rmt_inet_addr.s_addr = inet_addr (host); + if (rmt_inet_addr.s_addr != -1) { + rmt_inet_addr_pntr = &rmt_inet_addr; + }else { + rmt_hostent = gethostbyname (host); + if (rmt_hostent == NULL) { + printf ("failed!\n\n" + " Host name, \"%s\", is not a known " + "Internet address.\n", host); + return 0; + } + rmt_inet_addr_pntr = (struct in_addr *) rmt_hostent->h_addr_list[0]; + } + /*--------------------------- + ** Create a TCP/IP socket for connecting to server and bind it. + */ + my_skt = socket (AF_INET, SOCK_STREAM, 0); + if (my_skt <= 0) { + printf ("failed!\n\n" + " Could not create a socket.\n\n"); + perror ("OpenSocket"); + return 0; + } + lcl_sockname.sin_family = AF_INET; + lcl_sockname.sin_port = htons (0); + lcl_sockname.sin_addr.s_addr = 0; + status = bind (my_skt, (struct sockaddr *) &lcl_sockname, + sizeof (lcl_sockname)); + if (status == -1) { + close (my_skt); + printf ("failed!\n\n" + " Could not bind the socket.\n\n"); + perror ("OpenSocket"); + return 0; + } + /*--------------------------- + ** Set short time-out + */ + oto_len = sizeof (old_time_out); /* Save current time-out first */ + oto_status = getsockopt (my_skt, IPPROTO_TCP, tcp_option, + old_time_out, &oto_len); + if (oto_status == 0) { + time_out.val = 5; /* Set new time-out */ + status = setsockopt (my_skt, IPPROTO_TCP, tcp_option, + time_out.chars, sizeof (time_out)); + } + /*--------------------------- + ** Connect to host + */ + my_port = port; + rmt_sockname_len = sizeof (rmt_sockname); + rmt_sockname.sin_family = AF_INET; + rmt_sockname.sin_port = htons (my_port); + rmt_sockname.sin_addr.s_addr = rmt_inet_addr_pntr->s_addr; + status = connect (my_skt, (struct sockaddr *) &rmt_sockname, + sizeof (rmt_sockname)); + if (status != 0) { + close (my_skt); + printf ("failed!\n\n" + " Could not connect to Host %s, Port %d.\n\n", + host, my_port); + perror ("OpenSocket"); + return 0; + } + /*--------------------------- + ** Restore time-out + */ + if (oto_status == 0) { + setsockopt (my_skt, IPPROTO_TCP, tcp_option, + old_time_out, oto_len); + } + return my_skt; + } +/* +**-------------------------------------------------------------------------- +*/ + void print_HM_mode ( +/* ============= +** Interpret the HM configuration. +** +*/ uint mode) { /* The configuration to be interpreted */ + + uint my_mode; + + printf (" Histogramming Mode = 0x%x", mode); + + my_mode = mode & (~SQHM__SUB_MODE_MSK); + if (my_mode == SQHM__TRANS) printf (" SQHM__TRANS"); + if (my_mode == SQHM__HM_DIG) printf (" SQHM__HM_DIG"); + if (my_mode == SQHM__TOF) printf (" SQHM__TOF"); + if (my_mode == SQHM__HM_PSD) printf (" SQHM__HM_PSD"); + if (my_mode == SQHM__HRPT) printf (" SQHM__HRPT"); + if ((mode & SQHM__DEBUG) != 0) printf ("/DEBUG"); + if ((mode & SQHM__UD) != 0) printf ("/UD"); + if ((mode & SQHM__STROBO) != 0) printf ("/STROBO"); + if ((mode & SQHM__REFLECT) != 0) printf ("/REFLECT"); + if ((mode & SQHM__NO_STAT) != 0) printf ("/NO_FILLER_STATUS"); + + printf ("\n Bin overflow mode = "); + my_mode = mode & SQHM__BO_MSK; + if (my_mode == SQHM__BO_IGN) { + printf ("\"Ignore\"\n"); + }else if (my_mode == SQHM__BO_SMAX) { + printf ("\"Stop-at-Max\"\n"); + }else if (my_mode == SQHM__BO_CNT) { + printf ("\"Count\""); + }else { + printf ("\"Unrecognised\" = 0x%x\n", my_mode); + } + } +/* +**--------------------------------------------------------------------------*/ + void print_uptime ( +/* ============ +** Print out the up-time +*/ + FILE *lun, /* The output stream */ + char *prefix, /* A message prefix */ + int secs, /* The up-time in seconds */ + char *suffix) { /* A message suffix */ + + int mins, hrs, days; + + mins = secs/60; secs -= mins * 60; + hrs = mins/60; mins -= hrs * 60; + days = hrs/24; hrs -= days * 24; + fprintf (lun, "%s", prefix); + if (days > 0) { + printf (" %d days, %d%02d%02d%s", days, hrs, mins, secs, suffix); + }else if (hrs > 0) { + printf (" %d hrs, %d mins, %d secs%s", hrs, mins, secs, suffix); + }else if (mins > 0) { + printf (" %d mins, %d secs%s", mins, secs, suffix); + }else { + printf (" %d secs%s", secs, suffix); + } + } +/* +**--------------------------------------------------------------------------- +** setup_xrm_database - setup Resource Manager Database +*/ + int setup_xrm_database ( +/* ================== +*/ XrmDatabase *db, + char *name[], + int *argc, + char *argv[], + int verbose) { + + static char our_name[80] = "Unknown"; /* This holds the program name */ + static char lkup_name[80] = "Unknown"; /* Name for looking in database */ + + int status, i, first = True; + char text[80]; + char full_nm0[80]; + char full_nm1[80]; + char *p_fil[] = {0,0,0,0,0,0,0,0,0,0}; + char *my_name; + char *my_name_last; + + char *name_type; + XrmValue name_value; + + XrmDatabase cmnd_line_db = NULL; + XrmDatabase lcl_db = NULL; + /*----------------------------------------------------- + ** This routine merges some resource databases with options specified on + ** the command line. Resources can then be looked up using XrmGetResource. + ** This is a bit like the X-toolkit routine XtAppInitialize does for the + ** extraction of resources by XtGetApplicationResources. + ** + ** I can't help but think that there's a simpler way of doing this but I + ** can't find it in the X manuals. Basically, the problem arises with wanting + ** to avoid the calling program being associated with an X-display, i.e. it + ** is intended for use by "command-line oriented" programs. All the nice, + ** easy-to-use resource/command-line setup routines in Xlib or Xtlib seem to + ** assume one is going to use a display -- not surprising, I suppose, + ** since the concept of Xlib is for writing window based applications! + ** + ** Anyway, the point is that the following way turns out to be lacking + ** when it gets tested in anger. + */ + status = True; /* Assume success */ + + our_name[0] = NIL; + /* + ** Make a list of the databases to be merged, highest priority first. + */ +#ifdef __VMS + p_fil[0] = "decw$user_defaults:SinQ_rc.dat"; + p_fil[1] = "decw$group_defaults:SinQ_rc.dat"; + p_fil[2] = "decw$system_defaults:SinQ_rc.dat"; + p_fil[3] = "decw$user_defaults:decw$xdefaults.dat"; + p_fil[4] = "decw$group_defaults:decw$xdefaults.dat"; + p_fil[5] = "decw$system_defaults:decw$xdefaults.dat"; + p_fil[6] = NULL; + if (*argc > 0) { /* Find out what we are called - parse file nm */ + my_name = strstr (argv[0], "]"); /* Find end of directory, i.e. "]" */ + my_name++; /* Skip over "]" */ + if (my_name[0] == '[') { /* Handle possible concealed device */ + my_name = strstr (my_name, "]"); + my_name++; + } + i = sizeof (our_name); + StrEdit (our_name, my_name, "lowercase", &i); /* Copy the rest */ + strtok (our_name, "."); /* Close it off at "." */ + } +#else + p_fil[0] = StrJoin (full_nm0, sizeof (full_nm0), + getenv ("HOME"), "/SinQ_rc"); + p_fil[1] = "/usr/lib/X11/app-defaults/SinQ_rc"; + p_fil[2] = StrJoin (full_nm1, sizeof (full_nm1), + getenv ("HOME"), "/.Xdefaults"); + p_fil[3] = "/usr/lib/X11/app-defaults/Xdefaults"; + p_fil[4] = NULL; + if (*argc > 0) { /* Find out what we are called - parse file nm */ + /* Find end of directories */ + my_name = argv[0] - 1; + while (my_name != NULL) { + my_name_last = my_name; + my_name_last++; + my_name = strstr (my_name_last, "/"); + } + StrJoin (our_name, sizeof (our_name), my_name_last, ""); + } +#endif + if (verbose) printf ("My name is \"%s\"\n", our_name); + /* + ** Initialise and combine all databases + */ + XrmInitialize (); + for (i = 0; i < XtNumber (p_fil); i++) { + if (p_fil[i] == NULL) break; + status = XrmCombineFileDatabase (p_fil[i], &lcl_db, False); + if ((status != 0) && verbose) { + if (first) + printf ("Resource database created from file %s.\n", p_fil[i]); + if (!first) + printf ("File %s merged into resource database.\n", p_fil[i]); + first = False; + } + } + /*---------------------------------------------------------------- + ** See if there's anything specified on cmnd line, incl "name". + */ + XrmParseCommand (&cmnd_line_db, + OpTable_0, XtNumber(OpTable_0), our_name, argc, argv); + if (cmnd_line_db != NULL) { + /* + ** There was at least 1 item on cmnd line. Process the line. + ** If -name was specified, adopt it. + */ + status = XrmGetResource (cmnd_line_db, /* See if a name was specified */ + StrJoin (text, sizeof (text), our_name, ".name"), + "ProgramName.Values", + &name_type, &name_value); + if (status) { + i = sizeof (lkup_name); + StrEdit (lkup_name, name_value.addr, "lowercase", &i); + printf ("Option list name is \"%s\"\n", lkup_name); + }else { + strcpy (lkup_name, our_name); + } + /* + ** Loop over all items in OpTable_0 and merge them into database, + ** taking care of any possible name changes. + */ + for (i = 0; i < XtNumber (OpTable_0); i++) { + if (strcmp (OpTable_0[i].option, "-name") == 0) continue; + status = XrmGetResource (cmnd_line_db, + StrJoin (text, sizeof (text), + our_name, OpTable_0[i].specifier), + "ProgramName.Values", + &name_type, &name_value); + if (status) { + StrJoin (text, sizeof (text), lkup_name, OpTable_0[i].specifier); + XrmPutResource (&lcl_db, text, "String", &name_value); + } + } + } +/*---------------------------------------------------------------- +*/ + *name = lkup_name; + *db = lcl_db; + if ((lcl_db == NULL) && verbose) + printf ("\007Warning -- no resource database found.\n"); + + XrmDestroyDatabase (cmnd_line_db); +/* +** XrmPutFileDatabase (lcl_db, "sinqhm_client.db"); +*/ + return status; + } +/* +**--------------------------------------------------------------------------*/ + void show_help (char *mod0, char *mod1) { +/* ========= +*/ + int len; + + len = (mod0 == NULL) ? 0 : strlen (mod0); + if (len == 0) goto sh_basic; + + if (StrMatch (mod0, "host", 1)) goto sh_host; + if (StrMatch (mod0, "resources", 2)) goto sh_resources; + if (StrMatch (mod0, "config", 1)) goto sh_config; + if (StrMatch (mod0, "debug", 3)) goto sh_debug; + if (StrMatch (mod0, "deconfig", 3)) goto sh_deconfig; + if (StrMatch (mod0, "go", 1)) goto sh_go; + if (StrMatch (mod0, "rundown", 2)) goto sh_rundown; + if (StrMatch (mod0, "show", 1)) goto sh_show; + if (StrMatch (mod0, "status", 2)) goto sh_status; + if (StrMatch (mod0, "stop", 3)) goto sh_stop; + if (StrMatch (mod0, "zero", 1)) goto sh_zero; + + printf ("\n" + " \"%s\" in an unrecognised help option. Here are some\n" + " hints on using sinqhm_ctrl:\n", mod0); +sh_basic: + printf ("\n" + " The following major command options are recognised by sinqhm_ctrl:\n" + "\n" + " -host ... - specifies the target histogram memory.\n" + "\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" + " -rundown - run down SinqHM server.\n" + " -status (or -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, the DCL$PATH logical\n" + " name must be defined, e.g:\n" + " $ define/job dcl$path mad_exe:\n" + "\n" + " To get more help, issue the command: sinqhm_ctrl -help \n" + "\n" + " where may be any of\n" + "\n" + " host\n" + " config debug deconfig go\n" + " rundown status stop zero\n" + " resources\n" + "\n"); + return; + + sh_host: + printf ("\n -host\n" + "\n" + " The histogram memory with which sinqhm_ctrl is to communicate is\n" + " specified on the command line, thus:\n" + "\n" + " -host -port -size \n" + "\n" + " is the Internet name of the histogram memory specified as\n" + " a name or in the normal Internet dot notation. There is no default.\n" + "\n" + " defaults to 2400 and is the Internet port number at which " + "the\n" + " SinqHM server in is accepting connections.\n" + "\n" + " defaults to 8192 and is the maximum size to be used " + "in send/recv\n" + " calls for transmitting messegas and data between the client and " + ".\n" + " It is not recommended to make this value too large since it causes " + "the\n" + " network software to reserve too much dynamic memory.\n" + "\n"); + return; + + sh_resources: + printf ("\n" + " Sorry, \"-help resources\" is not yet available.\n\n"); + + sh_config: + len = (mod1 == NULL) ? 0 : strlen (mod1); + if (len == 0) goto shc_basic; + + if (StrMatch (mod1, "hm_dig", 4)) goto shmc_hm_dig; + if (StrMatch (mod1, "tof", 2)) goto shmc_tof; + if (StrMatch (mod1, "hrpt", 2)) goto shmc_hrpt; + if (StrMatch (mod1, "hm_psd", 4)) goto shmc_psd; + if (StrMatch (mod1, "trans", 2)) goto shmc_trans; + printf ("\n" + " \"%s\" in an unrecognised \"-help config\" option. Here is\n" + " the basic \"-help config\" information:\n", mod1); + shc_basic: + printf ("\n -config Configure the histogram memory.\n" + "\n" + " When the -config option is used to configure the histogram memory,\n" + " the -mode option must also be given to specify the histogramming mode.\n" + " The -mode option takes the form:\n" + "\n" + " -mode [/][/]...\n" + " \n" + " specifies the histogramming mode. Recognised values are:\n" + " HM_DIG = Digitised histogramming mode (e.g. DMC or SANS)\n" + " TOF = Time-of-Flight mode\n" + " HRPT = HRPT mode\n" + " HM_PSD = Position-Sensitive-Detector mode\n" + " TRANS = Transparent mode\n" + "\n" + " specifies extra options for the mode. Recognised values are:\n" + " DEBUG - debug mode. The filler task will suspend itself as\n" + " soon as it is started so that it can be debugged.\n" + " UD - Up/Down mode.\n" + " BO_IGN - Ignore bin overflows when histogramming.\n" + " BO_SMAX - If a bin overflows, stop at maximum value.\n" + " BO_CNT - Keep a count of bin overflows (not yet available).\n" + " STROBO - Stroboscopic (gummi) mode.\n" + " REFLECT - histograms are reflected (used on HRPT)\n" + " NO_STAT - Suppress status information from the filler task.\n" + "\n" + " Further options must also be specified depending on the value of .\n" + " To get more help, issue the command:\n" + "\n" + " sinqhm_ctrl -help config \n" + "\n" + " where may be any of HM_DIG, TOF, HRPT, HM_PSD or TRANS.\n" + "\n" + " The configuring of the histogram memory results in the starting up\n" + " of the filler process.\n" + "\n"); + return; + + shmc_hm_dig: + printf ("\n -config -mode HM_DIG Digitised histogramming mode.\n" + "\n" + " The following options are required to define the HM_DIG mode:\n"); + goto shmc_hm_dig_hrpt_comn; + + shmc_hrpt: + printf ("\n -config -mode HRPT HRPT histogramming mode.\n" + "\n" + " The following options are required to define the HRPT mode:\n"); + + shmc_hm_dig_hrpt_comn: + printf ("\n" + " -nhist <#-hists> (Dflt = 1) = Number of histograms.\n" + " -nbins <#-bins> (Dflt = none) = Number of bins.\n" + " -bpb (Dflt = 4) = Bytes per bin.\n" + " -lo_bin (Dflt = 0) = Number of lowest bin.\n" + " -compress (Dflt = 1) = Bin compression factor.\n" + "\n"); + return; + + shmc_tof: + printf ("\n -config -mode TOF Time-of-Flight histogramming mode.\n" + "\n" + " The following options are required to define the TOF mode:\n" + " -ncntr <#-cntrs> (Dflt = none) = Number of counters.\n" + " -nbins <#-bins> (Dflt = none) = Number of bins.\n" + " -lo_bin (Dflt = 0) = Tick value of first bin.\n" + " -lo_cntr (Dflt = 0) = Number of first counter.\n" + " -bpb (Dflt = 4) = Bytes per bin.\n" + " -span (Dflt = none) = Number of ticks spanned by a bin.\n" + " -delay (Dflt = 0) = Delay time to start\n" + "\n"); + return; + + shmc_psd: + printf ("\n -config -mode HM_PSD PSD histogramming mode.\n" + "\n" + " Not yet available!\n" + "\n"); + return; + + shmc_trans: + printf ("\n -config -mode TRANS Transparent mode.\n" + "\n" + " The following options are required to define the Transparent mode:\n" + " -nbuff <#-buff> (Dflt = 5) = Number of buffers.\n" + " -buff_size (Dflt = 8192) = Size in bytes of each buffer.\n" + "\n"); + return; + + sh_debug: + printf ("\n -debug Set the level of debug messages.\n" + "\n" + " The value of sets the verbosity of the SinqHM system\n" + " in generating messages to the COM1 port of the histogram\n" + " memory.\n" + "\n" + " may be set to \"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 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 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 Runs down SinqHM\n" + "\n" + " +------------------+\n" + " | USE WITH CAUTION |\n" + " +------------------+\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 Same as -status\n" + "\n" + " Get and display the status of the hist memory.\n" + "\n"); + return; + + sh_status: + printf ("\n -status Get and display the status of the hist memory.\n" + "\n"); + return; + + sh_stop: + printf ("\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 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; + } +/* +**========================================================================== +** +** Main line program +** ------------------ +**==========================================================================*/ + main (int argc, char *argv[]) { +/*==========================================================================*/ + int i, j, k, status, cmnd_len, mod_len; + int is1, is2, mode; + int nh, ch, bph, bpb, span; + int tsi_status, tsi_flags, dt_or_dts, num_bad_ev; + char *p_addr, *opt, tmp_ch; + char buff[64], my_cmnd[32], my_mod[32]; + char *token; + unsigned int daq_state_now; + unsigned int daq_state_was; + unsigned int filler_mask; + unsigned int server_mask; + XrmDatabase my_db; + char *appName; + + int cnct_skt; /* Connect 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; + int oto_status; + char old_time_out[4]; + union { + char chars[4]; + int val; + } time_out; +/*============================================================================*/ + printf ("sinqhm_ctrl ident %s.\n", IDENT); + + /*------------------------------------------------------------- + ** Setup the resource database and look up the resources. + */ + Verbose = False; + for (i = 1; i < argc; i++) if (strcmp ("-v", argv[i]) == 0) Verbose = True; + + setup_xrm_database (&my_db, &appName, &argc, argv, Verbose); + status = get_check_resources (&my_db, appName, &argc, argv, Verbose); + if (!status) return False; + + if (Verbose) printf (" Server is %s ", Rmt_host); + if (Verbose) printf ("(%s),", inet_ntoa (*rmt_inet_addr_pntr)); + if (Verbose) printf (" Port %d.\n", Rmt_port); +/*============================================================================ +** Execute the user's wish. +*/ + i = 0; + if (Do_config) i++; + if (Do_debug) i++; + if (Do_deconfig) i++; + if (Do_go) i++; + if (Do_rundown) i++; + if (Do_status) i++; + if (Do_stop) i++; + if (Do_zero) i++; + if (i == 0) { + printf ("No action has been specified. Assume \"-status\" ...\n"); + Do_status = True; + }else if (i != 1) { + printf ("Only one action may be specified on the command line.\n"); + show_help (NULL, NULL); exit (EXIT_FAILURE); + } +/*============================================================================ +** Switch according to value of +*/ + if (Do_config) goto config; + if (Do_debug) goto debug; + if (Do_deconfig) goto deconfig; + if (Do_go) goto go; + if (Do_rundown) goto rundown; + if (Do_status) goto status; + if (Do_stop) goto stop; + if (Do_zero) goto zero; + goto status; +/*============================================================================*/ + config: +/*====== Configure - Extract values from the logical names. +*/ + Hm_mode = 0; + StrJoin (buff, sizeof (buff), Mode, ""); + token = strtok (buff, "/"); /* Split up the tokens */ + while (token != NULL) { + if (StrMatch (token, "HM_DIG", 4)) { + Hm_mode = (Hm_mode & ~SQHM__SUB_MODE_MSK) | SQHM__HM_DIG; + }else if (StrMatch (token, "TOF", 3)) { + Hm_mode = (Hm_mode & ~SQHM__SUB_MODE_MSK) | SQHM__TOF; + }else if (StrMatch (token, "HRPT", 3)) { + Hm_mode = (Hm_mode & ~SQHM__SUB_MODE_MSK) | SQHM__HRPT; + }else if (StrMatch (token, "TRANS", 3)) { + Hm_mode = (Hm_mode & ~SQHM__SUB_MODE_MSK) | SQHM__TRANS; + }else if (StrMatch (token, "HM_PSD", 4)) { + Hm_mode = (Hm_mode & ~SQHM__SUB_MODE_MSK) | SQHM__HM_PSD; + }else if (StrMatch (token, "DEBUG", 3)) { + Hm_mode |= SQHM__DEBUG; + }else if (StrMatch (token, "UD", 2)) { + Hm_mode |= SQHM__UD; + }else if (StrMatch (token, "BO_IGN", 4)) { + Hm_mode = (Hm_mode & ~SQHM__BO_MSK ) | SQHM__BO_IGN; + }else if (StrMatch (token, "BO_SMAX", 4)) { + Hm_mode = (Hm_mode & ~SQHM__BO_MSK ) | SQHM__BO_SMAX; + }else if (StrMatch (token, "BO_CNT", 4)) { + Hm_mode = (Hm_mode & ~SQHM__BO_MSK ) | SQHM__BO_CNT; + }else if (StrMatch (token, "STROBO", 3)) { + Hm_mode |= SQHM__STROBO; + }else if (StrMatch (token, "REFLECT", 4)) { + Hm_mode |= SQHM__REFLECT; + }else if (StrMatch (token, "NO_STAT", 4)) { + Hm_mode |= SQHM__NO_STAT; + }else { + printf ("\007 The -mode option is not valid.\n"); + printf (" Here is some help ...\n"); + show_help ("config", NULL); + return EXIT_FAILURE; + } + token = strtok (NULL, "/"); + } + + is1 = EXIT_SUCCESS; + if (((Hm_mode & ~SQHM__SUB_MODE_MSK) == SQHM__HM_DIG) || + ((Hm_mode & ~SQHM__SUB_MODE_MSK) == SQHM__HRPT)) { + if (Nbins <= 0) {is1 = !EXIT_SUCCESS; opt = "-nbins";} + }else if ((Hm_mode & ~SQHM__SUB_MODE_MSK) == SQHM__TOF) { + if (Ncntrs <= 0) { + is1 = !EXIT_SUCCESS; + opt = "-ncntr"; + }else if (Nbins <= 0) { + is1 = !EXIT_SUCCESS; + opt = "-nbins"; + }else if (Span < 0) { + is1 = !EXIT_SUCCESS; + opt = "-span"; + } + }else if ((Hm_mode & ~SQHM__SUB_MODE_MSK) == SQHM__TRANS) { + }else { + is1 = !EXIT_SUCCESS; + opt = "-mode"; + } + if (is1 != EXIT_SUCCESS) { + printf ("\007 The configuration is not defined or not complete.\n"); + printf (" Here is some help ...\n"); + show_help ("config", NULL); + printf (" The problem is with %s\n", opt); + printf ("\n"); + return EXIT_FAILURE; + } +/* +** The configuration seems to be OK. Connect to the target. +*/ + cnct_skt = open_socket (Rmt_host, Rmt_port); + if (cnct_skt <= 0) exit (EXIT_FAILURE); +/* +** Set up and send the configure message. +*/ + Req_buff.bigend = htonl (0x12345678); + Req_buff.cmnd = htonl (SQHM_CONFIG); + + Req_buff.u.cnfg.mode = htonl (Hm_mode); + if ((Hm_mode & ~SQHM__SUB_MODE_MSK) == SQHM__HM_DIG) { + Req_buff.u.cnfg.u.hm_dig.n_hists = htonl (Nhist); + Req_buff.u.cnfg.u.hm_dig.lo_bin = htonl (Lo_bin); + Req_buff.u.cnfg.u.hm_dig.num_bins = htonl (Nbins); + Req_buff.u.cnfg.u.hm_dig.bytes_per_bin = htonl (Bytes_per_bin); + Req_buff.u.cnfg.u.hm_dig.compress = htonl (Compress); + }else if ((Hm_mode & ~SQHM__SUB_MODE_MSK) == SQHM__TOF) { + Req_buff.u.cnfg.u.tof.n_extra_bytes = htonl (0); + Req_buff.u.cnfg.u.tof.n_edges = htons (1); + Req_buff.u.cnfg.u.tof.n_banks = htons (1); + + Req_buff.u.cnfg.u.tof.edge_0.n_bins = htonl (Nbins); + Req_buff.u.cnfg.u.tof.edge_0.flag = htonl (0); /* Fixed bin span */ + Req_buff.u.cnfg.u.tof.edge_0.edges[0] = htonl (Lo_bin); + Req_buff.u.cnfg.u.tof.edge_0.edges[1] = htonl (Lo_bin+Span); + Req_buff.u.cnfg.u.tof.preset_delay = htonl (Delay_time_to_start); + + Req_buff.u.cnfg.u.tof.bank_0.first = htons (Lo_cntr); + Req_buff.u.cnfg.u.tof.bank_0.n_cntrs = htons (Ncntrs); + Req_buff.u.cnfg.u.tof.bank_0.edge_indx = htons (0); + Req_buff.u.cnfg.u.tof.bank_0.bytes_per_bin = htons (Bytes_per_bin); + }else if ((Hm_mode & ~SQHM__SUB_MODE_MSK) == SQHM__TRANS) { + Req_buff.u.cnfg.u.trans.n_buffs = htonl (Nbuff); + Req_buff.u.cnfg.u.trans.n_bytes = htons (Buff_size); + } + + printf (" Configuration:\n" + " Histogramming mode is 0x%08x", Hm_mode); + if ((Hm_mode & ~SQHM__SUB_MODE_MSK) == SQHM__HM_DIG) { + printf (" = HM_DIG"); + }else if ((Hm_mode & ~SQHM__SUB_MODE_MSK) == SQHM__HM_PSD) { + printf (" = HM_PSD"); + }else if ((Hm_mode & ~SQHM__SUB_MODE_MSK) == SQHM__HRPT) { + printf (" = HRPT"); + }else if ((Hm_mode & ~SQHM__SUB_MODE_MSK) == SQHM__TRANS) { + printf (" = TRANS"); + }else if ((Hm_mode & ~SQHM__SUB_MODE_MSK) == SQHM__TOF) { + printf (" = TOF"); + } + if ((Hm_mode & SQHM__DEBUG) != 0) printf (" + DEBUG"); + printf ("\n"); + if ((Hm_mode & ~SQHM__SUB_MODE_MSK) != SQHM__TOF) { + 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", + Nhist, Lo_bin, Nbins, Bytes_per_bin, Compress); + } else if (((Hm_mode & ~SQHM__SUB_MODE_MSK) != SQHM__HM_DIG) || + ((Hm_mode & ~SQHM__SUB_MODE_MSK) != SQHM__HRPT)) { + printf (" Number of counters = %5d\n" + " First counter = %5d\n" + " Number of bins per histogram = %5d\n" + " Lower edge of first bin = %5d\n" + " Bin width = %5d\n" + " Number of bytes per bin = %5d\n" + " Delay-Time-to-Start = %5d\n", + Ncntrs, Lo_cntr, Nbins, Lo_bin, Span, Bytes_per_bin, + Delay_time_to_start); + } + if ((Hm_mode & SQHM__DEBUG) != 0) + printf ("\007\n Warning -- DEBUG suspend flag is set!\n\n"); + printf (" Configuring ..."); fflush (NULL); + + 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.. +*/ + printf (" Setting SinqHM debug mask = 0x%04x ...", Dbg_level); fflush (NULL); + Req_buff.bigend = htonl (0x12345678); + Req_buff.cmnd = htonl (SQHM_DBG); + Req_buff.u.dbg.mask = htonl (Dbg_level); + + cnct_skt = open_socket (Rmt_host, Rmt_port); + if (cnct_skt <= 0) exit (EXIT_FAILURE); + + 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); + status = close (cnct_skt); + 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 (Be_harsh) { + Req_buff.u.decnfg.sub_code = htonl (1); /* But be harsh, if ordered */ + printf (" Deconfiguring (mit Gewalt!) ..."); + }else { + printf (" Deconfiguring ..."); + } + fflush (NULL); + + cnct_skt = open_socket (Rmt_host, Rmt_port); + if (cnct_skt <= 0) exit (EXIT_FAILURE); + + 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); + status = close (cnct_skt); + 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 ..."); fflush (NULL); + + Req_buff.bigend = htonl (0x12345678); + Req_buff.cmnd = htonl (SQHM_DAQ); + Req_buff.u.daq.sub_cmnd = htonl (DAQ__GO); + + cnct_skt = open_socket (Rmt_host, Rmt_port); + if (cnct_skt <= 0) exit (EXIT_FAILURE); + + 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); + status = close (cnct_skt); + return EXIT_FAILURE; + } +/* +** Wait for the status response. +*/ + status = getCheckStatusResponse (cnct_skt, &Rply_buff, sizeof (Rply_buff)); + if (status == SUCCESS) { + daq_state_now = ntohs (Rply_buff.u.daq.daq_now); + daq_state_was = ntohs (Rply_buff.u.daq.daq_was); + filler_mask = ntohs (Rply_buff.u.daq.filler_mask); + server_mask = ntohs (Rply_buff.u.daq.server_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" + " Daq-state-now is 0x%04x\n" + " Filler-mask is 0x%04x\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 ..."); fflush (NULL); + Req_buff.bigend = htonl (0x12345678); + Req_buff.cmnd = htonl (SQHM_EXIT); + + cnct_skt = open_socket (Rmt_host, Rmt_port); + if (cnct_skt <= 0) exit (EXIT_FAILURE); + + 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); + status = close (cnct_skt); + 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; +/*============================================================================*/ + status: +/*====== Show-status. Set up and send the status message. +*/ + printf (" Getting status of SinqHM ..."); fflush (NULL); + + Req_buff.bigend = htonl (0x12345678); + Req_buff.cmnd = htonl (SQHM_STATUS); + + cnct_skt = open_socket (Rmt_host, Rmt_port); + if (cnct_skt <= 0) exit (EXIT_FAILURE); + + 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); + status = close (cnct_skt); + 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'; + printf ("\n" + " 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)); + print_uptime (stdout, " Up-time = ", + ntohl (Rply_buff.u.status.up_time), "\n\n"); + if (Rply_buff.u.status.cfg_state == 0) { + printf (" SINQHM has not yet been configured.\n"); + }else { + mode = ntohl (Rply_buff.u.status.cfg_state); + print_HM_mode (mode); + printf ("\n"); + + nh = ntohs (Rply_buff.u.status.n_hists); + ch = ntohs (Rply_buff.u.status.curr_hist); + bph = ntohl (Rply_buff.u.status.num_bins); + bpb = Rply_buff.u.status.bytes_per_bin; + span = Rply_buff.u.status.compress; + tsi_status = ntohs (Rply_buff.u.status.tsi_status); + tsi_flags = ntohs (Rply_buff.u.status.flags); + dt_or_dts = ntohl (Rply_buff.u.status.dt_or_dts.both); + num_bad_ev = ntohl (Rply_buff.u.status.num_bad_events); + + if (((mode & ~SQHM__SUB_MODE_MSK) == SQHM__HM_DIG) || + ((mode & ~SQHM__SUB_MODE_MSK) == SQHM__HRPT)) { + if (nh != 0) { + printf (" Number of histograms = %d\n", nh); + printf (" Current histogram = %d\n", ch); + } + printf (" Number of bins per histogram = %d\n", bph); + printf (" Number of bytes per bin = %d\n", bpb); + if (span > 1) printf (" Bin compression factor = %d\n", span); + if (dt_or_dts != 0) + printf (" Dead-Time = %u\n", dt_or_dts); + }else if ((mode & ~SQHM__SUB_MODE_MSK) == SQHM__TOF) { + nh = ntohs (Rply_buff.u.status.n_hists); + printf (" Number of counters = %d\n", nh); + printf (" Number of bins per histogram = %d\n", bph); + printf (" Number of bytes per bin = %d\n", bpb); + if (span > 1) printf (" Time span per bin = %d\n", span); + if (dt_or_dts != 0) + printf (" Delay-Time-to-Start = %u\n", dt_or_dts); + }else if ((mode & ~SQHM__SUB_MODE_MSK) == SQHM__HM_PSD) { + }else if ((mode & ~SQHM__SUB_MODE_MSK) == SQHM__TRANS) { + printf (" Number of buffers = %d\n", nh); + printf (" Current buffer = %d\n", ch); + printf (" Number of bytes per buffer = %d\n", bph); + } + printf (" Number of active connections = %d\n", + Rply_buff.u.status.act_srvrs); + if (Rply_buff.u.status.daq_now == 0) { + printf (" Data acquisition is active\n"); + }else { + printf (" Data acquisition is not active\n"); + } + if ((tsi_status != 0) || (tsi_flags != 0)) { + if (tsi_flags != 0) { + printf (" TSI Flags = 0x%04x", tsi_flags); + if ((tsi_flags & STATUS_FLAGS__PF) != 0) printf ("/PF"); + if ((tsi_flags & STATUS_FLAGS__SWC) != 0) printf ("/SWC"); + if ((tsi_flags & STATUS_FLAGS__NRL) != 0) printf ("/NRL"); + if ((tsi_flags & STATUS_FLAGS__DAQ) != 0) printf ("/DAQ"); + if ((tsi_flags & STATUS_FLAGS__SYNC3) != 0) printf ("/SYNC3"); + if ((tsi_flags & STATUS_FLAGS__SYNC2) != 0) printf ("/SYNC2"); + if ((tsi_flags & STATUS_FLAGS__SYNC1) != 0) printf ("/SYNC1"); + if ((tsi_flags & STATUS_FLAGS__SYNC0) != 0) printf ("/SYNC0"); + if ((tsi_flags & STATUS_FLAGS__UD) != 0) printf ("/UD"); + if ((tsi_flags & STATUS_FLAGS__GU) != 0) printf ("/GU"); + } + printf ("\n"); + } + if (num_bad_ev != 0) + printf (" Number-of-Bad-Events = %u\n", num_bad_ev); + } + } +/* +** 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 ..."); fflush (NULL); + + Req_buff.bigend = htonl (0x12345678); + Req_buff.cmnd = htonl (SQHM_DAQ); + Req_buff.u.daq.sub_cmnd = htonl (DAQ__STOP); + + cnct_skt = open_socket (Rmt_host, Rmt_port); + if (cnct_skt <= 0) exit (EXIT_FAILURE); + + 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); + status = close (cnct_skt); + return EXIT_FAILURE; + } +/* +** Wait for the status response. +*/ + status = getCheckStatusResponse (cnct_skt, &Rply_buff, sizeof (Rply_buff)); + if (status == SUCCESS) { + daq_state_now = ntohs (Rply_buff.u.daq.daq_now); + daq_state_was = ntohs (Rply_buff.u.daq.daq_was); + filler_mask = ntohs (Rply_buff.u.daq.filler_mask); + server_mask = ntohs (Rply_buff.u.daq.server_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" + " Daq-state-now is 0x%04x\n" + " Filler-mask is 0x%04x\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 ..."); fflush (NULL); + + cnct_skt = open_socket (Rmt_host, Rmt_port); + if (cnct_skt <= 0) exit (EXIT_FAILURE); + + 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); + status = close (cnct_skt); + 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; + } +/*================================================ End of SINQHM_CTRL.C =====*/