#define IDENT "1C06" /*---------------------------------------------------------------------------*/ #ifdef __DECC #pragma module SinqHM_Client IDENT #endif /* ** Link_options - Here is the Linker Option File **! sinqhm_client **! sinq_olb/lib/inc=deltat_messages **! pgplot_dir:cpgplot.olb/lib **! pgplot_dir:grpckg.olb/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_client debug ** Link_options_end ** ** Building on Alpha OSF/1: ** ** cc -Dmain=MAIN__ -std1 -g -c -o sinqhm_client.o \ ** -I/data/lnslib -I. \ ** ~/SinqHM/sinqhm_client.c ** f77 -g -o ~/bin/sinqhm_client sinqhm_client.o \ ** -L/public/lib -lsinq -lcpgplot -lpgplot -lX11 ** rm sinqhm_client.o ** ** +--------------------------------------------------------------+ ** | 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 . . . . . . . . : [...sinqhm]sinqhm_client.c ** ** Author . . . . . . . . . . : D. Maden ** Date of creation . . . . . . : Jan 1997 ** ** SinqHM_Client is the main program of an Internet Client which transmits ** requests to a SinqHM server running on a front-end processor. ** ** Updates: ** 9-Jan-1997 DM. Initial version. ** **==================================================================== */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __VMS #include #else #include #endif /* **==================== Global Definitions ===================================== */ #include #include "SinqHM_def.h" #define uchar unsigned char #define usint unsigned short int #define uint unsigned int #define NIL '\0' #define NL '\n' #define MAXERR 10 #define MAX_HIS 16 #define BSIZE ((128*1024)/512) /* Specify 128 kbyte buffer */ #ifndef True #define True 1 #endif #ifndef False #define False 0 #endif /* ** Define the Data Structures we need */ /* **==================== Global Variables ====================================== */ int My_errno, My_vaxc_errno; struct req_buff_struct Req_buff; struct rply_buff_struct Rply_buff; int Verbose; int Rmt_port; int Pkt_size; char Rmt_host[32]; int Rw_bytes_got, Rw_bytes_put; static int Cnct_skt = 0; /* Connect socket */ static int Rw_skt = 0; /* Read/write socket */ int Dbg_mode; /* Setting of in the SQHM_CNCT ** message to SINQHM server */ /* ** The buffer for holding Hist Mem data is pointed to ** by Hm_buff_addr. The number of bytes allocated is Hm_buff_size. */ void *Hm_buff_addr = NULL; uint Hm_buff_size; uint Hm_buff_used; uint Hm_mode; /* Histogramming Mode of Histogram Memory */ uint N_hists; /* The number of histograms */ uint Hm_nbins; /* The number of bins per histogram */ uint Compress; /* The span of each bin */ uint Bytes_per_bin; /* The number of bytes per bin */ uint Curr_hist; /* The current histogram */ uint Max_block; uint Lo_cntr; uint Lo_bin; uint Total_bytes; int PGPLOT_started = 0; float P1 = 2000000, P2 = 10000, P3 = 0, P4 = 200000, P5 = 500, P6 = 0; static XrmOptionDescRec OpTable_0[] = { {"-name", ".name", XrmoptionSepArg, (XPointer) NULL}, {"-dbg", ".sqhmDebug", XrmoptionNoArg, (XPointer) "1"}, {"-debug", ".sqhmDebug", XrmoptionNoArg, (XPointer) "1"}, {"-h", ".sqhmHelp", XrmoptionNoArg, (XPointer) "1"}, {"-he", ".sqhmHelp", XrmoptionNoArg, (XPointer) "1"}, {"-hel", ".sqhmHelp", XrmoptionNoArg, (XPointer) "1"}, {"-help", ".sqhmHelp", XrmoptionNoArg, (XPointer) "1"}, {"-ho", ".sqhmHost", XrmoptionSepArg, (XPointer) NULL}, {"-hos", ".sqhmHost", XrmoptionSepArg, (XPointer) NULL}, {"-host", ".sqhmHost", XrmoptionSepArg, (XPointer) NULL}, {"-port", ".sqhmPort", XrmoptionSepArg, (XPointer) NULL}, {"-pktsize", ".sqhmPktSize", XrmoptionSepArg, (XPointer) NULL}, {"-size", ".sqhmPktSize", XrmoptionSepArg, (XPointer) NULL}, {"-v", ".sqhmVerbose", XrmoptionNoArg, (XPointer) "1"}, {"-?", ".sqhmHelpItem", XrmoptionSepArg, (XPointer) NULL}, }; /* **============================================================================= ** Local routines. ** ** do_dump : Dump out the contents of the histogram buffer. ** do_load : Load the histogram buffer from a file. ** do_plot : Plot the data. ** do_project : Handle the "PROJECT" command. ** do_status : Get and display status of SinqHM_srv. ** do_1d : Handle the "READ" command. ** do_2d : Handle the "2D" command. ** do_2d_plot : Plot the data 2-dimensionally. ** exit_handler : Exit handler in case a forced exit is made. ** gen_data : Generate sum of 2 Lorenzians. ** gen_data_2d : Generate sum of 2 Lorenzians in pseudo 2-dim mode. ** get_recd : Read a record from file. ** new_config_quit : Quit because SinqHM config'n has changed. ** openConnection : Open connection to SinqHM. ** openConnectionGbl : Call openConnection then set up some globals. ** print_HM_mode : Interpret the HM configuration. ** print_uptime : Print out the up-time. ** read_hm : Read block of bins from SINQHM_SRV ** read_project : Read projected block of bins from SINQHM_SRV ** show_help : Display the help text. ** split_args : Parse a command line. ** write_hm : Write block of bins to SINQHM_SRV **---------------------------------------------------------------------------- ** Prototypes */ void do_dump (char *args); void do_load (char *args, int dbg_mode); void do_plot (uint first, uint n_bins, uint bytes_per_bin, uint total); void do_project (char *args, int dbg_mode); void do_status (int dbg_mode); void do_1d (char *args, int dbg_mode); void do_2d (char *args, int dbg_mode); void do_2d_plot (uint f_hist, uint n_hists, uint f_bin, uint n_bins, uint bytes_per_bin, uint total); void exit_handler (); void gen_data (char *args); void gen_data_2d (char *args); int get_check_resources (XrmDatabase *db, char *appName, int *argc, char *argv[], int verbose); int get_recd (FILE *lun, char *recd, int recd_len); void new_config_quit (char *txt); int openConnection (char *node, int *port, int *pkt_size, int mode, struct rply_buff_struct *reply, int verbose); int openConnectionGbl (char *node, int *port, int *pkt_size, int mode, struct rply_buff_struct *reply, int verbose); void print_HM_mode (uint mode, int n_pad); void print_uptime (FILE *lun, char *prefix, int secs, char *suffix); int read_hm (char *buff, uint hbuf_size, uint f_bin, uint n_bins, uint hist_num, uint *cntr_lo, uint *cntr_hi); int read_project (char *buff, uint hbuf_size, uint f_hist, uint n_hists, uint f_bin, uint n_bins, uint axis, uint xdim, uint h_select, uint *cntr_lo, uint *cntr_hi); int setup_xrm_database (XrmDatabase *db, char *name[], int *argc, char *argv[], int verbose); void show_help (char *token); void split_args (char *args, ...); int write_hm (void *buff, uint hist_no, uint f_bin, uint n_bins, uint bpb); /* **----------------------------------------------------------------------------*/ void do_dump (char *args) { /* ======= ** Dump out the contents of the histogram buffer ** Args are: ** Number of first bin to dump (dflt = 0) ** Number of bins to dump (dflt = rest of buffer) ** File to receive the data (dflt = standard output) */ int i, j, k; time_t time_now; uint n_items, f_bin, n_bins; uint total = 0; char *p_p1, *p_p2, *p_p3; char recd[256]; FILE *lun; uchar *p_byte; usint *p_word; uint *p_long; if (Hm_buff_used == 0) { printf ("There is nothing available to dump!\n"); return; } n_items = Hm_buff_used/Bytes_per_bin; split_args (args, &p_p1, &p_p2, &p_p3, NULL); if (p_p1 == NULL) p_p1 = "0"; if ((sscanf (p_p1, "%u", &f_bin) != 1) || (f_bin >= n_items)) { printf ("<1st-bin> is invalid: \"%s\"\n", p_p1); return; } if (p_p2 == NULL) { n_bins = n_items - f_bin; }else { if ((sscanf (p_p2, "%u", &n_bins) != 1) || (n_bins > n_items) || ((n_bins + f_bin) > n_items)) { printf ("<#-bins> is invalid: \"%s\"\n", p_p2); n_bins = n_items - f_bin; printf ("It has been set to %d\n", n_bins); } } if (p_p3 == NULL) { printf (" Dumping histogram memory buffer ...\n"); lun = stdout; }else { printf (" Opening file %s to receive the memory dump ...\n", p_p3); lun = fopen (p_p3, "w"); if (lun == NULL) { printf (" ... failed to open file. No dump made!\n"); return; } time_now = time (NULL); fprintf (lun, "! Histogram Memory Dump of %s at %s", Rmt_host, asctime (localtime (&time_now))); fprintf (lun, "! =====================\n"); } fprintf (lun, "First-bin: %5u\n", f_bin); fprintf (lun, "Number-of-bins: %5u\n", n_bins); p_byte = (uchar *) Hm_buff_addr; p_word = (usint *) Hm_buff_addr; p_long = (uint *) Hm_buff_addr; for (i = 0; i < n_bins; i += 10) { k = 0; for (j = 0; j < 10; j++) { if ((i + j) >= n_bins) break; switch (Bytes_per_bin) { case 1: k += sprintf (&recd[k], "%5d", p_byte[f_bin+i+j]); total += p_byte[f_bin+i+j]; break; case 2: k += sprintf (&recd[k], "%6d", p_word[f_bin+i+j]); total += p_word[f_bin+i+j]; break; case 4: k += sprintf (&recd[k], "%7d", p_long[f_bin+i+j]); total += p_long[f_bin+i+j]; } } if (j > 0) fprintf (lun, "%6d: %s\n", f_bin+i, recd); } if (lun == stdout) printf ("\n"); fprintf (lun, "Total: %u\n", total); if (lun != stdout) { fclose (lun); chmod (p_p3, 0644); printf (" ... dump completed.\n"); } } /* **----------------------------------------------------------------------------*/ void do_load (char *args, int dbg_mode) { /* ======= ** Load the contents of the histogram buffer from a file ** Args are: ** File to read to get the data (dflt = standard input) */ int i, j, binnum, status; uint bytes_needed, f_bin, n_bins, value; uint total = 0; char *p_p1, *pBinnum, *tok; char recd[256]; FILE *lun; uchar *p_byte; usint *p_word; uint *p_long; if (Rw_skt == 0) { Rw_skt = openConnectionGbl (Rmt_host, &Rmt_port, &Pkt_size, dbg_mode, &Rply_buff, Verbose); if (Rw_skt == 0) FailInet ("\ndo_load/openConnectionGbl error."); } split_args (args, &p_p1, NULL); if (p_p1 == NULL) { printf (" Loading histogram memory from standard input ...\n"); lun = stdin; }else { printf (" Reading histogram memory data from file %s ...\n", p_p1); lun = fopen (p_p1, "r"); if (lun == NULL) { printf (" ... failed to open file. No load done!\n"); return; } } get_recd (lun, recd, sizeof (recd)); /* Get first non-comment record */ i = sscanf (recd, "First-bin: %i%n", &f_bin, &j); if ((i != 1) || (j != strlen (recd))) { printf (" ... First-bin record not found. No load done!\n"); if (lun != stdin) fclose (lun); return; } get_recd (lun, recd, sizeof (recd)); /* Get second non-comment record */ i = sscanf (recd, "Number-of-bins: %i%n", &n_bins, &j); if ((i != 1) || (j != strlen (recd))) { printf (" ... Number-of-bins record not found. No load done!\n"); if (lun != stdin) fclose (lun); return; } printf ("First-bin: %5u\n", f_bin); printf ("Number-of-bins: %5u\n", n_bins); bytes_needed = n_bins * Bytes_per_bin; if (bytes_needed > Hm_buff_size) { /* Expand buffer space? */ Hm_buff_addr = realloc (Hm_buff_addr, bytes_needed); /* Yes */ if (Hm_buff_addr != NULL) { Hm_buff_size = bytes_needed; }else { printf ("Error getting memory buffer for file data. No load done!\n"); if (lun != stdin) fclose (lun); return; } } Hm_buff_used = bytes_needed; p_byte = (uchar *) Hm_buff_addr; p_word = (usint *) Hm_buff_addr; p_long = (uint *) Hm_buff_addr; for (i = 0; i < n_bins; i += 10) { status = get_recd (lun, recd, sizeof (recd)); /* Get another record */ if (!status) { printf ("Error getting data from file at record %d! No load done!\n", (i+10)/10); if (lun != stdin) fclose (lun); return; } pBinnum = strtok (recd, ":"); if ((pBinnum == NULL) || (sscanf (pBinnum, "%i", &binnum) != 1) || (binnum != (i + f_bin))) { printf ("Bin number wrong at record %d! No load done!\n", (i+10)/10); if (lun != stdin) fclose (lun); return; } for (j = 0; j < 10; j++) { if ((i + j) >= n_bins) break; tok = strtok (NULL, " "); if ((tok == NULL) || (sscanf (tok , "%u", &value) != 1)) { printf ("Bad data value on record %d! No load done!\n", (i+10)/10); if (lun != stdin) fclose (lun); return; } switch (Bytes_per_bin) { case 1: p_byte[i+j] = value; total += p_byte[i+j]; break; case 2: p_word[i+j] = value; total += p_word[i+j]; break; case 4: p_long[i+j] = value; total += p_long[i+j]; } } } get_recd (lun, recd, sizeof (recd)); /* Get last non-comment record */ i = sscanf (recd, "Total: %i%n", &value, &j); if ((i != 1) || (j != strlen (recd))) { printf (" ... \"Total\" record not found. No load done!\n"); if (lun != stdin) fclose (lun); return; } if (value != total) { printf (" ... the \"Total\" record is inconsistent. No load done!\n"); printf (" Total of bins = %6u\n" " Total on \"Total\" record = %6u\n", total, value); if (lun != stdin) fclose (lun); return; } printf (" Sending the data ..."); status = write_hm (Hm_buff_addr, -1, f_bin, n_bins, Bytes_per_bin); if (lun != stdin) fclose (lun); if (status) printf (" load completed.\n"); } /* **----------------------------------------------------------------------------*/ void do_plot (uint first, uint n_bins, uint bytes_per_bin, uint total) { /* ======= ** Make a plot of the data. */ int i; char total_txt[21]; #ifdef LINUX char dev[] = "/XSERV"; #else char dev[] = "/XW"; #endif char xlab[] = "Bins"; char ylab[] = "Counts"; float xlo, xhi, yhi; float *x; float *y; uchar *p_byte; usint *p_word; uint *p_long; if ((n_bins <= 0) || (total == 0)) { printf ("Nothing to plot!\n"); return; } x = (float *) malloc ((n_bins + 1) * sizeof (float)); if (x == NULL) { printf ("Cannot get plot memory for x-array\n"); return; } y = (float *) malloc (n_bins * sizeof (float)); if (y == NULL) { printf ("Cannot get plot memory for y-array\n"); return; } sprintf (total_txt, "Bin Total = %8d", total); p_byte = (uchar *) Hm_buff_addr; p_word = (usint *) Hm_buff_addr; p_long = (uint *) Hm_buff_addr; if (PGPLOT_started == 0) { cpgbeg (0, dev, 1, 1); /* - - - - - - - - - - - - - - - - - - - - - - ** Set black on white (hopefully) */ cpgscr (0, 0.79, 0.67, 0.57); cpgscr (1, 0.0, 0.0, 0.0); cpgask (0); PGPLOT_started = 1; } xlo = (float) first; xhi = (float) first + n_bins + 1; yhi = 10.0; switch (bytes_per_bin) { case 1: for (i = 0; i < n_bins; i++) { x[i] = first + i; y[i] = p_byte[i]; if (y[i] > yhi) yhi = y[i]; } break; case 2: for (i = 0; i < n_bins; i++) { x[i] = first + i; y[i] = p_word[i]; if (y[i] > yhi) yhi = y[i]; } break; case 4: for (i = 0; i < n_bins; i++) { x[i] = first + i; y[i] = p_long[i]; if (y[i] > yhi) yhi = y[i]; } break; } x[n_bins] = first + n_bins; yhi = cpgrnd (yhi, &i); cpgenv (xlo, xhi, 0.0, yhi, 0, 0); cpglab (xlab, ylab, total_txt); cpgbin (n_bins, x, y, False); cpgmove (x[n_bins], y[n_bins-1]); cpgdraw (x[n_bins], 0.0); free (x); free (y); } /* **----------------------------------------------------------------------------*/ void do_project (char *args, int dbg_mode) { /* ========== ** Generate a projected plot of a 2-dim hist (e.g. of TOF array of cntrs) ** Args are: ** Number of first histogram ** Number of histograms ** Number of first bin ** Number of bins ** Axis ('X' = x-axis, 'Y' = y-axis) ** x-dim ** Default is to project everything onto x-axis */ char *p_p1, *p_p2, *p_p3, *p_p4, *p_p5, *p_p6, *p_p7; int i, status, axis; uint f_hist, n_hists, f_bin, n_bins; uint x_dim, h_slct, eff_nbins, eff_nhists; uint nbins_to_read, bytes_needed, total, cntr_lo, cntr_hi; uchar *p_byte; usint *p_word; uint *p_long; if (Rw_skt == 0) { Rw_skt = openConnectionGbl (Rmt_host, &Rmt_port, &Pkt_size, dbg_mode, &Rply_buff, Verbose); if (Rw_skt == 0) FailInet ("\ndo_project/openConnectionGbl error."); } split_args (args, &p_p1, &p_p2, &p_p3, &p_p4, /* Get pntrs to */ &p_p5, &p_p6, &p_p7, NULL); /* the 7 args */ if (p_p6 == NULL) { x_dim = 0; }else { if ((sscanf (p_p6, "%u", &x_dim) != 1) || (x_dim > Hm_nbins) || ((x_dim != 0) && ((Hm_nbins % x_dim) != 0))) { printf (" is invalid: \"%s\"\n", p_p6); printf (" must be an exact divisor of the number of bins " "per histogram, %d\n", Hm_nbins); return; } } eff_nbins = (x_dim == 0) ? Hm_nbins : x_dim; eff_nhists = (x_dim == 0) ? N_hists : (Hm_nbins/x_dim); if (p_p1 == NULL) p_p1 = "0"; if ((sscanf (p_p1, "%u", &f_hist) != 1) || (f_hist >= eff_nhists)) { printf ("<1st-hist> is invalid: \"%s\"\n", p_p1); printf ("It must be an integer in the range 0 to %d\n", (eff_nhists - 1)); return; } if (p_p2 == NULL) { n_hists = eff_nhists - f_hist; }else { if ((sscanf (p_p2, "%u", &n_hists) != 1) || (n_hists == 0) || (n_hists > eff_nhists) || ((n_hists + f_hist) > eff_nhists)) { printf ("<#-hists> is invalid: \"%s\"\n", p_p2); printf ("It must be an integer in the range 1 to %d\n", (eff_nhists - f_hist)); return; } } if (p_p3 == NULL) p_p3 = "0"; if ((sscanf (p_p3, "%u", &f_bin) != 1) || (f_bin >= eff_nbins)) { printf ("<1st-bin> is invalid: \"%s\"\n", p_p3); printf ("It must be an integer in the range 0 to %d\n", (eff_nbins - 1)); return; } if (p_p4 == NULL) { n_bins = eff_nbins - f_bin; }else { if ((sscanf (p_p4, "%u", &n_bins) != 1) || (n_bins > eff_nbins) || ((n_bins + f_bin) > eff_nbins)) { printf ("<#-bins> is invalid: \"%s\"\n", p_p4); printf ("It must be an integer in the range 1 to %d\n", (eff_nbins - f_bin)); return; } } if (p_p5 == NULL) { axis = 0; }else { if (strcmp ("x", p_p5) == 0) { axis = 0; }else if (strcmp ("y", p_p5) == 0) { axis = 1; }else if (sscanf (p_p4, "%u", &axis) == 1) { if (axis != 0) axis = 1; }else { printf (" is invalid: \"%s\"\n", p_p5); printf ("It should be \"x\" or \"y\"\n"); return; } } if (p_p7 == NULL) { h_slct = 0; }else { if ((sscanf (p_p7, "%u", &h_slct) != 1) || (h_slct > N_hists)) { printf (" is invalid: \"%s\"\n", p_p7); printf ("It must be an integer in the range 1 to %d\n", (N_hists - 1)); return; } } printf ("\n Read Projected Region of 2-dimensional histogram ...\n" " First histogram = %5u\n" " Number of histograms = %5u\n" " First bin = %5u\n" " Number of bins = %5u\n", f_hist, n_hists, f_bin, n_bins, axis); if (axis == 0) printf (" Axis = X\n"); if (axis != 0) printf (" Axis = Y\n"); if (x_dim != 0) printf (" x-dimension = %5u\n", x_dim); /* ** Allocate buffer space for holding the data. The space needed ** depends on whether it is an x- or y-projection. */ nbins_to_read = (axis == 0) ? n_bins : n_hists; bytes_needed = nbins_to_read * sizeof (uint); if (bytes_needed > Hm_buff_size) { /* Expand buffer space? */ Hm_buff_addr = realloc (Hm_buff_addr, bytes_needed); /* Yes */ if (Hm_buff_addr != NULL) { Hm_buff_size = bytes_needed; }else { printf ("SinqHM_Client -- " "error getting memory buffer for histogram data.\n"); exit (EXIT_FAILURE); } } Hm_buff_used = bytes_needed; status = read_project (Hm_buff_addr, Hm_buff_size, f_bin, n_bins, f_hist, n_hists, axis, x_dim, h_slct, &cntr_lo, &cntr_hi); if (status == EXIT_SUCCESS) { total = 0; switch (Bytes_per_bin) { case 1: p_byte = (uchar *) Hm_buff_addr; for (i = 0; i < nbins_to_read; i++) total += p_byte[i]; break; case 2: p_word = (usint *) Hm_buff_addr; for (i = 0; i < nbins_to_read; i++) total += p_word[i]; break; case 4: p_long = (uint *) Hm_buff_addr; for (i = 0; i < nbins_to_read; i++) total += p_long[i]; } printf (" Done! Total contents of bins = %d\n", total); if (cntr_lo != 0) printf (" Number of underflow events = %u\n", cntr_lo); if (cntr_hi != 0) printf (" Number of overflow events = %u\n", cntr_hi); if (axis == 0) { do_plot (f_bin, n_bins, Bytes_per_bin, total); }else { do_plot (f_hist, n_hists, Bytes_per_bin, total); } } } /* **----------------------------------------------------------------------------*/ void do_status (int dbg_mode) { /* ========= ** Get and display status of SinqHM_srv */ int i, status, secs, mins, hrs, days; int off_a, off_b, off_c, off_d, off_e, off_f; int off_g, off_h, off_i, off_j, off_k, off_l; uint state, nh, nb, bpb, span, ch, bytes_to_come; char recd[256], *p_buff, *p_nxt; uint tsi_status, tsi_flags, dt_or_dts, num_bad_ev; if (Rw_skt == 0) { Rw_skt = openConnectionGbl (Rmt_host, &Rmt_port, &Pkt_size, dbg_mode, &Rply_buff, Verbose); if (Rw_skt == 0) FailInet ("\ndo_status/openConnectionGbl error."); } printf ("\n Getting histogram memory identification ...\n"); /* ** Send the ident request message first */ Req_buff.bigend = htonl (0x12345678); Req_buff.cmnd = htonl (SQHM_IDENT); status = send (Rw_skt, (char *) &Req_buff, sizeof (Req_buff), 0); if (status == -1) FailInet ("do_status -- R/W-Socket send error\n"); if (status != sizeof (Req_buff)) { printf ("SinqHM_Client -- wrong number of bytes sent: %d", status); exit (EXIT_FAILURE); } /* ** Now get the server's ident message. */ status = recv (Rw_skt, (char *) &Rply_buff, sizeof (Rply_buff), 0); if (status == -1) { FailInet ("do_status -- R/W-Socket recv error\n"); exit (EXIT_FAILURE); }else if (status != sizeof (Rply_buff)) { printf ("do_status -- Cnct-Socket recv error - "); printf ("unexpected byte count: %d.\n", status); exit (EXIT_FAILURE); } if (ntohl (Rply_buff.bigend) != 0x12345678) { printf ( "SinqHM_Client -- big-endian/little-endian problem!\n" " Buffer received in non-network byte order!\n"); exit (EXIT_FAILURE); }else if (ntohl (Rply_buff.status) == KER__BAD_VALUE) { printf (" ... identification request not supported\n"); }else if (ntohl (Rply_buff.status) != KER__SUCCESS) { printf ("SinqHM_Client -- Bad status from Ident Request: %d.\n", ntohl (Rply_buff.status)); printf (" \"%s\"\n", Rply_buff.u.message); exit (EXIT_FAILURE); }else { /* ** Get the rest of the response */ bytes_to_come = ntohl (Rply_buff.u.ident.n_extra_bytes); p_buff = calloc (bytes_to_come, 1); if (p_buff == NULL) { printf ("Could not get buffer space for ident information\n"); exit (EXIT_FAILURE); } p_nxt = p_buff; while (bytes_to_come > 0) { i = (bytes_to_come > Pkt_size) ? Pkt_size : bytes_to_come; status = recv (Rw_skt, p_nxt, i, 0); Rw_bytes_got += status; if (status == -1) FailInet ("do_status -- R/W-Socket data recv error\n"); bytes_to_come -= status; p_nxt += status; } /* ** Extract and print the information */ off_a = ntohs (Rply_buff.u.ident.offset_vxWorks_ident); off_b = ntohs (Rply_buff.u.ident.offset_vxWorks_date); off_c = ntohs (Rply_buff.u.ident.offset_instr); off_d = ntohs (Rply_buff.u.ident.offset_def_ident); off_e = ntohs (Rply_buff.u.ident.offset_sinqhm_main_ident); off_f = ntohs (Rply_buff.u.ident.offset_sinqhm_main_date); off_g = ntohs (Rply_buff.u.ident.offset_sinqhm_server_ident); off_h = ntohs (Rply_buff.u.ident.offset_sinqhm_server_date); off_i = ntohs (Rply_buff.u.ident.offset_sinqhm_filler_ident); off_j = ntohs (Rply_buff.u.ident.offset_sinqhm_filler_date); off_k = ntohs (Rply_buff.u.ident.offset_sinqhm_routines_ident); off_l = ntohs (Rply_buff.u.ident.offset_sinqhm_routines_date); i = strlen (&p_buff[off_b]) + 1; StrEdit (&p_buff[off_b], &p_buff[off_b], "compress trim", &i); i = strlen (&p_buff[off_f]) + 1; StrEdit (&p_buff[off_f], &p_buff[off_f], "compress trim", &i); i = strlen (&p_buff[off_h]) + 1; StrEdit (&p_buff[off_h], &p_buff[off_h], "compress trim", &i); i = strlen (&p_buff[off_j]) + 1; StrEdit (&p_buff[off_j], &p_buff[off_j], "compress trim", &i); i = strlen (&p_buff[off_l]) + 1; StrEdit (&p_buff[off_l], &p_buff[off_l], "compress trim", &i); printf (" Instrument = %s, SinqHM Protocol Identifier = %s\n", &p_buff[off_c], &p_buff[off_d]); printf (" SinqHM_srv_main Identifier %s compiled on %s\n", &p_buff[off_e], &p_buff[off_f]); printf (" SinqHM_srv_server Identifier %s compiled on %s\n", &p_buff[off_g], &p_buff[off_h]); printf (" SinqHM_srv_filler Identifier %s compiled on %s\n", &p_buff[off_i], &p_buff[off_j]); printf (" SinqHM_srv_routines Identifier %s compiled on %s\n", &p_buff[off_k], &p_buff[off_l]); printf (" vxWorks Version %s created on %s\n", &p_buff[off_a], &p_buff[off_b]); print_uptime (stdout, " Up-time = ", ntohl (Rply_buff.u.ident.up_time), "\n"); free (p_buff); } /*----------------------------------------------------------------------------*/ printf ("\n Getting histogram memory status ...\n"); /* ** Send the request message first */ Req_buff.bigend = htonl (0x12345678); Req_buff.cmnd = htonl (SQHM_STATUS); status = send (Rw_skt, (char *) &Req_buff, sizeof (Req_buff), 0); if (status == -1) FailInet ("do_status -- R/W-Socket send error\n"); if (status != sizeof (Req_buff)) { printf ("SinqHM_Client -- wrong number of bytes sent: %d", status); exit (EXIT_FAILURE); } /* ** Now get the server's status message. */ status = recv (Rw_skt, (char *) &Rply_buff, sizeof (Rply_buff), 0); if (status == -1) { FailInet ("do_status -- R/W-Socket recv error\n"); exit (EXIT_FAILURE); }else if (status != sizeof (Rply_buff)) { printf ("do_status -- Cnct-Socket recv error - "); printf ("unexpected byte count: %d.\n", status); exit (EXIT_FAILURE); } if (ntohl (Rply_buff.bigend) != 0x12345678) { printf ( "SinqHM_Client -- big-endian/little-endian problem!\n" " Buffer received in non-network byte order!\n"); exit (EXIT_FAILURE); }else if (ntohl (Rply_buff.status) != KER__SUCCESS) { printf ("SinqHM_Client -- Bad status from Status Request: %d.\n", ntohl (Rply_buff.status)); printf (" \"%s\"\n", Rply_buff.u.message); exit (EXIT_FAILURE); }else { /* ** Display the status obtained. */ printf (" Maximum number of connections = %6d\n", Rply_buff.u.status.max_srvrs); printf (" Maximum number of histograms = %6d\n", ntohl (Rply_buff.u.status.max_n_hists)); printf (" Maximum number of bins per histogram = %6d\n", ntohl (Rply_buff.u.status.max_num_bins)); if (Rply_buff.u.status.cfg_state == 0) { printf (" Space available for histograms = %6d\n\n", ntohl (Rply_buff.u.status.max_block)); }else { printf (" Free buffer space available = %6d\n\n", ntohl (Rply_buff.u.status.max_block)); } if (Rply_buff.u.status.cfg_state == 0) { printf (" SINQHM has not yet been configured.\n"); }else { state = ntohl (Rply_buff.u.status.cfg_state); nh = ntohs (Rply_buff.u.status.n_hists); ch = ntohs (Rply_buff.u.status.curr_hist); nb = ntohl (Rply_buff.u.status.num_bins); bpb = Rply_buff.u.status.bytes_per_bin; span = Rply_buff.u.status.compress; if ((Hm_mode & (~SQHM__SUB_MODE_MSK)) != (state & (~SQHM__SUB_MODE_MSK))) new_config_quit ("hm_mode/cfg_state"); if (N_hists != nh) new_config_quit ("n_hists"); if (Hm_nbins != nb) new_config_quit ("num_bins"); if (Bytes_per_bin != bpb) new_config_quit ("bytes_per_bin"); print_HM_mode (state, 10); if (nh != 1) printf (" Number of histograms = %6d\n", nh); if (ch != 0) printf (" Current histogram = %6d\n", ch); printf (" Number of bins per histogram = %6d\n", nb); if (nh > 1) printf (" Total number of bins = %6d\n", nh * nb); if (span > 1) printf (" Bin span = %6d\n", span); printf (" Number of bytes per bin = %6d\n", bpb); printf (" Number of active connections = %6d\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"); } 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 (dt_or_dts != 0) { if ((Hm_mode & (~SQHM__SUB_MODE_MSK)) == SQHM__TOF) { printf (" Delay-Time-to-Start = %6u\n", dt_or_dts); }else { printf (" Dead-Time = %6u\n", dt_or_dts); } } if (num_bad_ev != 0) { printf (" Number-of-Bad-Events = %u\n", num_bad_ev); } if ((tsi_status != 0) || (tsi_flags != 0)) { printf (" TSI Status Info = 0x%04x\n", tsi_status); 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"); } } } } /* **----------------------------------------------------------------------------*/ void do_1d (char *args, int dbg_mode) { /* ===== ** Generate a 1-dim plot ** Args are: ** Number of first bin (dflt = 0) ** Number of bins (dflt = rest of histogram) ** Number of histogram (dflt = -1) ** Default is to plot everything. */ int i, status; uint f_bin, n_bins, hist_num; uint cntr_lo, cntr_hi; uint total; char *p_p1, *p_p2, *p_p3; unsigned char *p_byte; unsigned short int *p_word; unsigned int *p_long; if (Rw_skt == 0) { Rw_skt = openConnectionGbl (Rmt_host, &Rmt_port, &Pkt_size, dbg_mode, &Rply_buff, Verbose); if (Rw_skt == 0) FailInet ("\ndo_1d/openConnectionGbl error."); } split_args (args, &p_p1, &p_p2, &p_p3, NULL); if (p_p1 == NULL) p_p1 = "0"; if (sscanf (p_p1, "%u", &f_bin) != 1) { printf ("<1st-bin> is invalid: \"%s\"\n", p_p1); return; } if (p_p3 == NULL) p_p3 = "-1"; if ((sscanf (p_p3, "%u", &hist_num) != 1) || ((hist_num != -1) && (hist_num >= N_hists))) { printf (" is invalid: \"%s\"\n", p_p3); printf ("There are %d histograms defined.\n", N_hists); return; } if (((hist_num != -1) && (f_bin >= Hm_nbins)) || (f_bin >= (N_hists * Hm_nbins))) { printf ("<1st-bin> is invalid: \"%s\"\n", p_p1); printf ("The number of bins is %d\n", (hist_num == -1) ? (N_hists * Hm_nbins) : Hm_nbins); return; } if (p_p2 != NULL) { if ((sscanf (p_p2, "%d", &n_bins) != 1) || ((hist_num != -1) && ((f_bin + n_bins) > Hm_nbins)) || ((f_bin + n_bins) >= (N_hists * Hm_nbins))) { printf ("<#-bins> is invalid: \"%s\"\n", p_p2); n_bins = (hist_num == -1) ? (N_hists * Hm_nbins) : Hm_nbins; n_bins = n_bins - f_bin; printf ("The value has been set to %d.\n", n_bins); } }else { n_bins = (hist_num == -1) ? (N_hists * Hm_nbins) : Hm_nbins; n_bins = n_bins - f_bin; } printf (" Read histogram memory ...\n" " First bin = %5d\n" " Number of bins = %5d\n" " Histogram number = %5d\n", f_bin, n_bins, hist_num); /* ** Allocate buffer space for holding the data. */ if ((n_bins * Bytes_per_bin) > Hm_buff_size) { /* Expand buffer space? */ Hm_buff_addr = realloc (Hm_buff_addr, (n_bins * Bytes_per_bin)); /* Yes */ if (Hm_buff_addr != NULL) { Hm_buff_size = n_bins * Bytes_per_bin; }else { printf ("SinqHM_Client -- " "error getting memory buffer for histogram data.\n"); exit (EXIT_FAILURE); } } Hm_buff_used = n_bins * Bytes_per_bin; status = read_hm (Hm_buff_addr, Hm_buff_size, f_bin, n_bins, hist_num, &cntr_lo, &cntr_hi); if (status == EXIT_SUCCESS) { total = 0; switch (Bytes_per_bin) { case 1: p_byte = (uchar *) Hm_buff_addr; for (i=0; i < n_bins; i++) total += p_byte[i]; break; case 2: p_word = (usint *) Hm_buff_addr; for (i=0; i < n_bins; i++) total += p_word[i]; break; case 4: p_long = (uint *) Hm_buff_addr; for (i=0; i < n_bins; i++) total += p_long[i]; break; } printf (" Done! Total contents of bins = %d\n", total); if (cntr_lo != 0) printf (" Number of underflow events = %u\n", cntr_lo); if (cntr_hi != 0) printf (" Number of overflow events = %u\n", cntr_hi); do_plot (f_bin, n_bins, Bytes_per_bin, total); } } /* **----------------------------------------------------------------------------*/ void do_2d (char *args, int dbg_mode) { /* ===== ** Generate a 2-dim plot (e.g. of TOF array of counters ** Args are: ** Number of first histogram ** Number of histograms ** Number of first bin ** Number of bins ** Default is to plot everything. */ char *p_p1, *p_p2, *p_p3, *p_p4; int i, status; uint f_hist, n_hists, f_bin, n_bins; uint bytes_needed, total, cntr_lo, cntr_hi; uchar *p_byte; usint *p_word; uint *p_long; if (Rw_skt == 0) { Rw_skt = openConnectionGbl (Rmt_host, &Rmt_port, &Pkt_size, dbg_mode, &Rply_buff, Verbose); if (Rw_skt == 0) FailInet ("\ndo_2d/openConnectionGbl error."); } split_args (args, &p_p1, &p_p2, &p_p3, &p_p4, NULL); /* Get pointers to ** the 4 args */ if (p_p1 == NULL) p_p1 = "0"; if ((sscanf (p_p1, "%u", &f_hist) != 1) || (f_hist >= N_hists)) { printf ("<1st-hist> is invalid: \"%s\"\n", p_p1); printf ("There are %d histograms defined.\n", N_hists); return; } if (p_p2 == NULL) { n_hists = N_hists - f_hist; }else { if ((sscanf (p_p2, "%u", &n_hists) != 1) || (n_hists > N_hists) || ((n_hists + f_hist) > N_hists)) { printf ("<#-hists> is invalid: \"%s\"\n", p_p2); printf ("There are %d histograms defined.\n", N_hists); return; } } if (p_p3 == NULL) p_p3 = "0"; if ((sscanf (p_p3, "%u", &f_bin) != 1) || (f_bin >= Hm_nbins)) { printf ("<1st-bin> is invalid: \"%s\"\n", p_p3); printf ("The number of bins is %d\n", Hm_nbins); return; } if (p_p4 == NULL) { n_bins = Hm_nbins - f_bin; }else { if ((sscanf (p_p4, "%u", &n_bins) != 1) || (n_bins > Hm_nbins) || ((n_bins + f_bin) > Hm_nbins)) { printf ("<#-bins> is invalid: \"%s\"\n", p_p4); printf ("The number of bins is %d\n", Hm_nbins); return; } } printf ("\n Read 2-dimensional histogram memory ...\n" " First histogram = %5u\n" " Number of histograms = %5u\n" " First bin = %5u\n" " Number of bins = %5u\n", f_hist, n_hists, f_bin, n_bins); /* ** Allocate buffer space for holding the data. Note that the ** data in the Hist Mem is stored as a 1-dim array with ** the bins of each histogram contiguous. It is usually ** more efficient (at least, it is easier to program) to ** transfer over complete histograms if we need to pick out ** a sub-range of bins. */ bytes_needed = n_hists * Hm_nbins * Bytes_per_bin; if (bytes_needed > Hm_buff_size) { /* Expand buffer space? */ Hm_buff_addr = realloc (Hm_buff_addr, bytes_needed); /* Yes */ if (Hm_buff_addr != NULL) { Hm_buff_size = bytes_needed; }else { printf ("SinqHM_Client -- " "error getting memory buffer for histogram data.\n"); exit (EXIT_FAILURE); } } Hm_buff_used = bytes_needed; status = read_hm (Hm_buff_addr, Hm_buff_size, (f_hist * Hm_nbins), (n_hists * Hm_nbins), -1, &cntr_lo, &cntr_hi); if (status == EXIT_SUCCESS) { total = 0; switch (Bytes_per_bin) { case 1: p_byte = (uchar *) Hm_buff_addr; for (i=0; i<(n_hists * Hm_nbins); i++) total += p_byte[i]; break; case 2: p_word = (usint *) Hm_buff_addr; for (i=0; i<(n_hists * Hm_nbins); i++) total += p_word[i]; break; case 4: p_long = (uint *) Hm_buff_addr; for (i=0; i<(n_hists * Hm_nbins); i++) total += p_long[i]; } printf (" Done! Total contents of bins = %d\n", total); if (cntr_lo != 0) printf (" Number of underflow events = %u\n", cntr_lo); if (cntr_hi != 0) printf (" Number of overflow events = %u\n", cntr_hi); do_2d_plot (f_hist, n_hists, f_bin, n_bins, Bytes_per_bin, total); } } /* **----------------------------------------------------------------------------*/ void do_2d_plot ( /* ========== ** Make a 2-dimensional plot of the data. */ uint f_hist, uint n_hists, uint f_bin, uint n_bins, uint bytes_per_bin, uint total) { int i, t_bins, ix1, ix2, iy1, iy2, ioff; int nx = 1; int ny = 1; char total_txt[21]; #ifdef LINUX char dev[] = "/XSERV"; #else char dev[] = "/XW"; #endif char xlab[] = "Bins"; char ylab[] = "Counts"; float xlo, xhi, yhi, bias; float *data; float *x, *ylims; uchar *p_byte; usint *p_word; uint *p_long; if ((n_hists == 0) || (n_bins == 0) || (total == 0)) { printf ("Nothing to plot!\n"); return; } p_byte = (uchar *) Hm_buff_addr; p_word = (usint *) Hm_buff_addr; p_long = (uint *) Hm_buff_addr; t_bins = n_hists * Hm_nbins; data = (float *) malloc (t_bins * sizeof (float)); if (data == NULL) { printf ("Cannot get plot memory for 2-dim array\n"); return; } x = (float *) malloc ((n_bins + 1) * sizeof (float)); if (x == NULL) { printf ("Cannot get plot memory for x-array\n"); return; } ylims = (float *) malloc ((n_bins + 1) * sizeof (float)); if (x == NULL) { printf ("Cannot get workspace memory for 2-dim plot\n"); return; } switch (bytes_per_bin) { case 1: for (i = 0; i < t_bins; i++) data[i] = p_byte[i]; break; case 2: for (i = 0; i < t_bins; i++) data[i] = p_word[i]; break; case 4: for (i = 0; i < t_bins; i++) data[i] = p_long[i]; break; } yhi = 10.0; for (i = 0; i < t_bins; i++) if (data[i] > yhi) yhi = data[i]; yhi = yhi * 1.3; yhi = cpgrnd (yhi, &i); ioff = 1; for (i = 0; i <= n_bins; i++) x[i] = (float) (f_bin + i); xlo = (float) f_bin; xhi = (float) f_bin + n_bins + 1 + (n_hists * ioff); ix1 = 1; ix2 = n_hists; iy1 = f_bin + 1; iy2 = f_bin + n_bins; bias = yhi * 0.0001; sprintf (total_txt, "Bin Total = %8d", total); if (PGPLOT_started == 0) { cpgbeg (0, dev, 1, 1); /* - - - - - - - - - - - - - - - - - - - - - - ** Set black on white (hopefully) */ cpgscr (0, 0.79, 0.67, 0.57); cpgscr (1, 0.0, 0.0, 0.0); cpgask (0); PGPLOT_started = 1; } cpgenv (xlo, xhi, 0.0, yhi, 0, 0); cpglab (xlab, ylab, total_txt); cpghi2d (data, n_hists, Hm_nbins, ix1, ix2, iy1, iy2, x, ioff, bias, False, ylims); free (data); free (x); free (ylims); } /* **--------------------------------------------------------------------------*/ void exit_handler () { /* ============ ** We must exit. Tidy up first. ** Close TCP/IP link to front-end. */ int status; /* ** Tell server we're quitting. */ if (Rw_skt != 0) { printf ("Closing connection to %s ...\n", Rmt_host); Req_buff.bigend = htonl (0x12345678); Req_buff.cmnd = htonl (SQHM_CLOSE); status = send (Rw_skt, (char *) &Req_buff, sizeof (Req_buff), 0); Rw_bytes_put += status; if (status == -1) FailInet ("exit_handler -- R/W-Socket send error\n"); if (status != sizeof (Req_buff)) { printf ("EXIT_HANDLER -- wrong number of bytes sent: %d", status); exit (EXIT_FAILURE); } status = close (Rw_skt); Rw_skt = 0; if (status != 0) FailInet ("exit_handler -- R/W-Socket close error\n"); } } /* **--------------------------------------------------------------------------*/ void gen_data (char *args) { /* ======== ** Generate sum of 2 Lorenzians. */ int i, j, nbins; char *p_p1, *p_p2, *p_p3, *p_p4, *p_p5, *p_p6; float p1, p2, p3, p4, p5, p6; float ff, fact_1, fact_2; char *p_byte; short int *p_word; int *p_long; /* ** Allocate buffer space for holding the data. */ nbins = Hm_nbins * N_hists; if ((nbins * Bytes_per_bin) > Hm_buff_size) { /* Expand buffer space? */ Hm_buff_addr = realloc (Hm_buff_addr, (nbins * Bytes_per_bin)); /* Yes */ if (Hm_buff_addr != NULL) { Hm_buff_size = nbins * Bytes_per_bin; }else { printf ("SinqHM_Client -- " "error getting memory buffer for histogram data.\n"); exit (EXIT_FAILURE); } } Hm_buff_used = nbins * Bytes_per_bin; /* ** Parse the arguments */ split_args (args, &p_p1, &p_p2, &p_p3, &p_p4, &p_p5, &p_p6, NULL); if ((p_p1 != NULL) && (sscanf (p_p1, "%f", &p1) == 1)) P1 = p1; if ((p_p2 != NULL) && (sscanf (p_p2, "%f", &p2) == 1)) P2 = p2; if ((p_p3 != NULL) && (sscanf (p_p3, "%f", &p3) == 1)) P3 = p3; if ((p_p4 != NULL) && (sscanf (p_p4, "%f", &p4) == 1)) P4 = p4; if ((p_p5 != NULL) && (sscanf (p_p5, "%f", &p5) == 1)) P5 = p5; if ((p_p6 != NULL) && (sscanf (p_p6, "%f", &p6) == 1)) P6 = p6; if (P2 <= 0) P2 = 1000; if (P5 <= 0) P5 = 1000; if (P3 <= 0) P3 = ((float) Hm_nbins) * 0.25; if (P6 <= 0) P6 = ((float) Hm_nbins) * 0.60; p_byte = (char *) Hm_buff_addr; p_word = (short int *) Hm_buff_addr; p_long = (int *) Hm_buff_addr; for (j = 0; j < N_hists; j++) { /* Calculate sum of 2 Lorenzians */ fact_1 = 0.5 + (float) (j)/(float) (N_hists); fact_2 = 2.0 - fact_1; for (i = 0; i < Hm_nbins; i++) { p1 = ((float) i) - P3; /* First Lorenzian */ p1 = p1 * p1; p2 = P1/(P2 + p1); p2 *= fact_1; p3 = ((float) i) - P6; /* Second Lorenzian */ p3 = p3 * p3; p4 = P4/(P5 + p3); p4 *= fact_2; ff = p2 + p4; switch (Bytes_per_bin) { case 1: *p_byte++ = (char) ff; break; case 2: *p_word++ = (short int) ff; break; case 4: *p_long++ = (int) ff; break; } } } } /* **--------------------------------------------------------------------------*/ void gen_data_2d (char *args) { /* =========== ** Same as gen_data, i.e. generate sum of 2 ** Lorenzians, but suitable for pseudo 2-dim mode. ** The first arg is the number of sub-histograms. */ char *p_nhis, *p_p1, *p_p2, *p_p3, *p_p4, *p_p5, *p_p6; int i, j, totbins, nhis, nbins; float p1, p2, p3, p4, p5, p6; float ff, fact_1, fact_2; char *p_byte; short int *p_word; int *p_long; /* ** Allocate buffer space for holding the data. */ totbins = Hm_nbins * N_hists; if ((totbins * Bytes_per_bin) > Hm_buff_size) { /* Expand buffer space? */ Hm_buff_addr = realloc (Hm_buff_addr, (totbins * Bytes_per_bin)); /* Yes */ if (Hm_buff_addr != NULL) { Hm_buff_size = totbins * Bytes_per_bin; }else { printf ("SinqHM_Client -- " "error getting memory buffer for histogram data.\n"); exit (EXIT_FAILURE); } } Hm_buff_used = totbins * Bytes_per_bin; /* ** Parse the arguments */ split_args (args, &p_nhis, &p_p1, &p_p2, &p_p3, &p_p4, &p_p5, &p_p6, NULL); if (p_nhis != NULL) { i = sscanf (p_nhis, "%i", &nhis); if ((i != 1) || ((totbins % nhis) != 0)) { if (i != 1) printf ("<#-hists> is invalid. It must be an integer!\n"); if (i == 1) printf ("<#-hists> is invalid. It must be a factor" " of the total number of bins!\n"); printf ("<#-hists> is \"%s\", total number of bins = %d\n", p_nhis, totbins); printf ("<#-hists> set to 1\n"); nhis = 1; } }else { nhis = 1; } nbins = totbins/nhis; if ((p_p1 != NULL) && (sscanf (p_p1, "%f", &p1) == 1)) P1 = p1; if ((p_p2 != NULL) && (sscanf (p_p2, "%f", &p2) == 1)) P2 = p2; if ((p_p3 != NULL) && (sscanf (p_p3, "%f", &p3) == 1)) P3 = p3; if ((p_p4 != NULL) && (sscanf (p_p4, "%f", &p4) == 1)) P4 = p4; if ((p_p5 != NULL) && (sscanf (p_p5, "%f", &p5) == 1)) P5 = p5; if ((p_p6 != NULL) && (sscanf (p_p6, "%f", &p6) == 1)) P6 = p6; if (P2 <= 0) P2 = 1000; if (P5 <= 0) P5 = 1000; if (P3 <= 0) P3 = ((float) nbins) * 0.25; if (P6 <= 0) P6 = ((float) nbins) * 0.60; p_byte = (char *) Hm_buff_addr; p_word = (short int *) Hm_buff_addr; p_long = (int *) Hm_buff_addr; for (j = 0; j < nhis; j++) { /* Calculate sum of 2 Lorenzians */ fact_1 = 0.5 + (float) (j)/(float) (nhis); fact_2 = 2.0 - fact_1; for (i = 0; i < nbins; i++) { p1 = ((float) i) - P3; /* First Lorenzian */ p1 = p1 * p1; p2 = P1/(P2 + p1); p2 *= fact_1; p3 = ((float) i) - P6; /* Second Lorenzian */ p3 = p3 * p3; p4 = P4/(P5 + p3); p4 *= fact_2; ff = p2 + p4; switch (Bytes_per_bin) { case 1: *p_byte++ = (char) ff; break; case 2: *p_word++ = (short int) ff; break; case 4: *p_long++ = (int) ff; break; } } } } /* **--------------------------------------------------------------------------- ** 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, do_help; char buff[80]; char *type; XrmValue value; time_t time_now; float tmp_secs; /*---------------------------------------------------------- -help */ status = XrmGetResource (*db, StrJoin (buff, sizeof (buff), appName, ".sqhmHelp"), "ProgramName.Values", &type, &value); do_help = (status) ? True : False; if (do_help) { show_help (NULL); exit (EXIT_SUCCESS); } /*---------------------------------------------------------- -? */ status = XrmGetResource (*db, StrJoin (buff, sizeof (buff), appName, ".sqhmHelpItem"), "ProgramName.Values", &type, &value); do_help = (status) ? True : False; if (do_help) { len = sizeof (buff); StrEdit (buff, value.addr, "trim lowercase", &len); show_help (buff); exit (EXIT_SUCCESS); } /*---------------------------------------------------------- -verbose */ 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); 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); /*---------------------------------------------------------- -pktsize */ 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); /*---------------------------------------------------------- -debug */ status = XrmGetResource (*db, StrJoin (buff, sizeof (buff), appName, ".sqhmDebug"), "ProgramName.Values", &type, &value); Dbg_mode = (status) ? 1 : 0; /*----------------------------------------------------------*/ return True; } /* **----------------------------------------------------------------------------*/ int get_recd (FILE *lun, char *recd, int recd_len) { /* ======== ** Get a non-comment record from a file */ int nbytes = -1; while (nbytes <= 0) { if (fgets (recd, (recd_len - 1), lun) == NULL) return False; nbytes = recd_len; StrEdit (recd, recd, "trim compress uncomment", &nbytes); } return True; } /* **--------------------------------------------------------------------------*/ void new_config_quit ( /* =============== ** Quit because SinqHM config'n has changed. ** */ char *txt) { printf ("\n" " It looks as though the configuration of SinqHM has been changed\n" " whilst we were not looking. This should not be possible!\n" " Please report the incident.\n" " The item which has changed is \"%s\".\n\n", txt); exit (EXIT_FAILURE); } /* **--------------------------------------------------------------------------*/ int openConnection ( /* ============== ** Open connection to histogram memory front-end. ** Return value is socket id for communication with server. ** On successful connection, the SQHM_CNCT status reply ** is returned in . */ char *node, int *port, /* <== this arg gets modified! */ int *pkt_size, /* <== this arg gets modified! */ int mode, struct rply_buff_struct *reply, /* <== this arg gets modified! */ int verbose) { int i, status; int my_skt = 0; 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; /* ** Get Internet address of the front-end. */ for (i=0; i < strlen (node); i++) node[i] = tolower (node[i]); rmt_hostent = gethostbyname (node); if (rmt_hostent == NULL) { /* ** The following code is to handle nodes which are not yet ** in the BIND data base. */ if (strcmp (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", node); FailInet ("\nopenConnection/Gethostbyname error."); } }else { rmt_inet_addr_pntr = (struct in_addr *) rmt_hostent->h_addr_list[0]; } printf (" SinqHM Server is %s ", rmt_hostent->h_name); printf ("(%s),", inet_ntoa (*rmt_inet_addr_pntr)); printf (" Base port %d\n", *port); /* ** Create a TCP/IP socket for prelim. connect to server and bind it. */ Cnct_skt = socket (AF_INET, SOCK_STREAM, 0); if (Cnct_skt == -1) FailInet ("openConnection -- Cnct_skt socket error.\n"); 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 ("openConnection -- Cnct_skt bind error.\n"); /* **========================================= Now connect to the server. */ rmt_sockname_len = sizeof (rmt_sockname); rmt_sockname.sin_family = AF_INET; rmt_sockname.sin_port = htons (*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 ("openConnection -- connect error\n"); } /* **============================== Set up and send a connection request message. */ Req_buff.bigend = htonl (0x12345678); Req_buff.cmnd = htonl (SQHM_CNCT); Req_buff.u.cnct.max_pkt = htonl (*pkt_size); Req_buff.u.cnct.strt_mode = htonl (mode); if (mode != 0) { printf (" Warning -- mode = %d\n", mode); printf (" Use the debugger in the Hist Mem to get our server to run.\n"); } status = send (Cnct_skt, (char *) &Req_buff, sizeof (Req_buff), 0); if (status == -1) FailInet ("openConnection -- Cnct-Socket send error\n"); if (status != sizeof (Req_buff)) { printf ("SinqHM_Client -- wrong number of bytes sent: %d\n", status); exit (EXIT_FAILURE); } /* ** Wait for the response telling us the port to use. */ status = recv (Cnct_skt, (char *) &Rply_buff, sizeof (Rply_buff), 0); if (status == -1) { FailInet ("openConnection -- Cnct-Socket recv error\n"); }else if (status != sizeof (Rply_buff)) { printf ("SinqHM_Client -- Cnct-Socket recv error - "); printf ("unexpected byte count: %d.\n", status); exit (EXIT_FAILURE); } if (ntohl (reply->bigend) != 0x12345678) { printf ( "SinqHM_Client -- big-endian/little-endian problem!\n" " Buffer received in non-network byte order!\n"); exit (EXIT_FAILURE); } status = ntohl (reply->status); if (status != KER__SUCCESS) { if (status == KER__BAD_STATE) { printf (" SinqHM_Client -- Histogram memory has not yet been " "configured!\n"); print_uptime (stdout, " Up-time = ", ntohl (reply->u.cnct.up_time), "\n"); }else if (status == KER__BAD_CREATE) { status = ntohl (reply->sub_status); printf ( "SinqHM_Client -- creation of histogram memory server process " "failed!\n" " Sub-status = "); switch (status) { case -1: printf ("%d. Spawn failed.\n", status); break; case -2: printf ("%d. No more ports available.\n", status); break; case -3: printf ("%d. Time-out.\n", status); break; case -4: printf ("%d. Child process detected a problem " "during startup.\n", status); break; default: printf ("%d. Undefined. Refer to the source code!\n", status); } }else { printf ("SinqHM_Client -- Bad and unrecognised status from Connect " "Request: %d.\n", status); } exit (EXIT_FAILURE); } status = close (Cnct_skt); Cnct_skt = 0; if (status != 0) FailInet ("openConnection -- Cnct-Socket close error\n"); *port = ntohl (reply->u.cnct.port); if (verbose) printf (" Server port to use = %6d\n", *port); *pkt_size = ntohl (reply->u.cnct.pkt_size); if (verbose) printf (" Agreed packet size = %6d\n", *pkt_size); /* ** Now create, bind and connect a TCP/IP socket to our remote server port. */ my_skt = socket (AF_INET, SOCK_STREAM, 0); if (my_skt == -1) { FailInet ("openConnection -- Srvr-Skt socket error.\n"); 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) { FailInet ("openConnection -- Srvr-Skt bind error.\n"); return 0; } rmt_sockname_len = sizeof (rmt_sockname); rmt_sockname.sin_family = AF_INET; rmt_sockname.sin_port = htons (*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 == -1) { GetErrno (&My_errno, &My_vaxc_errno); FailInet ("openConnection -- Srvr-Skt connect error\n"); return 0; } Rw_bytes_got = 0; Rw_bytes_put = 0; return my_skt; } /* **--------------------------------------------------------------------------*/ int openConnectionGbl ( /* ================= ** Call openConnection then set up some global variables. * Return value is socket id for communication with server. */ char *node, int *port, /* <== this arg gets modified! */ int *pkt_size, /* <== this arg gets modified! */ int mode, struct rply_buff_struct *reply, /* <== this arg gets modified! */ int verbose) { int my_skt = 0; my_skt = openConnection (node, port, pkt_size, mode, reply, verbose); if (my_skt == 0) return my_skt; Hm_mode = ntohl (Rply_buff.u.cnct.hm_mode); if (verbose) print_HM_mode (Hm_mode, 10); N_hists = ntohl (Rply_buff.u.cnct.n_hists); if (verbose && (N_hists != 1)) printf (" Number of histograms = %6d\n", N_hists); Hm_nbins = ntohl (Rply_buff.u.cnct.num_bins); if (verbose) printf (" Number of bins per histogram = %6d\n", Hm_nbins); Compress = ntohl (Rply_buff.u.cnct.compress); if ((verbose) && (Compress > 1)) printf (" Bin span = %6d\n", Compress); if (verbose && (N_hists > 1)) printf (" Total number of bins = %6d\n", N_hists * Hm_nbins); Bytes_per_bin = ntohl (Rply_buff.u.cnct.bytes_per_bin); if (verbose) printf (" Number of bytes per bin = %6d\n", Bytes_per_bin); Lo_cntr = ntohl (Rply_buff.u.cnct.lo_cntr); if (verbose && (Lo_cntr != 0)) printf (" Low counter number = %6d\n", Lo_cntr); Lo_bin = ntohl (Rply_buff.u.cnct.lo_bin); if (verbose && (Lo_bin != 0)) printf (" Low counter number = %6d\n", Lo_bin); Curr_hist = ntohl (Rply_buff.u.cnct.curr_hist); if (verbose && (Curr_hist != 0)) printf (" Current histogram = %6d\n", Curr_hist); Total_bytes = ntohl (Rply_buff.u.cnct.total_bytes); if (verbose) printf (" Histogram buffer size = %6d bytes\n", Total_bytes); Max_block = ntohl (Rply_buff.u.cnct.max_block); if (verbose) printf (" Free memory space available = %6d bytes\n", Max_block); return my_skt; } /* **-------------------------------------------------------------------------- */ void print_HM_mode ( /* ============= ** Interpret the HM configuration. ** */ uint mode, /* The configuration to be interpreted */ int n_pad) { /* A padding count to move the "=" */ uint my_mode; printf (" Histogramming Mode%*s = 0x%x", n_pad, "", mode); my_mode = mode & (~SQHM__SUB_MODE_MSK); if (my_mode == SQHM__TRANS) printf (" TRANS"); if (my_mode == SQHM__HM_DIG) printf (" HM_DIG"); if (my_mode == SQHM__TOF) printf (" TOF"); if (my_mode == SQHM__HM_PSD) printf (" HM_PSD"); if (my_mode == SQHM__HRPT) printf (" 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"); printf (" Bin Overflow Mode %*s = ", n_pad, ""); 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); } } /* **--------------------------------------------------------------------------*/ int read_hm ( /* ======= ** Read block of bins from SINQHM_SRV */ char *hbuf, /* Buffer to hold data */ uint hbuf_size, /* Size of hbuf */ uint f_bin, /* First bin to read */ uint n_bins, /* Number of bins to read */ uint hist_no, /* Histogram number to read */ uint *cntr_lo, /* # events below histo range */ uint *cntr_hi) { /* # events above histo range */ /* ** Send SQHM_READ request to server to read n_bins hist mem bins ** starting at bin f_bin. On return, the data is in the buffer ** pointed to by Hm_buff_addr. */ int status, is, i; int bytes_to_come; uint my_n_bins, my_bytes_per_bin; uchar *nxt_byte; usint *nxt_word; uint *nxt_long; bytes_to_come = n_bins * Bytes_per_bin; if (bytes_to_come > hbuf_size) { printf ("read_hm: buffer is too small!\n" " It is %d rather than %d bytes long.\n", hbuf_size, bytes_to_come); return EXIT_FAILURE; } status = EXIT_SUCCESS; /* Assume success. */ Req_buff.bigend = htonl (0x12345678); Req_buff.cmnd = htonl (SQHM_READ); Req_buff.u.read.n_bins = htonl (n_bins); Req_buff.u.read.first_bin = htonl (f_bin); Req_buff.u.read.hist_no = htonl (hist_no); status = send (Rw_skt, (char *) &Req_buff, sizeof (Req_buff), 0); Rw_bytes_put += status; if (status == -1) FailInet ("read_hm -- R/W-Socket send error\n"); if (status != sizeof (Req_buff)) { printf ("read_hm: wrong number of bytes sent: %d", status); return EXIT_FAILURE; } /* ** Wait for the status response. */ status = recv (Rw_skt, (char *) &Rply_buff, sizeof (Rply_buff), 0); Rw_bytes_got += status; if (status == -1) { FailInet ("read_hm -- R/W-Socket recv error\n"); }else if (status != sizeof (Rply_buff)) { printf ("read_hm: R/W-Socket recv error - "); printf ("unexpected byte count: %d.\n", status); return EXIT_FAILURE; } if (ntohl (Rply_buff.bigend) != 0x12345678) { printf ( "read_hm: big-endian/little-endian problem!\n" " Buffer received in non-network byte order!\n"); return EXIT_FAILURE; } if (ntohl (Rply_buff.status) != KER__SUCCESS) { printf ("read_hm: Bad status from SQHM_READ Request: %d.\n", ntohl (Rply_buff.status)); printf (" Sub-status: %d.\n", ntohl (Rply_buff.sub_status)); if (Rply_buff.u.message[0] != NIL) printf (" Message is: %s\n", Rply_buff.u.message); return EXIT_FAILURE; } /* ** Data was read OK so read the data which has been sent. */ my_n_bins = ntohl (Rply_buff.u.read.n_bins); my_bytes_per_bin = ntohl (Rply_buff.u.read.bytes_per_bin); *cntr_lo = ntohl (Rply_buff.u.read.cnts_lo); *cntr_hi = ntohl (Rply_buff.u.read.cnts_hi); if (my_n_bins != n_bins) { printf ("read_hm: " "Warning -- server is sending us %d bins of data rather than %d!\n", my_n_bins, n_bins); } bytes_to_come = my_n_bins * my_bytes_per_bin; if (bytes_to_come > hbuf_size) { printf ("read_hm: Warning -- buffer size = %d bytes\n" " Server is sending us %d bytes of data.\n" " Some data will have to be flushed!\n", hbuf_size, bytes_to_come); } nxt_byte = (uchar *) Hm_buff_addr; while (bytes_to_come > 0) { i = (bytes_to_come > Pkt_size) ? Pkt_size : bytes_to_come; if (bytes_to_come > hbuf_size) { i = hbuf_size; nxt_byte = (uchar *) Hm_buff_addr; } status = recv (Rw_skt, nxt_byte, i, 0); Rw_bytes_got += status; if (status == -1) FailInet ("read_hm -- R/W-Socket data recv error\n"); bytes_to_come = bytes_to_come - status; nxt_byte = nxt_byte + status; } /* ** If byte swapping is necessary, do it! */ if ((Bytes_per_bin > 0) && (Rply_buff.bigend != 0x12345678)) { switch (Bytes_per_bin) { /* Byte swapping is necessary */ case 2: /* Not sure how to do this - this might be wrong! */ nxt_word = (usint *) Hm_buff_addr; for (i = 0; i < n_bins; i++) nxt_word[i] = ntohs (nxt_word[i]); break; case 4: nxt_long = (uint *) Hm_buff_addr; for (i = 0; i < n_bins; i++) nxt_long[i] = ntohl (nxt_long[i]); break; } } return EXIT_SUCCESS; } /* **--------------------------------------------------------------------------*/ int read_project ( /* ============ ** Read projected block of bins from SINQHM_SRV. ** Send SQHM_PROJECT request to server. ** On return, the data is in the buffer pointed to by hbuf. */ char *hbuf, /* Buffer to hold data */ uint hbuf_size, /* Size of hbuf */ uint f_bin, /* First bin to read */ uint n_bins, /* Number of bins to read */ uint f_hist, /* First histogram to read */ uint n_hists, /* Number of histograms to read */ uint axis, /* Projection axis */ uint xdim, /* Pseudo-x-dimension */ uint h_select, /* Histogram to select (pseudo 2-d mode) */ uint *cntr_lo, /* # events below histo range */ uint *cntr_hi) { /* # events above histo range */ int status, is, i; int bytes_to_come; uint nbins_to_read, my_n_bins, my_bytes_per_bin; uchar *nxt_byte; usint *nxt_word; uint *nxt_long; nbins_to_read = (axis == 0) ? n_bins : n_hists; bytes_to_come = nbins_to_read * sizeof (uint); if (bytes_to_come > hbuf_size) { printf ("read_project: buffer is too small!\n" " It is %d rather than %d bytes long.\n", hbuf_size, bytes_to_come); return EXIT_FAILURE; } status = EXIT_SUCCESS; /* Assume success. */ Req_buff.bigend = htonl (0x12345678); Req_buff.cmnd = htonl (SQHM_PROJECT); i = (axis == 0) ? 0 : PROJECT__ON_Y; if (xdim != 0) i |= PROJECT__1_DIM; Req_buff.u.project.sub_code = htonl (i); Req_buff.u.project.x_lo = htonl (f_bin); Req_buff.u.project.nx = htonl (n_bins); Req_buff.u.project.y_lo = htonl (f_hist); Req_buff.u.project.ny = htonl (n_hists); Req_buff.u.project.xdim = htonl (xdim); Req_buff.u.project.nhist = htonl (h_select); status = send (Rw_skt, (char *) &Req_buff, sizeof (Req_buff), 0); Rw_bytes_put += status; if (status == -1) FailInet ("read_project -- R/W-Socket send error\n"); if (status != sizeof (Req_buff)) { printf ("read_project: wrong number of bytes sent: %d", status); return EXIT_FAILURE; } /* ** Wait for the status response. */ status = recv (Rw_skt, (char *) &Rply_buff, sizeof (Rply_buff), 0); Rw_bytes_got += status; if (status == -1) { FailInet ("read_project -- R/W-Socket recv error\n"); }else if (status != sizeof (Rply_buff)) { printf ("read_project: R/W-Socket recv error - "); printf ("unexpected byte count: %d.\n", status); return EXIT_FAILURE; } if (ntohl (Rply_buff.bigend) != 0x12345678) { printf ( "read_project: big-endian/little-endian problem!\n" " Buffer received in non-network byte order!\n"); return EXIT_FAILURE; } if (ntohl (Rply_buff.status) != KER__SUCCESS) { printf ("read_project: Bad status from SQHM_READ Request: %d.\n", ntohl (Rply_buff.status)); printf (" Sub-status: %d.\n", ntohl (Rply_buff.sub_status)); if (Rply_buff.u.message[0] != NIL) printf (" Message is: %s\n", Rply_buff.u.message); return EXIT_FAILURE; } /* ** Data was read OK so read the data which has been sent. */ my_n_bins = ntohl (Rply_buff.u.project.n_bins); my_bytes_per_bin = ntohl (Rply_buff.u.project.bytes_per_bin); *cntr_lo = ntohl (Rply_buff.u.project.cnts_lo); *cntr_hi = ntohl (Rply_buff.u.project.cnts_hi); if (my_n_bins != nbins_to_read) { printf ("read_project: Warning -- " "server is sending us %d bins of data rather than %d!\n", my_n_bins, n_bins); } bytes_to_come = my_n_bins * my_bytes_per_bin; /* Compute length of data */ if (bytes_to_come > hbuf_size) { printf ("read_project: Warning -- buffer size = %d bytes\n" " Server is sending us %d bytes of data.\n" " Some data will have to be flushed!\n", hbuf_size, bytes_to_come); } nxt_byte = (uchar *) hbuf; while (bytes_to_come > 0) { i = (bytes_to_come > Pkt_size) ? Pkt_size : bytes_to_come; if (bytes_to_come > hbuf_size) { i = hbuf_size; nxt_byte = (uchar *) hbuf; } status = recv (Rw_skt, nxt_byte, i, 0); Rw_bytes_got += status; if (status == -1) FailInet ("read_project -- R/W-Socket data recv error\n"); bytes_to_come = bytes_to_come - status; nxt_byte = nxt_byte + status; } /* ** If byte swapping is necessary, do it! */ if ((my_bytes_per_bin > 0) && (Rply_buff.bigend != 0x12345678)) { switch (my_bytes_per_bin) { /* Byte swapping is necessary */ case 2: /* Not sure how to do this - this might be wrong! */ nxt_word = (usint *) hbuf; for (i = 0; i < nbins_to_read; i++) nxt_word[i] = ntohs (nxt_word[i]); break; case 4: nxt_long = (uint *) hbuf; for (i = 0; i < nbins_to_read; i++) nxt_long[i] = ntohl (nxt_long[i]); break; } } return EXIT_SUCCESS; } /* **--------------------------------------------------------------------------- ** 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 ("Warning -- no resource database found.\n"); XrmDestroyDatabase (cmnd_line_db); /* ** XrmPutFileDatabase (lcl_db, "sinqhm_client.db"); */ return status; } /* **--------------------------------------------------------------------------*/ void show_help (char *token) { /* ========= ** Display help text */ int len; if (token == NULL) token = ""; if (token[0] == NIL) { printf ("\n" " The following commands are recognised by SinqHM_Client:\n" "\n" " Help or ? - generate this help information\n" " Open or - open the connection to the histogram memory\n" " Connect\n" " Status or - show the status of the histogram memory\n" " Show\n" " Read - read a region of histogram memory\n" " 2D - read a region of a 2-dimensional histogram\n" " Project - read a projected region of a 2-dim histogram\n" " Dump - dump the contents of the histogram buffer\n" " LOAD - write the histogram buffer from a file\n" " WRIte - write data to a histogram region\n" " W2D - write data to a histogram region in pseudo 2-dim mode\n" " GO - start data acquisition\n" " STOP - stop data acquisition\n" " ZERO - zero a region of histogram memory\n" " Quit or - end the program\n" " Exit or End\n" "\n" " To get more detailed help on a specific command, issue " "the command:\n" "\n" " ? \n" "\n" " For information on environment setup for SinqHM_Client, issue" "the command:\n" "\n" " ? SETUP\n" "\n"); } else { len = strlen (token); if (StrMatch (token, "read", 1)) { printf ("\n" " Read <1st-bin> <#-bins> \n" " ^ ^ ^\n" " | | |\n" " | | +--- Dflt = -1\n" " | +------------ Dflt = see below\n" " +--------------------- Dflt = 0\n" "\n" " Read <#-bins> bins starting at <1st-bin> of histogram .\n" "\n" " If is -1, the histogram data is regarded as a single " "histogram.\n" " The default for <#-bins> depends on the value of . " "If \n" " is -1, it defaults to the total histogram size (i.e. " "<#-bins-per-hist> *\n" " <#-histograms>). Otherwise, it defaults to <#-bins-per-hist>.\n" "\n" " The command verb should be terminated by a space or tab.\n" " Arguments may be separated by spaces, tabs or commas.\n" "\n" " Hence, to read the whole of histogram number 5, for example, " "specify:\n" "\n" " READ ,,5\n" "\n"); }else if (StrMatch (token, "2d", 2)) { printf ("\n" " 2D <1st-hist> <#-hists> <1st-bin> <#-bins>\n" " ^ ^ ^ ^\n" " | | | |\n" " | | | +--- Dflt = histogram size\n" " | | +------------ Dflt = 0\n" " | +---------------------- Dflt = number of histograms\n" " +--------------------------------- Dflt = 0\n" "\n" " Read a rectangular array of the 2-dim histogram memory (e.g. a TOF\n" " spectrum). From each histogram, <#-bins> bins starting at <1st-bin>\n" " are read. The same region is read from histograms <1st-hist> to\n" " <1st-hist>+<#-hists>-1.\n" "\n"); }else if (StrMatch (token, "project", 1)) { printf ("\n" " Project <1st-hist>, <-- dflt = 0.\n" " <#-hists>, <-- dflt = number of histograms.\n" " <1st-bin>, <-- dflt = 0.\n" " <#-bins>, <-- dflt = histogram size.\n" " , <-- \"X\" or \"Y\" for proj'n onto x- or " "y-axis. Dflt = \"X\".\n" " , <-- gives x-extent of histog in pseudo-2-" "dim mode.\n" " <-- selects a histogram in pseudo-2-dim " "mode. Dflt = 0.\n" "\n" " Read a rectangular array of the 2-dim histogram memory (e.g. " "a TOF\n" " spectrum) projected onto the x or y axis. From each histogram, " "<#-bins> bins\n" " starting at <1st-bin> are read. The same region is read" "from histograms\n" " <1st-hist> to <1st-hist>+<#-hists>-1.\n" "\n" " If is non-zero, pseudo-2-dim mode will be assumed " "(i.e. the\n" " PROJECT__1_DIM sub_code bit will be set.\n" "\n"); }else if (StrMatch (token, "dump", 1)) { printf ("\n" " DUMP <1st-bin> <#-bins> \n" " ^ ^ ^\n" " | | |\n" " | | +---- Dflt = standard output\n" " | +------------ Dflt = rest of buffer\n" " +--------------------- Dflt = 0\n" "\n" " Dump <#-bins> bins starting at <1st-bin> of buffer.\n" "\n" " The command verb should be terminated by a space or tab.\n" " Arguments may be separated by spaces, tabs or commas.\n" "\n" " Hence, to dump 25 bins starting at bin 100, specify:\n" "\n" " DUMP 100,25\n" "\n"); }else if (StrMatch (token, "load", 1)) { printf ("\n" " LOAD \n" " ^\n" " |\n" " +---- Dflt = standard input\n" "\n" " Read the contents of the file and write to hist mem.\n" " The file format should be the same as that generated by DUMP\n" "\n"); }else if (StrMatch (token, "write", 2)) { printf ("\n" " WRITE \n" " ^ ^ ^ ^ ^ ^\n" " | | | | | |\n" " | | | | | +--- Dflt = 0.60 * Number of bins\n" " | | | | +-------- Dflt = 1000\n" " | | | +------------- Dflt = 200000\n" " | | +------------------ Dflt = 0.23 * Number of bins\n" " | +----------------------- Dflt = 1000\n" " +---------------------------- Dflt = 2000000\n" "\n" " Preset the histogram memory to the sum of 2 Lorenzians given by\n" " ... .\n" "\n"); }else if (StrMatch (token, "w2d", 2)) { printf ("\n" " WRITE <#-hists> \n" " ^ ^ ^ ^ ^ ^ ^\n" " | | | | | | |\n" " | | | | | | +--- Dflt = 0.60 * Number of bins\n" " | | | | | +-------- Dflt = 1000\n" " | | | | +------------- Dflt = 200000\n" " | | | +------------------ Dflt = 0.23 * Number of bins\n" " | | +----------------------- Dflt = 1000\n" " | +---------------------------- Dflt = 2000000\n" " +--------- Dflt = 1. The total allocated hist mem is\n" " split into <#-hists> histograms.\n" "\n" " Preset the histogram memory to the sum of 2 Lorenzians given by\n" " ... .\n" "\n"); }else if (StrMatch (token, "go", 1)) { printf ("\n" " GO\n" "\n" " Start data acquisition.\n" "\n"); }else if (StrMatch (token, "show", 2)) { printf ("\n" " SHOW\n" "\n" " Show Hist Mem status.\n" "\n"); }else if (StrMatch (token, "stop", 2)) { printf ("\n" " STOP\n" "\n" " Stop data acquisition.\n" "\n"); }else if (StrMatch (token, "zero", 1)) { printf ("\n" " ZERO <1st-bin> <#-bins>\n" " ^ ^\n" " | |\n" " | +---- Dflt = histogram size\n" " +------------- Dflt = 0\n" "\n" " Zero <#-bins> bins starting at <1st-bin>.\n" "\n"); }else if ((StrMatch (token, "open", 1)) || (StrMatch (token, "connect", 1))) { if (StrMatch (token, "open", 1)) { printf ("\n OPEN\n\n"); }else { printf ("\n CONNECT\n\n"); } printf ( " Open the connection to the Hist Mem.\n" " The connection is usually not opened until the first " "action command\n" " is given.\n" "\n"); }else if (StrMatch (token, "setup", 2)) { printf ("\n" " The following environment variables should be set on Unix systems:\n" "\n" " setenv SINQHM_FRONTEND \" \"\n" " setenv SINQHM_DBG_MODE \n" "\n" " The following logical names should be set on VMS systems:\n" "\n" " DEFINE/GROUP SINQHM_FRONTEND \" \"\n" " DEFINE/GROUP SINQHM_DBG_MODE \n" "\n" " Defaults:\n" " None 0\n" " 2400\n" " 8192\n" "\n" " If is non-zero, the server will suspend itself to allow debugging.\n" "\n"); }else { printf ("Sorry, no help available for \"%s\"!\n", token); } } } /* **--------------------------------------------------------------------------*/ void split_args ( /* ========== ** Split up a text string into arguments. The arguments ** may be separated by white space or commas. Adjacent ** commas indicate a default argument. ** ** Each argument in the variable length argument list will ** get set to the address of the start of the appropriate ** argument. A defaulted argument is returned as NULL. */ char *str, /* The string to be parsed. This string will get modified ** as it is split up into tokens */ ...) { /* A NULL terminated list of char** arguments. */ va_list ap; /* Pointer to variable args */ int i, s_len, l_nxt; char *nxt_str; char **arg_ptr; va_start (ap, str); /* Set up var arg machinery */ s_len = strlen (str); if (s_len <= 0) { /* If input string is null, return lots of NULLs */ arg_ptr = va_arg (ap, char **); while (arg_ptr != NULL) { *arg_ptr = NULL; arg_ptr = va_arg (ap, char **); } return; } /* Turn all white space chars into spaces */ l_nxt = strcspn (str, "\t\f\v\n"); while (l_nxt != s_len) { str[l_nxt] = ' '; l_nxt = strcspn (str, "\t\f\v\n"); } /* Now compress out multiple spaces */ nxt_str = strstr (str, " "); while (nxt_str != NULL) { nxt_str[1] = NIL; StrJoin (str, (s_len + 1), str, &nxt_str[2]); nxt_str = strstr (str, " "); } if (str[0] == ' ') str++; /* Remove a leading space, if present */ /* Remove a space if followed by a comma */ nxt_str = strstr (str, " ,"); while (nxt_str != NULL) { nxt_str[0] = NIL; StrJoin (str, (s_len + 1), str, &nxt_str[1]); nxt_str = strstr (str, " ,"); } /* Remove a space if preceded by a comma */ nxt_str = strstr (str, ", "); while (nxt_str != NULL) { nxt_str[1] = NIL; StrJoin (str, (s_len + 1), str, &nxt_str[2]); nxt_str = strstr (str, ", "); } /* Turn all remaining spaces into commas */ s_len = strlen (str); l_nxt = strcspn (str, " "); while (l_nxt != s_len) { str[l_nxt] = ','; l_nxt = strcspn (str, " "); } /* Now split up the comma-separated tokens */ arg_ptr = va_arg (ap, char **); /* Get pntr to first argument */ while (arg_ptr != NULL) { /* Loop till all have been done */ if (strlen (str) == 0) { *arg_ptr = NULL; /* If str is exhausted, keep giving NULL */ }else { l_nxt = strcspn (str, ","); /* Find end of next token */ if (l_nxt > 0) { /* Is it a null token? */ *arg_ptr = str; /* No, so set up next arg pntr */ str[l_nxt] = NIL; /* Terminate the token */ str = &str[l_nxt+1]; /* Move over the separator */ }else { /* It is a null token */ *arg_ptr = NULL; str++; /* Move over the separator */ } } arg_ptr = va_arg (ap, char **); /* Get pntr to next parameter ident */ } } /* **--------------------------------------------------------------------------*/ int write_hm ( /* ======== ** Write block of bins to SINQHM_SRV */ void *hbuf, /* Buffer holding data */ uint hist_no, /* Histogram number to write */ uint f_bin, /* First bin to write */ uint n_bins, /* Number of bins to write */ uint bpb) { /* # bytes per bin */ int i, status, bytes_to_go; uchar *p_byte; usint *p_word; uint *p_long; p_byte = (uchar *) hbuf; p_word = (usint *) hbuf; p_long = (uint *) hbuf; if (0x12345678 != ntohl (0x12345678)) { /* Swap bytes, if necessary */ switch (bpb) { case 1: break; case 2: for (i=0; i 0) { i = (bytes_to_go > Pkt_size) ? Pkt_size : bytes_to_go; status = send (Rw_skt, (char *) p_byte, i, 0); if (status <= 0) { FailInet ("write_hm -- R/W-Socket send error\n"); exit (EXIT_FAILURE); } bytes_to_go -= status; p_byte += status; } /* ** Now get the server's status message. */ status = recv (Rw_skt, (char *) &Rply_buff, sizeof (Rply_buff), 0); if (status == -1) { FailInet ("write_hm -- R/W-Socket recv error\n"); exit (EXIT_FAILURE); }else if (status != sizeof (Rply_buff)) { printf ("SinqHM_Client -- Cnct-Socket recv error - "); printf ("unexpected byte count: %d.\n", status); exit (EXIT_FAILURE); } if (ntohl (Rply_buff.bigend) != 0x12345678) { printf ( "SinqHM_Client -- big-endian/little-endian problem!\n" " Buffer received in non-network byte order!\n"); exit (EXIT_FAILURE); }else if (ntohl (Rply_buff.status) != KER__SUCCESS) { printf ("SinqHM_Client -- Bad status from Write Request: %d.\n", ntohl (Rply_buff.status)); printf (" \"%s\"\n", Rply_buff.u.message); exit (EXIT_FAILURE); } /* Finally, swap bytes back again, if necessary, ** so that a DUMP command will make sense. */ if (0x12345678 != ntohl (0x12345678)) { switch (bpb) { case 1: break; case 2: for (i=0; i 1) { printf ("\nThe following arguments were not used:\n\n "); for (i = 1; i < argc; i++) { printf ("\"%s\" ", argv[i]); } printf ("\n"); show_help (NULL); return False; } /*====================================================== Wait for work ========= */ printf ("\n" " The following commands are available:\n" " Help Open Status Read 2D Project Dump LOAD WRITE W2D GO STOP ZERO " "Quit\n"); recd[0] = NIL; printf ("> "); while (fgets (recd, sizeof (recd), stdin) != NULL) { nerr = 0; /* Reset error counter for each unit of work. */ if (strlen (recd) == (sizeof (recd) - 1)) { printf ("\n\nInput buffer overflow -- command ignored!\n\n"); do { /* Flush the remains */ fgets (recd, sizeof (recd), stdin); } while (strlen (recd) == (sizeof (recd) - 1)); printf ("> "); continue; } i = strlen (recd) - 1; if (recd[i] == NL) recd[i] = NIL; /* Suppress the trailing \n */ if (recd[0] == NIL) { /* If just , repeat */ strcpy (recd, last_recd); } l_recd = sizeof (recd1); StrEdit (recd1, recd, "trim compress uncomment lowercase", &l_recd); if (l_recd <= 0) { /* Skip empty lines */ printf ("\n> "); continue; } StrJoin (recd1, sizeof (recd1), recd1, " ,,,,,,,,,,"); /* ** Parse the command */ verb = strtok (recd1, " \t\f\v\n"); vlen = strlen (verb); if (StrMatch (verb, "read", 1)) { do_1d (&verb[vlen+1], Dbg_mode); /* Generate a 1-dim plot */ }else if (StrMatch (verb, "2d", 2)) { do_2d (&verb[vlen+1], Dbg_mode); /* Generate a 2-dim plot */ }else if (StrMatch (verb, "project", 1)) { do_project (&verb[vlen+1], Dbg_mode); /* Do a projected read */ }else if (StrMatch (verb, "dump", 1)) { do_dump (&verb[vlen+1]); /* Generate a dump of the data */ }else if (StrMatch (verb, "load", 4)) { do_load (&verb[vlen+1], Dbg_mode); /* Load histog mem from file */ }else if (StrMatch (verb, "write", 5)) { if (Rw_skt == 0) { Rw_skt = openConnectionGbl (Rmt_host, &Rmt_port, &Pkt_size, Dbg_mode, &Rply_buff, Verbose); if (Rw_skt == 0) FailInet ("\nmain/openConnectionGbl error."); } printf ("\n Writing data to histogram memory ..."); gen_data (&verb[vlen+1]); /* Generate some pseudo data */ hist_num = -1; f_bin = 0; nbins = Hm_nbins * N_hists; status = write_hm (Hm_buff_addr, hist_num, f_bin, nbins, Bytes_per_bin); if (status) printf (" OK\n"); }else if (StrMatch (verb, "w2d", 3)) { if (Rw_skt == 0) { Rw_skt = openConnectionGbl (Rmt_host, &Rmt_port, &Pkt_size, Dbg_mode, &Rply_buff, Verbose); if (Rw_skt == 0) FailInet ("\nmain/openConnectionGbl error."); } printf ("\n Writing pseudo 2-dim data to histogram memory ..."); gen_data_2d (&verb[vlen+1]); /* Generate some pseudo data */ hist_num = -1; f_bin = 0; nbins = Hm_nbins * N_hists; status = write_hm (Hm_buff_addr, hist_num, f_bin, nbins, Bytes_per_bin); if (status) printf (" OK\n"); }else if (StrMatch (verb, "go", 2)) { if (Rw_skt == 0) { Rw_skt = openConnectionGbl (Rmt_host, &Rmt_port, &Pkt_size, Dbg_mode, &Rply_buff, Verbose); if (Rw_skt == 0) FailInet ("\nmain/openConnectionGbl error."); } printf ("\n Starting data acquisition ..."); /* ** Send the request message */ Req_buff.bigend = htonl (0x12345678); Req_buff.cmnd = htonl (SQHM_DAQ); Req_buff.u.daq.sub_cmnd = htonl (DAQ__GO); status = send (Rw_skt, (char *) &Req_buff, sizeof (Req_buff), 0); if (status == -1) FailInet ("SinqHM_Client -- R/W-Socket send error\n"); if (status != sizeof (Req_buff)) { printf ("\n" "SinqHM_Client -- wrong number of bytes sent: %d", status); exit (EXIT_FAILURE); } /* ** Now get the server's status message. */ status = recv (Rw_skt, (char *) &Rply_buff, sizeof (Rply_buff), 0); if (status == -1) { FailInet ("\nSinqHM_Client -- R/W-Socket recv error\n"); exit (EXIT_FAILURE); }else if (status != sizeof (Rply_buff)) { printf ("\n" "SinqHM_Client -- Cnct-Socket recv error - " "unexpected byte count: %d.\n", status); exit (EXIT_FAILURE); } if (ntohl (Rply_buff.bigend) != 0x12345678) { printf ("\n" "SinqHM_Client -- big-endian/little-endian problem!\n" " Buffer received in non-network byte order!\n"); exit (EXIT_FAILURE); }else if (ntohl (Rply_buff.status) != KER__SUCCESS) { printf ("\n" "SinqHM_Client -- Bad status from Go Request: %d.\n", ntohl (Rply_buff.status)); printf (" \"%s\"\n", Rply_buff.u.message); exit (EXIT_FAILURE); }else { daq_was = ntohs (Rply_buff.u.daq.daq_was); daq_now = ntohs (Rply_buff.u.daq.daq_now); filler_mask = ntohs (Rply_buff.u.daq.filler_mask); server_mask = ntohs (Rply_buff.u.daq.server_mask); if (daq_now == 0) { printf (" OK.\n"); if (daq_was == 0) printf (" Actually, data acquisition was already active.\n"); }else { printf ("\n" " Data acquisition not yet started. The various masks" " are:\n" " Daq-state-now = 0x%04x\n" " Filler-mask = 0x%04x\n" " Server-mask = 0x%04x\n", daq_now, filler_mask, server_mask); } } }else if ((StrMatch (verb, "show", 1)) || (StrMatch (verb, "status", 1))) { do_status (Dbg_mode); /* Get status of SinqHM_srv */ }else if (StrMatch (verb, "stop", 4)) { if (Rw_skt == 0) { Rw_skt = openConnectionGbl (Rmt_host, &Rmt_port, &Pkt_size, Dbg_mode, &Rply_buff, Verbose); if (Rw_skt == 0) FailInet ("\nmain/openConnectionGbl error."); } printf ("\n Stopping data acquisition ..."); /* ** Send the request message */ Req_buff.bigend = htonl (0x12345678); Req_buff.cmnd = htonl (SQHM_DAQ); Req_buff.u.daq.sub_cmnd = htonl (DAQ__STOP); status = send (Rw_skt, (char *) &Req_buff, sizeof (Req_buff), 0); if (status == -1) FailInet ("\nmain/send -- R/W-Socket send error\n"); if (status != sizeof (Req_buff)) { printf ("\n" "SinqHM_Client -- wrong number of bytes sent: %d", status); exit (EXIT_FAILURE); } /* ** Now get the server's status message. */ status = recv (Rw_skt, (char *) &Rply_buff, sizeof (Rply_buff), 0); if (status == -1) { FailInet ("\nmain/recv -- R/W-Socket recv error\n"); exit (EXIT_FAILURE); }else if (status != sizeof (Rply_buff)) { printf ("\n" "SinqHM_Client -- Cnct-Socket recv error - " "unexpected byte count: %d.\n", status); exit (EXIT_FAILURE); } if (ntohl (Rply_buff.bigend) != 0x12345678) { printf ("\n" "SinqHM_Client -- big-endian/little-endian problem!\n" " Buffer received in non-network byte order!\n"); exit (EXIT_FAILURE); }else if (ntohl (Rply_buff.status) != KER__SUCCESS) { printf ("\n" "SinqHM_Client -- Bad status from Stop Request: %d.\n", ntohl (Rply_buff.status)); printf (" \"%s\"\n", Rply_buff.u.message); exit (EXIT_FAILURE); }else { daq_was = ntohs (Rply_buff.u.daq.daq_was); daq_now = ntohs (Rply_buff.u.daq.daq_now); filler_mask = ntohs (Rply_buff.u.daq.filler_mask); server_mask = ntohs (Rply_buff.u.daq.server_mask); if (daq_now != 0) { printf (" OK. The various masks are:\n" " Daq-state-now = 0x%04x\n" " Filler-mask = 0x%04x\n" " Server-mask = 0x%04x\n", daq_now, filler_mask, server_mask); }else { printf ("\n" " Data acquisition is still active!\n"); } } }else if (StrMatch (verb, "zero", 4)) { if (Rw_skt == 0) { Rw_skt = openConnectionGbl (Rmt_host, &Rmt_port, &Pkt_size, Dbg_mode, &Rply_buff, Verbose); if (Rw_skt == 0) FailInet ("\nmain/openConnectionGbl error."); } p_p1 = strtok (NULL, " \t,"); /* Get pointers to the 2 args */ p_p2 = strtok (NULL, " \t,"); if ((p_p1 != NULL) && (sscanf (p_p1, "%d", &f_bin) == 1)) { if (p_p2 != NULL) { if (sscanf (p_p2, "%d", &n_bins) != 1) n_bins = Hm_nbins; } }else { f_bin = 0; n_bins = Hm_nbins * N_hists; } printf ("\n Zeroing histogram memory ...\n" " First bin = %d\n" " # bins = %d\n", f_bin, n_bins); /* ** Send the request message first */ 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 (f_bin); Req_buff.u.zero.n_bins = htonl (n_bins); status = send (Rw_skt, (char *) &Req_buff, sizeof (Req_buff), 0); if (status == -1) FailInet ("\nmain/send -- R/W-Socket send error\n"); if (status != sizeof (Req_buff)) { printf ("SinqHM_Client -- wrong number of bytes sent: %d", status); exit (EXIT_FAILURE); } /* ** Now get the server's status message. */ status = recv (Rw_skt, (char *) &Rply_buff, sizeof (Rply_buff), 0); if (status == -1) { FailInet ("\nmain/recv -- R/W-Socket recv error\n"); exit (EXIT_FAILURE); }else if (status != sizeof (Rply_buff)) { printf ("SinqHM_Client -- Cnct-Socket recv error - "); printf ("unexpected byte count: %d.\n", status); exit (EXIT_FAILURE); } if (ntohl (Rply_buff.bigend) != 0x12345678) { printf ( "SinqHM_Client -- big-endian/little-endian problem!\n" " Buffer received in non-network byte order!\n"); exit (EXIT_FAILURE); }else if (ntohl (Rply_buff.status) != KER__SUCCESS) { printf ("SinqHM_Client -- Bad status from Zero Request: %d.\n", ntohl (Rply_buff.status)); printf (" \"%s\"\n", Rply_buff.u.message); exit (EXIT_FAILURE); }else { printf (" done.\n"); } }else if ((StrMatch (verb, "open", 1)) || (StrMatch (verb, "connect", 1))) { if (Rw_skt == 0) { printf ("\n Opening the connection ...\n"); Rw_skt = openConnectionGbl (Rmt_host, &Rmt_port, &Pkt_size, Dbg_mode, &Rply_buff, Verbose); if (Rw_skt == 0) FailInet ("\nmain/openConnection error."); }else { printf ("\n The connection is already open!\n"); } }else if ((StrMatch (verb, "exit", 1)) || (StrMatch (verb, "quit", 1)) || (StrMatch (verb, "end", 1))) { break; }else if ((StrMatch (verb, "?", 1)) || (StrMatch (verb, "help", 1))) { show_help (strtok (NULL, " \t,")); }else { printf (" Illegal command - type \"?\" for help.\n"); } strcpy (last_recd, recd); /* ** Get another command. */ printf ("> "); } /* ** Time to quit. Note that the exit handler will tidy ** up any open connection to the Hist Mem Server, */ exit (EXIT_SUCCESS); } /*============================================= End of SinqHM_Client.C ======*/