Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include "EventFilter/ResourceBroker/interface/ResourceChecker.h"
00009 #include "EventFilter/Utilities/interface/GlobalEventNumber.h"
00010 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00011
00012 #include "interface/evb/i2oEVBMsgs.h"
00013 #include "interface/shared/frl_header.h"
00014 #include "interface/shared/fed_header.h"
00015 #include "interface/shared/fed_trailer.h"
00016 #include "EvffedFillerRB.h"
00017
00018 #include <sstream>
00019
00020 using namespace evf;
00021 using std::stringstream;
00022 using std::ostringstream;
00023 using std::hex;
00024 using std::dec;
00025
00026
00027 ResourceChecker::ResourceChecker(FUResource* const resToCheck) :
00028 res_(resToCheck) {
00029 }
00030
00031
00032 void ResourceChecker::processDataBlock(MemRef_t* bufRef) throw (evf::Exception) {
00033
00034 if (res_->iBlock_ == res_->nBlock_) {
00035 res_->iBlock_ = 0;
00036 res_->nBlock_ = 0xffffffff;
00037 }
00038
00039 I2O_EVENT_DATA_BLOCK_MESSAGE_FRAME *block =
00040 (I2O_EVENT_DATA_BLOCK_MESSAGE_FRAME*) bufRef->getDataLocation();
00041
00042 UInt_t iBlock = block->blockNb;
00043 UInt_t nBlock = block->nbBlocksInSuperFragment;
00044 UInt_t iSuperFrag = block->superFragmentNb;
00045 UInt_t nSuperFrag = block->nbSuperFragmentsInEvent;
00046 UInt_t fuResourceId = block->fuTransactionId;
00047 UInt_t buResourceId = block->buResourceId;
00048 UInt_t evtNumber = block->eventNumber;
00049 stringstream oss;
00050 oss << "TransId:" << fuResourceId << " BUResourceId:" << buResourceId
00051 << " eventNumber:" << evtNumber << " ";
00052
00053 if (fuResourceId != res_->fuResourceId_) {
00054 res_->nbErrors_++;
00055
00056 oss << "RU/FU fuResourceId mismatch." << " Received:" << fuResourceId
00057 << " Expected:" << res_->fuResourceId_;
00058 XCEPT_RAISE(evf::Exception, oss.str());
00059 }
00060
00061
00062 if (iBlock != res_->iBlock_) {
00063 res_->nbErrors_++;
00064 oss << "RU/FU block number mismatch." << " Received:" << iBlock
00065 << " Expected:" << res_->iBlock_;
00066 XCEPT_RAISE(evf::Exception, oss.str());
00067 }
00068
00069
00070 if (iSuperFrag != res_->iSuperFrag_) {
00071 res_->nbErrors_++;
00072 oss << "RU/FU superfragment number mismatch." << " Received:"
00073 << iSuperFrag << " Expected:" << res_->iSuperFrag_;
00074 XCEPT_RAISE(evf::Exception, oss.str());
00075 }
00076
00077
00078 if (iBlock == 0) {
00079 res_->nBlock_ = nBlock;
00080 } else {
00081
00082 if (nBlock != res_->nBlock_) {
00083 res_->nbErrors_++;
00084 oss << "RU/FU number of blocks mismatch." << " Received:" << nBlock
00085 << " Expected:" << res_->nBlock_;
00086 XCEPT_RAISE(evf::Exception, oss.str());
00087 }
00088 }
00089
00090
00091
00092 if (iBlock == 0 && iSuperFrag == 0) {
00093 res_->evtNumber_ = evtNumber;
00094 res_->buResourceId_ = buResourceId;
00095 res_->nSuperFrag_ = nSuperFrag;
00096
00097 res_->shmCell_->setEvtNumber(evtNumber);
00098 res_->shmCell_->setBuResourceId(buResourceId);
00099
00100
00101 if (res_->nSuperFrag_ > res_->nSuperFragMax_) {
00102 res_->nbErrors_++;
00103 oss << "Invalid maximum number of superfragments."
00104 << " fuResourceId:" << res_->fuResourceId_ << " evtNumber:"
00105 << res_->evtNumber_ << " nSuperFrag:" << res_->nSuperFrag_
00106 << " nSuperFragMax:" << res_->nSuperFragMax_;
00107 XCEPT_RAISE(evf::Exception, oss.str());
00108 }
00109 }
00110
00111
00112 else {
00113
00114 if (evtNumber != res_->evtNumber_) {
00115 res_->nbErrors_++;
00116 oss << "RU/FU evtNumber mismatch." << " Received:" << evtNumber
00117 << " Expected:" << res_->evtNumber_;
00118 XCEPT_RAISE(evf::Exception, oss.str());
00119 }
00120
00121
00122 if (buResourceId != res_->buResourceId_) {
00123 res_->nbErrors_++;
00124 oss << "RU/FU buResourceId mismatch."
00125 << buResourceId << " Expected:" << res_->buResourceId_;
00126 XCEPT_RAISE(evf::Exception, oss.str());
00127 }
00128
00129
00130 if (nSuperFrag != res_->nSuperFrag_) {
00131 res_->nbErrors_++;
00132 oss << "RU/FU number of superfragments mismatch." << " Received:"
00133 << nSuperFrag << " Expected:" << res_->nSuperFrag_;
00134 XCEPT_RAISE(evf::Exception, oss.str());
00135 }
00136 }
00137
00138
00139 try {
00140 checkDataBlockPayload(bufRef);
00141 } catch (xcept::Exception& e) {
00142 oss << "data block payload failed check." << " evtNumber:"
00143 << res_->evtNumber_ << " buResourceId:" << res_->buResourceId_
00144 << " iSuperFrag:" << res_->iSuperFrag_;
00145 XCEPT_RETHROW(evf::Exception, oss.str(), e);
00146 }
00147
00148 res_->appendBlockToSuperFrag(bufRef);
00149
00150
00151 res_->iBlock_++;
00152
00153
00154 bool lastBlockInSuperFrag = (iBlock == nBlock - 1);
00155 if (lastBlockInSuperFrag) {
00156
00157
00158 try {
00159
00160 res_->superFragSize();
00161 } catch (xcept::Exception& e) {
00162 oss << "Invalid super fragment size." << " evtNumber:"
00163 << res_->evtNumber_ << " buResourceId:"
00164 << res_->buResourceId_ << " iSuperFrag:"
00165 << res_->iSuperFrag_;
00166 res_->removeLastAppendedBlockFromSuperFrag();
00167 XCEPT_RETHROW(evf::Exception, oss.str(), e);
00168 }
00169 try {
00170 res_->fillSuperFragPayload();
00171 findFEDs();
00172
00173 } catch (xcept::Exception& e) {
00174 oss << "Invalid super fragment." << " evtNumber:"
00175 << res_->evtNumber_ << " buResourceId:"
00176 << res_->buResourceId_ << " iSuperFrag:"
00177 << res_->iSuperFrag_;
00178 res_->removeLastAppendedBlockFromSuperFrag();
00179 XCEPT_RETHROW(evf::Exception, oss.str(), e);
00180 }
00181
00182
00183 try {
00184 res_->releaseSuperFrag();
00185 } catch (xcept::Exception& e) {
00186 res_->nbErrors_++;
00187 oss << "Failed to release super fragment." << " evtNumber:"
00188 << res_->evtNumber_ << " buResourceId:"
00189 << res_->buResourceId_ << " iSuperFrag:"
00190 << res_->iSuperFrag_;
00191 XCEPT_RETHROW(evf::Exception, oss.str(), e);
00192 }
00193
00194
00195 res_->iSuperFrag_++;
00196
00197 }
00198
00199 return;
00200 }
00201
00202
00203 void ResourceChecker::checkDataBlockPayload(MemRef_t* bufRef)
00204 throw (evf::Exception) {
00205 UInt_t frameSize = 0;
00206 UInt_t bufSize = 0;
00207 UInt_t segSize = 0;
00208 UInt_t segSizeExpected = 0;
00209
00210 frlh_t *frlHeader = 0;
00211
00212 UChar_t *blockAddr = 0;
00213 UChar_t *frlHeaderAddr = 0;
00214
00215 frameSize = sizeof(I2O_EVENT_DATA_BLOCK_MESSAGE_FRAME);
00216
00217 blockAddr = (UChar_t*) bufRef->getDataLocation();
00218 frlHeaderAddr = blockAddr + frameSize;
00219 frlHeader = (frlh_t*) frlHeaderAddr;
00220
00221 I2O_EVENT_DATA_BLOCK_MESSAGE_FRAME *block =
00222 (I2O_EVENT_DATA_BLOCK_MESSAGE_FRAME*) blockAddr;
00223
00224
00225 if (res_->evtNumber_ != frlHeader->trigno) {
00226 res_->nbErrors_++;
00227 stringstream oss;
00228 oss << "FRL header \"trigno\" does not match " << "FU \"evtNumber\"."
00229 << " trigno:" << frlHeader->trigno << " evtNumber:"
00230 << res_->evtNumber_;
00231 XCEPT_RAISE(evf::Exception, oss.str());
00232 }
00233
00234
00235 if (block->eventNumber != frlHeader->trigno) {
00236 res_->nbErrors_++;
00237 stringstream oss;
00238 oss << "FRL header \"trigno\" does not match "
00239 << "RU builder header \"eventNumber\"." << " trigno:"
00240 << frlHeader->trigno << " eventNumber:" << block->eventNumber;
00241 XCEPT_RAISE(evf::Exception, oss.str());
00242 }
00243
00244
00245 if (block->blockNb != frlHeader->segno) {
00246 res_->nbErrors_++;
00247 stringstream oss;
00248 oss << "FRL header \"segno\" does not match"
00249 << "RU builder header \"blockNb\"." << " segno:"
00250 << frlHeader->segno << " blockNb:" << block->blockNb;
00251 XCEPT_RAISE(evf::Exception, oss.str());
00252 }
00253
00254
00255 if (block->blockNb != res_->iBlock_) {
00256 res_->nbErrors_++;
00257 stringstream oss;
00258 oss << "Incorrect block number." << " Expected:" << res_->iBlock_
00259 << " Received:" << block->blockNb;
00260 XCEPT_RAISE(evf::Exception, oss.str());
00261 }
00262
00263
00264 bufSize = bufRef->getDataSize();
00265 segSizeExpected = bufSize - frameSize - sizeof(frlh_t);
00266 segSize = frlHeader->segsize & FRL_SEGSIZE_MASK;
00267 if (segSize != segSizeExpected) {
00268 res_->nbErrors_++;
00269 stringstream oss;
00270 oss << "FRL header segment size is not as expected." << " Expected:"
00271 << segSizeExpected << " Received:" << segSize;
00272 XCEPT_RAISE(evf::Exception, oss.str());
00273 }
00274
00275
00276 bool fuLastBlockInSuperFrag = (block->blockNb
00277 == (block->nbBlocksInSuperFragment - 1));
00278 bool frlLastBlockInSuperFrag = ((frlHeader->segsize & FRL_LAST_SEGM) != 0);
00279 if (fuLastBlockInSuperFrag != frlLastBlockInSuperFrag) {
00280 res_->nbErrors_++;
00281 stringstream oss;
00282 oss << "FU / FRL header end-of-superfragment mismatch."
00283 << " FU header:" << fuLastBlockInSuperFrag << " FRL header:"
00284 << frlLastBlockInSuperFrag;
00285 XCEPT_RAISE(evf::Exception, oss.str());
00286 }
00287
00288 return;
00289 }
00290
00291
00292 void ResourceChecker::findFEDs() throw (evf::Exception) {
00293 UChar_t* superFragAddr = 0;
00294 UInt_t superFragSize = 0;
00295
00296 UChar_t *fedTrailerAddr = 0;
00297 UChar_t *fedHeaderAddr = 0;
00298
00299 UInt_t fedSize = 0;
00300 UInt_t sumOfFedSizes = 0;
00301 UInt_t evtNumber = 0;
00302
00303 UShort_t crc = 0;
00304 UShort_t crcChk = 0;
00305
00306 fedt_t *fedTrailer = 0;
00307 fedh_t *fedHeader = 0;
00308
00309 superFragAddr = res_->shmCell_->superFragAddr(res_->iSuperFrag_);
00310 superFragSize = res_->shmCell_->superFragSize(res_->iSuperFrag_);
00311 fedTrailerAddr = superFragAddr + superFragSize - sizeof(fedt_t);
00312
00313 while (fedTrailerAddr > superFragAddr) {
00314
00315 fedTrailer = (fedt_t*) fedTrailerAddr;
00316 fedSize = (fedTrailer->eventsize & FED_EVSZ_MASK) << 3;
00317 sumOfFedSizes += fedSize;
00318
00319
00320 if ((fedTrailer->eventsize & FED_TCTRLID_MASK) != FED_TCTRLID) {
00321 res_->nbErrors_++;
00322 stringstream oss;
00323 oss << "Missing FED trailer id." << " evtNumber:"
00324 << res_->evtNumber_ << " iSuperFrag:" << res_->iSuperFrag_;
00325 XCEPT_RAISE(evf::Exception, oss.str());
00326 }
00327
00328 fedHeaderAddr = fedTrailerAddr - fedSize + sizeof(fedt_t);
00329
00330
00331 if (fedHeaderAddr < superFragAddr) {
00332 res_->nbErrors_++;
00333 stringstream oss;
00334 oss << "FED header address out-of-bounds." << " evtNumber:"
00335 << res_->evtNumber_ << " iSuperFrag:" << res_->iSuperFrag_;
00336 XCEPT_RAISE(evf::Exception, oss.str());
00337 }
00338
00339
00340 if ((fedHeaderAddr + sizeof(fedh_t)) > (superFragAddr + superFragSize)) {
00341 res_->nbErrors_++;
00342 stringstream oss;
00343 oss << "FED payload out-of-bounds." << " evtNumber:"
00344 << res_->evtNumber_ << " iSuperFrag:" << res_->iSuperFrag_;
00345 XCEPT_RAISE(evf::Exception, oss.str());
00346 }
00347
00348 fedHeader = (fedh_t*) fedHeaderAddr;
00349
00350
00351 if ((fedHeader->eventid & FED_HCTRLID_MASK) != FED_HCTRLID) {
00352 res_->nbErrors_++;
00353 stringstream oss;
00354 oss << "Missing FED header id." << " evtNumber:"
00355 << res_->evtNumber_ << " iSuperFrag:" << res_->iSuperFrag_;
00356 XCEPT_RAISE(evf::Exception, oss.str());
00357 }
00358
00359 UInt_t fedId = (fedHeader->sourceid & REAL_SOID_MASK) >> 8;
00360
00361
00362 evtNumber = fedHeader->eventid & FED_LVL1_MASK;
00363 if (evtNumber != res_->evtNumber_) {
00364 res_->nbErrors_++;
00365 stringstream oss;
00366 oss << "FU / FED evtNumber mismatch." << " FU:" << res_->evtNumber_
00367 << " FED:" << evtNumber << " fedid:" << fedId;
00368 XCEPT_RAISE(evf::Exception, oss.str());
00369 }
00370
00371
00372 if (fedId >= 1024 || (res_->doFedIdCheck_ && (!FEDNumbering::inRange(
00373 fedId)))) {
00374 LOG4CPLUS_WARN(
00375 res_->log_,
00376 "Invalid fedid. Data will still be logged" << " evtNumber:"
00377 << res_->evtNumber_ << " fedid:" << fedId);
00378 res_->nbErrors_++;
00379 }
00380
00381
00382
00383 if (res_->fedSize_[fedId] != 0) {
00384 LOG4CPLUS_ERROR(
00385 res_->log_,
00386 "Duplicated fedid. Data will be lost for" << " evtNumber:"
00387 << res_->evtNumber_ << " fedid:" << fedId);
00388 res_->nbErrors_++;
00389 }
00390
00391 if (fedId < 1024)
00392 res_->fedSize_[fedId] = fedSize;
00393
00394
00395
00396
00397 if (fedId == res_->gtpeId_)
00398 if (evf::evtn::gtpe_board_sense(fedHeaderAddr))
00399 res_->shmCell_->setEvtNumber(evf::evtn::gtpe_get(fedHeaderAddr));
00400 if (res_->useEvmBoard_ && (fedId == res_->gtpEvmId_))
00401
00402 if (evf::evtn::evm_board_sense(fedHeaderAddr, fedSize)) {
00403 res_->shmCell_->setEvtNumber(
00404 evf::evtn::get(fedHeaderAddr, true));
00405 res_->shmCell_->setLumiSection(evf::evtn::getlbn(fedHeaderAddr));
00406 }
00407 if (!res_->useEvmBoard_ && (fedId == res_->gtpDaqId_))
00408
00409 if (evf::evtn::daq_board_sense(fedHeaderAddr)) {
00410 res_->shmCell_->setEvtNumber(
00411 evf::evtn::get(fedHeaderAddr, false));
00412 }
00413
00414 if (res_->doCrcCheck_) {
00415 UInt_t conscheck = fedTrailer->conscheck;
00416 crc = ((fedTrailer->conscheck & FED_CRCS_MASK) >> FED_CRCS_SHIFT);
00417 fedTrailer->conscheck &= (~FED_CRCS_MASK);
00418 fedTrailer->conscheck &= (~FED_RBIT_MASK);
00419 crcChk = compute_crc(fedHeaderAddr, fedSize);
00420 if (res_->nextEventWillHaveCRCError_ && random() > RAND_MAX / 2) {
00421 crc--;
00422 res_->nextEventWillHaveCRCError_ = false;
00423 }
00424 if (crc != crcChk) {
00425 ostringstream oss;
00426 oss << "crc check failed." << " evtNumber:" << res_->evtNumber_
00427 << " fedid:" << fedId << " crc:" << crc << " chk:"
00428 << crcChk;
00429 LOG4CPLUS_INFO(res_->log_, oss.str());
00430 XCEPT_DECLARE(evf::Exception, sentinelException, oss.str());
00431 res_->app_->notifyQualified("error", sentinelException);
00432 res_->nbErrors_++;
00433 res_->nbCrcErrors_++;
00434 }
00435 fedTrailer->conscheck = conscheck;
00436 }
00437
00438
00439 if (!res_->shmCell_->markFed(fedId, fedSize, fedHeaderAddr)) {
00440 res_->nbErrors_++;
00441 stringstream oss;
00442 oss << "Failed to mark fed in buffer." << " evtNumber:"
00443 << res_->evtNumber_ << " fedId:" << fedId << " fedSize:"
00444 << fedSize << " fedAddr:0x" << hex
00445 << (unsigned long) fedHeaderAddr << dec;
00446 XCEPT_RAISE(evf::Exception, oss.str());
00447 }
00448
00449
00450 fedTrailerAddr = fedTrailerAddr - fedSize;
00451 }
00452
00453
00454 if ((fedTrailerAddr + sizeof(fedh_t)) != superFragAddr) {
00455 stringstream oss;
00456 oss << "First FED in superfragment ouf-of-bound." << " evtNumber:"
00457 << res_->evtNumber_ << " iSuperFrag:" << res_->iSuperFrag_;
00458 XCEPT_RAISE(evf::Exception, oss.str());
00459 }
00460
00461 return;
00462 }