00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "TGo4MbsSource.h"
00015
00016 #include <stdlib.h>
00017
00018 #include "TObjArray.h"
00019 #include "TClass.h"
00020 #include "TSystem.h"
00021
00022 #include "TGo4MbsEvent.h"
00023 #include "TGo4MbsSubEvent.h"
00024 #include "TGo4MbsSourceParameter.h"
00025
00026 #include "TGo4Log.h"
00027 #include "TGo4EventErrorException.h"
00028 #include "TGo4EventTimeoutException.h"
00029 #include "TGo4EventEndException.h"
00030
00031 const UInt_t TGo4MbsSource::fguLONGBYCHAR = sizeof(Int_t) / sizeof(Char_t);
00032 const UInt_t TGo4MbsSource::fguSHORTBYCHAR = sizeof(Short_t) / sizeof(Char_t);
00033 const UInt_t TGo4MbsSource::fguLONGBYSHORT = sizeof(Int_t) / sizeof(Short_t);
00034 const UInt_t TGo4MbsSource::fguEVHEBYCHAR = sizeof(s_evhe) / sizeof(Char_t);
00035
00036 TGo4MbsSource::TGo4MbsSource(TGo4MbsSourceParameter* par, Int_t mode) :
00037 TGo4EventSource(par->GetName()),
00038 fiMode(mode),
00039 fiRetryCnt(par->GetRetryCnt()),
00040 fxEvent(0), fxBuffer(0), fxInfoHeader(0),
00041 fbIsOpen(kFALSE), fbDataCopyMode(kFALSE),
00042 fuEventCounter(0), fbFirstEvent(kTRUE),
00043 fuStartEvent(par->GetStartEvent()) ,
00044 fuStopEvent(par->GetStopEvent()),
00045 fuEventInterval(par->GetEventInterval()),
00046 fiTimeout(par->GetTimeout()),
00047 fiPort(par->GetPort())
00048 {
00049 fxInputChannel=f_evt_control();
00050 GO4TRACE((15,"TGo4MbsSource::TGo4MbsSource(const char*, Int_t)",__LINE__, __FILE__));
00051
00052
00053 }
00054
00055
00056 TGo4MbsSource::TGo4MbsSource(const char* name, Int_t mode) :
00057 TGo4EventSource(name),
00058 fiMode(mode),
00059 fiRetryCnt(0),
00060 fxEvent(0), fxBuffer(0), fxInfoHeader(0),
00061 fbIsOpen(kFALSE), fbDataCopyMode(kFALSE),
00062 fuEventCounter(0), fbFirstEvent(kTRUE),
00063 fuStartEvent(0) ,fuStopEvent(0), fuEventInterval(0),
00064 fiTimeout(-1), fiPort(0)
00065 {
00066 fxInputChannel = f_evt_control();
00067 GO4TRACE((15,"TGo4MbsSource::TGo4MbsSource(const char*, Int_t)",__LINE__, __FILE__));
00068
00069 SetTimeout(fgiTIMEOUTDEFAULT);
00070
00071
00072
00073 }
00074
00075
00076 TGo4MbsSource::TGo4MbsSource() :
00077 TGo4EventSource("default mbs source"),
00078 fiMode(0),
00079 fiRetryCnt(0),
00080 fxEvent(0), fxBuffer(0), fxInfoHeader(0),
00081 fbIsOpen(kFALSE), fbDataCopyMode(kFALSE),
00082 fuEventCounter(0), fbFirstEvent(kTRUE),
00083 fuStartEvent(0) ,fuStopEvent(0), fuEventInterval(0),
00084 fiTimeout(-1), fiPort(0)
00085 {
00086 fxInputChannel = f_evt_control();
00087 GO4TRACE((15,"TGo4MbsSource::TGo4MbsSource()",__LINE__, __FILE__));
00088 }
00089
00090 TGo4MbsSource::~TGo4MbsSource()
00091 {
00092 GO4TRACE((15,"TGo4MbsSource::~TGo4MbsSource()",__LINE__, __FILE__));
00093 Close();
00094 if(fxInputChannel)free(fxInputChannel);
00095 }
00096
00097 void TGo4MbsSource::SetPrintEvent(Int_t num, Int_t sid, Int_t longw, Int_t hexw, Int_t dataw)
00098 {
00099 fxPrEventPar.fiNum = num;
00100 fxPrEventPar.fiSid = sid;
00101 fxPrEventPar.fiLong = longw;
00102 fxPrEventPar.fiHex = hexw;
00103 fxPrEventPar.fiData = dataw;
00104 }
00105
00106 Bool_t TGo4MbsSource::CheckEventClass(TClass* cl)
00107 {
00108 return cl->InheritsFrom(TGo4MbsEvent::Class());
00109 }
00110
00111 Bool_t TGo4MbsSource::BuildEvent(TGo4EventElement* dest)
00112 {
00113 Int_t rev = NextEvent();
00114 if(rev != GETEVT__SUCCESS) {
00115 TGo4Log::Debug(" Mbs Event -- !!! NextEvent() error: %s !!! ", GetErrMess());
00116 return kFALSE;
00117 }
00118
00119 BuildMbsEvent((TGo4MbsEvent*) dest);
00120 return kTRUE;
00121 }
00122
00123
00124 void TGo4MbsSource::BuildMbsEvent(TGo4MbsEvent* target)
00125 {
00126 GO4TRACE((12,"TGo4MbsSource::BuildMbsEvent(TGo4MbsEvent*)",__LINE__, __FILE__));
00127 TGo4MbsSubEvent* subtarget=0;
00128 if(fxEvent!=0 && GetEventStatus()==GETEVT__SUCCESS) {
00129
00130 if(fxPrEventPar.fiNum>0) {
00131 f_evt_type(fxBuffer,
00132 (s_evhe *) fxEvent,
00133 fxPrEventPar.fiSid,
00134 fxPrEventPar.fiLong,
00135 fxPrEventPar.fiHex,
00136 fxPrEventPar.fiData);
00137 std::cout << std::endl;
00138 fxPrEventPar.fiNum--;
00139 }
00140
00141 Char_t* endofevent = (Char_t*) (fxEvent) +
00142 (fxEvent->l_dlen) * fguSHORTBYCHAR + fguEVHEBYCHAR ;
00143
00144 target->SetValid(kTRUE);
00145 target->SetDlen(fxEvent->l_dlen);
00146 target->SetType(fxEvent->i_type);
00147 target->SetSubtype(fxEvent->i_subtype);
00148
00149
00150
00151
00152
00153 if(fxEvent->i_type==10) {
00154 s_ves10_1* subevent;
00155 Char_t* subevtpointer;
00156 target->SetTrigger(fxEvent->i_trigger);
00157 target->SetCount(fxEvent->l_count);
00158 target->SetDummy(fxEvent->i_dummy);
00159 Int_t totalsubdatalength=0;
00160 if(fxEvent->l_dlen > 4) {
00161
00162 subevent = (s_ves10_1*) (fxEvent + 1);
00163
00164
00165 Int_t datalength = 0;
00166
00167 while((datalength = subevent->l_dlen) >0 ) {
00168 totalsubdatalength+=datalength-2+sizeof(s_ves10_1)/sizeof(Short_t);
00169 if(datalength>fxEvent->l_dlen) {
00170 TGo4Log::Debug(" !!! MbsSource -- SUBEVENTS LENGTH mismatch!!! skipping event #%d",fxEvent->l_count);
00171 TGo4Log::Debug("\t sub dlen:%d, event dlen:%d ",datalength-2, fxEvent->l_dlen-4);
00172 target->SetValid(kFALSE);
00173 break;
00174 }
00175 Int_t * subeventid= (Int_t *) (subevent) + 2;
00176
00177 Short_t* data = (Short_t*) (subevent+1);
00178 subtarget = target->AddSubEvent(*subeventid, data, datalength, fbDataCopyMode);
00179 subtarget->SetType(subevent->i_type);
00180 subtarget->SetSubtype(subevent->i_subtype);
00181 subevtpointer = (Char_t*) (subevent) +
00182 datalength * fguSHORTBYCHAR + fguEVHEBYCHAR;
00183 subevent = (s_ves10_1*) subevtpointer;
00184 if ((Char_t*) subevent >= endofevent) {
00185
00186 break;
00187 }
00188 }
00189 if(totalsubdatalength!=fxEvent->l_dlen-4) {
00190 TGo4Log::Debug(" !!! MbsSource -- SUBEVENTS TOTAL LENGTH mismatch!!! disabling event #%d",fxEvent->l_count);
00191 TGo4Log::Debug("\t subdlen sum:%d, event dlen:%d ",totalsubdatalength, fxEvent->l_dlen-4);
00192 target->SetValid(kFALSE);
00193 }
00194 } else {
00195
00196 TGo4Log::Debug(" !!! MbsSource -- NO SUBEVENTS!!! ");
00197 SetErrMess("!!! BuildMbsEvent: -- NO SUBEVENTS!!!");
00198 throw TGo4EventTimeoutException(this);
00199 }
00200 } else
00201
00202
00203
00204 if(fxEvent->i_type==4) {
00205
00206 s_evhe* eventfourone= (s_evhe*) fxEvent;
00207
00208 target->SetTrigger(4);
00209 target->SetCount(1);
00210 target->SetDummy(0);
00211 if(fxEvent->l_dlen > 0) {
00212 Int_t subeventid= 4;
00213 Short_t* data = (Short_t*) (eventfourone+1);
00214 Int_t datalength=eventfourone->l_dlen+2;
00215
00216 subtarget = target->AddSubEvent(subeventid, data, datalength, fbDataCopyMode);
00217 subtarget->SetType(4);
00218 subtarget->SetSubtype(1);
00219 } else {
00220
00221 TGo4Log::Debug(" !!! MbsSource -- NO Data in event 4,1!!! ");
00222 SetErrMess("!!! BuildMbsEvent: -- NO Data in event 4,1!!!");
00223 throw TGo4EventTimeoutException(this);
00224 }
00225 } else {
00226 TGo4Log::Debug(" !!! Mbs Source -- ERROR: Unknown event type %d !!! ",fxEvent->i_type);
00227 throw TGo4EventErrorException(this);
00228 }
00229
00230 } else {
00231
00232 TGo4Log::Debug(" !!! Mbs Source -- ERROR: %s !!! ",GetErrMess());
00233 throw TGo4EventErrorException(this);
00234 }
00235 }
00236
00237
00238 TGo4MbsSubEvent* TGo4MbsSource::BuildMbsSubEvent(TGo4MbsEvent * target, Int_t fullID, Short_t* source, Int_t datalength)
00239 {
00240
00241
00242 return target->AddSubEvent(fullID, source, datalength, fbDataCopyMode);
00243 }
00244
00245 Int_t TGo4MbsSource::NextEvent()
00246 {
00247
00248 frombegin:
00249
00250 GO4TRACE((12,"TGo4MbsSource::NextEvent()",__LINE__, __FILE__));
00251
00252 ULong_t eventstep;
00253
00254 if (fbFirstEvent) {
00255 fbFirstEvent = kFALSE;
00256 eventstep = fuStartEvent + 1;
00257 TGo4Log::Info("MBS source:: First event = %lu step = %lu\n", fuStartEvent, fuEventInterval);
00258
00259 } else
00260 if(fuEventInterval > 0)
00261 eventstep = fuEventInterval;
00262 else
00263 eventstep = 1;
00264
00265
00266 if(fuStopEvent!=0 && fuEventCounter>=fuStopEvent)
00267 SetEventStatus(GETEVT__NOMORE);
00268 else {
00269
00270 if(fuEventCounter+eventstep<fuEventCounter)
00271 {
00272 TGo4Log::Warn("TGo4MbsSource::NextEvent(): Overflow of eventcounter at %d, reset to 0",fuEventCounter),
00273 fuEventCounter=0;
00274 }
00275 while (eventstep > 0) {
00276
00277 Int_t status = f_evt_get_event(fxInputChannel,
00278 (Int_t **) (void*) &fxEvent,
00279 (Int_t **) (void*) &fxBuffer);
00280 SetEventStatus(status);
00281 if(status!=0) break;
00282 eventstep--;
00283 fuEventCounter++;
00284 }
00285 }
00286
00287 if(GetEventStatus()!=0) {
00288 char buffer[TGo4EventSource::fguTXTLEN];
00289 f_evt_error(GetEventStatus(),buffer,1);
00290 SetErrMess(Form("%s name:%s", buffer, GetName()));
00291 }
00292
00293 switch(GetEventStatus()) {
00294 case 0:
00295 return 0;
00296 break;
00297 case GETEVT__TIMEOUT:
00298 throw TGo4EventTimeoutException(this);
00299 break;
00300 case GETEVT__NOMORE:
00301 throw TGo4EventEndException(this);
00302 break;
00303 default: {
00304 if (((fiMode==GETEVT__STREAM) || (fiMode==GETEVT__TRANS) || (fiMode==GETEVT__REVSERV) || (fiMode==GETEVT__EVENT)) && (fiRetryCnt>0)) {
00305
00306 printf("Error code %d mess %s\n", GetEventStatus(), GetErrMess());
00307
00308 Close();
00309 Int_t cnt = fiRetryCnt;
00310
00311 while (cnt-->0) {
00312 gSystem->Sleep(1000);
00313
00314
00315
00316 try {
00317 Open();
00318 if (fbIsOpen) {
00319 printf("Retry %d successful\n", cnt);
00320 fflush(stdout);
00321 goto frombegin;
00322 }
00323 } catch (TGo4EventErrorException e) {
00324 }
00325 printf("Retry %d failed\n", cnt);
00326 fflush(stdout);
00327 }
00328 }
00329
00330 throw TGo4EventErrorException(this);
00331 break;
00332 }
00333 }
00334
00335 TGo4Log::Error("MbsSource::NextEvent -- NEVER COME HERE");
00336 return GetEventStatus();
00337 }
00338
00339 Int_t TGo4MbsSource::Open()
00340 {
00341 GO4TRACE((12,"TGo4MbsSource::Open()",__LINE__, __FILE__));
00342
00343 if(fbIsOpen) return -1;
00344
00345
00346
00347 char name[5000];
00348 strncpy(name, GetName(), sizeof(name));
00349 int nport = fiPort;
00350
00351 char* separ = strrchr(name, ':');
00352 if ((nport<=0) && (separ!=0) && (GetMode() != GETEVT__FILE)) {
00353 if ((sscanf(separ+1,"%d",&nport)==1) && (nport>0)) {
00354 *separ = 0;
00355 } else {
00356 nport = fiPort;
00357 }
00358 }
00359
00360 Int_t status = f_evt_source_port(nport);
00361 SetCreateStatus(status);
00362 if(GetCreateStatus() != GETEVT__SUCCESS) {
00363 char buffer[TGo4EventSource::fguTXTLEN];
00364 f_evt_error(GetCreateStatus(), buffer, 1);
00365 SetErrMess(Form("%s name:%s port:%d", buffer, name, nport));
00366 throw TGo4EventErrorException(this);
00367 }
00368
00369 void* headptr= &fxInfoHeader;
00370 f_evt_timeout(fxInputChannel, fiTimeout);
00371 status = f_evt_get_open(
00372 fiMode,
00373 name,
00374 fxInputChannel,
00375 (Char_t**) headptr,
00376 0,
00377 0);
00378 SetCreateStatus(status);
00379 if(GetCreateStatus() !=GETEVT__SUCCESS) {
00380 char buffer[TGo4EventSource::fguTXTLEN];
00381 f_evt_error(GetCreateStatus(),buffer,1);
00382 SetErrMess(Form("%s name:%s", buffer, GetName()));
00383 fbIsOpen = kFALSE;
00384 throw TGo4EventErrorException(this);
00385 } else {
00386 TGo4Log::Debug(" Mbs Source -- opened input from type %d: %s . Timeout=%d s",
00387 fiMode, GetName(), fiTimeout);
00388 fbIsOpen = kTRUE;
00389 }
00390 return status;
00391 }
00392
00393 Int_t TGo4MbsSource::Close()
00394 {
00395 GO4TRACE((12,"TGo4MbsSource::Close()",__LINE__, __FILE__));
00396 if(!fbIsOpen) return -1;
00397
00398 Int_t rev = GetCreateStatus();
00399
00400 if(rev == GETEVT__SUCCESS) {
00401 f_evt_get_close(fxInputChannel);
00402 fbIsOpen=kFALSE;
00403 }
00404
00405 return rev;
00406 }
00407
00408 s_bufhe * TGo4MbsSource::GetBufferHeader()
00409 {
00410 return (s_bufhe*) f_evt_get_buffer_ptr(fxInputChannel);
00411 }