Main Page   Class Hierarchy   Alphabetical List   Data Structures   File List   Data Fields   Globals  

nml_mod.cc

Go to the documentation of this file.
00001 
00002 /*
00003    nml_mod.cc
00004 
00005    Definition of NML_MODULE class.
00006    */
00007 
00008 /*
00009    Modification history:
00010 
00011     9-Sep-1997 WPS eliminated LOAL_LOCAL_VARIABLES, UNLOAD_LOCAL_VARIABLES,
00012     READ_CHILD_BUFFERS, WRITE_CHILD_BUFFERS, and DETERMINE_CHILD_STATUS
00013    29-May-1997 WPS replaced include nml_emc.hh with nml_oi.hh
00014     3-Apr-1997 WPS brought over the functions from RCS_MODULE_C
00015    11-Feb-1997 WPS modified  calc_avg_time, update_line_history, and
00016    stop_timing all use exec_history but fail to check to
00017    see if it is initialized.
00018    I override them here minimize changes to rcs_module.cc
00019    3-Dec-1996  FMP changed NML to RCS_CMD/STAT_CHANNEL for commandIn,
00020    statusOut, etc.
00021    112696-hui, changed the base class for commandInData, etc., from NMLmsg
00022    to RCS_CMD_MSG and RCS_STAT_MSG.
00023    16-Oct-1996  FMP inited done to 0 in ctor
00024    29-Jul-1996  FMP moved NML_ERROR, NML_TEXT, NML_DISPLAY, and NML_STATUS
00025    into nml_emc.cc
00026    29-Jul-1996  FMP added NML_TEXT and NML_DISPLAY classes
00027    10-Jun-1996  Fred Proctor added malloc/free of cmdOutstanding array
00028    5-Jun-1996  Fred Proctor added NML error stuff
00029    16-Apr-1996  Fred Proctor added NMLmsg * initing
00030    5-Apr-1996  Fred Proctor created
00031     */
00032 
00033 #ifdef EXTERN_C_STD_HEADERS
00034 extern "C"
00035 {
00036 #endif
00037 
00038 #include <stdlib.h>             // malloc()
00039 #include <string.h>             // strcpy()
00040 #ifndef UNDER_CE
00041 #include <errno.h>              // errno
00042 #endif
00043 #include <stdarg.h>
00044 #include <math.h>               // fabs()
00045 
00046 #ifdef EXTERN_C_STD_HEADERS
00047 }
00048 #endif
00049 
00050 
00051 #include "nml_mod.hh"
00052 #include "nml_oi.hh"            // NML_ERROR, NML_TEXT, NML_DISPLAY
00053 #include "rcs_prnt.hh"
00054 #include "rcs_exit.hh"
00055 
00056 #ifdef UNDER_CE
00057 #include "rcs_ce.h"
00058 #endif
00059 
00060 #if 0
00061 
00062 NML_MODULE_INI_INFO::NML_MODULE_INI_INFO (const char *inifile,
00063                                           const char *section)
00064 {
00065   const char *temp;
00066   if (NULL == inifile)
00067     {
00068       rcs_print_error ("inifile is NULL.\n");
00069       return;
00070     }
00071   if (NULL == section)
00072     {
00073       rcs_print_error ("section is NULL\n");
00074     }
00075   strncpy (ini_file, inifile, 256);
00076   strncpy (ini_section, section, 80);
00077   inif = new INIFILE (ini_file);
00078   num_entries = inif->section (section, entries, 32);
00079   temp = inif->find ("module_name");
00080   if (NULL != temp)
00081     {
00082       strncpy (module_name, temp, 80);
00083     }
00084   else
00085     {
00086       strncpy (module_name, section, 80);
00087     }
00088   temp = inif->find ("nml_file");
00089   if (NULL != temp)
00090     {
00091       strncpy (nml_file, temp, 256);
00092     }
00093   else
00094     {
00095       strncpy (nml_file, inifile, 256);
00096       char *pdot = strchr (nml_file, '.');
00097       if (NULL != pdot)
00098         {
00099           pdot = nml_file + strlen (nml_file);
00100         }
00101       strcpy (pdot, ".nml");
00102     }
00103   temp = inif->find ("cmd_buf_name");
00104   if (NULL != temp)
00105     {
00106       strncpy (cmd_buf_name, temp, 80);
00107     }
00108   else
00109     {
00110       strcpy (cmd_buf_name, module_name);
00111       strcat (cmd_buf_name, "_cmd");
00112     }
00113   temp = inif->find ("stat_buf_name");
00114   if (NULL != temp)
00115     {
00116       strncpy (stat_buf_name, temp, 80);
00117     }
00118   else
00119     {
00120       strcpy (stat_buf_name, module_name);
00121       strcat (stat_buf_name, "_stat");
00122     }
00123   temp = inif->find ("err_buf_name");
00124   if (NULL != temp)
00125     {
00126       strncpy (err_buf_name, temp, 80);
00127     }
00128   else
00129     {
00130       strcpy (err_buf_name, "errlog");
00131     }
00132 
00133 }
00134 
00135 NML_MODULE_INI_INFO::~NML_MODULE_INI_INFO ()
00136 {
00137   if (NULL != inif)
00138     {
00139       delete inif;
00140       inif = NULL;
00141     }
00142 }
00143 
00144 
00145 
00146 const char *
00147 NML_MODULE_INI_INFO::getString (const char *tag, const char *def)
00148 {
00149   if (NULL == inif)
00150     {
00151       return def;
00152     }
00153   const char *temp = inif->find (tag);
00154   if (NULL == temp)
00155     {
00156       return def;
00157     }
00158   return temp;
00159 }
00160 
00161 double
00162 NML_MODULE_INI_INFO::getDouble (const char *tag, double def)
00163 {
00164   const char *temp = getString (tag, NULL);
00165   if (NULL == temp)
00166     {
00167       return def;
00168     }
00169   errno = 0;
00170   double d = strtod (temp, NULL);
00171   if (0 != errno)
00172     {
00173       return def;
00174     }
00175   return d;
00176 }
00177 
00178 long
00179 NML_MODULE_INI_INFO::getLongInt (const char *tag, long def)
00180 {
00181   const char *temp = getString (tag, NULL);
00182   if (NULL == temp)
00183     {
00184       return def;
00185     }
00186   errno = 0;
00187   long li = strtol (temp, NULL, 0);
00188 
00189   if (0 != errno)
00190     {
00191       return def;
00192     }
00193   return li;
00194 }
00195 #endif
00196 
00197 NML_MODULE::NML_MODULE (const char *inifile, const char *section)
00198 {
00199   zero_common_vars ();
00200 #if 0
00201   ini = new NML_MODULE_INI_INFO (inifile, section);
00202 #endif
00203 }
00204 
00205 
00206 NML_MODULE::NML_MODULE ()
00207 {
00208   zero_common_vars ();
00209 }
00210 
00211 
00212 void
00213 NML_MODULE::zero_common_vars ()
00214 {
00215   commandIn = 0;
00216   force_command = 0;
00217   commandInData = 0;
00218   statusOut = 0;
00219   statusOutData = 0;
00220   subs = 0;
00221   commandLastNum = 0;
00222   commandOutstanding = 0;
00223   timer = 0;
00224   numSubordinates = 0;
00225   errorLog = 0;
00226   done = 0;
00227   statusInData = 0;
00228   commandOutData = 0;
00229 
00230 
00231   cycle_start = 0;
00232   cycle_stop = 0;
00233   command_time_averaged = 0;
00234   new_command_sequence = 0;
00235   new_line_num_sequence = 0;
00236   new_sup_request = 0;
00237 
00238   delta_clock = 0;
00239   command_current_time = 0;
00240 
00241   pause_status = 0;
00242   command = 0;
00243   last_line = 0;
00244 
00245   execute = 0;
00246   command_time = 0;
00247   state = UNINITIALIZED_STATE;
00248   status = UNINITIALIZED_STATUS;
00249 
00250   sup_req_num = 0;
00251   sup_req_num_echo = 0;
00252   command_num = 0;
00253   command_num_echo = 0;
00254 
00255   // state table vars
00256   matched = 0;
00257   stateBegin = 0;
00258 
00259 #if 0
00260 //below 010997-hui
00261   exec_status.command_num = 0;
00262   exec_status.command = 0;
00263   exec_status.status = 0;
00264   exec_status.state = 0;
00265   exec_status.line_num = 0;
00266   exec_status.command_time = 0;
00267 
00268   run_command.run_state = 0;
00269   run_command.step_num = 0;
00270 
00271   run_status.step_num_echo = 0;
00272   run_status.dummy1 = 0;
00273 #endif
00274 
00275   source_line = -1;
00276   source_file = NULL;
00277 
00278   commands_received = 0;
00279   commands_executed = 0;
00280   last_command_completed_serial_number = -1;
00281   total_run_time = 0;
00282   cycles = 0;
00283   max_cycle_time = 0;
00284   min_cycle_time = 1e6;
00285   last_cycle_time = 0;
00286   start_run_time = 0;
00287   stop_run_time = 0;
00288   last_start_run_time = 0;
00289   subs_allocated = 0;
00290   expected_cycle_time = 0;
00291   min_run_time = 1e6;
00292   max_run_time = 0;
00293   start_cycle_time = 0;
00294   temp_file = 0;
00295   temp_line = 0;
00296   Dclock_expiration = 0;
00297   Dclock_start_time = 0;
00298   log_line = 0;
00299   log_src = 0;
00300 }
00301 
00302 NML_MODULE::~NML_MODULE ()
00303 {
00304   int t;
00305 
00306   if (commandIn != 0)
00307     delete commandIn;
00308   commandIn = 0;
00309 
00310   if (statusOut != 0)
00311     delete statusOut;
00312   statusOut = 0;
00313 
00314   if (errorLog != 0)
00315     delete (errorLog);
00316   errorLog = 0;
00317 
00318   if (subs != 0)
00319     {
00320       for (t = 0; t < numSubordinates; t++)
00321         {
00322           if (subs[t] == 0)
00323             {
00324               continue;
00325             }
00326           if (subs[t]->commandOut != 0)
00327             {
00328               delete subs[t]->commandOut;
00329               subs[t]->commandOut = 0;
00330             }
00331           if (subs[t]->statusIn != 0)
00332             {
00333               delete subs[t]->statusIn;
00334               subs[t]->statusIn = 0;
00335             }
00336           subs[t]->commandOutData = 0;
00337           subs[t]->statusInData = 0;
00338           delete subs[t];
00339           subs[t] = 0;
00340         }
00341 
00342       free (subs);
00343 
00344 #if 0
00345       if (NULL != ini)
00346         {
00347           delete ini;
00348           ini = NULL;
00349         }
00350 #endif
00351       subs = 0;
00352     }
00353 
00354   if (commandOutstanding != 0)
00355     {
00356       free (commandOutstanding);
00357       commandOutstanding = 0;
00358     }
00359 
00360   if (commandLastNum != 0)
00361     {
00362       free (commandLastNum);
00363       commandLastNum = 0;
00364     }
00365 
00366   if (timer != 0)
00367     {
00368       delete timer;
00369       timer = 0;
00370     }
00371 
00372   if (proc_name != 0)
00373     {
00374       free (proc_name);
00375       proc_name = 0;
00376     }
00377 
00378 }
00379 
00380 void
00381 NML_MODULE::setCmdChannel (RCS_CMD_CHANNEL * cmd_channel)
00382 {
00383   if (NULL == cmd_channel)
00384     {
00385       rcs_print_error ("Command channel is NULL.\n");
00386       rcs_exit (-1);
00387     }
00388 
00389   commandIn = cmd_channel;
00390   if (!commandIn->valid ())
00391     {
00392       rcs_print_error ("Command channel is invalid.\n");
00393       rcs_exit (-1);
00394     }
00395   else
00396     {
00397       commandInData = commandIn->get_address ();
00398     }
00399   if (NULL != commandIn->cms)
00400     {
00401       if (NULL != commandIn->cms->ProcessName)
00402         {
00403           proc_name =
00404             (char *) malloc (strlen (commandIn->cms->ProcessName) + 1);
00405           strcpy (proc_name, commandIn->cms->ProcessName);
00406         }
00407     }
00408 }
00409 
00410 void
00411 NML_MODULE::setStatChannel (RCS_STAT_CHANNEL * stat_channel,
00412                             RCS_STAT_MSG * stat_msg)
00413 {
00414   if (NULL == stat_channel)
00415     {
00416       rcs_print_error ("Status channel is NULL.\n");
00417       rcs_exit (-1);
00418     }
00419 
00420   statusOut = stat_channel;
00421   if (!statusOut->valid ())
00422     {
00423       rcs_print_error ("Status channel is invalid.\n");
00424       rcs_exit (-1);
00425     }
00426   if (NULL == stat_msg)
00427     {
00428       rcs_print_error ("Status out message is NULL.\n");
00429       rcs_exit (-1);
00430     }
00431   if (stat_msg->type <= 0)
00432     {
00433       rcs_print_error
00434         ("Status out message must have positive type. (type = %d)\n",
00435          stat_msg->type);
00436       rcs_exit (-1);
00437     }
00438   if (stat_msg->size < ((long) sizeof (RCS_STAT_MSG)))
00439     {
00440       rcs_print_error
00441         ("Status out message must have a size of atleast sizeof(RCS_STAT_MSG) or %d bytes,",
00442          sizeof (RCS_STAT_MSG));
00443       rcs_print_error ("but the status out message size was only %d.\n",
00444                        stat_msg->size);
00445       rcs_exit (-1);
00446     }
00447   statusOutData = stat_msg;
00448 }
00449 
00450 void
00451 NML_MODULE::setErrorLogChannel (NML * errorLog_channel)
00452 {
00453   if (NULL == errorLog_channel)
00454     {
00455       rcs_print_error ("Error Log channel is NULL.\n");
00456       rcs_exit (-1);
00457     }
00458 
00459   errorLog = errorLog_channel;
00460   if (!errorLog->valid ())
00461     {
00462       rcs_print_error ("Error Log channel is invalid.\n");
00463       rcs_exit (-1);
00464     }
00465 
00466 }
00467 
00468 int
00469 NML_MODULE::addSubordinate (RCS_CMD_CHANNEL * cmd_channel,
00470                             RCS_STAT_CHANNEL * stat_channel)
00471 {
00472   int sub_num = numSubordinates;
00473   setSubordinates (numSubordinates + 1);
00474   if (NULL == cmd_channel)
00475     {
00476       logError ("Command Channel for subordinate %d is NULL.\n", sub_num);
00477       rcs_exit (-1);
00478     }
00479   if (NULL == stat_channel)
00480     {
00481       logError ("Status Channel for subordinate %d is NULL.\n", sub_num);
00482       rcs_exit (-1);
00483     }
00484   subs[sub_num]->commandOut = cmd_channel;
00485   if (!subs[sub_num]->commandOut->valid ())
00486     {
00487       logError ("Command Channel for subordinate %d is invalid.\n", sub_num);
00488       rcs_exit (-1);
00489     }
00490   else
00491     {
00492       subs[sub_num]->commandOutData =
00493         subs[sub_num]->commandOut->get_address ();
00494     }
00495   commandOutData[sub_num] = subs[sub_num]->commandOutData;
00496 
00497   subs[sub_num]->statusIn = stat_channel;
00498   if (!subs[sub_num]->statusIn->valid ())
00499     {
00500       logError ("Command Channel for subordinate %d is invalid.\n", sub_num);
00501       rcs_exit (-1);
00502     }
00503   else
00504     {
00505       subs[sub_num]->statusInData = subs[sub_num]->statusIn->get_address ();
00506     }
00507   statusInData[sub_num] = subs[sub_num]->statusInData;
00508   return sub_num;
00509 }
00510 
00511 int
00512   NML_MODULE::use_realloc = 1;
00513 
00514 int
00515 NML_MODULE::setSubordinates (int number)
00516 {
00517   int t;
00518   int previousNumSubordinates = numSubordinates;
00519   if (NULL == subs)
00520     {
00521       subs_allocated = 0;
00522     }
00523 
00524   if (subs_allocated > numSubordinates)
00525     {
00526       numSubordinates = number;
00527       subs[number]->commandOut = 0;
00528       subs[number]->commandOutData = 0;
00529       subs[number]->statusIn = 0;
00530       subs[number]->statusInData = 0;
00531       statusInData[number] = 0;
00532       commandOutData[number] = 0;
00533       return 0;
00534     }
00535 
00536   if (number < 0)
00537     return -1;
00538 
00539   // record number of subordinates
00540   numSubordinates = number;
00541 
00542   // get out now if nothing else to do
00543   if (number == 0)
00544     return 0;
00545 
00546   // allocate subordinate NML channels
00547   // On NT we sometimes get a lame problem with realloc
00548   if (use_realloc)
00549     {
00550       subs = (NML_SUBORDINATE_STRUCT **) realloc (subs,
00551                                                   number *
00552                                                   sizeof
00553                                                   (NML_SUBORDINATE_STRUCT *));
00554 
00555       statusInData = (RCS_STAT_MSG **) realloc (statusInData,
00556                                                 number *
00557                                                 sizeof (RCS_STAT_MSG *));
00558 
00559       commandOutData = (RCS_CMD_MSG **) realloc (statusInData,
00560                                                  number *
00561                                                  sizeof (RCS_CMD_MSG *));
00562     }
00563   else
00564     {
00565       NML_SUBORDINATE_STRUCT **old_subs = subs;
00566       RCS_STAT_MSG **old_statusInData = statusInData;
00567       RCS_CMD_MSG **old_commandOutData = commandOutData;
00568 
00569       subs =
00570         (NML_SUBORDINATE_STRUCT **) malloc (number *
00571                                             sizeof (NML_SUBORDINATE_STRUCT
00572                                                     *));
00573       if (NULL != old_subs && NULL != subs)
00574         {
00575           memcpy (subs, old_subs,
00576                   previousNumSubordinates *
00577                   sizeof (NML_SUBORDINATE_STRUCT *));
00578         }
00579 
00580 
00581       statusInData =
00582         (RCS_STAT_MSG **) malloc (number * sizeof (RCS_STAT_MSG *));
00583       if (NULL != old_statusInData && NULL != statusInData)
00584         {
00585           memcpy (statusInData, old_statusInData,
00586                   previousNumSubordinates * sizeof (RCS_STAT_MSG *));
00587         }
00588 
00589       commandOutData =
00590         (RCS_CMD_MSG **) malloc (number * sizeof (RCS_CMD_MSG *));
00591       if (NULL != old_commandOutData && NULL != commandOutData)
00592         {
00593           memcpy (commandOutData, old_commandOutData,
00594                   previousNumSubordinates * sizeof (RCS_CMD_MSG *));
00595         }
00596 
00597 
00598     }
00599 #if 0
00600   // allocate commandOutstanding array
00601   commandLastNum = (int *) realloc (commandLastNum, number * sizeof (int));
00602   commandOutstanding = (int *) realloc (commandOutstanding,
00603                                         number * sizeof (int));
00604 #endif
00605 
00606   if (NULL == subs || NULL == statusInData)
00607     {
00608       rcs_print_error ("Out of memory.\n");
00609       rcs_exit (-1);
00610     }
00611 
00612 
00613   // initialize each NML channel in the new arrays to 0
00614   for (t = previousNumSubordinates; t < number; t++)
00615     {
00616       subs[t] = new NML_SUBORDINATE_STRUCT ();
00617       if (NULL == subs[t])
00618         {
00619           rcs_print_error ("Out of memory.\n");
00620           rcs_exit (-1);
00621         }
00622       subs[t]->commandOut = 0;
00623       subs[t]->commandOutData = 0;
00624       subs[t]->statusIn = 0;
00625       subs[t]->statusInData = 0;
00626       statusInData[t] = 0;
00627       commandOutData[t] = 0;
00628 
00629       //      commandOutstanding[t] = 0;
00630     }
00631 
00632   subs_allocated = numSubordinates;
00633   return 0;
00634 }
00635 
00636 /*
00637    Error, text, and display functions. Note that all these go to
00638    the errorLog channel
00639    */
00640 
00641 int
00642 NML_MODULE::setLogInfo (const char *src, int l)
00643 {
00644   log_line = l;
00645   log_src = src;
00646   return (0);
00647 };
00648 
00649 int
00650 NML_MODULE::logError (const char *fmt, ...)
00651 {
00652   NML_ERROR error_msg;
00653   va_list ap;
00654 
00655   memset (error_msg.error, 0, NML_ERROR_LEN);
00656   if (log_line > 0 && log_src != NULL)
00657     {
00658       sprintf (error_msg.error, "%s:%d ", log_src, log_line);
00659     }
00660 
00661   // write args to NML message
00662   va_start (ap, fmt);
00663 #ifndef UNDER_CE
00664   vsprintf (error_msg.error, fmt, ap);
00665 #else
00666   RCS_CE_VSPRINTF (error_msg.error, fmt, ap);
00667 #endif
00668 
00669   va_end (ap);
00670 
00671   // force a NULL at the end for safety
00672   error_msg.error[NML_ERROR_LEN - 1] = 0;
00673 
00674   set_print_rcs_error_info (NULL, -1);
00675   print_rcs_error_new ("%s\n", error_msg.error);
00676 
00677 
00678   // check channel for validity
00679   if (errorLog == NULL)
00680     return -1;
00681   if (!errorLog->valid ())
00682     return -1;
00683 
00684   // write it
00685   errorLog->write (error_msg);
00686 
00687   return 0;
00688 }
00689 
00690 
00691 int
00692 NML_MODULE::logText (const char *fmt, ...)
00693 {
00694   NML_TEXT text_msg;
00695   va_list ap;
00696 
00697   // check channel for validity
00698   if (errorLog == NULL)
00699     return -1;
00700   if (!errorLog->valid ())
00701     return -1;
00702 
00703   // write args to NML message
00704   va_start (ap, fmt);
00705 #ifndef UNDER_CE
00706   vsprintf (text_msg.text, fmt, ap);
00707 #else
00708   RCS_CE_VSPRINTF (text_msg.text, fmt, ap);
00709 #endif
00710   va_end (ap);
00711 
00712   rcs_print ("%s\n", text_msg.text);
00713 
00714   // force a NULL at the end for safety
00715   text_msg.text[NML_TEXT_LEN - 1] = 0;
00716 
00717   // write it
00718   errorLog->write (text_msg);
00719 
00720   return 0;
00721 }
00722 
00723 int
00724 logTextToNML (NML * errorLog, const char *fmt, ...)
00725 {
00726   NML_TEXT text_msg;
00727   va_list ap;
00728 
00729   // check channel for validity
00730   if (errorLog == NULL)
00731     return -1;
00732 
00733   // write args to NML message
00734   va_start (ap, fmt);
00735 #ifndef UNDER_CE
00736   vsprintf (text_msg.text, fmt, ap);
00737 #else
00738   RCS_CE_VSPRINTF (text_msg.text, fmt, ap);
00739 #endif
00740   va_end (ap);
00741 
00742   //  rcs_print("%s\n", text_msg.text);
00743 
00744   // force a NULL at the end for safety
00745   text_msg.text[NML_TEXT_LEN - 1] = 0;
00746 
00747   // write it
00748   if (errorLog->write (text_msg) < 0)
00749     {
00750       return -1;
00751     }
00752 
00753   return 0;
00754 }
00755 
00756 int
00757 NML_MODULE::requestDisplay (const char *display)
00758 {
00759   NML_DISPLAY display_msg;
00760 
00761   // check channel for validity
00762   if (errorLog == NULL)
00763     return -1;
00764   if (!errorLog->valid ())
00765     return -1;
00766 
00767   // write args to NML message
00768   strcpy (display_msg.display, display);
00769 
00770   // force a NULL at the end for safety
00771   display_msg.display[NML_DISPLAY_LEN - 1] = 0;
00772 
00773   // write it
00774   errorLog->write (display_msg);
00775 
00776   return 0;
00777 }
00778 
00779 
00780 
00781 
00782 // The rest of the functions here were taken from RCS_MODULE_C
00783 
00784 
00785 // Virtual Functions
00786 //
00787 
00788 void
00789 NML_MODULE::DECISION_PROCESS (void)
00790 {
00791 
00792 }
00793 
00794 
00795 void
00796 NML_MODULE::setSelfCommand (RCS_CMD_MSG * cmd)
00797 {
00798   if (NULL == cmd || NULL == statusOutData || NULL == commandInData
00799       || NULL == commandIn)
00800     {
00801       return;
00802     }
00803   if (NULL == commandIn->cms)
00804     {
00805       return;
00806     }
00807   if (cmd->size > commandIn->cms->size)
00808     {
00809       rcs_print_error
00810         ("NML_MODULE::setSelfCommand, Command too big! %d(0x%X) > %d(0x%X)\n",
00811          cmd->size, cmd->size, commandIn->cms->size, commandIn->cms->size);
00812     }
00813   statusOutData->echo_serial_number++;
00814   cmd->serial_number = statusOutData->echo_serial_number + 1;
00815   commandIn->write (cmd);
00816   memcpy (commandInData, cmd, cmd->size);
00817   statusOutData->command_type = cmd->type;
00818   force_command = 1;
00819 }
00820 
00821 void
00822 NML_MODULE::read_command_in ()
00823 {
00824   NMLTYPE type;
00825 
00826   if (force_command)
00827     {
00828       force_command = 0;
00829       return;
00830     }
00831 
00832   switch (type = commandIn->read ())
00833     {
00834     case -1:
00835       logError ("Can not read input command. (%d)", commandIn->error_type);
00836       if (NULL != statusOutData)
00837         {
00838           statusOutData->command_type = type;
00839         }
00840       break;
00841 
00842     case 0:
00843       // no new command
00844       break;
00845 
00846     default:
00847       commandInData = commandIn->get_address ();
00848       if (NULL != statusOutData)
00849         {
00850           statusOutData->command_type = type;
00851         }
00852       break;
00853     }
00854 }
00855 
00856 void
00857 NML_MODULE::read_subordinates_status ()
00858 {
00859   int t;
00860   NMLTYPE type;
00861 
00862   // read NML STATUS buffer from subordinates
00863   for (t = 0; t < numSubordinates; t++)
00864     {
00865       if (NULL == subs[t])
00866         {
00867           continue;
00868         }
00869       if (NULL == subs[t]->statusIn)
00870         {
00871           continue;
00872         }
00873       switch (type = subs[t]->statusIn->peek ())
00874         {
00875         case -1:
00876           // error on NML channel
00877           logError ("Can not read status from subodinate %s (%d).\n",
00878                     subs[t]->statusIn->cms->BufferName,
00879                     subs[t]->statusIn->error_type);
00880           break;
00881 
00882         case 0:
00883           // no new data
00884           break;
00885 
00886         default:
00887           subs[t]->statusInData = subs[t]->statusIn->get_address ();
00888           if (NULL != subs[t]->statusInData
00889               && NULL != subs[t]->commandOutData)
00890             {
00891               if (subs[t]->statusInData->echo_serial_number !=
00892                   subs[t]->commandOutData->serial_number)
00893                 {
00894                   subs[t]->statusInData->status = RCS_EXEC;
00895                 }
00896             }
00897           // something new in STATUS
00898           break;
00899         }
00900     }
00901 }
00902 
00903 void
00904 NML_MODULE::READ_COMM_BUFFERS (void)
00905 {
00906   read_command_in ();
00907   read_subordinates_status ();
00908   check_if_new_command ();
00909 }
00910 
00911 void
00912 NML_MODULE::PRE_PROCESS (void)
00913 {
00914 
00915 }
00916 
00917 void
00918 NML_MODULE::POST_PROCESS (void)
00919 {
00920 
00921 }
00922 
00923 void
00924 NML_MODULE::write_status_out ()
00925 {
00926   if (NULL == statusOutData)
00927     {
00928       return;
00929     }
00930   // update NML STATUS
00931   statusOutData->command_type = commandInData->type;
00932   statusOutData->state = state;
00933   statusOutData->status = status;
00934   if (status == RCS_DONE &&
00935       last_command_completed_serial_number != commandInData->serial_number)
00936     {
00937       last_command_completed_serial_number = commandInData->serial_number;
00938       commands_executed++;
00939     }
00940 
00941   statusOutData->source_line = source_line;
00942   if (NULL != source_file)
00943     {
00944       strncpy (statusOutData->source_file, source_file, 64);
00945     }
00946 
00947   // write STATUS
00948   if (-1 == statusOut->write (statusOutData))
00949     {
00950       logError ("bad write to status (%d)\n", statusOut->error_type);
00951     }
00952 }
00953 
00954 void
00955 NML_MODULE::write_commands_to_subordinates ()
00956 {
00957   int t;
00958   // write subordinates
00959   for (t = 0; t < numSubordinates; t++)
00960     {
00961       if (subs[t]->commandOutData == NULL)
00962         {
00963           continue;
00964         }
00965       if (subs[t]->commandOutData->type == 0)
00966         {
00967           continue;
00968         }
00969       if (subs[t]->statusInData != NULL)
00970         {
00971           if (subs[t]->statusInData->echo_serial_number ==
00972               subs[t]->commandOutData->serial_number
00973               && subs[t]->statusInData->echo_serial_number > 0
00974               && subs[t]->modification_number <= 0)
00975             {
00976               subs[t]->commandOutData->type = 0;
00977               continue;
00978             }
00979         }
00980       if (-1 == subs[t]->commandOut->write (subs[t]->commandOutData))
00981         {
00982           logError ("Error writing to %s (%d).\n",
00983                     subs[t]->commandOut->cms->BufferName,
00984                     subs[t]->commandOut->error_type);
00985         }
00986       else
00987         {
00988           //if the subordinates  command buffer is queued then
00989           // mark the command so it isn't sent out again.
00990           if (subs[t]->commandOut->cms->queuing_enabled)
00991             {
00992               subs[t]->commandOutData->type = 0;
00993             }
00994         }
00995     }
00996 }
00997 
00998 void
00999 NML_MODULE::WRITE_COMM_BUFFERS (void)
01000 {
01001   write_status_out ();
01002   write_commands_to_subordinates ();
01003 }
01004 
01005 
01006 //***********************************************************************************
01007 //* Overhead ** Overhead ** Overhead ** Overhead **Overhead ** Overhead **Overhead **
01008 //***********************************************************************************
01009 
01010 void
01011 NML_MODULE::controller (void)
01012 {
01013 
01014   check_cycle_time_start ();
01015   READ_COMM_BUFFERS ();
01016   PRE_PROCESS ();
01017 
01018   /* reset state table flags */
01019   stateBegin = 1;
01020   matched = 0;
01021 
01022   if (commandInData != NULL)
01023     {
01024       if (statusOutData != NULL)
01025         {
01026           if (statusOutData->command_type > 0)
01027             {
01028               DECISION_PROCESS ();
01029             }
01030         }
01031     }
01032 
01033   POST_PROCESS ();
01034   WRITE_COMM_BUFFERS ();
01035   check_cycle_time_end ();
01036 
01037 }
01038 
01039 void
01040 NML_MODULE::check_cycle_time_start ()
01041 {
01042   start_run_time = etime ();
01043   cycles++;
01044   if (cycles < 2)
01045     {
01046       start_cycle_time = start_run_time;
01047     }
01048   else
01049     {
01050       last_cycle_time = start_run_time - last_start_run_time;
01051       if (last_cycle_time > max_cycle_time)
01052         {
01053           max_cycle_time = last_cycle_time;
01054         }
01055       if (last_cycle_time < min_cycle_time)
01056         {
01057           min_cycle_time = last_cycle_time;
01058         }
01059     }
01060   last_start_run_time = start_run_time;
01061 }
01062 
01063 
01064 void
01065 NML_MODULE::check_if_new_command (void)
01066 {
01067   if (NULL == commandInData)
01068     {
01069       return;
01070     }
01071   if (NULL == statusOutData)
01072     {
01073       return;
01074     }
01075   if (statusOutData->echo_serial_number != commandInData->serial_number)
01076     {
01077       state = NEW_COMMAND;
01078       status = RCS_EXEC;
01079       commands_received++;
01080       statusOutData->echo_serial_number = commandInData->serial_number;
01081       statusOutData->command_type = commandInData->type;
01082       command_time_averaged = 0;
01083       new_command_sequence = 1;
01084       new_line_num_sequence = 1;
01085 //    exec_status.line_num = 0;
01086     }
01087 }
01088 
01089 void
01090 NML_MODULE::print_statistics ()
01091 {
01092   double total_time = stop_run_time - start_cycle_time;
01093   rcs_print ("\n*************************************************\n");
01094   if (NULL != proc_name)
01095     {
01096       rcs_print ("Module Name: %s\n", proc_name);
01097     }
01098   rcs_print ("Total cycles: %d\n", cycles);
01099   rcs_print ("Total time: %f\n", total_time);
01100   if (cycles > 0)
01101     {
01102       rcs_print ("Average Cycle Time: %f\n", total_time / cycles);
01103     }
01104   else
01105     {
01106       rcs_print ("Average Cycle Time: CAN NOT BE DETERMINED\n");
01107     }
01108 
01109   rcs_print ("Minimum Cycle Time: %f\n", min_cycle_time);
01110   rcs_print ("Max Cycle Time: %f\n", max_cycle_time);
01111   rcs_print ("Commands Received: %d\n", commands_received);
01112   if (total_time > 0)
01113     {
01114       rcs_print ("Commands Received per second: %f\n",
01115                  commands_received / total_time);
01116     }
01117   else
01118     {
01119       rcs_print ("Commands Received per second: CAN NOT BE DETERMINED\n");
01120     }
01121 
01122   if (total_time > 0)
01123     {
01124       rcs_print ("Load: %f%%\n", total_run_time * 100 / total_time);
01125     }
01126   else
01127     {
01128       rcs_print ("Load: CAN NOT BE DETERMINED\n");
01129     }
01130 
01131   rcs_print ("*************************************************\n");
01132 }
01133 
01134 void
01135 NML_MODULE::check_cycle_time_end ()
01136 {
01137   stop_run_time = etime ();
01138   total_run_time += stop_run_time - start_run_time;
01139 }
01140 
01141 
01142 
01143 
01144 void
01145 NML_MODULE::set_file_and_line (char *_source_file, int _source_line)
01146 {
01147   temp_file = _source_file;
01148   temp_line = _source_line;
01149 }
01150 
01151 
01152 /*  'stateBegin' and 'matched' are set to 1 and 0, respectively, by
01153     controller(). Calls to stateMatch() in the controller logic
01154     will use these to determine if the line number needs to be set to
01155     1 or incremented, and if matches have occurred so that only one
01156     state table line is executed per pass. */
01157 int
01158 NML_MODULE::stateMatch (char *_source_file, int _source_line, int st,
01159                         int conds)
01160 {
01161   set_file_and_line (_source_file, _source_line);
01162   return stateMatch (st, conds);
01163 }
01164 
01165 int
01166 NML_MODULE::stateMatch (int st, int conds)
01167 {
01168   if (matched)
01169     {
01170       return 0;
01171     }
01172 
01173   // check if this is the first line in the state table
01174   if (stateBegin)
01175     {
01176       if (NULL != statusOutData)
01177         {
01178           statusOutData->line = 0;
01179         }
01180       source_line = -1;
01181       source_file = NULL;
01182       stateBegin = 0;
01183       if (state != st || !conds)
01184         {
01185           temp_line = -1;
01186           temp_file = NULL;
01187         }
01188     }
01189   else
01190     {
01191       // lines have gone before-- just increment
01192       if (NULL != statusOutData)
01193         {
01194           statusOutData->line++;
01195         }
01196     }
01197 
01198   // see if we match state and conditions
01199   if (state == st && conds)
01200     {
01201       matched = 1;
01202       source_file = temp_file;
01203       source_line = temp_line;
01204       return 1;
01205     }
01206   else
01207     {
01208       // no match
01209       return 0;
01210     }
01211 }
01212 
01213 void
01214 NML_MODULE::stateNext (int st)
01215 {
01216   state = (RCS_STATE) st;
01217 }
01218 
01219 void
01220 NML_MODULE::stateNext (RCS_STATE st)
01221 {
01222   state = (RCS_STATE) st;
01223 }
01224 
01225 int
01226 NML_MODULE::sendCommand (RCS_CMD_MSG * cmd_msg, int sub_num)
01227 {
01228   if (sub_num >= numSubordinates || sub_num < 0)
01229     {
01230       return -1;
01231     }
01232   if (cmd_msg == NULL)
01233     {
01234       return -1;
01235     }
01236   if (cmd_msg->size <= 0 || cmd_msg->type <= 0)
01237     {
01238       return -1;
01239     }
01240   if (NULL == subs[sub_num])
01241     {
01242       return -1;
01243     }
01244   if (NULL == subs[sub_num]->statusInData)
01245     {
01246       return -1;
01247     }
01248   if (NULL == subs[sub_num]->commandOutData)
01249     {
01250       return -1;
01251     }
01252   if (NULL == subs[sub_num]->commandOut)
01253     {
01254       return -1;
01255     }
01256   if (NULL == subs[sub_num]->commandOut->cms)
01257     {
01258       return -1;
01259     }
01260 
01261   if (cmd_msg->size >= subs[sub_num]->commandOut->cms->size)
01262     {
01263       return -1;
01264     }
01265   memcpy (subs[sub_num]->commandOutData, cmd_msg, cmd_msg->size);
01266   subs[sub_num]->modification_number = 0;
01267   subs[sub_num]->commandOutData->serial_number =
01268     subs[sub_num]->statusInData->echo_serial_number + 1;
01269   return (0);
01270 }
01271 
01272 int
01273 NML_MODULE::modifyCommand (RCS_CMD_MSG * cmd_msg, int sub_num)
01274 {
01275   if (sub_num >= numSubordinates || sub_num < 0)
01276     {
01277       return -1;
01278     }
01279   if (cmd_msg == NULL)
01280     {
01281       return -1;
01282     }
01283   if (NULL == subs[sub_num])
01284     {
01285       return -1;
01286     }
01287   if (NULL == subs[sub_num]->commandOutData)
01288     {
01289       return -1;
01290     }
01291   cmd_msg->serial_number = subs[sub_num]->commandOutData->serial_number;
01292   memcpy (subs[sub_num]->commandOutData, cmd_msg, cmd_msg->size);
01293   subs[sub_num]->modification_number++;
01294   return (0);
01295 }
01296 
01297 void
01298 NML_MODULE::loadDclock (double expiration)
01299 {
01300   Dclock_expiration = expiration;
01301   Dclock_start_time = etime ();
01302 }
01303 
01304 int
01305 NML_MODULE::checkDclock ()
01306 {
01307   return (fabs (etime () - Dclock_start_time) < Dclock_expiration);
01308 }

Generated on Sun Dec 2 15:56:50 2001 for rcslib by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001