CMS 3D CMS Logo

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