CMS 3D CMS Logo

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