ARPDAS_QNX6 1.0
DC.cc
Go to the documentation of this file.
00001 /** \file DC.cc
00002  * Data Client Clases
00003  */
00004 #include <fcntl.h>
00005 #include <string.h>
00006 #include <stdlib.h>
00007 #include <errno.h>
00008 #include <limits.h>
00009 #include <process.h>
00010 #include "DC.h"
00011 #include "nortlib.h"
00012 #include "nl_assert.h"
00013 
00014 unsigned int data_client::next_minor_frame;
00015 unsigned int data_client::minf_row;
00016 unsigned int data_client::majf_row;
00017 char *data_client::srcnode = NULL;
00018 
00019 void dc_set_srcnode(char *nodename) {
00020   data_client::srcnode = nodename;
00021 }
00022 
00023 void data_client::init(int bufsize_in, int non_block, const char *srcfile) {
00024   bufsize = bufsize_in;
00025   bytes_read = 0;
00026   next_minor_frame = 0;
00027   majf_row = 0;
00028   minf_row = 0;
00029   dc_state = DC_STATE_HDR;
00030   toread = sizeof(tm_hdr_t);
00031   buf = new char[bufsize];
00032   tm_info_ready = false;
00033   dc_quit = false;
00034   if ( buf == 0)
00035     nl_error( 3, "Memory allocation failure in data_client::data_client");
00036   msg = (tm_msg_t *)buf;
00037   non_block = non_block ? O_NONBLOCK : 0;
00038   bfr_fd =
00039     srcfile ?
00040     tm_open_name( srcfile, srcnode, O_RDONLY | non_block ) :
00041     -1;
00042   if (bfr_fd != -1) {
00043     int nb1, nb2;
00044     char *filename;
00045     FILE *fp;
00046     const char *Exp = getenv("Experiment");
00047     if (Exp == NULL) Exp = "none";
00048     nb1 = snprintf(NULL, 0, "/var/huarp/run/%s/%d", Exp, getpid());
00049     filename = (char *)new_memory(nb1+1);
00050     nb2 = snprintf(filename, nb1+1, "/var/huarp/run/%s/%d", Exp, getpid());
00051     nl_assert(nb1 == nb2);
00052     fp = fopen( filename, "w" );
00053     if (fp) fclose(fp);
00054     else nl_error(2, "Unable to create run file '%s'", filename);
00055   }
00056 }
00057 
00058 data_client::data_client(int bufsize_in, int non_block, char *srcfile) {
00059   init(bufsize_in, non_block, srcfile );
00060 }
00061 
00062 data_client::data_client(int bufsize_in, int fast, int non_block) {
00063   init(bufsize_in, non_block, tm_dev_name( fast ? "TM/DCf" : "TM/DCo" ));
00064 }
00065 
00066 int data_client::process_eof() {
00067   dc_quit = true;
00068   return 1;
00069 }
00070 
00071 void data_client::read() {
00072   int nb;
00073   do {
00074     nb = (bfr_fd == -1) ? 0 :
00075         ::read( bfr_fd, buf + bytes_read, bufsize-bytes_read);
00076     if ( nb == -1 ) {
00077       if ( errno == EAGAIN ) return; // must be non-blocking
00078       else nl_error( 1, "data_client::read error from read(): %s",
00079         strerror(errno));
00080     }
00081     if (nb <= 0) {
00082       bytes_read = 0;
00083       toread = sizeof(tm_hdr_t);
00084       if ( process_eof() ) return;
00085     }
00086     if ( dc_quit ) return; // possible if set from an outside command
00087   } while (nb == 0 );
00088   bytes_read += nb;
00089   if ( bytes_read >= toread )
00090     process_message();
00091 }
00092 
00093 /** This is the basic operate loop for a simple extraction
00094  *
00095  */
00096 void data_client::operate() {
00097   tminitfunc();
00098   while ( !dc_quit ) {
00099     read();
00100   }
00101 }
00102 
00103 /* *
00104  * Internal function to establish input_tm_type.
00105  */
00106 void data_client::init_tm_type() {
00107   if ( tmi(mfc_lsb) == 0 && tmi(mfc_msb) == 1
00108        && tm_info.nrowminf == 1 ) {
00109     input_tm_type = TMTYPE_DATA_T3;
00110     nbQrow = tmi(nbrow) - 4;
00111     nbDataHdr = 8;
00112   } else if ( tm_info.nrowminf == 1 ) {
00113     input_tm_type = TMTYPE_DATA_T1;
00114     nbQrow = tmi(nbrow);
00115     nbDataHdr = 6;
00116   } else {
00117     input_tm_type = TMTYPE_DATA_T2;
00118     nbQrow = tmi(nbrow);
00119     nbDataHdr = 10;
00120   }
00121   tm_info_ready = true;
00122 }
00123 
00124 void data_client::process_init() {
00125   if ( memcmp( &tm_info, &msg->body.init.tm, sizeof(tm_dac_t) ) )
00126     nl_error(3, "tm_dac differs");
00127   tm_info.nrowminf = msg->body.init.nrowminf;
00128   tm_info.max_rows = msg->body.init.max_rows;
00129   tm_info.t_stmp = msg->body.init.t_stmp;
00130   init_tm_type();
00131 }
00132 
00133 void data_client::process_tstamp() {
00134   tm_info.t_stmp = msg->body.ts;
00135 }
00136 
00137 void data_client::process_message() {
00138   while ( bytes_read >= toread ) {
00139     switch ( dc_state ) {
00140       case DC_STATE_HDR:
00141         switch ( msg->hdr.tm_type ) {
00142           case TMTYPE_INIT:
00143             if ( tm_info_ready )
00144               nl_error( 3, "Received redundant TMTYPE_INIT" );
00145             toread += sizeof(tm_info);
00146             break;
00147           case TMTYPE_TSTAMP:
00148             if ( !tm_info_ready )
00149               nl_error( 3, "Expected TMTYPE_INIT, received TMTYPE_TSTAMP" );
00150             toread += sizeof(tstamp_t);
00151             break;
00152           case TMTYPE_DATA_T1:
00153           case TMTYPE_DATA_T2:
00154           case TMTYPE_DATA_T3:
00155           case TMTYPE_DATA_T4:
00156             if ( !tm_info_ready )
00157               nl_error( 3, "Expected TMTYPE_INIT, received TMTYPE_DATA_Tn" );
00158             if ( msg->hdr.tm_type != input_tm_type )
00159               nl_error(3, "Invalid data type: %04X", msg->hdr.tm_type );
00160             toread = nbDataHdr + nbQrow * msg->body.data1.n_rows;
00161             break;
00162           default: nl_error( 3, "Invalid TMTYPE: %04X", msg->hdr.tm_type );
00163         }
00164         dc_state = DC_STATE_DATA;
00165         if ( toread > bufsize )
00166           nl_error( 3, "Record size %d exceeds allocated buffer size %d",
00167             toread, bufsize );
00168         break;
00169       case DC_STATE_DATA:
00170         switch ( msg->hdr.tm_type ) {
00171           case TMTYPE_INIT:
00172             process_init();
00173             break;
00174           case TMTYPE_TSTAMP:
00175             process_tstamp();
00176             break;
00177           case TMTYPE_DATA_T1:
00178           case TMTYPE_DATA_T2:
00179           case TMTYPE_DATA_T3:
00180           case TMTYPE_DATA_T4:
00181             process_data();
00182             break;
00183         }
00184         if ( bytes_read > toread ) {
00185           memmove(buf, buf+toread, bytes_read - toread);
00186           bytes_read -= toread;
00187         } else if ( bytes_read == toread ) {
00188           bytes_read = 0;
00189         }
00190         toread = sizeof(tm_hdr_t);
00191         dc_state = DC_STATE_HDR;
00192         break;
00193       default: nl_error( 4, "Invalid dc_state" );
00194     }
00195   }
00196 }
00197 
00198 void data_client::resize_buffer( int bufsize_in ) {
00199   delete buf;
00200   bufsize = bufsize_in;
00201   buf = new char[bufsize];
00202   if ( buf == 0)
00203     nl_error( 3,
00204        "Memory allocation failure in data_client::resize_buffer");
00205 }
00206 
00207 void data_client::load_tmdac(char *path) {
00208   ::load_tmdac(path);
00209   init_tm_type();
00210 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines