CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/EventFilter/ResourceBroker/src/FUResource.cc

Go to the documentation of this file.
00001 
00002 //
00003 // FUResource
00004 // ----------
00005 //
00006 //            12/10/2006 Philipp Schieferdecker <philipp.schieferdecker@cern.ch>
00008 
00009 
00010 #include "EventFilter/ResourceBroker/interface/FUResource.h"
00011 #include "FWCore/Utilities/interface/CRC16.h"
00012 #include "EventFilter/Utilities/interface/GlobalEventNumber.h"
00013 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00014 
00015 #include "EvffedFillerRB.h"
00016 
00017 #include "interface/shared/frl_header.h"
00018 #include "interface/shared/fed_header.h"
00019 #include "interface/shared/fed_trailer.h"
00020 #include "interface/shared/i2oXFunctionCodes.h"
00021 #include "interface/evb/i2oEVBMsgs.h"
00022 
00023 
00024 #include "xdaq/Application.h"
00025 #include "toolbox/mem/Reference.h"
00026 #include "xcept/tools.h"
00027 
00028 #include <sstream>
00029 #include <sys/shm.h>
00030 
00031 
00032 #define FED_HCTRLID    0x50000000
00033 #define FED_TCTRLID    0xa0000000
00034 #define REAL_SOID_MASK 0x0003FF00
00035 #define FED_RBIT_MASK  0x0000C004
00036 
00037 
00038 using namespace std;
00039 using namespace evf;
00040 
00041 
00043 // initialize static members
00045 
00046 //______________________________________________________________________________
00047 bool FUResource::doFedIdCheck_ = true;
00048 bool FUResource::useEvmBoard_ = true;
00049 unsigned int FUResource::gtpEvmId_ =  FEDNumbering::MINTriggerGTPFEDID;
00050 unsigned int FUResource::gtpDaqId_ =  FEDNumbering::MAXTriggerGTPFEDID;
00051 unsigned int FUResource::gtpeId_ =  FEDNumbering::MINTriggerEGTPFEDID;
00052 
00054 // construction/destruction
00056 
00057 //______________________________________________________________________________
00058 FUResource::FUResource(UInt_t fuResourceId
00059                        , log4cplus::Logger logger
00060                        , EvffedFillerRB *frb
00061                        , xdaq::Application *app)
00062   : log_(logger)
00063   , fuResourceId_(fuResourceId)
00064   , superFragHead_(0)
00065   , superFragTail_(0)
00066   , nbBytes_(0)
00067   , superFragSize_(0)
00068   , frb_(frb)
00069   , app_(app)
00070   , nextEventWillHaveCRCError_(false)
00071 {
00072   release();
00073 }
00074 
00075 
00076 //______________________________________________________________________________
00077 FUResource::~FUResource()
00078 {
00079   
00080 }
00081 
00082 
00084 // implementation of member functions
00086 
00087 //______________________________________________________________________________
00088 void FUResource::allocate(FUShmRawCell* shmCell)
00089 {
00090   //release();
00091   shmCell_=shmCell;
00092   shmCell_->clear();
00093   shmCell_->setFuResourceId(fuResourceId_);
00094   eventPayloadSize_=shmCell_->payloadSize();
00095   nFedMax_         =shmCell_->nFed();
00096   nSuperFragMax_   =shmCell_->nSuperFrag();
00097 }
00098 
00099 
00100 //______________________________________________________________________________
00101 void FUResource::release()
00102 {
00103   doCrcCheck_   =false;
00104   fatalError_   =false;
00105   
00106   buResourceId_ =0xffffffff;
00107   evtNumber_    =0xffffffff;
00108   
00109   if (0!=superFragHead_) {
00110     try {
00111       superFragHead_->release();
00112     }
00113     catch (xcept::Exception& e) {
00114       LOG4CPLUS_ERROR(log_,"Failed to release superFragHead: "
00115                       <<xcept::stdformat_exception_history(e));
00116     }
00117   }
00118   
00119   superFragHead_=0;
00120   superFragTail_=0;
00121   
00122   iBlock_       =0;
00123   nBlock_       =0xffffffff;
00124   iSuperFrag_   =0;
00125   nSuperFrag_   =0xffffffff;
00126 
00127   nbSent_       =0;
00128   
00129   nbErrors_     =0;
00130   nbCrcErrors_  =0;
00131 
00132   for (UInt_t i=0;i<1024;i++) fedSize_[i]=0;
00133   eventSize_    =0;
00134   
00135   if (0!=shmCell_) {
00136     shmdt(shmCell_);
00137     shmCell_=0;
00138   }
00139 }
00140 
00141 
00142 //______________________________________________________________________________
00143 void FUResource::process(MemRef_t* bufRef)
00144 {
00145   if (fatalError()) {
00146     LOG4CPLUS_WARN(log_,"THIS SHOULD *NEVER* HAPPEN!."); // DEBUG
00147     bufRef->release();
00148     return;
00149   }
00150   
00151   MemRef_t* itBufRef = bufRef;
00152   while(0!=itBufRef&&!fatalError()) {
00153     MemRef_t* next=itBufRef->getNextReference();
00154     itBufRef->setNextReference(0);
00155     try {
00156       processDataBlock(itBufRef);
00157     }
00158     catch (xcept::Exception& e) {
00159       LOG4CPLUS_ERROR(log_,"EVENT LOST:"
00160                       <<xcept::stdformat_exception_history(e));
00161       fatalError_=true;
00162       itBufRef->setNextReference(next); 
00163     }
00164     
00165     itBufRef=next;
00166   }
00167   if(isComplete()){
00168     frb_->putHeader(evtNumber_,0);
00169     frb_->putTrailer();
00170     fedSize_[frb_->fedId()]=frb_->size();  
00171     UChar_t *startPos = shmCell_->writeData(frb_->getPayload(),frb_->size());
00172     superFragSize_=frb_->size();
00173     if (!shmCell_->markSuperFrag(iSuperFrag_,superFragSize_,startPos)) {
00174       nbErrors_++;
00175       stringstream oss;
00176       oss<<"Failed to mark super fragment in shared mem buffer."
00177          <<" fuResourceId:"<<fuResourceId_
00178          <<" evtNumber:"<<evtNumber_
00179          <<" iSuperFrag:"<<iSuperFrag_;
00180       XCEPT_RAISE(evf::Exception,oss.str());
00181     }
00182     
00183     if (!shmCell_->markFed(frb_->fedId(),frb_->size(),startPos)) {
00184       nbErrors_++;
00185       stringstream oss;
00186       oss<<"Failed to mark fed in buffer."
00187          <<" evtNumber:"<<evtNumber_
00188          <<" fedId:"<<frb_->fedId()
00189          <<" fedSize:"<<frb_->size()
00190          <<" fedAddr:0x"<<hex<<(unsigned long)frb_->getPayload()<<dec;
00191       XCEPT_RAISE(evf::Exception,oss.str());
00192     }
00193 
00194   }
00195   return;
00196 }
00197 
00198 
00199 //______________________________________________________________________________
00200 void FUResource::processDataBlock(MemRef_t* bufRef)
00201   throw (evf::Exception)
00202 {
00203   // reset iBlock_/nBlock_ counters
00204   if (iBlock_==nBlock_) {
00205     iBlock_=0;
00206     nBlock_=0xffffffff;
00207   }
00208   
00209   I2O_EVENT_DATA_BLOCK_MESSAGE_FRAME *block=
00210     (I2O_EVENT_DATA_BLOCK_MESSAGE_FRAME*)bufRef->getDataLocation();
00211   
00212   UInt_t iBlock      =block->blockNb;
00213   UInt_t nBlock      =block->nbBlocksInSuperFragment;
00214   UInt_t iSuperFrag  =block->superFragmentNb;
00215   UInt_t nSuperFrag  =block->nbSuperFragmentsInEvent;
00216   
00217   UInt_t fuResourceId=block->fuTransactionId;
00218   UInt_t buResourceId=block->buResourceId;
00219   UInt_t evtNumber   =block->eventNumber;
00220   stringstream oss;
00221   oss << "TransId:" << fuResourceId << " BUResourceId:" 
00222       << buResourceId << " eventNumber:" << evtNumber << " "; 
00223   // check fuResourceId consistency
00224   if (fuResourceId!=fuResourceId_) {
00225     nbErrors_++;
00226 
00227     oss<<"RU/FU fuResourceId mismatch."
00228        <<" Received:"<<fuResourceId
00229        <<" Expected:"<<fuResourceId_;
00230     XCEPT_RAISE(evf::Exception,oss.str());
00231   }
00232   
00233   // check iBlock consistency
00234   if (iBlock!=iBlock_) {
00235     nbErrors_++;
00236     oss<<"RU/FU block number mismatch."
00237        <<" Received:"<<iBlock
00238        <<" Expected:"<<iBlock_;
00239     XCEPT_RAISE(evf::Exception,oss.str());
00240   }
00241   
00242   // check iSuperFrag consistency
00243   if (iSuperFrag!=iSuperFrag_) {
00244     nbErrors_++;
00245     oss<<"RU/FU superfragment number mismatch."
00246        <<" Received:"<<iSuperFrag
00247        <<" Expected:"<<iSuperFrag_;
00248     XCEPT_RAISE(evf::Exception,oss.str());
00249   }
00250 
00251   // assign nBlock_
00252   if (iBlock==0) {
00253     nBlock_=nBlock;
00254   }
00255   else {
00256     // check nBlock_
00257     if (nBlock!=nBlock_) {
00258       nbErrors_++;
00259       oss<<"RU/FU number of blocks mismatch."
00260          <<" Received:"<<nBlock
00261          <<" Expected:"<<nBlock_;
00262       XCEPT_RAISE(evf::Exception,oss.str());
00263     }
00264   }
00265   
00266   
00267   // if this is the first block in the event,
00268   // *assign* evtNumber,buResourceId,nSuperFrag ...
00269   if (iBlock==0&&iSuperFrag==0) {
00270     evtNumber_   =evtNumber;
00271     buResourceId_=buResourceId;
00272     nSuperFrag_  =nSuperFrag;
00273     
00274     shmCell_->setEvtNumber(evtNumber);
00275     shmCell_->setBuResourceId(buResourceId);
00276 
00277     // check that buffers are allocated for nSuperFrag superfragments
00278     if(nSuperFrag_>nSuperFragMax_) {
00279       nbErrors_++;
00280       oss<<"Invalid maximum number of superfragments."
00281          <<" fuResourceId:"<<fuResourceId_
00282          <<" evtNumber:"<<evtNumber_
00283          <<" nSuperFrag:"<<nSuperFrag_
00284          <<" nSuperFragMax:"<<nSuperFragMax_;
00285       XCEPT_RAISE(evf::Exception,oss.str());
00286     }
00287   }
00288   // ... otherwise,
00289   // *check* evtNumber,buResourceId,nSuperFrag
00290   else {
00291     // check evtNumber
00292     if (evtNumber!=evtNumber_) {
00293       nbErrors_++;
00294       oss<<"RU/FU evtNumber mismatch."
00295          <<" Received:"<<evtNumber
00296          <<" Expected:"<<evtNumber_;
00297       XCEPT_RAISE(evf::Exception,oss.str());
00298     }
00299     
00300     // check buResourceId
00301     if (buResourceId!=buResourceId_) {
00302       nbErrors_++;
00303       oss<<"RU/FU buResourceId mismatch."
00304          <<" Received:"<<buResourceId
00305          <<" Expected:"<<buResourceId_;
00306       XCEPT_RAISE(evf::Exception,oss.str());
00307     }
00308     
00309     // check nSuperFrag
00310     if (nSuperFrag!=nSuperFrag_) {
00311       nbErrors_++;
00312       oss<<"RU/FU number of superfragments mismatch."
00313          <<" Received:"<<nSuperFrag
00314          <<" Expected:"<<nSuperFrag_;
00315       XCEPT_RAISE(evf::Exception,oss.str());
00316     }
00317   }
00318   
00319   
00320   // check payload
00321   try {
00322     checkDataBlockPayload(bufRef);
00323   }
00324   catch (xcept::Exception& e) {
00325     oss<<"data block payload failed check."
00326        <<" evtNumber:"<<evtNumber_
00327        <<" buResourceId:"<<buResourceId_
00328        <<" iSuperFrag:"<<iSuperFrag_;
00329     XCEPT_RETHROW(evf::Exception,oss.str(),e);
00330   }
00331   
00332   appendBlockToSuperFrag(bufRef);
00333 
00334   // increment iBlock_, as expected for the next message
00335   iBlock_++;
00336   
00337   // superfragment complete ...
00338   bool lastBlockInSuperFrag=(iBlock==nBlock-1);
00339   if (lastBlockInSuperFrag) {
00340     
00341     // ... fill the FED buffers contained in the superfragment
00342     try {
00343       superFragSize();
00344       fillSuperFragPayload();
00345       findFEDs();
00346     }
00347     catch (xcept::Exception& e) {
00348       oss<<"Invalid super fragment."
00349          <<" evtNumber:"<<evtNumber_
00350          <<" buResourceId:"<<buResourceId_
00351          <<" iSuperFrag:"<<iSuperFrag_;
00352       removeLastAppendedBlockFromSuperFrag();
00353       XCEPT_RETHROW(evf::Exception,oss.str(),e);
00354     }
00355     
00356     // ... release the buffers associated with the superfragment
00357     try {
00358       releaseSuperFrag();
00359     }
00360     catch (xcept::Exception& e) {
00361       nbErrors_++;
00362       oss<<"Failed to release super fragment."
00363          <<" evtNumber:"<<evtNumber_
00364          <<" buResourceId:"<<buResourceId_
00365          <<" iSuperFrag:"<<iSuperFrag_;
00366       XCEPT_RETHROW(evf::Exception,oss.str(),e);
00367     }
00368 
00369     // increment iSuperFrag_, as expected for the next message(s)
00370     iSuperFrag_++;
00371     
00372   } // lastBlockInSuperFragment
00373   
00374   return;
00375 }
00376 
00377 
00378 //______________________________________________________________________________
00379 void FUResource::checkDataBlockPayload(MemRef_t* bufRef)
00380   throw (evf::Exception)
00381 {
00382   UInt_t   frameSize      =0;
00383   UInt_t   bufSize        =0;
00384   UInt_t   segSize        =0;
00385   UInt_t   segSizeExpected=0;
00386 
00387   frlh_t  *frlHeader      =0;
00388   
00389   UChar_t *blockAddr      =0;
00390   UChar_t *frlHeaderAddr  =0;
00391   
00392   frameSize    =sizeof(I2O_EVENT_DATA_BLOCK_MESSAGE_FRAME);
00393 
00394   blockAddr    =(UChar_t*)bufRef->getDataLocation();
00395   frlHeaderAddr=blockAddr+frameSize;
00396   frlHeader    =(frlh_t*)frlHeaderAddr;
00397   
00398   I2O_EVENT_DATA_BLOCK_MESSAGE_FRAME *block
00399     =(I2O_EVENT_DATA_BLOCK_MESSAGE_FRAME*)blockAddr;
00400     
00401 
00402   // check that FRL trigno is consistent with FU evtNumber
00403   if(evtNumber_!=frlHeader->trigno) {
00404     nbErrors_++;
00405     std::stringstream oss;
00406     oss<<"FRL header \"trigno\" does not match "
00407        <<"FU  \"evtNumber\"."
00408        <<" trigno:"<<frlHeader->trigno
00409        <<" evtNumber:"<<evtNumber_;
00410     XCEPT_RAISE(evf::Exception,oss.str());
00411   }
00412   
00413 
00414   // check that FRL trigno is consistent with RU eventNumber
00415   if(block->eventNumber!=frlHeader->trigno) {
00416     nbErrors_++;
00417     std::stringstream oss;
00418     oss<<"FRL header \"trigno\" does not match "
00419        <<"RU builder header \"eventNumber\"."
00420        <<" trigno:"<<frlHeader->trigno
00421        <<" eventNumber:"<<block->eventNumber;
00422     XCEPT_RAISE(evf::Exception,oss.str());
00423   }
00424   
00425 
00426   // check that block numbers reported by FRL / RU are consistent
00427   if(block->blockNb!=frlHeader->segno) {
00428     nbErrors_++;
00429     std::stringstream oss;
00430     oss<<"FRL header \"segno\" does not match"
00431        <<"RU builder header \"blockNb\"."
00432        <<" segno:"<<frlHeader->segno
00433        <<" blockNb:"<<block->blockNb;
00434     XCEPT_RAISE(evf::Exception,oss.str());
00435   }
00436   
00437   
00438   // reported block number consistent with expectation
00439   if(block->blockNb!=iBlock_) {
00440     nbErrors_++;
00441     std::stringstream oss;
00442     oss<<"Incorrect block number."
00443        <<" Expected:"<<iBlock_
00444        <<" Received:"<<block->blockNb;
00445     XCEPT_RAISE(evf::Exception, oss.str());
00446   }
00447   
00448   
00449   // reported payload size consistent with expectation
00450   bufSize        =bufRef->getDataSize();
00451   segSizeExpected=bufSize-frameSize-sizeof(frlh_t);
00452   segSize        =frlHeader->segsize & FRL_SEGSIZE_MASK;
00453   if(segSize!=segSizeExpected) {
00454     nbErrors_++;
00455     std::stringstream oss;
00456     oss<<"FRL header segment size is not as expected."
00457        <<" Expected:"<<segSizeExpected
00458        <<" Received:"<<segSize;
00459     XCEPT_RAISE(evf::Exception, oss.str());
00460   }
00461   
00462   
00463   // Check that FU and FRL headers agree on end of super-fragment
00464   bool fuLastBlockInSuperFrag =(block->blockNb==(block->nbBlocksInSuperFragment-1));
00465   bool frlLastBlockInSuperFrag=((frlHeader->segsize & FRL_LAST_SEGM)!=0);
00466   if (fuLastBlockInSuperFrag!=frlLastBlockInSuperFrag) {
00467     nbErrors_++;
00468     std::stringstream oss;
00469     oss<<"FU / FRL header end-of-superfragment mismatch."
00470        <<" FU header:"<<fuLastBlockInSuperFrag
00471        <<" FRL header:"<<frlLastBlockInSuperFrag;
00472     XCEPT_RAISE(evf::Exception,oss.str());
00473   }
00474   
00475   return;
00476 }
00477 
00478 
00479 //______________________________________________________________________________
00480 void FUResource::appendBlockToSuperFrag(MemRef_t* bufRef)
00481 {
00482   if (0==superFragHead_) {
00483     superFragHead_=bufRef;
00484     superFragTail_=bufRef;
00485   }
00486   else {
00487     superFragTail_->setNextReference(bufRef);
00488     superFragTail_=bufRef;
00489   }
00490   return;
00491 }
00492 
00493 //______________________________________________________________________________
00494 void FUResource::removeLastAppendedBlockFromSuperFrag()
00495 {
00496   if (0==superFragHead_) {
00497     //nothing to do... why did we get here then ???
00498   }
00499   else if(superFragHead_==superFragTail_){
00500     superFragHead_ = 0; 
00501     superFragTail_ = 0;
00502   }
00503   else{
00504     MemRef_t *next = 0;
00505     MemRef_t *current = superFragHead_;
00506     while((next=current->getNextReference()) != superFragTail_){
00507       //get to the next-to-last block
00508     }
00509     superFragTail_ = current;
00510     current->setNextReference(0);
00511   }
00512   return;
00513 }
00514 
00515 
00516 //______________________________________________________________________________
00517 void FUResource::superFragSize() throw (evf::Exception)
00518 {
00519   UChar_t *blockAddr    =0;
00520   UChar_t *frlHeaderAddr=0;
00521   frlh_t  *frlHeader    =0;
00522 
00523   superFragSize_=0;
00524 
00525   UInt_t frameSize=sizeof(I2O_EVENT_DATA_BLOCK_MESSAGE_FRAME);
00526   MemRef_t* bufRef=superFragHead_;
00527   
00528   while (0!=bufRef) {
00529     blockAddr      =(UChar_t*)bufRef->getDataLocation();
00530     frlHeaderAddr  =blockAddr+frameSize;
00531     frlHeader      =(frlh_t*)frlHeaderAddr;
00532     superFragSize_+=frlHeader->segsize & FRL_SEGSIZE_MASK; 
00533     bufRef         =bufRef->getNextReference();
00534   }
00535   
00536   eventSize_+=superFragSize_;
00537 
00538   if (eventSize_>eventPayloadSize_) {  
00539     nbErrors_++;
00540     stringstream oss;
00541     oss<<"Event size exceeds maximum size."
00542        <<" fuResourceId:"<<fuResourceId_
00543        <<" evtNumber:"<<evtNumber_
00544        <<" iSuperFrag:"<<iSuperFrag_
00545        <<" eventSize:"<<eventSize_
00546        <<" eventPayloadSize:"<<eventPayloadSize_;
00547     XCEPT_RAISE(evf::Exception,oss.str());
00548   }
00549   
00550 }
00551 
00552 
00553 //______________________________________________________________________________
00554 void FUResource::fillSuperFragPayload() throw (evf::Exception)
00555 {
00556   UChar_t *blockAddr    =0;
00557   UChar_t *frlHeaderAddr=0;
00558   UChar_t *fedAddr      =0;
00559   UInt_t   nbBytes      =0;
00560   UInt_t   nbBytesTot   =0;
00561   frlh_t  *frlHeader    =0;
00562   UChar_t *bufferPos    =0;
00563   UChar_t *startPos     =0;
00564   
00565   MemRef_t* bufRef=superFragHead_;
00566   while(bufRef != 0) {
00567     blockAddr    =(UChar_t*)bufRef->getDataLocation();
00568     frlHeaderAddr=blockAddr+sizeof(I2O_EVENT_DATA_BLOCK_MESSAGE_FRAME);
00569     fedAddr      =frlHeaderAddr+sizeof(frlh_t);
00570     frlHeader    =(frlh_t*)frlHeaderAddr;
00571     nbBytes      =frlHeader->segsize & FRL_SEGSIZE_MASK;
00572     nbBytesTot  +=nbBytes;
00573     
00574     // check if still within limits
00575     if(nbBytesTot>superFragSize_) {
00576       nbErrors_++;
00577       stringstream oss;
00578       oss<<"Reached end of buffer."
00579          <<" fuResourceId:"<<fuResourceId_
00580          <<" evtNumber:"<<evtNumber_
00581          <<" iSuperFrag:"<<iSuperFrag_;
00582       XCEPT_RAISE(evf::Exception,oss.str());
00583     }
00584     
00585     bufferPos=shmCell_->writeData(fedAddr,nbBytes);
00586     if (0==startPos) startPos=bufferPos;
00587     
00588     nbBytes_+=nbBytes;
00589     bufRef=bufRef->getNextReference();
00590   }
00591   
00592   if (!shmCell_->markSuperFrag(iSuperFrag_,superFragSize_,startPos)) {
00593     nbErrors_++;
00594     stringstream oss;
00595     oss<<"Failed to mark super fragment in shared mem buffer."
00596        <<" fuResourceId:"<<fuResourceId_
00597        <<" evtNumber:"<<evtNumber_
00598        <<" iSuperFrag:"<<iSuperFrag_;
00599     XCEPT_RAISE(evf::Exception,oss.str());
00600   }
00601   
00602   return;
00603 }
00604 
00605 
00606 //______________________________________________________________________________
00607 void FUResource::findFEDs() throw (evf::Exception)
00608 {
00609   UChar_t* superFragAddr =0;
00610   UInt_t   superFragSize =0;
00611   
00612   UChar_t *fedTrailerAddr=0;
00613   UChar_t *fedHeaderAddr =0;
00614   
00615   UInt_t   fedSize       =0;
00616   UInt_t   sumOfFedSizes =0;
00617   UInt_t   evtNumber     =0;
00618   
00619   UShort_t crc           =0;
00620   UShort_t crcChk        =0;
00621   
00622   fedt_t  *fedTrailer    =0;
00623   fedh_t  *fedHeader     =0;
00624 
00625 
00626   
00627   superFragAddr =shmCell_->superFragAddr(iSuperFrag_);
00628   superFragSize =shmCell_->superFragSize(iSuperFrag_);
00629   fedTrailerAddr=superFragAddr+superFragSize-sizeof(fedt_t);
00630   
00631   while (fedTrailerAddr>superFragAddr) {
00632     
00633     fedTrailer    =(fedt_t*)fedTrailerAddr;
00634     fedSize       =(fedTrailer->eventsize & FED_EVSZ_MASK) << 3;
00635     sumOfFedSizes+=fedSize;
00636     
00637     // check for fed trailer id
00638     if ((fedTrailer->eventsize & FED_TCTRLID_MASK)!=FED_TCTRLID) {
00639       nbErrors_++;
00640       stringstream oss;
00641       oss<<"Missing FED trailer id."
00642          <<" evtNumber:"<<evtNumber_
00643          <<" iSuperFrag:"<<iSuperFrag_;
00644       XCEPT_RAISE(evf::Exception,oss.str());
00645     }
00646     
00647     fedHeaderAddr=fedTrailerAddr-fedSize+sizeof(fedt_t);
00648     
00649     // check that fed header is within buffer
00650     if(fedHeaderAddr<superFragAddr) {
00651       nbErrors_++;
00652       stringstream oss;
00653       oss<<"FED header address out-of-bounds."
00654          <<" evtNumber:"<<evtNumber_
00655          <<" iSuperFrag:"<<iSuperFrag_;
00656       XCEPT_RAISE(evf::Exception,oss.str());
00657     }
00658     
00659     // check that payload starts within buffer
00660     if((fedHeaderAddr+sizeof(fedh_t))>(superFragAddr+superFragSize)) {
00661       nbErrors_++;
00662       stringstream oss;
00663       oss<<"FED payload out-of-bounds."
00664          <<" evtNumber:"<<evtNumber_
00665          <<" iSuperFrag:"<<iSuperFrag_;
00666       XCEPT_RAISE(evf::Exception,oss.str());
00667     }
00668     
00669     fedHeader  =(fedh_t*)fedHeaderAddr;
00670     
00671     // check for fed header id
00672     if ((fedHeader->eventid & FED_HCTRLID_MASK)!=FED_HCTRLID) {
00673       nbErrors_++;
00674       stringstream oss;
00675       oss<<"Missing FED header id."
00676          <<" evtNumber:"<<evtNumber_
00677          <<" iSuperFrag:"<<iSuperFrag_;
00678       XCEPT_RAISE(evf::Exception,oss.str());
00679     }
00680     
00681     UInt_t fedId=(fedHeader->sourceid & REAL_SOID_MASK) >> 8;
00682     
00683     // check evtNumber consisency
00684     evtNumber=fedHeader->eventid & FED_LVL1_MASK;
00685     if (evtNumber!=evtNumber_) {
00686       nbErrors_++;
00687       stringstream oss;
00688       oss<<"FU / FED evtNumber mismatch."
00689          <<" FU:"<<evtNumber_
00690          <<" FED:"<<evtNumber
00691          <<" fedid:"<<fedId;
00692       XCEPT_RAISE(evf::Exception,oss.str());
00693     }
00694   
00695     // check that fedid is within valid ranges
00696     if (fedId>=1024||
00697         (doFedIdCheck_&&(!FEDNumbering::inRange(fedId)))) {
00698       LOG4CPLUS_WARN(log_,"Invalid fedid. Data will still be logged"
00699                      <<" evtNumber:"<<evtNumber_
00700                      <<" fedid:"<<fedId);
00701       nbErrors_++;
00702     }
00703 
00704     // check if a previous fed has already claimed same fed id
00705 
00706     if(fedSize_[fedId]!=0) {
00707       LOG4CPLUS_ERROR(log_,"Duplicated fedid. Data will be lost for"
00708                       <<" evtNumber:"<<evtNumber_
00709                       <<" fedid:"<<fedId);
00710       nbErrors_++;
00711     }
00712     
00713     if (fedId<1024) fedSize_[fedId]=fedSize;
00714 
00715     //if gtp EVM block is available set cell event number to global partition-independent trigger number
00716     //daq block partition-independent event number is left as an option in case of problems
00717 
00718     if(fedId == gtpeId_)
00719       if(evf::evtn::gtpe_board_sense(fedHeaderAddr)) shmCell_->setEvtNumber(evf::evtn::gtpe_get(fedHeaderAddr));
00720     if(useEvmBoard_ && (fedId == gtpEvmId_))
00721       if(evf::evtn::evm_board_sense(fedHeaderAddr,fedSize)) shmCell_->setEvtNumber(evf::evtn::get(fedHeaderAddr, true));
00722     if(!useEvmBoard_ && (fedId == gtpDaqId_))
00723       if(evf::evtn::daq_board_sense(fedHeaderAddr)) shmCell_->setEvtNumber(evf::evtn::get(fedHeaderAddr, false));
00724     // crc check
00725     if (doCrcCheck_) {
00726       UInt_t conscheck=fedTrailer->conscheck;
00727       crc=((fedTrailer->conscheck & FED_CRCS_MASK) >> FED_CRCS_SHIFT);
00728       fedTrailer->conscheck &= (~FED_CRCS_MASK);
00729       fedTrailer->conscheck &= (~FED_RBIT_MASK);
00730       crcChk=compute_crc(fedHeaderAddr,fedSize);
00731       if(nextEventWillHaveCRCError_ && random() > RAND_MAX/2){
00732         crc--;
00733         nextEventWillHaveCRCError_ = false;
00734       }
00735       if (crc!=crcChk) {
00736         std::ostringstream oss;
00737         oss << "crc check failed."
00738             <<" evtNumber:"<<evtNumber_
00739             <<" fedid:"<<fedId
00740             <<" crc:"<<crc
00741             <<" chk:"<<crcChk;
00742         LOG4CPLUS_INFO(log_,oss.str());
00743         XCEPT_DECLARE(evf::Exception,
00744                       sentinelException, oss.str());
00745         app_->notifyQualified("error",sentinelException);
00746         nbErrors_++;
00747         nbCrcErrors_++;
00748       }
00749       fedTrailer->conscheck=conscheck;
00750     }
00751     
00752     
00753     // mark fed
00754     if (!shmCell_->markFed(fedId,fedSize,fedHeaderAddr)) {
00755       nbErrors_++;
00756       stringstream oss;
00757       oss<<"Failed to mark fed in buffer."
00758          <<" evtNumber:"<<evtNumber_
00759          <<" fedId:"<<fedId
00760          <<" fedSize:"<<fedSize
00761          <<" fedAddr:0x"<<hex<<(unsigned long)fedHeaderAddr<<dec;
00762       XCEPT_RAISE(evf::Exception,oss.str());
00763     }
00764     
00765     // Move to the next fed trailer
00766     fedTrailerAddr=fedTrailerAddr-fedSize;
00767   }
00768   
00769   // check that we indeed end up on the starting address of the buffer
00770   if ((fedTrailerAddr+sizeof(fedh_t))!=superFragAddr) {
00771     std::stringstream oss;
00772     oss<<"First FED in superfragment ouf-of-bound."
00773        <<" evtNumber:"<<evtNumber_
00774        <<" iSuperFrag:"<<iSuperFrag_;
00775     XCEPT_RAISE(evf::Exception,oss.str());
00776   }
00777   
00778   return;
00779 }
00780 
00781 
00782 //______________________________________________________________________________
00783 void FUResource::releaseSuperFrag()
00784 {
00785   if (0==superFragHead_) return;
00786   superFragHead_->release(); // throws xcept::Exception
00787   superFragHead_=0;
00788   superFragTail_=0;
00789   return;
00790 }
00791 
00792 
00793 //______________________________________________________________________________
00794 UInt_t FUResource::nbErrors(bool reset)
00795 {
00796   UInt_t result=nbErrors_;
00797   if (reset) nbErrors_=0;
00798   return result;
00799 }
00800 
00801 
00802 //______________________________________________________________________________
00803 UInt_t FUResource::nbCrcErrors(bool reset)
00804 {
00805   UInt_t result=nbCrcErrors_;
00806   if (reset) nbCrcErrors_=0;
00807   return result;
00808 }
00809 
00810 
00811 //______________________________________________________________________________
00812 UInt_t FUResource::nbBytes(bool reset)
00813 {
00814   UInt_t result=nbBytes_;
00815   if (reset) nbBytes_=0;
00816   return result;
00817 }