00001
00002
00004
00005 #include "mfc_dlog_modl_base.h"
00006 #include <worm_environ.h>
00007
00008 #include <timefuncs.h>
00009
00010
00011
00012
00013
00014
00015
00016
00018
00020
00021 CMFCDialogModuleBase::CMFCDialogModuleBase()
00022 {
00023 MyGlobalUtils = NULL;
00024
00025 CommandRingKey = WORM_RING_INVALID;
00026 CommandRegion.addr = NULL;
00027 InputRingKey = WORM_RING_INVALID;
00028 InputRegion.addr = NULL;
00029 MaxMessageLength = 0;
00030 MessageBuffer = NULL;
00031 AcceptLogoCount = 0;
00032 }
00033
00034 CMFCDialogModuleBase::~CMFCDialogModuleBase()
00035 {
00036 if ( InputRingKey != CommandRingKey )
00037 {
00038 if ( InputRegion.addr != NULL )
00039 {
00040 tport_detach( &InputRegion );
00041 InputRegion.addr = NULL;
00042 }
00043 }
00044 if ( CommandRingKey )
00045 {
00046 if ( CommandRegion.addr != NULL )
00047 {
00048 tport_detach( &CommandRegion );
00049 CommandRegion.addr = NULL;
00050 }
00051 }
00052 if ( MessageBuffer != NULL )
00053 {
00054 delete( MessageBuffer );
00055 MessageBuffer = NULL;
00056 }
00057 if ( MyGlobalUtils != NULL )
00058 {
00059 delete( MyGlobalUtils );
00060 MyGlobalUtils = NULL;
00061 }
00062 }
00063
00065
00066 bool CMFCDialogModuleBase::PrepApp(const char * p_configfilename)
00067 {
00068 try
00069 {
00070
00071
00072
00073
00074
00075
00076
00077
00078 if ( (MyGlobalUtils = new TGlobalUtils(m_lpCmdLine)) == NULL )
00079 {
00080 throw worm_exception("failed creating global utilities object");
00081 }
00082
00083 LoggingLevel = TGlobalUtils::GetLoggingLevel();
00084
00085
00086 char * runPath = NULL;
00087
00088 bool _isEW = false;
00089
00090 if ( (runPath = TGlobalUtils::GetEnvironmentValue( WORM_CONFIG_DIR )) == NULL )
00091 {
00092 _isEW = true;
00093 runPath = TGlobalUtils::GetEnvironmentValue( EW_CONFIG_DIR );
00094 }
00095
00096 if ( runPath == NULL )
00097 {
00098 worm_exception _expt( "Neither environment variable <" );
00099 _expt += WORM_CONFIG_DIR;
00100 _expt += "> nor <";
00101 _expt += EW_CONFIG_DIR;
00102 _expt += "> is defined";
00103 throw _expt;
00104 }
00105
00106 if ( *runPath == '\0' )
00107 {
00108 worm_exception _expt( "Environment variable " );
00109 _expt += (_isEW ? EW_CONFIG_DIR : WORM_CONFIG_DIR);
00110 _expt += " defined, but has no value";
00111 throw _expt;
00112 }
00113
00114 if ( ! SetCurrentDirectory( runPath ) )
00115 {
00116 worm_exception _expt( "Params directory not found: " );
00117 _expt += runPath;
00118 _expt += "\nPlease set environment variable ";
00119 _expt += WORM_CONFIG_DIR;
00120 throw _expt;
00121 }
00122 }
00123 catch( worm_exception _we )
00124 {
00125 TLogger::Logit( WORM_LOG_TOFILE|WORM_LOG_TIMESTAMP
00126 , "CMFCDialogModuleBase::PrepApp(): %s\n"
00127 , _we.what()
00128 );
00129 return false;
00130 }
00131
00132 return true;
00133 }
00134
00136
00137 HANDLE_STATUS CMFCDialogModuleBase::HandleConfigLine(ConfigSource *p_parser)
00138 {
00139
00140
00141
00142 HANDLE_STATUS r_handled = MyGlobalUtils->HandleConfigLine( p_parser );
00143
00144
00145 if ( r_handled == HANDLER_UNUSED )
00146 {
00147 try
00148 {
00149 static char * _token;
00150
00151 do
00152 {
00153
00154
00155 if( p_parser->Its("AcceptLogo") )
00156 {
00157 r_handled = HANDLER_USED;
00158
00159 if ( AcceptLogoCount == SERVE_MAX_LOGOS )
00160 {
00161 throw worm_exception("Attempt to load too many <AcceptLogo> lines");
00162 }
00163
00164
00165
00166
00167
00168 _token = p_parser->String();
00169
00170 if ( strlen(_token) == 0 )
00171 {
00172 throw worm_exception("Incomplete <AcceptLogo> line (no installation)");
00173 }
00174
00175 AcceptLogo[AcceptLogoCount].instid = TGlobalUtils::LookupInstallationId(_token);
00176
00177 if ( AcceptLogo[AcceptLogoCount].instid == TGlobalUtils::LookupInstallationId("INST_WILDCARD")
00178 && strcmp(_token, "INST_WILDCARD") != 0
00179 )
00180 {
00181 worm_exception _expt("Unrecognized installation id: ");
00182 _expt += _token;
00183 throw _expt;
00184 }
00185
00186
00187
00188 _token = p_parser->String();
00189
00190 if ( strlen(_token) == 0 )
00191 {
00192 throw worm_exception("Incomplete <AcceptLogo> line (no module)");
00193 }
00194
00195 AcceptLogo[AcceptLogoCount].mod = TGlobalUtils::LookupModuleId(_token);
00196
00197 if ( AcceptLogo[AcceptLogoCount].mod == TGlobalUtils::LookupModuleId("MOD_WILDCARD")
00198 && strcmp(_token, "MOD_WILDCARD") != 0
00199 )
00200 {
00201 worm_exception _expt("Unrecognized module id: ");
00202 _expt += _token;
00203 throw _expt;
00204 }
00205
00206
00207
00208 _token = p_parser->String();
00209
00210 if ( strlen(_token) == 0 )
00211 {
00212 throw worm_exception("Incomplete <AcceptLogo> line (no message type)");
00213 }
00214
00215 AcceptLogo[AcceptLogoCount].type = TGlobalUtils::LookupMessageTypeId(_token);
00216
00217 if ( AcceptLogo[AcceptLogoCount].type == TGlobalUtils::LookupMessageTypeId("TYPE_WILDCARD")
00218 && strcmp(_token, "TYPE_WILDCARD") != 0
00219 )
00220 {
00221 worm_exception _expt("Unrecognized message type id: ");
00222 _expt += _token;
00223 throw _expt;
00224 }
00225
00226 AcceptLogoCount++;
00227
00228 continue;
00229 }
00230
00231 if ( p_parser->Its("CmdRingName") )
00232 {
00233 r_handled = HANDLER_USED;
00234 _token = p_parser->String();
00235 if ( strlen(_token) == 0 )
00236 {
00237 throw worm_exception("missing <CmdRingName> value");
00238 }
00239 strncpy( CommandRingName, _token, MAX_RINGNAME_LEN );
00240
00241 if ( (CommandRingKey = TGlobalUtils::LookupRingKey(CommandRingName)) == WORM_RING_INVALID )
00242 {
00243 throw worm_exception("invalid <CmdRingName> value");
00244 }
00245
00246 continue;
00247 }
00248
00249 if( p_parser->Its("InputRingName") )
00250 {
00251 r_handled = HANDLER_USED;
00252 _token = p_parser->String();
00253 if ( strlen(_token) == 0 )
00254 {
00255 throw worm_exception("missing <InputRing> for input messages");
00256 }
00257 strncpy( InputRingName, _token, MAX_RINGNAME_LEN );
00258
00259 if ( (InputRingKey = TGlobalUtils::LookupRingKey(InputRingName)) == WORM_RING_INVALID )
00260 {
00261 throw worm_exception("invalid <InputRing>");
00262 }
00263 continue;
00264 }
00265
00266 if( p_parser->Its("MaxMsgSize") )
00267 {
00268 r_handled = HANDLER_USED;
00269 int _maxmsglen = p_parser->Int();
00270 if ( _maxmsglen <= 0 )
00271 {
00272 throw worm_exception("invalid <MaxMsgSize> for input messages");
00273 }
00274 MaxMessageLength = _maxmsglen;
00275 continue;
00276 }
00277
00278 } while( false );
00279 }
00280 catch( worm_exception _we )
00281 {
00282 r_handled = HANDLER_INVALID;
00283 TLogger::Logit( WORM_LOG_TOFILE
00284 , "CMFCDialogModuleBase::HandleConfigLine(): configuration error: %s\nin line: %s\n"
00285 , _we.what()
00286 , p_parser->GetCurrentLine()
00287 );
00288 }
00289 }
00290
00291 return r_handled;
00292 }
00293
00295
00296 void CMFCDialogModuleBase::CheckConfig()
00297 {
00298
00299
00300 if ( MyGlobalUtils == NULL )
00301 {
00302 TLogger::Logit( WORM_LOG_TOFILE
00303 , "CMFCDialogModuleBase::CheckConfig(): Global Configurations object not created\n"
00304 );
00305 ConfigState = WORM_STAT_BADSTATE;
00306 }
00307 else
00308 {
00309 LoggingLevel = TGlobalUtils::GetLoggingLevel();
00310
00311 if ( ! MyGlobalUtils->IsReady() )
00312 {
00313 TLogger::Logit( WORM_LOG_TOFILE
00314 , "CMFCDialogModuleBase::CheckConfig(): Global Configurations object not configured\n"
00315 );
00316 ConfigState = WORM_STAT_BADSTATE;
00317 }
00318 }
00319
00320 if ( TGlobalUtils::GetHeartbeatInt() < 1 )
00321 {
00322 TLogger::Logit( WORM_LOG_TOFILE
00323 , "CMFCDialogModuleBase::CheckConfig(): No <HeartBeatInt> value from the config file\n"
00324 );
00325 ConfigState = WORM_STAT_BADSTATE;
00326 }
00327
00328 if ( AcceptLogoCount == 0 )
00329 {
00330 TLogger::Logit( WORM_LOG_TOFILE
00331 , "CMFCDialogModuleBase::CheckConfig(): No <AcceptLogo> lines found in the config file\n"
00332 );
00333 ConfigState = WORM_STAT_BADSTATE;
00334 }
00335
00336 if ( CommandRingKey == WORM_RING_INVALID )
00337 {
00338 TLogger::Logit( WORM_LOG_TOFILE
00339 , "CMFCDialogModuleBase::CheckConfig(): No <CmdRingName> value from the config file\n"
00340 );
00341 ConfigState = WORM_STAT_BADSTATE;
00342 }
00343
00344
00345 if( (TYPE_HEARTBEAT = TGlobalUtils::LookupMessageTypeId("TYPE_HEARTBEAT")) == WORM_MSGTYPE_INVALID )
00346 {
00347 TLogger::Logit( WORM_LOG_TOFILE
00348 , "CMFCDialogModuleBase::CheckConfig(): Message type TYPE_HEARTBEAT not defined\n"
00349 );
00350 ConfigState = WORM_STAT_BADSTATE;
00351 }
00352
00353 if( (TYPE_ERROR = TGlobalUtils::LookupMessageTypeId("TYPE_ERROR")) == WORM_MSGTYPE_INVALID )
00354 {
00355 TLogger::Logit( WORM_LOG_TOFILE
00356 , "CMFCDialogModuleBase::CheckConfig(): Message type TYPE_ERROR not defined\n"
00357 );
00358 ConfigState = WORM_STAT_BADSTATE;
00359 }
00360
00361 if ( MaxMessageLength <= 1 )
00362 {
00363 TLogger::Logit( WORM_LOG_TOFILE
00364 , "CMFCDialogModuleBase::CheckConfig(): No valid <MaxMsgSize> found in the config file\n"
00365 );
00366 ConfigState = WORM_STAT_BADSTATE;
00367 }
00368 }
00369
00371
00372 bool CMFCDialogModuleBase::InitApp()
00373 {
00374 bool r_status = true;
00375
00376
00377 try
00378 {
00379
00380
00381
00382 if ( (StatusThread = AfxBeginThread( StartMFCWorkerThread
00383 , this
00384 , 0
00385 , 0
00386 , NULL
00387 )) == NULL )
00388 {
00389 throw worm_exception("Failed starting the status thread");
00390 }
00391
00392
00393 TTimeFuncs::MSecSleep( 300 );
00394
00395 }
00396 catch( worm_exception _we )
00397 {
00398 TLogger::Logit( WORM_LOG_TOFILE|WORM_LOG_TIMESTAMP
00399 , "CMFCDialogModuleBase::InitApp(): Error: %s\n"
00400 , _we.what()
00401 );
00402 r_status = false;
00403 }
00404
00405 return r_status;
00406 }
00407
00409
00410 bool CMFCDialogModuleBase::BeforeMessage() { return true; }
00411
00413
00414 UINT CMFCDialogModuleBase::StartWorkerThread()
00415 {
00416 return StatusAndReadLoop();
00417 }
00418
00420
00421 UINT CMFCDialogModuleBase::StatusAndReadLoop()
00422 {
00423 unsigned char InstallWildcard = TGlobalUtils::LookupInstallationId("INST_WILDCARD")
00424 , ModuleWildcard = TGlobalUtils::LookupModuleId("MOD_WILDCARD")
00425 , MessageWildcard = TGlobalUtils::LookupMessageTypeId("TYPE_WILDCARD")
00426 ;
00427
00428 UINT r_status = 0;
00429
00430 try
00431 {
00432
00433 TTimeFuncs::MSecSleep( 1000 );
00434
00435
00436
00437
00438
00439
00440
00441
00442 tport_attach( &CommandRegion, CommandRingKey );
00443
00444
00445 if ( InputRingKey != WORM_RING_INVALID )
00446 {
00447
00448
00449
00450
00451
00452 if ( (MessageBuffer = new char[MaxMessageLength+1]) == NULL )
00453 {
00454 throw worm_exception("RingReaderServer::PrepareToRun(): failed allocating message buffer");
00455 }
00456
00457
00458
00459 if ( InputRingKey != CommandRingKey )
00460 {
00461 tport_attach( &InputRegion, InputRingKey );
00462 }
00463 else
00464 {
00465 memcpy( (void *)&InputRegion , (void *)&CommandRegion, sizeof(InputRegion) );
00466 }
00467 }
00468
00469
00470
00471 int flag;
00472
00473 long CurrentTime
00474 , LastBeatTime
00475 ;
00476 bool MsgIsReady = false;
00477 MSG_LOGO _arrivelogo;
00478 long _arr_msg_len;
00479 char _errormsg[300];
00480
00481
00482
00483
00484 time(&CurrentTime);
00485 LastBeatTime = CurrentTime;
00486
00487
00488
00489
00490 while( tport_getmsg( &InputRegion
00491 , AcceptLogo
00492 , AcceptLogoCount
00493 , &_arrivelogo
00494 , &_arr_msg_len
00495 , MessageBuffer
00496 , MaxMessageLength
00497 ) != GET_NONE );
00498
00499
00500 if ( ! BeforeMessage() )
00501 {
00502 throw worm_exception("BeforeMessage() returned error");
00503 }
00504
00505
00506 Running = true;
00507 do
00508 {
00509
00510 flag = tport_getflag(&CommandRegion);
00511 if( flag == TERMINATE || flag == (int)TGlobalUtils::GetPID() )
00512 {
00513 Running = false;
00514 continue;
00515 }
00516
00517
00518 if( TGlobalUtils::GetHeartbeatInt() <= (time(&CurrentTime) - LastBeatTime) )
00519 {
00520 LastBeatTime = CurrentTime;
00521 SendStatus( TYPE_HEARTBEAT, 0, "" );
00522 }
00523
00524
00525
00526 if ( CheckForFatal() )
00527 {
00528 Running = false;
00529 continue;
00530 }
00531
00532
00533 if ( InputRingKey != WORM_RING_INVALID )
00534 {
00535
00536
00537
00538
00539 MsgIsReady = true;
00540
00541 switch(
00542 tport_getmsg( &InputRegion
00543 , AcceptLogo
00544 , AcceptLogoCount
00545 , &_arrivelogo
00546 , &_arr_msg_len
00547 , MessageBuffer
00548 , MaxMessageLength
00549 )
00550 )
00551 {
00552 case GET_OK:
00553 break;
00554
00555 case GET_MISS:
00556 case GET_MISS_LAPPED:
00557
00558 SendStatus( TYPE_ERROR, ERR_MISSMSG, "missed messages" );
00559 break;
00560
00561 case GET_MISS_SEQGAP:
00562
00563 SendStatus( TYPE_ERROR, ERR_MISSMSG, "saw sequence gap" );
00564 break;
00565
00566 case GET_NOTRACK:
00567
00568 sprintf( _errormsg
00569 , "no tracking for logo i%d m%d t%d in %s"
00570 , (int)_arrivelogo.instid
00571 , (int)_arrivelogo.mod
00572 , (int)_arrivelogo.type
00573 , InputRingName
00574 );
00575 SendStatus( TYPE_ERROR, ERR_NOTRACK, _errormsg );
00576 break;
00577
00578 case GET_TOOBIG:
00579
00580 sprintf( _errormsg
00581 , "tport msg[%ld] i%d m%d t%d too big. Max is %ld"
00582 , _arr_msg_len
00583 , (int)_arrivelogo.instid
00584 , (int)_arrivelogo.mod
00585 , (int)_arrivelogo.type
00586 , MaxMessageLength
00587 );
00588 SendStatus( TYPE_ERROR, ERR_TOOBIG, _errormsg );
00589
00590
00591
00592 case GET_NONE:
00593
00594 MsgIsReady = false;
00595 break;
00596 }
00597
00598 }
00599
00600
00601 if ( MsgIsReady )
00602 {
00603
00604 MessageBuffer[_arr_msg_len] = 0;
00605
00606
00607 if ( MessageBuffer[_arr_msg_len-1] == '\n' )
00608 {
00609 _arr_msg_len--;
00610 MessageBuffer[_arr_msg_len] = 0;
00611 }
00612
00613 for ( int _i = 0, _sz = AcceptLogoCount ; _i < _sz ; _i++ )
00614 {
00615 if ( ( AcceptLogo[_i].instid == InstallWildcard
00616 || _arrivelogo.instid == InstallWildcard
00617 || _arrivelogo.instid == AcceptLogo[_i].instid
00618 )
00619 && ( AcceptLogo[_i].mod == ModuleWildcard
00620 || _arrivelogo.mod == ModuleWildcard
00621 || _arrivelogo.mod == AcceptLogo[_i].mod
00622 )
00623 && ( AcceptLogo[_i].type == MessageWildcard
00624 || _arrivelogo.type == MessageWildcard
00625 || _arrivelogo.type == AcceptLogo[_i].type
00626 )
00627 )
00628 {
00629 if ( ! HandleMessage(_arrivelogo, MessageBuffer) )
00630 {
00631
00632 Running = false;
00633 }
00634 break;
00635 }
00636 }
00637
00638 }
00639 else
00640 {
00641
00642 TTimeFuncs::MSecSleep(500);
00643 }
00644
00645 } while( Running );
00646
00647 }
00648 catch( worm_exception _we )
00649 {
00650 r_status = WORM_STAT_FAILURE;
00651 TLogger::Logit( WORM_LOG_TOFILE|WORM_LOG_TIMESTAMP
00652 , "CMFCDialogModuleBase::StatusAndReadLoop(): error: %s\n"
00653 , _we.what()
00654 );
00655 }
00656
00657 if ( GetMainWindow() != NULL )
00658 {
00659 ((CDialog *)GetMainWindow())->EndDialog(IDCANCEL);
00660 }
00661
00662 return r_status;
00663 }
00664
00666
00667 void CMFCDialogModuleBase::HeartBeat()
00668 {
00669 static long _lastBeat = 0
00670 , _interval = TGlobalUtils::GetHeartbeatInt()
00671 ;
00672
00673 if ( 0 < _interval )
00674 {
00675 if ( (_lastBeat + _interval) < time(NULL) )
00676 {
00677 SendStatus(TYPE_HEARTBEAT);
00678 _lastBeat = time(NULL);
00679 }
00680 }
00681 }
00682
00684
00685 void CMFCDialogModuleBase::SendStatus( WORM_MSGTYPE_ID p_type
00686 , short p_ierr
00687 , const char * p_text
00688 )
00689 {
00690 if ( CommandRegion.addr == NULL )
00691 {
00692 TLogger::Logit( WORM_LOG_TOFILE|WORM_LOG_TIMESTAMP
00693 , "CMFCDialogModuleBase::SendStatus(): Command Ring share is NULL\n"
00694 );
00695 return;
00696 }
00697
00698 try
00699 {
00700 MSG_LOGO logo;
00701 char msg[256];
00702 long size;
00703 long t;
00704
00705
00706
00707 logo.instid = TGlobalUtils::GetThisInstallationId();
00708 logo.mod = TGlobalUtils::GetThisModuleId();
00709 logo.type = p_type;
00710
00711 time( &t );
00712
00713 strcpy( msg, "" );
00714
00715 if( p_type == TYPE_HEARTBEAT )
00716 {
00717 sprintf( msg, "%ld %ld\n\0", t, TGlobalUtils::GetPID());
00718 }
00719 else if( p_type == TYPE_ERROR )
00720 {
00721 sprintf( msg, "%ld %hd %s\n\0", t, p_ierr, p_text);
00722 }
00723 else
00724 {
00725 if ( LoggingLevel == WORM_LOG_DEBUG )
00726 {
00727 TLogger::Logit( WORM_LOG_TOFILE|WORM_LOG_TIMESTAMP
00728 , "CMFCDialogModuleBase::SendStatus(): invalid message type %d\n"
00729 , p_type
00730 );
00731 }
00732 return;
00733 }
00734
00735 size = strlen( msg );
00736
00737
00738
00739
00740 if( tport_putmsg( &CommandRegion, &logo, size, msg ) != PUT_OK )
00741 {
00742 if( p_type == TYPE_HEARTBEAT )
00743 {
00744 TLogger::Logit( WORM_LOG_TOFILE|WORM_LOG_TIMESTAMP
00745 , "WormServerBase::SendStatus(): Error sending heartbeat.\n"
00746 );
00747 }
00748 else
00749 {
00750 TLogger::Logit( WORM_LOG_TOFILE|WORM_LOG_TIMESTAMP
00751 , "WormServerBase::SendStatus(): Error sending error: %d.\n"
00752 , p_ierr
00753 );
00754 }
00755 }
00756 }
00757 catch( ... )
00758 {
00759 TLogger::Logit( WORM_LOG_TOFILE|WORM_LOG_TIMESTAMP
00760 , "TModuleBase::SendStatus() Error\n"
00761 );
00762
00763 Running = false;
00764 }
00765 }
00766