00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifdef EXTERN_C_STD_HEADERS
00034 extern "C"
00035 {
00036 #endif
00037
00038 #include <stdlib.h>
00039 #include <string.h>
00040 #ifndef UNDER_CE
00041 #include <errno.h>
00042 #endif
00043 #include <stdarg.h>
00044 #include <math.h>
00045
00046 #ifdef EXTERN_C_STD_HEADERS
00047 }
00048 #endif
00049
00050
00051 #include "nml_mod.hh"
00052 #include "nml_oi.hh"
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
00256 matched = 0;
00257 stateBegin = 0;
00258
00259 #if 0
00260
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
00540 numSubordinates = number;
00541
00542
00543 if (number == 0)
00544 return 0;
00545
00546
00547
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
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
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
00630 }
00631
00632 subs_allocated = numSubordinates;
00633 return 0;
00634 }
00635
00636
00637
00638
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
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
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
00679 if (errorLog == NULL)
00680 return -1;
00681 if (!errorLog->valid ())
00682 return -1;
00683
00684
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
00698 if (errorLog == NULL)
00699 return -1;
00700 if (!errorLog->valid ())
00701 return -1;
00702
00703
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
00715 text_msg.text[NML_TEXT_LEN - 1] = 0;
00716
00717
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
00730 if (errorLog == NULL)
00731 return -1;
00732
00733
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
00743
00744
00745 text_msg.text[NML_TEXT_LEN - 1] = 0;
00746
00747
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
00762 if (errorLog == NULL)
00763 return -1;
00764 if (!errorLog->valid ())
00765 return -1;
00766
00767
00768 strcpy (display_msg.display, display);
00769
00770
00771 display_msg.display[NML_DISPLAY_LEN - 1] = 0;
00772
00773
00774 errorLog->write (display_msg);
00775
00776 return 0;
00777 }
00778
00779
00780
00781
00782
00783
00784
00785
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
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
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
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
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
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
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
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
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
00989
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
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
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
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
01153
01154
01155
01156
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
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
01192 if (NULL != statusOutData)
01193 {
01194 statusOutData->line++;
01195 }
01196 }
01197
01198
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
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 }