00001
00002 #include "ringreaderserver.h"
00003
00004
00005
00006 #include <logger.h>
00007 #include <worm_exceptions.h>
00008 #include <comfile.h>
00009
00010 #pragma package(smart_init)
00011
00012
00013
00014 RingReaderServer::RingReaderServer()
00015 {
00016 InputRingKey = WORM_RING_INVALID;
00017 InputRegion.addr = NULL;
00018 MaxMessageLength = 0;
00019 MessageBuffer = NULL;
00020 ServeLogoCount = 0;
00021 }
00022
00023 RingReaderServer::~RingReaderServer()
00024 {
00025 if ( InputRingKey != CommandRingKey )
00026 {
00027 if ( InputRegion.addr != NULL )
00028 {
00029 tport_detach( &InputRegion );
00030 InputRegion.addr = NULL;
00031 }
00032 }
00033 if ( MessageBuffer != NULL )
00034 {
00035 delete( MessageBuffer );
00036 }
00037 }
00038
00039 HANDLE_STATUS RingReaderServer::HandleConfigLine( ConfigSource * p_parser )
00040 {
00041
00042
00043 HANDLE_STATUS r_handled = WormServerBase::HandleConfigLine(p_parser);
00044
00045 if ( r_handled == HANDLER_UNUSED )
00046 {
00047
00048
00049 char * _token;
00050
00051 try
00052 {
00053 do
00054 {
00055
00056 if( p_parser->Its("ServeLogo") )
00057 {
00058 r_handled = HANDLER_USED;
00059
00060 if ( ServeLogoCount == SERVE_MAX_LOGOS )
00061 {
00062 throw worm_exception("Attempt to load too many <ServeLogo> lines");
00063 }
00064
00065
00066
00067
00068
00069 _token = p_parser->String();
00070
00071 if ( strlen(_token) == 0 )
00072 {
00073 throw worm_exception("Incomplete <ServeLogo> line (no installation)");
00074 }
00075
00076 ServeLogo[ServeLogoCount].instid = TGlobalUtils::LookupInstallationId(_token);
00077
00078 if ( ServeLogo[ServeLogoCount].type == TGlobalUtils::LookupInstallationId("INST_WILDCARD")
00079 && strcmp(_token, "INST_WILDCARD") != 0
00080 )
00081 {
00082 worm_exception _expt("Unrecognized installation id: ");
00083 _expt += _token;
00084 _expt += " in <ServeLogo> line";
00085 throw _expt;
00086 }
00087
00088
00089
00090 _token = p_parser->String();
00091
00092 if ( strlen(_token) == 0 )
00093 {
00094 throw worm_exception("Incomplete <ServeLogo> line (no module)");
00095 }
00096
00097 ServeLogo[ServeLogoCount].mod = TGlobalUtils::LookupModuleId(_token);
00098
00099 if ( ServeLogo[ServeLogoCount].mod == TGlobalUtils::LookupModuleId("MOD_WILDCARD")
00100 && strcmp(_token, "MOD_WILDCARD") != 0
00101 )
00102 {
00103 worm_exception _expt("Unrecognized module id: ");
00104 _expt += _token;
00105 _expt += " in <ServeLogo> line";
00106 throw _expt;
00107 }
00108
00109
00110
00111 _token = p_parser->String();
00112
00113 if ( strlen(_token) == 0 )
00114 {
00115 throw worm_exception("Incomplete <ServeLogo> line (no message type)");
00116 }
00117
00118 ServeLogo[ServeLogoCount].type = TGlobalUtils::LookupMessageTypeId(_token);
00119
00120 if ( ServeLogo[ServeLogoCount].type == TGlobalUtils::LookupMessageTypeId("TYPE_WILDCARD")
00121 && strcmp(_token, "TYPE_WILDCARD") != 0
00122 )
00123 {
00124 worm_exception _expt("Unrecognized message type id: ");
00125 _expt += _token;
00126 _expt += " in <ServeLogo> line";
00127 throw _expt;
00128 }
00129
00130 ServeLogoCount++;
00131
00132 continue;
00133 }
00134
00135 if( p_parser->Its("InputRing") )
00136 {
00137 r_handled = HANDLER_USED;
00138 _token = p_parser->String();
00139 if ( strlen(_token) == 0 )
00140 {
00141 throw worm_exception("missing <InputRing> for input messages");
00142 }
00143 strncpy( InputRingName, _token, MAX_RINGNAME_LEN );
00144
00145 if ( (InputRingKey = TGlobalUtils::LookupRingKey(InputRingName)) == WORM_RING_INVALID )
00146 {
00147 throw worm_exception("invalid <InputRing>");
00148 }
00149 continue;
00150 }
00151
00152 if( p_parser->Its("MaxMsgSize") )
00153 {
00154 r_handled = HANDLER_USED;
00155 int _maxmsglen = p_parser->Int();
00156 if ( _maxmsglen <= 0 )
00157 {
00158 throw worm_exception("invalid <MaxMsgSize> for input messages");
00159 }
00160 MaxMessageLength = _maxmsglen;
00161 continue;
00162 }
00163
00164 } while( false );
00165 }
00166 catch( worm_exception _rte )
00167 {
00168 r_handled = HANDLER_INVALID;
00169 TLogger::Logit( WORM_LOG_TOFILE|WORM_LOG_TOSTDERR|WORM_LOG_TIMESTAMP
00170 , "RingReaderServer::HandleConfigLine(): configuration error:\n%s\n"
00171 , _rte.what()
00172 );
00173 r_handled = HANDLER_INVALID;
00174 }
00175 }
00176 return r_handled;
00177 }
00178
00179 void RingReaderServer::CheckConfig()
00180 {
00181 WormServerBase::CheckConfig();
00182
00183 if ( ServeLogoCount == 0 )
00184 {
00185 TLogger::Logit( WORM_LOG_TOFILE|WORM_LOG_TOSTDERR|WORM_LOG_TIMESTAMP
00186 , "RingReaderServer::HaveMyConfigs(): No <ServeLogo> lines found in the config file\n"
00187 );
00188 ConfigState = WORM_STAT_BADSTATE;
00189 }
00190
00191 if ( InputRingKey == WORM_RING_INVALID )
00192 {
00193 TLogger::Logit( WORM_LOG_TOFILE|WORM_LOG_TOSTDERR|WORM_LOG_TIMESTAMP
00194 , "RingReaderServer::HaveMyConfigs(): No <InputRing> found in the config file\n"
00195 );
00196 ConfigState = WORM_STAT_BADSTATE;
00197 }
00198
00199 if ( MaxMessageLength <= 1 )
00200 {
00201 TLogger::Logit( WORM_LOG_TOFILE|WORM_LOG_TOSTDERR|WORM_LOG_TIMESTAMP
00202 , "RingReaderServer::HaveMyConfigs(): No valid <MaxMsgSize> found in the config file\n"
00203 );
00204 ConfigState = WORM_STAT_BADSTATE;
00205 }
00206 }
00207
00208 bool RingReaderServer::PrepareToRun()
00209 {
00210 bool r_state = true;
00211 try
00212 {
00213 if ( TGlobalUtils::LookupMessageTypeId("TYPE_ERROR") == WORM_MSGTYPE_INVALID )
00214 {
00215 throw worm_exception("RingReaderServer::PrepareToRun(): message type TYPE_ERROR not found in lookups");
00216 }
00217
00218 if ( (MessageBuffer = new char[MaxMessageLength+1]) == NULL )
00219 {
00220 throw worm_exception("RingReaderServer::PrepareToRun(): failed allocating message buffer");
00221 }
00222
00223
00224 if ( (LoggingLevel = TGlobalUtils::GetLoggingLevel()) == WORM_LOG_DEBUG )
00225 {
00226 TLogger::Logit( WORM_LOG_TOFILE|WORM_LOG_TOSTDOUT
00227 , "RingReaderServer::PrepareToRun(): A %s %d %d (%d + 1)\n"
00228 , InputRingName
00229 , InputRingKey
00230 , InputRegion.addr
00231 , MaxMessageLength
00232 );
00233 }
00234
00235 if ( InputRingKey != CommandRingKey )
00236 {
00237 tport_attach( &InputRegion, InputRingKey );
00238 }
00239 else
00240 {
00241 memcpy( (void *)&InputRegion , (void *)&CommandRegion, sizeof(InputRegion) );
00242 }
00243
00244 if ( TGlobalUtils::GetLoggingLevel() == WORM_LOG_DEBUG )
00245 {
00246 TLogger::Logit( WORM_LOG_TOFILE|WORM_LOG_TOSTDOUT
00247 , "RingReaderServer::PrepareToRun(): B %s %d %d\n"
00248 , InputRingName
00249 , InputRingKey
00250 , InputRegion.addr
00251 );
00252 }
00253 }
00254 catch( worm_exception _rte )
00255 {
00256 r_state = false;
00257 }
00258 return r_state;
00259 }
00260
00261 WORM_STATUS_CODE RingReaderServer::MainThreadActions()
00262 {
00263 static int _getmsg_status;
00264 static MSG_LOGO _arrivelogo;
00265 static long _arr_msg_len;
00266 static bool _msg_ready;
00267 static char _errormsg[300];
00268
00269 static InstallWildcard = TGlobalUtils::LookupInstallationId("INST_WILDCARD");
00270 static ModuleWildcard = TGlobalUtils::LookupModuleId("MOD_WILDCARD");
00271 static MessageWildcard = TGlobalUtils::LookupMessageTypeId("TYPE_WILDCARD");
00272
00273 WORM_STATUS_CODE r_status = WORM_STAT_SUCCESS;
00274
00275 try
00276 {
00277 _msg_ready = true;
00278
00279
00280 _getmsg_status = tport_getmsg( &InputRegion
00281 , ServeLogo
00282 , ServeLogoCount
00283 , &_arrivelogo
00284 , &_arr_msg_len
00285 , MessageBuffer
00286 , MaxMessageLength
00287 );
00288
00289 switch( _getmsg_status )
00290 {
00291 case GET_OK:
00292 break;
00293
00294 case GET_MISS:
00295 case GET_MISS_LAPPED:
00296
00297 SendStatus( TGlobalUtils::LookupMessageTypeId("TYPE_ERROR"), ERR_MISSMSG, "missed messages" );
00298 break;
00299
00300 case GET_MISS_SEQGAP:
00301
00302 SendStatus( TGlobalUtils::LookupMessageTypeId("TYPE_ERROR"), ERR_MISSMSG, "saw sequence gap" );
00303 break;
00304
00305 case GET_NOTRACK:
00306
00307 sprintf( _errormsg
00308 , "no tracking for logo i%d m%d t%d in %s"
00309 , (int)_arrivelogo.instid
00310 , (int)_arrivelogo.mod
00311 , (int)_arrivelogo.type
00312 , InputRingName
00313 );
00314 SendStatus( TGlobalUtils::LookupMessageTypeId("TYPE_ERROR"), ERR_NOTRACK, _errormsg );
00315 break;
00316
00317 case GET_TOOBIG:
00318
00319 sprintf( _errormsg
00320 , "tport msg[%ld] i%d m%d t%d too big. Max is %ld"
00321 , _arr_msg_len
00322 , (int)_arrivelogo.instid
00323 , (int)_arrivelogo.mod
00324 , (int)_arrivelogo.type
00325 , MaxMessageLength
00326 );
00327 SendStatus( TGlobalUtils::LookupMessageTypeId("TYPE_ERROR"), ERR_TOOBIG, _errormsg );
00328
00329
00330
00331 case GET_NONE:
00332 _msg_ready = false;
00333
00334
00335 break;
00336 }
00337
00338 if ( _msg_ready )
00339 {
00340
00341 MessageBuffer[_arr_msg_len] = 0;
00342
00343 if ( MessageBuffer[_arr_msg_len-1] == '\n' )
00344 {
00345 _arr_msg_len--;
00346 MessageBuffer[_arr_msg_len] = 0;
00347 }
00348
00349 for ( int _i = 0, _sz = ServeLogoCount ; _i < _sz ; _i++ )
00350 {
00351 if ( ( ServeLogo[_i].instid == InstallWildcard
00352 || _arrivelogo.instid == InstallWildcard
00353 || _arrivelogo.instid == ServeLogo[_i].instid
00354 )
00355 && ( ServeLogo[_i].mod == ModuleWildcard
00356 || _arrivelogo.mod == ModuleWildcard
00357 || _arrivelogo.mod == ServeLogo[_i].mod
00358 )
00359 && ( ServeLogo[_i].type == MessageWildcard
00360 || _arrivelogo.type == MessageWildcard
00361 || _arrivelogo.type == ServeLogo[_i].type
00362 )
00363 )
00364 {
00365 if ( ! MessageFromRing(_arrivelogo, MessageBuffer) )
00366 {
00367 throw worm_exception("MessageFromRing() reported failure");
00368 }
00369 break;
00370 }
00371 }
00372 }
00373 }
00374 catch( worm_exception _rte )
00375 {
00376 r_status = WORM_STAT_FAILURE;
00377 }
00378
00379 return r_status;
00380 }
00381
00382 void RingReaderServer::FinishedRunning()
00383 {
00384 if ( InputRegion.addr != NULL )
00385 {
00386 if ( InputRingKey != CommandRingKey )
00387 {
00388 tport_detach( &InputRegion );
00389 }
00390 InputRegion.addr = NULL;
00391 }
00392 }
00393
00394