Files
sics/hardsup/sinqhm_ctrl.c
2000-02-07 10:38:55 +00:00

1058 lines
36 KiB
C
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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 "<node> <port> <pkt_size>"
** <node> is the node where SINQHM_SRV is running,
** <port> is SINQHM_SRV's TCP/IP port number (dflt=2400),
** <pkt_size> 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 <cmnd> <modifier>
**
** where <cmnd> may be "CONFIG", "DEBUG", "DECONFIG", "GO", "HELP",
** "RUNDOWN", "SHOW", "STOP" or "ZERO". If <cmnd> 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, <modifier> 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, <modifier> is an integer specifying the debug
** level. <modifier> may also be specified as "ON" or "OFF", corresponding
** to levels 1 and 0 respectively. If <modifier> is anything else (or
** absent), "ON" is assumed.
**
** For the "DECONFIG" command, <modifier> is used to specify the
** "harshness" of the de-configure. If <modifier> is specified as
** "HARSH", the de-configure will be "harsh". If <modifier> 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 <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <math.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/types.h>
/*
**==================== 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 <mode> - configure the hist memory.\n"
" DEBUG <level> - sets the debug level.\n"
" DECONFIG <harshness> - de-configure the hist memory.\n"
" GO - start data acquisition.\n"
" HELP <subject> - 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 <subject>\n"
"\n"
" where <subject> 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 \"<host> <port> <pkt-size>\"\n"
"\n"
" In addition, the following environment variables are used by CONFIG\n"
"\n"
" setenv SINQHM_HM_MODE <mode> (Dflt = SQHM__HM_DIG)\n"
" setenv SINQHM_NHISTS <nhists> (Dflt = 1)\n"
" setenv SINQHM_LOW_BIN <lo_bin> (Dflt = 0)\n"
" setenv SINQHM_NBINS <nbins> (Dflt = none)\n"
" setenv SINQHM_BINWID <binwid> (Dflt = 4)\n"
" setenv SINQHM_COMPRESS <cmprs> (Dflt = 0)\n"
"\n"
" On VMS systems, logical names are used instead, e.g.\n"
"\n"
" define/group sinqhm_frontend \"<host> <port> <pkt-size>\"\n"
" define/group sinqhm_hm_mode <mode>\n"
"\n"
" Defaults: <host> = None <port> = 2400 <pkt-size> = 8192\n"
"\n");
return;
sh_config:
printf ("\n"
" CONFIG <mode> - 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 <mode> 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 <level> - sets the level of debug messages to the\n"
" hist memory console.\n"
"\n"
" <level> 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 <harshness> - de-configure the hist memory.\n"
"\n"
" If <harshness> is not specified, there must be no active clients\n"
" for the command to be accepted.\n"
"\n"
" If <harshness> 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> */
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> */
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 <cmnd>
*/
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 =====*/