My Project
 All Classes Files Functions Variables Enumerations Enumerator Friends Macros Pages
monitor_stream.h
1 #ifndef monitor_stream_h
2 #define monitor_stream_h
3 
4 #include <string>
5 
6 #include "arraymap.h"
7 #include "regset.h"
8 #include "regcal.h"
9 #include "regdata.h"
10 
11 #include "gcp/util/common/Complex.h"
12 #include "gcp/util/common/RegDate.h"
13 #include "gcp/util/common/RegisterSet.h"
14 #include "gcp/util/common/RegCal.h"
15 
16 namespace gcp {
17  namespace util {
18  class DataType;
19  class RegAxisRange;
20  }
21 }
22 
23 /*.......................................................................
24  * The following method is called upon to read all or part of the
25  * next frame of registers. It should behave like its generic
26  * counterpart described above.
27  */
28 #define MS_READ_FRAME(fn) \
29 gcp::control::MsReadState (fn)(gcp::control::MonitorStream *ms, int dowait)
30 
31 /*.......................................................................
32  * Where provided, the following optional method is called upon to
33  * send part or all of the most recently packed output message.
34  */
35 #define MS_SEND_MSG(fn) \
36 gcp::control::MsSendState (fn)(gcp::control::MonitorStream *ms, int dowait)
37 
38 /*.......................................................................
39  * Where provided the following optional method is called whenever the
40  * current selection of registers in ms->regset is changed. This allows
41  * for the register set to be packed for transmission to a remote
42  * register supplier. If calls to the MS_SEND_MSG() method will be
43  * needed to complete the transaction, MS_SEND_AGAIN should be returned.
44  */
45 #define MS_QUEUE_REGSET(fn) \
46 gcp::control::MsSendState (fn)(gcp::control::MonitorStream *ms)
47 
48 /*.......................................................................
49  * Where provided the following optional method is called whenever the
50  * current sampling interval [ms_get_interval()] is changed. This allows
51  * for the interval to be packed for transmission to a remote
52  * register supplier. If calls to the MS_SEND_MSG() method will be
53  * needed to complete the transaction, MS_SEND_AGAIN should be returned.
54  */
55 #define MS_QUEUE_INTERVAL(fn) \
56 gcp::control::MsSendState (fn)(gcp::control::MonitorStream *ms)
57 
58 /*.......................................................................
59  * Where pertinent, the following optional method requests that a stream
60  * be "rewound" to its beginning. If this requires a message to be sent
61  * to the supplier, then this function should pack the message in
62  * preparation for subsequent calls to ms_send_msg(), and return
63  * MS_SEND_AGAIN. Otherwise it should rewind the stream and return
64  * MS_SEND_DONE.
65  */
66 #define MS_QUEUE_REWIND(fn) \
67 gcp::control::MsSendState (fn)(gcp::control::MonitorStream *ms)
68 
69 /*.......................................................................
70  * The following method returns a file descriptor for use in select() to
71  * see when the stream is ready for reading or writing. Note that the
72  * select() user is expected to call this before each use of select().
73  * This allows the fd to change with time (for example, the file
74  * monitor will read across file boundaries, so the fd may well change).
75  */
76 #define MS_SELECT_FD(fn) int (fn)(gcp::control::MonitorStream *ms)
77 
78 /*.......................................................................
79  * The following method is called to delete the stream-specific
80  * implementation context.
81  */
82 #define MS_DESTRUCTOR(fn) void *(fn)(void *context)
83 
84 /*.......................................................................
85  * Return the current array map of the stream.
86  */
87 #define MS_ARRAYMAP(fn) ArrayMap *(fn)(gcp::control::MonitorStream *ms)
88 
89 /*.......................................................................
90  * Return the current register map of the stream.
91  */
92 #define MS_REGMAP(fn) RegMap *(fn)(gcp::control::MonitorStream *ms)
93 
94 namespace gcp {
95  namespace control {
96 
97  /*
98  * The function that reads data from the supplier can be told to wait
99  * for a complete record to be received, or to read as much as possible
100  * without blocking, then return with an indication that a future call
101  * will be necessary to retrieve the remaining data. The following
102  * values are returned by said function to indicate the state of the
103  * read operation.
104  *
105  * Special note should be taken of the MS_READ_REGMAP return value.
106  * This is a warning that the next call will return registers that may
107  * occupy different slots and have different dimensions than before.
108  * Furthermore some registers that existed in the previous register
109  * map may not exist in the new register map, and some new ones may
110  * now be available.
111  *
112  * Note that when MS_READ_REGMAP is returned, the previous register
113  * map and all of the objects returned by previous calls to
114  * ms_RegMap(), ms_RegCalData(), ms_RegRawData(), ms_RegSet(), and
115  * ms_prep_RegSet() will have been destroyed, and thus should not be
116  * used. At this point you should destroy any of your own objects
117  * who's constructors took the return value of a previous call to
118  * ms_RegMap(), then create them anew using the return value of a new
119  * call to ms_RegMap().
120  *
121  * In order to give one a chance to finish up any defered work that
122  * involved the previous register map, ms_read_frame() returns
123  * MS_READ_BREAK whenever it encounters a point in the stream beyond
124  * which a new register map *might* change. For example, in multi-file
125  * file-input streams this occurs at the end of each file.
126  */
127  typedef enum { /* Frame-reader read status */
128  MS_READ_ENDED, /* The end of the stream has been reached */
129  MS_READ_AGAIN, /* The read operation is incomplete (dowait=0) */
130  MS_READ_BREAK, /* The end of one part of a multi-segment
131  stream has been */
132  /* reached. On the next call the register map may change, */
133  /* in which case MS_READ_REGMAP will be returned. */
134  /* This forewarning allows the caller to finish up any */
135  /* defered operations that involve the old register map */
136  /* before it gets destroyed. */
137  MS_READ_REGMAP, /* A new incompatible register map has been
138  encountered */
139  /* (see above for details). */
140  MS_READ_DONE /* A new frame of selected registers has been read */
141  } MsReadState;
142 
143  /*
144  * When sending a control message to the supplier, one first submits
145  * the message to be packed for transmission by calling the
146  * appropriate submittal function, then calls ms_send_msg() to
147  * transmit the message. When calling ms_send_msg() one can ask to have
148  * the message sent in its entirety before returning, or to have as much
149  * as possible sent without blocking. In the latter case, completion
150  * of the send operation must be completed by subsequent calls to
151  * ms_send_msg().
152  *
153  * Note that while a send operation is incomplete the values submitted
154  * via intervening calls to ms_queue_regset() and/or ms_queue_interval()
155  * will be queued for re-submision when the current send
156  * completes. ms_send_msg() will not return MS_SEND_DONE until all
157  * such transactions have been completed.
158  *
159  * The following values are returned by ms_send_msg() to indicate the
160  * state of the send operation.
161  */
162  typedef enum { /* Frame-reader write status */
163  MS_SEND_ERROR, /* An unrecoverable error occurred */
164  MS_SEND_AGAIN, /* The send operation is incomplete (dowait=0) */
165  MS_SEND_DONE /* The message has been sent */
166  } MsSendState;
167 
168  /*-----------------------------------------------------------------------
169  * This module provides a generic stream interface for reading monitor
170  * data from a variety of sources. Supported sources include a network
171  * connection to the control program, and sequential archive files on
172  * disk.
173  *
174  * The internals of a stream are logically split into two parts, a
175  * local consumer and a potentially remote supplier. Given that the
176  * supplier can be in a separate process, messaging via either
177  * non-blocking or blocking I/O is used to dispatch control messages
178  * to, and receive data from a given supplier. The only time that
179  * non-blocking I/O is not an option is when the stream makes a
180  * connection to a new supplier. At this time, information, such as
181  * the register map of the supplier and buffer size information is
182  * read from the supplier using blocking I/O.
183  *
184  * The following datatype provides an opaque handle for all stream
185  * types. Its internals are private to monitor_stream.c.
186  */
187  /*
188  * Define the contents of a generic monitor stream.
189  */
190  typedef struct MonitorStream {
191  void *context; // The context of the current
192  // data-source
193  MS_DESTRUCTOR(*del_fn); // The 'context' destructor
194  // function
195  MS_READ_FRAME(*read_fn); // The method used to read the
196  // next frame
197  MS_SEND_MSG(*send_fn); // The method that is called to
198  // send queued requests to the
199  // supplier.
200  MS_QUEUE_REGSET(*regset_fn); // The method that is called to
201  // queue a new register
202  // selection.
203  MS_QUEUE_INTERVAL(*interval_fn);// The method that is called to
204  // queue a new sub-sampling
205  // interval.
206  MS_QUEUE_REWIND(*rewind_fn); // The method that is called to
207  // queue a rewind request.
208  MS_SELECT_FD(*fd_fn); // The method that returns the current fd
209  MS_ARRAYMAP(*arraymap_fn); // The method that returns the
210  // current register map.
211 
212  bool archivedOnly_; // This flag affects the
213  // interpretation of all of the
214  // following:
215 
216  ArrayMap *arraymap; // The register map of the monitor supplier
217 
218  // The register set in which applications submit new register
219  // selections
220 
221  gcp::util::RegisterSet* prepRegSet;
222 
223  // The established selection of registers
224 
225  gcp::util::RegisterSet* regSet;
226 
227  // The register calibration object
228 
229  gcp::util::RegCal* regCal;
230 
231  RegRawData *raw; // The latest array of
232  // un-calibrated registers
233  RegCalData *cal; // The latest array of calibrated registers
234  unsigned interval; // The sampling interval. The
235  // supplier should drop all but
236  // one of every 'interval'
237  // frames.
238  int sending; // True while an ongoing send
239  // operation is incomplete.
240 
241  // If a request to send a regset or interval request to the
242  // supplier is received before a previous request has been
243  // completely dispatched, set the corresponding flag below to
244  // have the request dispatched as soon as the previous
245  // transaction is completed.
246 
247  int send_interval; // True to queue an update from 'interval'
248  int send_regset; // True to queue an update from
249  // 'prep_regset'
250  int send_rewind; // True to queue a rewind-stream message
251  } MonitorStream;
252  }
253 }
254 /*
255  * The following is an example of the simplest usage of a monitor
256  * stream.
257  *
258  * |* Start by defining indexes for the registers that you are interested *|
259  * |* in retrieving. *|
260  *
261  * typedef enum {
262  * FRAME_MJD, |* The frame.mjd register *|
263  * FRAME_UTC, |* The frame.utc register *|
264  * CORR0_VIS, |* The corr0.vis[] register *|
265  * NUM_MY_REGS |* The number of register selections - this must be last *|
266  * } MyRegIndex;
267  *
268  *
269  * |* Now in the same order as the above enumeration, associate each *|
270  * |* enumerator with the register-map name of the corresponding register. *|
271  *
272  * static MonitorSelection my_sel[NUM_MY_REGS] = {
273  * {FRAME_MJD, "frame", "mjd"},
274  * {FRAME_UTC, "frame", "utc"},
275  * {CORR0_VIS, "corr0", "vis"},
276  * };
277  *
278  * ...
279  * MonitorStream *ms; |* The monitor stream to be created *|
280  *
281  * |* The following array will be filled in below by ms_select_regs() *|
282  *
283  * ArrRegMapReg my_regs[NUM_MY_REGS]; |* The array of selected registers *|
284  *
285  * |* Create a monitor stream for all the files of a disk based archive *|
286  *
287  * ms = new_FileMonitorStream("/scr/archive", 0.0, 0.0);
288  * if(!ms)
289  * return error;
290  *
291  * |* Tell the monitor stream about the registers that we are interested in. *|
292  * |* Details of each of the selected registers are recorded in my_regs[] *|
293  * |* These details change from register map to register map, so later *|
294  * |* we are careful to reselect then if a new register map is encountered *|
295  *
296  * if(ms_select_regs(ms, 1, 0, my_sel, NUM_MY_REGS, &my_regs) != MS_SEND_DONE)
297  * return error...
298  *
299  * |* Load the calibration parameters of the initial register map. *|
300  *
301  * if(ms_load_cal_file(ms, "", calfile))
302  * return error...
303  *
304  * |* Read successive register samples, stopping at the end of the stream *|
305  *
306  * while(1) {
307  * switch(ms_read_frame(ms, 1)) {
308  * case MS_READ_AGAIN: |* We should never get this when the dowait *|
309  * |* argument of ms_read_frame() is 1 *|
310  * case MS_READ_BREAK: |* We have reached a point beyond which a *|
311  * |* new register map may be encountered. *|
312  * break;
313  * case MS_READ_ENDED: |* We have reached the end of the stream *|
314  * printf("End of stream reached.\n");
315  * return ok;
316  * break;
317  * case MS_READ_DONE: |* We received a new frame of registers *|
318  * if(ms_get_double(ms, my_regs + FRAME_MJD, 0, 1, &mjd) ||
319  * ms_get_double(ms, my_regs + FRAME_UTC, 0, 2, &utc) ||
320  * ms_get_float(ms, my_regs + CORR0_VIS, 0, 156 , &vis))
321  * return error;
322  * ....process the visibility data in vis[]....;
323  * break;
324  * case MS_READ_REGMAP: |* An incompatible register map was encountered *|
325  * |* Reselect our registers in the new register map *|
326  *
327  * if(ms_select_regs(ms, 1, 0, my_sel, NUM_MY_REGS, &my_regs)!=MS_SEND_DONE)
328  * return error...
329  * |* Load the calibration parameters of the new *|
330  * |* register map. *|
331  *
332  * if(ms_load_cal_file(ms, "", calfile))
333  * return error...
334  * break;
335  * };
336  * };
337  *
338  */
339 
340 
341 /*
342  * Create a new MonitorStream object and attach it to a control
343  * program on a given host. The host argument should contain
344  * the name or internet address of the computer on which the
345  * control program is running.
346  *
347  * When successful this function returns the new MonitorStream
348  * object. On failure it returns NULL.
349  */
350 gcp::control::MonitorStream *new_NetMonitorStream(char *host);
351 
352 /*
353  * Create a new MonitorStream object and attach it to a time-ordered
354  * sequence of disk files in the directory named by 'dir'. Note that
355  * expansion of ~/ and ~user/ is supported within directory names.
356  * The ta and tb arguments can be used to limit the time range over which
357  * data should be retrieved. They are UTC's, expressed as Modified
358  * Julian Dates. If ta <= 0, the earliest time available in the directory
359  * will be substituted. If tb <= 0, the latest time available will be
360  * substituted. So to retrieve all of the data in a given directory,
361  * irrespective of its time range, pass both ta and tb as 0.0.
362  *
363  * When successful this function returns the new MonitorStream
364  * object. On failure it returns NULL.
365  */
366 gcp::control::MonitorStream *new_FileMonitorStream(char *dir, double ta, double tb);
367 
368 // Constructor for reading a named file
369 
370 gcp::control::MonitorStream *new_FileMonitorStream(char *filename);
371 
372 /*
373  * The following function closes and deletes a monitor stream.
374  * Note that del_MonitorStream() is idempotent (ie. it returns NULL
375  * to represent a deleted stream, and can safely take NULL as an
376  * argument).
377  */
379 
380 /*-----------------------------------------------------------------------
381  * Stream method functions.
382  *
383  * The following functions should only be used while a stream is
384  * connected to a supplier.
385  *---------------------------------------------------------------------*/
386 
387 /*
388  * Incrementally read the next set of the selected registers from
389  * the established data supplier. If dowait==0, retrieval of each
390  * frame may require multiple calls to this function. In such cases
391  * select() can be used to wait for the arrival of more data. See
392  * ms_select_fd() below for details.
393  */
394 gcp::control::MsReadState ms_read_frame(gcp::control::MonitorStream *ms, int dowait);
395 gcp::control::MsReadState ms_count_frame(gcp::control::MonitorStream *ms, int dowait);
396 
397 /*
398  * After reading new register values with ms_read_frame() the
399  * following functions can be used to copy the returned values
400  * into local arrays. The reg argument of each function should
401  * be one of the register-range specifications that was used to
402  * select registers to be monitored. The index and n arguments
403  * should select subsets of these ranges, and the output data
404  * arrays must have room for at least n elements. Each of these
405  * functions returns non-zero on error. Note that zeroes will be
406  * substituted for any of the selected registers that aren't in the
407  * archive (see the documentation of the pedantic argument of
408  * ms_select_regs() above).
409  */
410 int ms_get_float(gcp::control::MonitorStream *ms, gcp::util::RegDescription* desc,
411  float *data, gcp::util::CoordRange* range=0);
412 int ms_get_double(gcp::control::MonitorStream *ms, gcp::util::RegDescription* desc,
413  double* data, gcp::util::CoordRange* range=0);
414 int ms_get_uint(gcp::control::MonitorStream *ms, gcp::util::RegDescription* desc,
415  unsigned* data, gcp::util::CoordRange* range=0);
416 int ms_get_int(gcp::control::MonitorStream *ms, gcp::util::RegDescription* desc,
417  int* data, gcp::util::CoordRange* range=0);
418 int ms_get_ushort(gcp::control::MonitorStream *ms, gcp::util::RegDescription* desc,
419  unsigned short* data, gcp::util::CoordRange* range=0);
420 int ms_get_short(gcp::control::MonitorStream *ms, gcp::util::RegDescription* desc,
421  short* data, gcp::util::CoordRange* range=0);
422 int ms_get_uchar(gcp::control::MonitorStream *ms, gcp::util::RegDescription* desc,
423  unsigned char* data, gcp::util::CoordRange* range=0);
424 int ms_get_char(gcp::control::MonitorStream *ms, gcp::util::RegDescription* desc,
425  char* data, gcp::util::CoordRange* range=0);
426 int ms_get_ulong(gcp::control::MonitorStream *ms, gcp::util::RegDescription* desc,
427  unsigned long* data, gcp::util::CoordRange* range=0);
428 int ms_get_long(gcp::control::MonitorStream *ms, gcp::util::RegDescription* desc,
429  long* data, gcp::util::CoordRange* range=0);
430 
431 int ms_get_date(gcp::control::MonitorStream *ms, gcp::util::RegDescription* desc,
433 
434 int ms_get_complex_float(gcp::control::MonitorStream *ms,
437  gcp::util::CoordRange* range=0);
438 
439 
440 int ms_get_float(gcp::control::MonitorStream *ms, gcp::util::RegDescription* desc,
442 
443 int ms_get_double(gcp::control::MonitorStream *ms, gcp::util::RegDescription* desc,
445 
446 int ms_get_uint(gcp::control::MonitorStream *ms, gcp::util::RegDescription* desc,
448 
449 int ms_get_int(gcp::control::MonitorStream *ms, gcp::util::RegDescription* desc,
451 
452 int ms_get_uchar(gcp::control::MonitorStream *ms, gcp::util::RegDescription* desc,
454 
455 int ms_get_char(gcp::control::MonitorStream *ms, gcp::util::RegDescription* desc,
457 
458 int ms_get_ulong(gcp::control::MonitorStream *ms, gcp::util::RegDescription* desc,
460 
461 int ms_get_long(gcp::control::MonitorStream *ms, gcp::util::RegDescription* desc,
463 
464 int ms_get_date(gcp::control::MonitorStream *ms, gcp::util::RegDescription* desc,
466 
467 int ms_get_complex_float(gcp::control::MonitorStream *ms, gcp::util::RegDescription* desc,
469 
470 
471 int ms_get_double(gcp::control::MonitorStream *ms, gcp::util::RegDescription* desc,
472  double* data, gcp::util::RegAxisRange& range);
473 
474 /*
475  * Unpack a string from a string register. The *reg argument must refer
476  * to the whole of the register. Up to nc-1 characters of the string
477  * will be returned in string[], which must be an array of at least nc
478  * characters. If the string won't fit within nc-1 characters, it will
479  * be terminated by placing a '\0' terminator in string[nc-1]. Otherwise
480  * the string will be terminated with a '\0' at the natural end of the
481  * string. On error non-zero is returned. Note that an empty string will be
482  * substituted if the register isn't in the archive (see the documentation
483  * of the pedantic argument of ms_select_regs() above).
484  */
485 int ms_get_string(gcp::control::MonitorStream *ms, gcp::util::RegDescription *reg, unsigned nc, char *string);
486 
487 /*
488  * Incrementally send a message, previously submitted via a
489  * call to ms_queue_interval(), ms_queue_regset() or ms_queue_rewind,
490  * to the supplier. Multiple calls to this function may be required if
491  * dowait==0. In such cases select() can be used to wait for the
492  * output channel to free up. See ms_select_fd() for details.
493  */
494 gcp::control::MsSendState ms_send_msg(gcp::control::MonitorStream *ms, int dowait);
495 
496 /*
497  * You probably won't need to use this function directly, because
498  * ms_select_regs() calls it for you (see later).
499  *
500  * Submit a modified register selection to be subsequently sent to the
501  * supplier via one or more calls to ms_send_msg(). The modified
502  * register set should be composed in the preparation register set
503  * that is returned by a call to ms_prep_RegSet(). If subsequent
504  * calls to ms_send_msg() will not be required, ms_queue_regset()
505  * returns MS_SEND_DONE.
506  */
507 gcp::control::MsSendState ms_queue_regset(gcp::control::MonitorStream *ms);
508 
509 /*
510  * Submit a new subsampling interval to be sent to the
511  * data supplier. If MsSendState is MS_SEND_AGAIN then subsequent
512  * calls to ms_send_msg() will be needed to complete the transaction.
513  *
514  * Note that an interval of 2 means "supply every second record".
515  * At startup the interval is initialized to 1.
516  */
517 gcp::control::MsSendState ms_queue_interval(gcp::control::MonitorStream *ms, unsigned interval);
518 
519 /*
520  * If the stream can be rewound, submit a rewind request to
521  * be sent to the supplier, otherwise do nothing more than return
522  * MS_SEND_DONE. If the return code is MS_SEND_AGAIN, subsequent
523  * calls to ms_send_msg() will be needed to complete the transaction.
524  */
525 gcp::control::MsSendState ms_queue_rewind(gcp::control::MonitorStream *ms);
526 
527 /*
528  * Return true if the data source of the specified stream can be rewound.
529  */
530 int ms_can_be_rewound(gcp::control::MonitorStream *ms);
531 
532 /*
533  * Return a file descriptor that can be used with select() to
534  * determine when more data is available, or when the output
535  * channel to the supplier is ready to accept more data. If the
536  * stream isn't connected, -1 will be returned.
537  *
538  * WARNING: This file descriptor may change after any call to
539  * ms_read_frame(), so be sure to call ms_select_fd()
540  * before every call to select().
541  */
542 int ms_select_fd(gcp::control::MonitorStream *ms);
543 
544 /*
545  * Load new calibration parameters from a calibration file. Note that
546  * the contents of the dir[] and name[] arguments of ms_load_cal_file()
547  * will be concatenated to form the path name of the calibration file,
548  * so if desired the directory part of the path name can be passed via
549  * the dir[] argument, and the file name can be passed via the name[]
550  * argument. Alternatively, if you want to specify the path name of
551  * the file as a single string, pass this string via the name[]
552  * argument and set the dir[] argument to "". The return value of
553  * ms_load_cal_file() is non-zero on failure.
554  */
555 int ms_load_cal_file(gcp::control::MonitorStream *ms, char *dir, char *name);
556 
557 /*
558  * Load calibration parameters from a text input stream.
559  * See input.h to see how to create input streams.
560  */
561 int ms_load_cal_stream(gcp::control::MonitorStream *ms, InputStream *stream);
562 
563 /*
564  * Reset all calibration parameters to unit scale factors, and
565  * zero offsets.
566  */
567 int ms_reset_cal(gcp::control::MonitorStream *ms);
568 
569 /*
570  * An array of 'nsel' elements of the following type of container
571  * is what you pass to ms_select_regs() to tell it which register
572  * ranges to select.
573  */
575  int id_; // The index of this MonitorSelection in its parent array
576  char *regMapName_; // The name of the target board in the register map
577  char *boardName_; // The name of the target board in the register map
578  char *blockName_; // The name of the target block on the above board
579  std::string regMapStr_;
580  std::string boardStr_;
581  std::string blockStr_;
582 
583  // The range of indices to select
584 
585  gcp::util::CoordRange* range_;
586 
587  // Leave this as NULL if you always want to select all of the
588  // elements of the register.
589 
590  // Initialize internals of this object
591 
592  void initialize(int id, std::string regMapName, std::string boardName,
593  std::string blockName, gcp::util::CoordRange* range);
594 
595  // Constructor
596 
597  MonitorSelection(int id, std::string regMapName, std::string boardName,
598  std::string blockName, gcp::util::CoordRange* range=0);
599 
600  // Copy constructor
601 
602  MonitorSelection(const MonitorSelection& selection);
603 
604  // Destructor
605 
607 };
608 
609 /*
610  * Tell a monitor stream which registers you are interested in
611  * receiving in subsequent calls to ms_read_frame().
612  *
613  * Input:
614  * ms MonitorStream * The stream to select registers from.
615  * dowait int If non-zero, don't return until the
616  * selection has been sent to the supplier
617  * or an error occurs. If zero, return immediately
618  * with a return code of MS_READ_AGAIN if the
619  * message can't be sent without blocking. In the
620  * latter case subsequent calls to ms_send_msg()
621  * will be required to complete the transaction.
622  * pedantic int If true, treat the non-existence of any of
623  * the registers in *sel as a fatal error. If
624  * false, simply emit a warning and arrange
625  * to substitute zero for the value of each
626  * missing register. The corresponding regs[]
627  * element will have its 'slot' member set to
628  * -1.
629  * sel MonitorSelection * An array of 'nsel' specifications of registers
630  * that are to be read on subsequent calls to
631  * ms_read_frame(). Note that the id field of
632  * each element must match the index of the element
633  * in the sel[] array.
634  * nsel unsigned The number of register selections in sel[]
635  * and the corresponding number of selection
636  * results to be recorded in regs[].
637  * Input/Output:
638  * regs ArrRegMapReg * On input pass an array of nsel elements.
639  * On output this will contain the details of
640  * each selection. Note that the contents are
641  * specific to the current register map, so
642  * they should be renewed via a further call
643  * to ms_select_regs() whenever ms_read_frame()
644  * reports the receipt of a new register map.
645  * ArrRegMapReg is defined in regmap.h.
646  * Output:
647  * return MsSendState The completion status of the transaction, from:
648  * MS_SEND_ERROR - An error occurred
649  * MS_SEND_AGAIN - The send operation remains
650  * incomplete (only if dowait=0).
651  * MS_SEND_DONE - The selection has been
652  * dispatched.
653  */
654 gcp::control::MsSendState ms_select_regs(gcp::control::MonitorStream *ms,
655  bool dowait, bool pedantic,
656  std::vector<MonitorSelection>& selections,
657  std::vector<gcp::util::RegDescription>& regs);
658 
659 /*-----------------------------------------------------------------------
660  * Functions that provide readonly access to selected stream internals.
661  *---------------------------------------------------------------------*/
662 
663 /*
664  * Get the array map of a monitor stream (or NULL if the stream
665  * is unconnected). See arraymap.h for a description of the ArrayMap
666  * datatype.
667  */
668 ArrayMap *ms_ArrayMap(gcp::control::MonitorStream *ms);
669 
670 /*
671  * Get the register map of a monitor stream (or NULL if the stream
672  * is unconnected). See regmap.h for a description of the RegMap
673  * datatype.
674  */
675 ArrayMap *ms_ArrayMap(gcp::control::MonitorStream *ms);
676 
677 /*
678  * Return the container of the array of calibrated registers (or NULL
679  * if the stream is unconnected). This will only contain valid data
680  * after each call to ms_read_frame() that returns MS_READ_DONE. Its
681  * contents will be overwritten on each call to ms_read_frame().
682  * See regdata.h for a description of the RegCalData datatype.
683  */
685 
686 /*
687  * Return the container of the array of uncalibrated registers (or NULL
688  * if the stream is unconnected). This will only contain valid data
689  * after each call to ms_read_frame() that returns MS_READ_DONE. Its
690  * contents will be overwritten on each call to ms_read_frame().
691  * See regdata.h for a description of the RegCalData datatype.
692  */
693 RegRawData *ms_RegRawData(gcp::control::MonitorStream *ms);
694 
695 /*
696  * Return the established register selection set (or NULL if the
697  * stream is unconnected). See regset.h for a description of
698  * the RegSet datatype.
699  */
701 
702 /*
703  * Return the current sub-sampling interval (or 0 if the stream is
704  * unconnected).
705  */
706 unsigned ms_get_interval(gcp::control::MonitorStream *ms);
707 
708 /*-----------------------------------------------------------------------
709  * Functions that provide read/write access to selected stream internals.
710  *---------------------------------------------------------------------*/
711 
712 /*
713  * You won't need this if you use ms_select_regs().
714  *
715  * Return the preparation register-selection set (or NULL if the
716  * stream is unconnected). This is to be used with ms_queue_regset()
717  * to select the set of registers to be supplied. Note that if a
718  * register set update initiated by ms_queue_regset() has to be
719  * postponed because of a preceding incomplete transaction,
720  * the re-submittal of the register set will be base on whatever is
721  * in the preparation register set at the time of the resubmission.
722  * Thus beware that while it is safe to modify this register set
723  * between calls to ms_send_msg(), the register set should be in a
724  * chosen state whenever ms_send_msg() is called.
725  */
727 
728 
729 /*-----------------------------------------------------------------------
730  * The rest of this file regards implementation of new stream sources.
731  *
732  * The specific implementation of a particular stream source is
733  * implemented through the following method functions, plus an
734  * anonymous implementation object allocated by the stream source.
735  *---------------------------------------------------------------------*/
736 
737 /*
738  * To create an unconnected monitor stream call new_MonitorStream().
739  */
740 gcp::control::MonitorStream *new_MonitorStream(bool archivedOnly);
741 
742 
743 /*.......................................................................
744  * The following function is used to connect a given stream source to
745  * a monitor stream object. It requires the register map read from the
746  * supplier, a stream-specific context object + its destructor, and
747  * the above method functions. It returns non-zero if the call fails.
748  */
749 int open_MonitorStream(gcp::control::MonitorStream *ms, void *context, MS_DESTRUCTOR(*del_fn),
750  MS_READ_FRAME(*read_fn), MS_SEND_MSG(*send_fn),
751  MS_QUEUE_REGSET(*regset_fn),
752  MS_QUEUE_INTERVAL(*interval_fn),
753  MS_QUEUE_REWIND(*rewind_fn),
754  MS_SELECT_FD(*fd_fn),
755  MS_ARRAYMAP(*arraymap_fn),
756  bool archivedOnly);
757 
758 /*
759  * The above method functions can retrieve the context object that
760  * was registered with open_MonitorStream(), by calling the following
761  * function.
762  */
763 void *ms_SourceContext(gcp::control::MonitorStream *ms);
764 
765 /*
766  * The following function is used to close a MonitorStream. This
767  * is done for you by del_MonitorStream(). Also open_MonitorStream()
768  * calls this function before connecting a stream to a new supplier.
769  * Note that close_MonitorStream() is idempotent.
770  */
771 void close_MonitorStream(gcp::control::MonitorStream *ms);
772 
773 #endif
Definition: monitor_stream.h:574
Definition: RegCal.h:70
Definition: MonitorDataType.h:16
Definition: RegisterSet.h:21
Definition: RegCal.h:58
Definition: RegDate.h:22
MonitorSelection(int id, std::string regMapName, std::string boardName, std::string blockName, gcp::util::CoordRange *range=0)
Definition: monitor_stream.c:1819
Definition: input.h:87
~MonitorSelection()
Definition: monitor_stream.c:1840
Definition: CoordRange.h:20
Definition: script.h:867
Definition: Complex.h:48
Definition: monitor_stream.h:190
void initialize(int id, std::string regMapName, std::string boardName, std::string blockName, gcp::util::CoordRange *range)
Definition: monitor_stream.c:1785
Definition: RegAxisRange.h:27
Definition: regcal.h:69
Definition: RegDescription.h:26
Definition: regdata.h:16
Definition: arraymap.h:177