#include "PrtCnvBroadcastMgr.hpp" #include "PrtCnvDbThread.hpp" #include #include #include #include namespace PrtCnv { PrtCnvBroadcastMgr::PrtCnvBroadcastMgr() : m_ClaimWindow(0) , m_HighLoadFactor(0) , m_BroadcastLimit(0) , m_Config(nullptr) , m_ActClaimWindow(0) , m_State(e_ST_UNDEFINED) , m_TickCounter(0) , m_DbThread(nullptr) , m_BroadcastIndex(0) , m_IsFullLoad(false) , m_FinishedBroadcastIndex(0) , m_FirstBroadcastIndexOfBc1(0) , m_logger(getLogger("PrtCnvBroadcastMgr")) , m_loggerBcRequest(getLogger("PrtCnvBroadcastMgr.BcRequest")) { } int32_t PrtCnvBroadcastMgr::create(NGL::Settings *settings) { m_Config = settings; return 0; } int32_t PrtCnvBroadcastMgr::init() { const QString broadcastGroup(QStringLiteral("Broadcast")); N_CoPrtCnv::CoPrtCnvRadioTelegram::setBroadcastDelayTimes( m_Config->getInteger(broadcastGroup, QStringLiteral("BroadcastDelay2"), 60), m_Config->getInteger(broadcastGroup, QStringLiteral("BroadcastDelay3"), 60)); N_CoPrtCnv::CoPrtCnvRadioTelegram::setMaxBroadcastSendCnt(m_Config->getInteger(broadcastGroup, QStringLiteral("MaxBroadcastSendCount"), 1)); const int sendGap = m_Config->getInteger(broadcastGroup, QStringLiteral("SendGap"), 500); m_ClaimWindow = (m_Config->getInteger(broadcastGroup, QStringLiteral("ClaimWindow"), 30) * 1000) / sendGap; m_HighLoadFactor = m_Config->getInteger(broadcastGroup, QStringLiteral("HighLoadFactor"), 3); m_BroadcastLimit = m_Config->getInteger(broadcastGroup, QStringLiteral("BroadcastLimit"), 10); cleanAndInit(true); INFO_LOG(m_loggerBcRequest) << "m_ActClaimWindow=" << m_ActClaimWindow << " m_State=" << m_State; return 0; } void PrtCnvBroadcastMgr::setDbThread(PrtCnvDbThread *a_dbThread) { m_DbThread = a_dbThread; } void PrtCnvBroadcastMgr::cleanAndInit(const bool a_deleteTelegrams) { if (a_deleteTelegrams) { m_deactivatedAesArea2bcIndex.clear(); m_deactivatedBcIndex2AesArea.clear(); m_deactivatedDusMine2bcIndex.clear(); m_deactivatedBcIndex2DusMine.clear(); m_deactivatedFuncArea2bcIndex.clear(); m_deactivatedBcIndex2FuncArea.clear(); m_BroadcastMap.clear(); m_LastTelegramMap.clear(); m_FunktionsraumTelegramMap.clear(); m_WirkfeldTelegramMapByKennung.clear(); m_WirkfeldTelegramMapByTime.clear(); m_BroadcastIndex = 0; } m_claimerArray.clear(); m_ActClaimWindow = m_ClaimWindow; m_IsFullLoad = false; m_TickCounter = 0; m_State = e_ST_COLLECT; m_FinishedBroadcastIndex = 0; m_FirstBroadcastIndexOfBc1 = 0; } bool PrtCnvBroadcastMgr::handleRadioTelegram(const N_CoPrtCnv::CoPrtCnvRadioTelegram &a_radioTelegram) { switch (a_radioTelegram.getTelID()) { case GEF_NACHFORDERUNG_BROADCAST_TELEGRAMME: handleNachforderungBroadcastTelegram(a_radioTelegram.getIdentity(), a_radioTelegram.getPayloadDataUInt32(8, 2) + 1, a_radioTelegram.getPayloadDataUInt8(7)); return false; default: break; } return true; } void PrtCnvBroadcastMgr::handleNachforderungBroadcastTelegram(int identity, int broadcastIndex, int resetCounter) { INFO_LOG(m_loggerBcRequest) << "Got NachforderungBroadcast from TNE with id=" << identity << " resetCounter=" << resetCounter << " broadcastIndex=" << broadcastIndex - 1 << " m_TickCounter=" << m_TickCounter << " m_State=" << m_State; if (resetCounter == m_DbThread->getResetCounter()) { m_DbThread->incClaimCount(identity); for (auto &ebi : m_claimerArray) { if (ebi.equipNo == identity) { ebi.bcIndex = broadcastIndex; return; } } m_claimerArray.emplace_back(identity, broadcastIndex); return; } WARNING_LOG(m_logger) << "NachforderungBroadcast from TNE with id=" << identity << ": resetCounter different we have: " << int(m_DbThread->getResetCounter()) << "; TNE has: " << resetCounter << " => discarded"; } std::shared_ptr PrtCnvBroadcastMgr::getNextBroadcastTelegramToSend(const uint16_t a_beginSearchWithBroadcastIndex, const time_t a_currentTime) { DEBUG_LOG(m_logger) << "getNextBroadcastTelegramToSend, startIdx: " << a_beginSearchWithBroadcastIndex; auto iter = m_BroadcastMap.upper_bound(0 == a_beginSearchWithBroadcastIndex ? m_FinishedBroadcastIndex : a_beginSearchWithBroadcastIndex); while (iter != m_BroadcastMap.end()) { auto broadcastTelegram = iter->second; gef_telegramm_id_et telId = broadcastTelegram->getTelID(); if (GEF_WF_SAMMELDEAKTIVIERUNG_FUNKTIONSRAUM == telId || GEF_WF_SAMMELDEAKTIVIERUNG == telId || GEF_WF_SAMMELDEAKTIVIERUNG_DUS_MINEN == telId) { if (!broadcastTelegram->getBroadcastonlyTelegram()) { ++iter; continue; } } bool isBcOnly = false; if (broadcastTelegram->getBroadcastonlyTelegram()) { broadcastTelegram = broadcastTelegram->getBroadcastonlyTelegram(); isBcOnly = true; } bool wasLast = false; if (broadcastTelegram->mustBeSentAsBroadcast(a_currentTime, wasLast)) { if (wasLast) { if (isBcOnly || broadcastTelegram->isBroadcastOnly()) { removeFromAllMaps(broadcastTelegram); } else { m_FinishedBroadcastIndex = broadcastTelegram->getBroadcastIndex(); } } broadcastTelegram->setIdentity(0); return broadcastTelegram; } else { uint16_t bcCounter = broadcastTelegram->getBroadcastCounter(); if (2 == bcCounter) { if (m_FirstBroadcastIndexOfBc1 > iter->first) { iter = m_BroadcastMap.lower_bound(m_FirstBroadcastIndexOfBc1); continue; } } else if (1 == bcCounter) { m_FirstBroadcastIndexOfBc1 = broadcastTelegram->getBroadcastIndex(); return nullptr; } } ++iter; } return nullptr; } std::shared_ptr PrtCnvBroadcastMgr::getNextNachforderungTelegramToSend() { removeExpiredTelegrams(); switch (m_State) { case e_ST_COLLECT: if (m_TickCounter >= m_ActClaimWindow && !m_IsFullLoad) { prepareForSendNachforderungen(); } else { getAllFinishedBroadcastsFromDb(); } break; case e_ST_SEND_NACHFORDERUNG: return evaluateNextNachforderungToSend(); default: break; } return {}; } void PrtCnvBroadcastMgr::removeExpiredTelegrams() { const time_t now = time(nullptr); auto iter = m_WirkfeldTelegramMapByTime.begin(); while (iter != m_WirkfeldTelegramMapByTime.end()) { if (iter->first + 5 > now) return; auto radioTelegram = iter->second; INFO_LOG(m_logger) << "Remove expired telegram with telId=" << radioTelegram->getTelID() << " and BC=" << radioTelegram->getBroadcastIndex() << " from BC-list"; uint16_t wirkfeldKennung = radioTelegram->getPayloadDataUInt32(5, 2); removeWirkfeldTelegrams(wirkfeldKennung); iter = m_WirkfeldTelegramMapByTime.begin(); } } void PrtCnvBroadcastMgr::prepareForSendNachforderungen() { m_TickCounter = 0; if (!m_claimerArray.empty()) { dump(); m_State = e_ST_SEND_NACHFORDERUNG; std::swap(m_claimerArray, m_claimerArray); std::sort(m_claimerArray.begin(), m_claimerArray.end(), [] (const EquipNoBcIndex &a, const EquipNoBcIndex &b) { if (a.bcIndex != b.bcIndex) return a.bcIndex < b.bcIndex; return a.equipNo < b.equipNo; }); INFO_LOG(m_loggerBcRequest) << "BroadcastLimit: " << m_BroadcastLimit; if (m_claimerArray.size() > m_BroadcastLimit) { m_claimerArray.clear(); m_claimerArray.emplace_back(0, m_claimerArray.begin()->bcIndex); } for (const EquipNoBcIndex &enbi : m_claimerArray) { int curBcIndex = enbi.bcIndex; int nextBcIndex = -1; while (true) { auto tel = getNachforderungsTelegram(curBcIndex, enbi.bcIndex, nextBcIndex); curBcIndex = nextBcIndex; if (tel) { auto copy(std::make_shared(*tel)); copy->setIdentity(enbi.equipNo); m_broadcastTelegamsToSend.push_back(copy); } else break; }; std::sort(m_broadcastTelegamsToSend.begin(), m_broadcastTelegamsToSend.end(), [] (const std::shared_ptr &a, const std::shared_ptr &b) { const int bcIndexA = a->getTelID() == GEF_NOP ? a->getPayloadDataUInt32(3, 2) : a->getBroadcastIndex(); const int bcIndexB = b->getTelID() == GEF_NOP ? b->getPayloadDataUInt32(3, 2) : b->getBroadcastIndex(); if (bcIndexA != bcIndexB) return bcIndexA > bcIndexB; return a->getIdentity() < b->getIdentity(); }); if (m_loggerBcRequest.isDebugEnabled()) { DEBUG_LOG(m_loggerBcRequest) << "Created broadcast list:"; for (const auto &tele : m_broadcastTelegamsToSend) DEBUG_LOG(m_loggerBcRequest) << "Identity: " << tele->getIdentity() << ", bc: " << tele->getBroadcastIndex() << ", type: " << tele->getTelID(); } } m_claimerArray.clear(); } } std::shared_ptr PrtCnvBroadcastMgr::evaluateNextNachforderungToSend() { if (m_broadcastTelegamsToSend.empty()) { m_State = e_ST_COLLECT; return nullptr; } auto tel = m_broadcastTelegamsToSend.back(); m_broadcastTelegamsToSend.pop_back(); return tel; } std::shared_ptr PrtCnvBroadcastMgr::createAccumulationTelegram(int curBcIndex, int startBcIndex, gef_telegramm_id_et telId, const QMap &bcIndex2Type, int maxIdsPerTelegram, int sizeOfSumField) const { if (bcIndex2Type.isEmpty()) return nullptr; auto itLastBcTele = m_BroadcastMap.end(); --itLastBcTele; const int endBcIndex = itLastBcTele->second->getBroadcastIndex(); DEBUG_LOG(m_loggerBcRequest) << "createAccumulationTelegram for telId " << telId << ", begin: " << startBcIndex << ", cur: " << curBcIndex << ", end: " << endBcIndex << ", #elements in container: " << bcIndex2Type.size(); DEBUG_LOG(m_loggerBcRequest) << "Given broadcast list for " << telegramId2String(telId); for (auto it = bcIndex2Type.begin(); it != bcIndex2Type.end(); ++it) DEBUG_LOG(m_loggerBcRequest) << " bcIndex: " << it.key() << ", id: " << it.value(); auto itStart = bcIndex2Type.lowerBound(startBcIndex); if (itStart == bcIndex2Type.end()) { Q_ASSERT(false); return nullptr; } auto itEnd = bcIndex2Type.lowerBound(endBcIndex); if (itEnd == bcIndex2Type.end()) --itEnd; const int completeTelegrams = std::distance(itStart, itEnd) + 1; if (completeTelegrams <= 0) { Q_ASSERT(false); return nullptr; } const auto itCur = bcIndex2Type.find(curBcIndex); if (itCur == bcIndex2Type.end()) { Q_ASSERT(false); return nullptr; } const int telegramsStillSendable = std::distance(itCur, itEnd) + 1; if (telegramsStillSendable <= 0) { Q_ASSERT(false); return nullptr; } const int telegramsToSend = (completeTelegrams / maxIdsPerTelegram) + 1; if (telegramsStillSendable > telegramsToSend) { INFO_LOG(m_loggerBcRequest) << telId << ": sending nop since accuTelegram is sent later (" << telegramsStillSendable << ", need only " << telegramsToSend << ")"; return nullptr; } const int curIdStart = (telegramsToSend - telegramsStillSendable) * maxIdsPerTelegram; const int idsToSendNow = (curIdStart + maxIdsPerTelegram <= completeTelegrams ? maxIdsPerTelegram : completeTelegrams % maxIdsPerTelegram); INFO_LOG(m_loggerBcRequest) << telId << ": creating accuTelegram from index " << curIdStart << ", count: " << idsToSendNow; itStart += curIdStart; auto tele(std::make_shared(telId, 3 + 2 + sizeOfSumField + sizeof(uint16_t) * idsToSendNow, 0)); tele->setPayload2Byte(curBcIndex); if (sizeOfSumField == 1) tele->setPayload1Byte(idsToSendNow); else if (sizeOfSumField == 2) tele->setPayload2Byte(idsToSendNow); else { Q_ASSERT(false); return nullptr; } for (int i = 0; i < idsToSendNow; ++i) { tele->setPayload2Byte(itStart.value()); ++itStart; } return tele; } std::shared_ptr PrtCnvBroadcastMgr::createAccuTeleDeactivatedAesAreas(int curBcIndex, int startBcIndex) const { return createAccumulationTelegram(curBcIndex, startBcIndex, GEF_WF_SAMMELDEAKTIVIERUNG, m_deactivatedBcIndex2AesArea, 100, 1); } std::shared_ptr PrtCnvBroadcastMgr::createAccuTeleDeactivatedFuncAreas(int curBcIndex, int startBcIndex) const { return createAccumulationTelegram(curBcIndex, startBcIndex, GEF_WF_SAMMELDEAKTIVIERUNG_FUNKTIONSRAUM, m_deactivatedBcIndex2FuncArea, 100, 1); } std::shared_ptr PrtCnvBroadcastMgr::createAccuTeleDeactivatedDusMines(int curBcIndex, int startBcIndex) const { return createAccumulationTelegram(curBcIndex, startBcIndex, GEF_WF_SAMMELDEAKTIVIERUNG_DUS_MINEN, m_deactivatedBcIndex2DusMine, 500, 2); } std::shared_ptr PrtCnvBroadcastMgr::createAccuTeleActivatedDusMines(int curBcIndex) { if (m_activatedDusMines.isEmpty()) return {}; const int idsToSendNow = m_activatedDusMines.size(); if (idsToSendNow > 500) { WARNING_LOG(m_logger) << "More than 500 activated DUS mines in system - this is not allowed!"; Q_ASSERT(false); return {}; } auto tele(std::make_shared(GEF_REAKTIVIERUNG_DUS_MINE, 5 + 2 + sizeof(uint16_t) * idsToSendNow, 0)); tele->setPayload2Byte(curBcIndex); tele->setPayload2Byte(idsToSendNow); for (int dusMineId : std::as_const(m_activatedDusMines)) tele->setPayload2Byte(dusMineId); return tele; } std::shared_ptrPrtCnvBroadcastMgr::getNachforderungsTelegram(int curBcIndex, int startBcIndex, int &nextBcIndex) { DEBUG_LOG(m_loggerBcRequest) << "getNachforderungsTelegram - curBcIndex: " << curBcIndex << ", startBcIndex: " << startBcIndex; if (curBcIndex == 0) curBcIndex++; DEBUG_LOG(m_loggerBcRequest) << "getNachforderungsTelegram - curBcIndex after Ssnity: " << curBcIndex << ", startBcIndex: " << startBcIndex; nextBcIndex = curBcIndex; bool doSendNop = false; while (true) { auto iter = m_BroadcastMap.lower_bound(nextBcIndex); if (iter == m_BroadcastMap.end()) break; auto radioTelegram = iter->second; DEBUG_LOG(m_loggerBcRequest) << "getNachforderungsTelegram - cur tel id is " << radioTelegram->getTelID() << ", bcIndex: " << radioTelegram->getBroadcastIndex() << ", send nop: " << doSendNop; if (nextBcIndex < iter->first) { doSendNop = true; nextBcIndex = iter->first; } else if (radioTelegram->isBroadcastOnly()) { doSendNop = true; nextBcIndex = iter->first + 1; } else { std::shared_ptr retTele; switch (radioTelegram->getTelID()) { case GEF_DEAKTIVIERUNG_WIRKFELD: retTele = createAccuTeleDeactivatedAesAreas(radioTelegram->getBroadcastIndex(), startBcIndex); break; case GEF_DEAKTIVIEREN_FUNKTIONSRAUM: retTele = createAccuTeleDeactivatedFuncAreas(radioTelegram->getBroadcastIndex(), startBcIndex); break; case GEF_DEAKTIVIERUNG_EINZELMINE: retTele = createAccuTeleDeactivatedDusMines(radioTelegram->getBroadcastIndex(), startBcIndex); break; case GEF_REAKTIVIERUNG_DUS_MINE: retTele = createAccuTeleActivatedDusMines(radioTelegram->getBroadcastIndex()); break; default: retTele = radioTelegram; break; } if (retTele && doSendNop) break; ++nextBcIndex; if (retTele) return retTele; doSendNop = true; } } if (!doSendNop && nextBcIndex <= m_BroadcastIndex) { nextBcIndex = m_BroadcastIndex + 1; doSendNop = true; } if (doSendNop) { INFO_LOG(m_loggerBcRequest) << "Returning NOP: " << curBcIndex << " to " << nextBcIndex - 1; return getNopTelegram(curBcIndex, nextBcIndex - 1); } return nullptr; } void PrtCnvBroadcastMgr::getAllFinishedBroadcastsFromDb(const bool a_doRestore) { uint16_t broadcastIndex = 0; while (true) { auto radioTelegram = m_DbThread->getNextBroadcastTelegram(); if (!radioTelegram) break; broadcastIndex = radioTelegram->getBroadcastIndex(); INFO_LOG(m_logger) << "Move Broadcast-telegram from DbThread>BroadcastMgr with telId=" << radioTelegram->getTelID() << " BC=" << broadcastIndex; dumpTelegram(m_logger, broadcastIndex, radioTelegram.get()); { addToBroadcastMap(radioTelegram); } if (a_doRestore && MAX_BROADCAST_INDEX == broadcastIndex) handleOverrunOfBroadcastCounter(a_doRestore); } if (m_logger.isDebugEnabled()) { static int iBroadcastDumpCounter = 0; if ((iBroadcastDumpCounter++ % 30) == 0) { DEBUG_LOG(m_logger) << "Dumping broadcast map:"; for (const auto &it : m_BroadcastMap) dumpTelegram(m_logger, it.first, it.second.get()); } } if (a_doRestore) { m_BroadcastIndex = broadcastIndex; m_FinishedBroadcastIndex = m_BroadcastIndex; } } void PrtCnvBroadcastMgr::addToBroadcastMap(const std::shared_ptr &a_radioTelegram) { INFO_LOG(m_logger) << "Move from radioList to bcList: BC=" << a_radioTelegram->getBroadcastIndex() << " telID=" << a_radioTelegram->getTelID(); switch (a_radioTelegram->getTelID()) { case GEF_INIT: case GEF_UMGEBUNGS_MELDUNG2: ERROR_LOG(m_logger) << "Internal error: telegram with telId=" << a_radioTelegram->getTelID() << " should never be a normal broadcast"; break; case GEF_DATENVERKEHR_TDS_SRT: case GEF_DATENVERKEHR_TDS_DMF: case GEF_TREFFER_AUSLOESUNG: case GEF_ALLGEMEINE_NACHRICHT: addBroadcastOnlyTelegramToMap(a_radioTelegram); break; case GEF_SPRACHAUSWAHL: case GEF_KONFIGURATION_WIRKMODELL: case GEF_TEILNEHMERMODE_SETZEN: case GEF_TEILNEHMER_KONFIG_SETZEN: replaceLastTelegramAndAddAtEnd(a_radioTelegram); break; case GEF_WIRKFELD_EINZELGESCHOSS: case GEF_WIRKFELD_FLAECHENDECKENDES_FEUER: case GEF_WIRKFELD_MINENSPERRE: case GEF_WIRKFELD_A_KAMPFMITTEL: case GEF_WIRKFELD_C_KAMPFMITTEL: case GEF_WIRKFELD_FLAECHENDECKENDES_FEUER_STOP: case GEF_WIRKFELD_FLAECHENDECKENDES_FEUER_FORTSETZEN: case GEF_WIRKFELD_STATUS_MINENSPERRE: case GEF_WIRKFELD_EINZELMINENSIMULATOR: { const uint16_t wirkfeldKennung = a_radioTelegram->getPayloadDataUInt32(5, 2); INFO_LOG(m_logger) << "Adding to braodcast map, Telegram Id: " << a_radioTelegram->getTelID() << ", kennung: " << wirkfeldKennung; if (isEffectSimulationIdDeactivated(wirkfeldKennung)) { INFO_LOG(m_logger) << "Got tele with tel id " << telegramId2String(a_radioTelegram->getTelID()) << ", wirkfeldkennung: " << wirkfeldKennung << ", bcIndex: " << a_radioTelegram->getBroadcastIndex() << " but this effect simulation is already deactivated... ignoring"; dumpTelegram(m_logger, a_radioTelegram->getBroadcastIndex(), a_radioTelegram.get()); emit areaEffectSimulationActivated(wirkfeldKennung); } else if (0 != wirkfeldKennung && wirkfeldKennung <= std::numeric_limits::max()) { switch (a_radioTelegram->getTelID()) { case GEF_WIRKFELD_FLAECHENDECKENDES_FEUER_STOP: addWirkfeldTelegram(a_radioTelegram, wirkfeldKennung, GEF_WIRKFELD_FLAECHENDECKENDES_FEUER_FORTSETZEN); break; case GEF_WIRKFELD_FLAECHENDECKENDES_FEUER_FORTSETZEN: addWirkfeldTelegram(a_radioTelegram, wirkfeldKennung, GEF_WIRKFELD_FLAECHENDECKENDES_FEUER_STOP); break; case GEF_WIRKFELD_AENDERUNG_BEZEICHNER: addWirkfeldTelegram(a_radioTelegram, wirkfeldKennung); break; case GEF_WIRKFELD_STATUS_MINENSPERRE: addWirkfeldTelegram(a_radioTelegram, wirkfeldKennung, GEF_DEAKTIVIERUNG_EINZELMINE); break; default: removeWirkfeldTelegrams(wirkfeldKennung); addWirkfeldTelegram(a_radioTelegram, wirkfeldKennung); removeFromDeactivatedAesArea(wirkfeldKennung); emit areaEffectSimulationActivated(wirkfeldKennung); break; } m_BroadcastMap.insert(std::make_pair(a_radioTelegram->getBroadcastIndex(), a_radioTelegram)); } else { ERROR_LOG(m_logger) << "Internal error: Got invalid kennung: " << wirkfeldKennung; } break; } case GEF_WIRKFELD_AENDERUNG_BEZEICHNER: { auto wirkfeldTyp = static_cast(a_radioTelegram->getPayloadDataUInt32(5, 1)); uint16_t wirkfeldKennung = a_radioTelegram->getPayloadDataUInt32(6, 2); INFO_LOG(m_logger) << "addToBroadcastMap - Wirkfeld Aenderung Bezeichner for type " << wirkfeldTyp2Str(wirkfeldTyp) << " - kennung: " << wirkfeldKennung; addWirkfeldTelegram(a_radioTelegram, wirkfeldKennung); break; } case GEF_DEAKTIVIERUNG_WIRKFELD: { auto wirkfeldTyp = static_cast(a_radioTelegram->getPayloadDataUInt32(5, 1)); uint16_t wirkfeldKennung = a_radioTelegram->getPayloadDataUInt32(6, 2); INFO_LOG(m_logger) << "Deaktivierung Wirkfeld for type " << wirkfeldTyp2Str(wirkfeldTyp) << " - kennung: " << wirkfeldKennung << ", bc: " << a_radioTelegram->getBroadcastIndex(); switch (wirkfeldTyp) { case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::MineArea: case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::ExplosionArea: case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::ExplosionSingle: case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::NContamination: case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::CContamination: case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::DusSingleMineSimulator: case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::DangerZoneExplosion: if (0 != wirkfeldKennung && wirkfeldKennung <= 32767) { emit areaEffectSimulationDeactivated(wirkfeldKennung); removeWirkfeldTelegrams(wirkfeldKennung); if (addToDeactivatedAesArea(wirkfeldKennung, a_radioTelegram->getBroadcastIndex())) addWirkfeldTelegram(a_radioTelegram, wirkfeldKennung); } else { ERROR_LOG(m_logger) << "Internal error: Got invalid kennung: " << wirkfeldKennung; } break; case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::FunctionalArea: default: ERROR_LOG(m_logger) << "Internal error: WirkfeldTyp " << wirkfeldTyp2Str(wirkfeldTyp) << " in GEF_DEAKTIVIERUNG_WIRKFELD not implemented"; } m_BroadcastMap.insert(std::make_pair(a_radioTelegram->getBroadcastIndex(), a_radioTelegram)); break; } case GEF_DEAKTIVIERUNG_EINZELMINE: { deactivateSingleMine(a_radioTelegram); break; } case GEF_REAKTIVIERUNG_DUS_MINE: { reactivateDusMine(a_radioTelegram); break; } case GEF_TECHNIK_FUNKTIONSRAUM: { uint16_t funktionsraumkennung = a_radioTelegram->getPayloadDataUInt32(5, 2); removeFromTechnikFunktionsAndBroadcastMaps(funktionsraumkennung); m_TechnikFunktionsraumTelegramMap.insert(std::make_pair(funktionsraumkennung, a_radioTelegram)); m_BroadcastMap.insert(std::make_pair(a_radioTelegram->getBroadcastIndex(), a_radioTelegram)); break; } case GEF_FUNKTIONSRAUM: { uint16_t funktionsraumkennung = a_radioTelegram->getPayloadDataUInt32(5, 2); removeFromFunktionsAndBroadcastMaps(funktionsraumkennung); removeFromDeactivatedFuncArea(funktionsraumkennung); m_FunktionsraumTelegramMap.insert(std::make_pair(funktionsraumkennung, a_radioTelegram)); m_BroadcastMap.insert(std::make_pair(a_radioTelegram->getBroadcastIndex(), a_radioTelegram)); break; } case GEF_DEAKTIVIEREN_FUNKTIONSRAUM: { uint16_t funktionsraumkennung = a_radioTelegram->getPayloadDataUInt32(5, 2); emit areaEffectSimulationDeactivated(funktionsraumkennung); removeFromFunktionsAndBroadcastMaps(funktionsraumkennung); if (addToDeactivatedFuncArea(funktionsraumkennung, a_radioTelegram->getBroadcastIndex())) m_FunktionsraumTelegramMap.insert(std::make_pair(funktionsraumkennung, a_radioTelegram)); m_BroadcastMap.insert(std::make_pair(a_radioTelegram->getBroadcastIndex(), a_radioTelegram)); break; } default: m_BroadcastMap.insert(std::make_pair(a_radioTelegram->getBroadcastIndex(), a_radioTelegram)); } } template bool removeFromContainers(T &id2bcIndex, S &BcIndex2id, int aesAreaId) { auto it = id2bcIndex.find(aesAreaId); if (it == id2bcIndex.end()) return false; BcIndex2id.remove(it.value()); id2bcIndex.erase(it); return true; } template bool addToContainers(T &id2bcIndex, S &BcIndex2id, int aesAreaId, int bcIndex) { auto it = id2bcIndex.find(aesAreaId); if (it != id2bcIndex.end()) { if (it.value() == bcIndex) return false; BcIndex2id.remove(it.value()); } id2bcIndex[aesAreaId] = bcIndex; BcIndex2id[bcIndex] = aesAreaId; return true; } bool PrtCnvBroadcastMgr::removeFromDeactivatedAesArea(int aesAreaId) { return removeFromContainers(m_deactivatedAesArea2bcIndex, m_deactivatedBcIndex2AesArea, aesAreaId); } bool PrtCnvBroadcastMgr::addToDeactivatedAesArea(int aesAreaId, int bcIndex) { return addToContainers(m_deactivatedAesArea2bcIndex, m_deactivatedBcIndex2AesArea, aesAreaId, bcIndex); } bool PrtCnvBroadcastMgr::removeFromDeactivatedFuncArea(int aesAreaId) { return removeFromContainers(m_deactivatedFuncArea2bcIndex, m_deactivatedBcIndex2FuncArea, aesAreaId); } bool PrtCnvBroadcastMgr::addToDeactivatedFuncArea(int aesAreaId, int bcIndex) { return addToContainers(m_deactivatedFuncArea2bcIndex, m_deactivatedBcIndex2FuncArea, aesAreaId, bcIndex); } bool PrtCnvBroadcastMgr::removeFromDeactivatedDusMine(int dusMineId) { return removeFromContainers(m_deactivatedDusMine2bcIndex, m_deactivatedBcIndex2DusMine, dusMineId); } bool PrtCnvBroadcastMgr::addToDeactivatedDusMine(int dusMineId, int bcIndex) { return addToContainers(m_deactivatedDusMine2bcIndex, m_deactivatedBcIndex2DusMine, dusMineId, bcIndex); } bool PrtCnvBroadcastMgr::removeFromActivatedDusMine(int dusMineId) { return (m_activatedDusMines.remove(dusMineId)); } void PrtCnvBroadcastMgr::addToActivatedDusMine(int dusMineId) { m_activatedDusMines.insert(dusMineId); } int PrtCnvBroadcastMgr::getSammeltelegramIndex(const std::shared_ptr &a_sammelTelegram, const uint16_t a_kennung) const { uint16_t nbrLength = 0; switch (a_sammelTelegram->getTelID()) { case GEF_WF_SAMMELDEAKTIVIERUNG: case GEF_WF_SAMMELDEAKTIVIERUNG_FUNKTIONSRAUM: nbrLength = 1; break; case GEF_WF_SAMMELDEAKTIVIERUNG_DUS_MINEN: case GEF_REAKTIVIERUNG_DUS_MINE: nbrLength = 2; break; default: ERROR_LOG(m_logger) << "Unknown Sammeltelegram with telId=" << a_sammelTelegram->getTelID(); return -1; } const int cntAesIds = a_sammelTelegram->getPayloadDataUInt32(5, nbrLength); for (int i = 0; i < cntAesIds; i++) { if (a_kennung == a_sammelTelegram->getPayloadDataUInt32(5 + nbrLength + i * 2, 2)) return i; } return -1; } void PrtCnvBroadcastMgr::deactivateSingleMine(const std::shared_ptr &a_radioTelegram) { uint32_t wirkfeldkennung = a_radioTelegram->getPayloadDataUInt32(9, 2); uint32_t minenkennung = a_radioTelegram->getPayloadDataUInt32(11, 2); if (0 == wirkfeldkennung) { removeFromActivatedDusMine(minenkennung); addToDeactivatedDusMine(minenkennung, a_radioTelegram->getBroadcastIndex()); DEBUG_LOG(m_logger) << "Deactivating DUS-Mine: " << minenkennung << ", #deactivated mines: " << m_deactivatedBcIndex2DusMine.size(); removeDusMineDeactivationFromBroadcastMap(minenkennung); m_BroadcastMap.insert(std::make_pair(a_radioTelegram->getBroadcastIndex(), a_radioTelegram)); } else { bool sentAsNormalBroadcastFinished = deactivateEinzelmineFromMinensperre(wirkfeldkennung, minenkennung, a_radioTelegram->getBroadcastIndex()); if (sentAsNormalBroadcastFinished) { addWirkfeldTelegram(a_radioTelegram, wirkfeldkennung, GEF_BESTAETIGUNG, minenkennung); addBroadcastOnlyTelegramToMap(a_radioTelegram); } else { } } } bool PrtCnvBroadcastMgr::deactivateEinzelmineFromMinensperre(const uint16_t a_wirkfeldKennung, const uint16_t a_minenKennung, const uint16_t a_broadcastIndex) { auto iter = m_WirkfeldTelegramMapByKennung.find(a_wirkfeldKennung); while (iter != m_WirkfeldTelegramMapByKennung.end()) { if (iter->first != a_wirkfeldKennung) break; auto radioTelegram = iter->second; if (radioTelegram->getTelID() == GEF_WIRKFELD_STATUS_MINENSPERRE && a_wirkfeldKennung == radioTelegram->getPayloadDataUInt32(5, 2)) { uint16_t nbrOfMines = radioTelegram->getPayloadDataUInt32(7, 2); if (nbrOfMines >= a_minenKennung && a_minenKennung != 0) { uint16_t bytePos = 9 + (a_minenKennung - 1) / 8; if (bytePos < radioTelegram->getPayloadSize()) { uint8_t mask = 0x80 >> ((a_minenKennung - 1) % 8); radioTelegram->setPayloadDataWithIndex(bytePos, (uint8_t)(radioTelegram->getPayloadDataUInt8(bytePos) & (~mask)), 1); moveTelegramInBroadcastMap(radioTelegram, a_broadcastIndex); bool dummy; if (radioTelegram->mustBeSentAsBroadcast(std::numeric_limits::max(), dummy, false)) { INFO_LOG(m_logger) << "A normal broadcast-telegram WirkfeldStatusMinensperre still exists"; return false; } return true; } else ERROR_LOG(m_logger) << "Got corrupt telegram WirkfeldstatusMinensperre with nbrOfMines=" << nbrOfMines << " and payloadSize=" << radioTelegram->getPayloadSize(); } else { ERROR_LOG(m_logger) << "Mine with kennung=" << a_minenKennung << " does not fit into status (nbrOfMines=" << nbrOfMines << ")"; } return true; } ++iter; } ERROR_LOG(m_logger) << "Did not find the WirkfeldStatusMinensperre with kennung=" << a_wirkfeldKennung << ", therefore deactivated mine with kennung=" << a_minenKennung << " could not be updated."; return true; } void PrtCnvBroadcastMgr::reactivateDusMine(const std::shared_ptr &a_radioTelegram) { const uint32_t nbrOfMines = a_radioTelegram->getPayloadDataUInt32(5, 2); DEBUG_LOG(m_logger) << "Reactivating DUS-Mines, #mines: " << nbrOfMines; if (0 == nbrOfMines) { for (int dusMineId : std::as_const(m_deactivatedBcIndex2DusMine)) { removeDusMineDeactivationFromBroadcastMap(dusMineId); addToActivatedDusMine(dusMineId); } m_deactivatedDusMine2bcIndex.clear(); m_deactivatedBcIndex2DusMine.clear(); } else { for (uint32_t i = 0; i < nbrOfMines; i++) { const int dusMineId = a_radioTelegram->getPayloadDataUInt32(7 + 2 * i, 2); DEBUG_LOG(m_logger) << "Reactivating DUS-Mines, mindId: " << dusMineId; removeDusMineDeactivationFromBroadcastMap(dusMineId); removeFromDeactivatedDusMine(dusMineId); addToActivatedDusMine(dusMineId); } } auto pred = [](const std::shared_ptr &tele) -> bool { return (tele->getTelID() == GEF_REAKTIVIERUNG_DUS_MINE); }; removeFromBroadcastMapFunc(pred); m_BroadcastMap.insert(std::make_pair(a_radioTelegram->getBroadcastIndex(), a_radioTelegram)); } void PrtCnvBroadcastMgr::addWirkfeldTelegram(const std::shared_ptr &a_radioTelegram, const uint16_t a_wirkfeldKennung, const gef_telegramm_id_et a_telId, const uint16_t a_minenKennung) { auto iter = m_WirkfeldTelegramMapByKennung.find(a_wirkfeldKennung); while (iter != m_WirkfeldTelegramMapByKennung.end()) { if (iter->first != a_wirkfeldKennung) break; auto radioTelegram = iter->second; bool isSameMine = true; if (0 != a_minenKennung) { if (GEF_DEAKTIVIERUNG_EINZELMINE == a_radioTelegram->getTelID()) { if (GEF_DEAKTIVIERUNG_EINZELMINE == radioTelegram->getTelID()) { uint16_t mineIndex = radioTelegram->getPayloadDataUInt32(11, 2); isSameMine = mineIndex == a_minenKennung; INFO_LOG(m_logger) << "Mine with kennung=" << a_minenKennung << " found: " << isSameMine; } } else ERROR_LOG(m_logger) << "Internal error: Only telegrams 'Deaktivierung_Einzelmine' must be called with a_mineKennung. I proceed without respecting mine-kennung..."; } if ((radioTelegram->getTelID() == a_radioTelegram->getTelID() || radioTelegram->getTelID() == a_telId) && isSameMine) { removeFromWirkfeldAndBroadcastMaps(iter); iter = m_WirkfeldTelegramMapByKennung.find(a_wirkfeldKennung); } else ++iter; } INFO_LOG(m_logger) << "Add kennung: " << a_wirkfeldKennung << " telId=" << a_radioTelegram->getTelID() << " BC=" << a_radioTelegram->getBroadcastIndex(); m_WirkfeldTelegramMapByKennung.insert(std::make_pair(a_wirkfeldKennung, a_radioTelegram)); time_t expireTime = a_radioTelegram->getExpireTime(); if (expireTime > 0) m_WirkfeldTelegramMapByTime.insert(std::make_pair(expireTime, a_radioTelegram)); } void PrtCnvBroadcastMgr::removeWirkfeldTelegrams(const uint16_t a_kennung) { INFO_LOG(m_logger) << "Removing all Wirkfeld-Telegrams with kennung=" << a_kennung; auto iter = m_WirkfeldTelegramMapByKennung.find(a_kennung); while (iter != m_WirkfeldTelegramMapByKennung.end()) { if (iter->first != a_kennung) break; removeFromWirkfeldAndBroadcastMaps(iter); iter = m_WirkfeldTelegramMapByKennung.find(a_kennung); } } void PrtCnvBroadcastMgr::removeFromFunktionsAndBroadcastMaps(const uint16_t a_funktionsraumKennung) { auto iter = m_FunktionsraumTelegramMap.find(a_funktionsraumKennung); if (iter != m_FunktionsraumTelegramMap.end()) { auto radioTelegram = iter->second; INFO_LOG(m_logger) << "Removing Funktionsraum-telegram with kennung=" << a_funktionsraumKennung << " and BC=" << radioTelegram->getBroadcastIndex(); m_FunktionsraumTelegramMap.erase(iter); removeFromBroadcastMap(radioTelegram); } } void PrtCnvBroadcastMgr::removeFromTechnikFunktionsAndBroadcastMaps(const uint16_t a_funktionsraumKennung) { auto iter = m_TechnikFunktionsraumTelegramMap.find(a_funktionsraumKennung); if (iter != m_TechnikFunktionsraumTelegramMap.end()) { auto radioTelegram = iter->second; INFO_LOG(m_logger) << "Removing Funktionsraum-telegram with kennung=" << a_funktionsraumKennung << " and BC=" << radioTelegram->getBroadcastIndex(); m_TechnikFunktionsraumTelegramMap.erase(iter); removeFromBroadcastMap(radioTelegram); } } void PrtCnvBroadcastMgr::removeFromWirkfeldAndBroadcastMaps(const std::multimap>::iterator &a_wirkfeldTelegramMapByKennungIterator) { auto radioTelegram = a_wirkfeldTelegramMapByKennungIterator->second; INFO_LOG(m_logger) << "Removing wirkfeld-telegram with telId=" << radioTelegram->getTelID() << ", kennung=" << a_wirkfeldTelegramMapByKennungIterator->first << " and BC=" << radioTelegram->getBroadcastIndex() << " from byWirkfeldKennung-map"; m_WirkfeldTelegramMapByKennung.erase(a_wirkfeldTelegramMapByKennungIterator); time_t expireTime = radioTelegram->getExpireTime(); if (0 != expireTime) { auto iter = m_WirkfeldTelegramMapByTime.find(expireTime); while (iter != m_WirkfeldTelegramMapByTime.end()) { if (iter->second == radioTelegram) { INFO_LOG(m_logger) << "Removing wirkfeld-telegram with telId=" << radioTelegram->getTelID() << " also from byTime-map"; m_WirkfeldTelegramMapByTime.erase(iter); break; } ++iter; } } removeFromBroadcastMap(radioTelegram); } void PrtCnvBroadcastMgr::removeFromBroadcastMap(const std::shared_ptr &a_radioTelegram) { if (!a_radioTelegram) return; auto iter = m_BroadcastMap.find(a_radioTelegram->getBroadcastIndex()); if (iter != m_BroadcastMap.end()) { if (iter->second == a_radioTelegram) { m_BroadcastMap.erase(iter); detachTelegram(a_radioTelegram); } else if (iter->second->getBroadcastonlyTelegram() == a_radioTelegram) iter->second->setBroadcastonlyTelegram(nullptr); } } void PrtCnvBroadcastMgr::removeFromBroadcastMapFunc(const std::function &)> &pred) { auto it = m_BroadcastMap.begin(); while (it != m_BroadcastMap.end()) { const auto &p = *it; if (pred(p.second)) it = m_BroadcastMap.erase(it); else ++it; } } void PrtCnvBroadcastMgr::removeDusMineDeactivationFromBroadcastMap(int dusMineId) { auto pred = [dusMineId](const std::shared_ptr &tele) -> bool { return (tele->getTelID() == GEF_DEAKTIVIERUNG_EINZELMINE && 0 == tele->getPayloadDataUInt32(9, 2) && uint32_t(dusMineId) == tele->getPayloadDataUInt32(11, 2)); }; removeFromBroadcastMapFunc(pred); } template void removeFromMap(T &cont, const std::shared_ptr &a_radioTelegram) { auto iter = cont.begin(); while (iter != cont.end()) { if (iter->second == a_radioTelegram) iter = cont.erase(iter); else ++iter; } } void PrtCnvBroadcastMgr::removeFromAllMaps(const std::shared_ptr &a_radioTelegram) { INFO_LOG(m_logger) << "Remove telegram with telId=" << a_radioTelegram->getTelID() << " BC=" << a_radioTelegram->getBroadcastIndex(); removeFromBroadcastMap(a_radioTelegram); removeFromMap(m_WirkfeldTelegramMapByKennung, a_radioTelegram); removeFromMap(m_WirkfeldTelegramMapByTime, a_radioTelegram); removeFromMap(m_FunktionsraumTelegramMap, a_radioTelegram); removeFromMap(m_LastTelegramMap, a_radioTelegram); } void PrtCnvBroadcastMgr::replaceLastTelegramAndAddAtEnd(const std::shared_ptr &a_newRadioTelegram) { auto iter = m_LastTelegramMap.find(a_newRadioTelegram->getTelID()); if (iter != m_LastTelegramMap.end()) { auto lastRadioTelegram = iter->second; INFO_LOG(m_logger) << "remove last telegram with telId=" << lastRadioTelegram->getTelID() << " and BC=" << lastRadioTelegram->getBroadcastIndex(); removeFromBroadcastMap(lastRadioTelegram); m_LastTelegramMap.erase(iter); } m_BroadcastMap.insert(std::make_pair(a_newRadioTelegram->getBroadcastIndex(), a_newRadioTelegram)); m_LastTelegramMap.insert(std::make_pair(a_newRadioTelegram->getTelID(), a_newRadioTelegram)); INFO_LOG(m_logger) << "New last telegram with with telId=" << a_newRadioTelegram->getTelID() << " and BC=" << a_newRadioTelegram->getBroadcastIndex(); } void PrtCnvBroadcastMgr::moveTelegramInBroadcastMap(const std::shared_ptr &a_radioTelegram, const uint16_t a_newBroadcastIndex, const std::shared_ptr &a_attachTelegram) { INFO_LOG(m_logger) << "Move telId=" << a_radioTelegram->getTelID() << " from BC=" << a_radioTelegram->getBroadcastIndex() << " to BC=" << a_newBroadcastIndex; removeFromBroadcastMap(a_radioTelegram); a_radioTelegram->setBroadcastIndex(a_newBroadcastIndex); m_BroadcastMap.insert(std::make_pair(a_newBroadcastIndex, a_radioTelegram)); if (a_attachTelegram && (a_attachTelegram->getTelID() != GEF_REAKTIVIERUNG_DUS_MINE)) { INFO_LOG(m_logger) << "Attach telID=" << a_attachTelegram->getTelID() << " to telID=" << a_radioTelegram->getTelID() << " BC=" << a_newBroadcastIndex; a_radioTelegram->setBroadcastonlyTelegram(a_attachTelegram); a_attachTelegram->setBroadcastIndex(a_newBroadcastIndex); } } uint16_t PrtCnvBroadcastMgr::getBroadcastIndex() const { return m_BroadcastIndex; } uint16_t PrtCnvBroadcastMgr::getNextBroadcastIndex() { return ++m_BroadcastIndex; } std::shared_ptr PrtCnvBroadcastMgr::getNopTelegram(const uint16_t a_from, const uint16_t a_to) { auto nopTelegram(std::make_shared(GEF_NOP, 7, 0)); nopTelegram->setPayloadDataWithIndex(3, a_from, 2); nopTelegram->setPayloadDataWithIndex(5, a_to, 2); return nopTelegram; } void PrtCnvBroadcastMgr::addBroadcastOnlyTelegramToMap(const std::shared_ptr &a_broadcastOnlyTelegram) { uint16_t broadcastIndex = a_broadcastOnlyTelegram->getBroadcastIndex(); auto iter = m_BroadcastMap.find(broadcastIndex); if (m_BroadcastMap.end() == iter) { INFO_LOG(m_logger) << "Insert telId=" << a_broadcastOnlyTelegram->getTelID() << " as broadcastonly telegram with BC=" << broadcastIndex; a_broadcastOnlyTelegram->setBroadcastOnly(); m_BroadcastMap.insert(std::make_pair(broadcastIndex, a_broadcastOnlyTelegram)); } else { INFO_LOG(m_logger) << "Add telId=" << a_broadcastOnlyTelegram->getTelID() << " as broadcastonly telegram to telegramm with BC=" << iter->second->getBroadcastIndex(); iter->second->setBroadcastonlyTelegram(a_broadcastOnlyTelegram); } } void PrtCnvBroadcastMgr::detachTelegram(const std::shared_ptr &a_radioTelegram) { auto broadcastOnlyTelegram = a_radioTelegram->getBroadcastonlyTelegram(); if (broadcastOnlyTelegram) { uint16_t broadcastIndex = a_radioTelegram->getBroadcastIndex(); INFO_LOG(m_logger) << "detach bconly-telegram : telId=" << a_radioTelegram->getTelID() << " BC=" << broadcastIndex; if (broadcastOnlyTelegram->getBroadcastIndex() != broadcastIndex) ERROR_LOG(m_logger) << "Internal error: BC=" << broadcastOnlyTelegram->getBroadcastIndex() << " of attached telegram is not equal BC=" << broadcastIndex; auto iter = m_BroadcastMap.find(broadcastIndex); if (iter != m_BroadcastMap.end()) ERROR_LOG(m_logger) << "Internal error: m_BroadcastMap-entry with BC=" << broadcastIndex << " must not exists"; else { INFO_LOG(m_logger) << "Insert broadcast-only BC=" << broadcastOnlyTelegram->getBroadcastIndex(); broadcastOnlyTelegram->setBroadcastOnly(); m_BroadcastMap.insert(std::make_pair(broadcastIndex, broadcastOnlyTelegram)); } a_radioTelegram->setBroadcastonlyTelegram(nullptr); } } void PrtCnvBroadcastMgr::handleOverrunOfBroadcastCounter(const bool a_doRestore) { WARNING_LOG(m_logger) << "Broadcast-counter reaches maximum => reduce broadcast-list and increment reset-counter"; if (!a_doRestore) { m_DbThread->waitUntilDbWritten(); getAllFinishedBroadcastsFromDb(); } uint16_t newBroadcastCounter = 0; std::map> newBroadcastMap; auto iter = m_BroadcastMap.begin(); while (iter != m_BroadcastMap.end()) { auto radioTelegram = iter->second; if (radioTelegram->isBroadcastOnly()) { ++iter; removeFromAllMaps(radioTelegram); } else { radioTelegram->setBroadcastIndex(++newBroadcastCounter); auto broadcastOnlyTelegram = radioTelegram->getBroadcastonlyTelegram(); if (broadcastOnlyTelegram) { radioTelegram->setBroadcastonlyTelegram(nullptr); ++iter; removeFromAllMaps(broadcastOnlyTelegram); } else { bool wasLast; if (radioTelegram->mustBeSentAsBroadcast(std::numeric_limits::max(), wasLast, false)) { do { radioTelegram->mustBeSentAsBroadcast(std::numeric_limits::max(), wasLast, true); } while (!wasLast); } ++iter; } INFO_LOG(m_logger) << "New BC-index for broadcast-telegram with telId=" << radioTelegram->getTelID() << " BC=" << newBroadcastCounter; newBroadcastMap.insert(std::make_pair(newBroadcastCounter, radioTelegram)); } } m_BroadcastMap.clear(); m_BroadcastMap = newBroadcastMap; cleanAndInit(false); if (!a_doRestore) m_DbThread->setResetCounter(m_DbThread->getResetCounter() + 1); WARNING_LOG(m_logger) << "New broadcast-counter=" << newBroadcastCounter << " new reset-counter=" << (int)m_DbThread->getResetCounter(); m_BroadcastIndex = newBroadcastCounter; } void PrtCnvBroadcastMgr::restoreAfterCrash() { getAllFinishedBroadcastsFromDb(true); } void PrtCnvBroadcastMgr::dump() { for (const auto &it : m_BroadcastMap) dumpTelegram(m_loggerBcRequest, it.first, it.second.get(), "m_BroadcastMap, "); for (const auto &it : m_WirkfeldTelegramMapByKennung) dumpTelegram(m_loggerBcRequest, it.first, it.second.get(), "m_WirkfeldTelegramMapByKennung, "); for (const auto &it : m_WirkfeldTelegramMapByTime) dumpTelegram(m_loggerBcRequest, it.first, it.second.get(), "m_WirkfeldTelegramMapByTime, "); for (const auto &it : m_FunktionsraumTelegramMap) dumpTelegram(m_loggerBcRequest, it.first, it.second.get(), "m_FunktionsraumTelegramMap, "); for (const auto &it : m_TechnikFunktionsraumTelegramMap) dumpTelegram(m_loggerBcRequest, it.first, it.second.get(), "m_TechnikFunktionsraumTelegramMap, "); for (const auto &it : m_LastTelegramMap) dumpTelegram(m_loggerBcRequest, it.first, it.second.get(), "m_LastTelegramMap, "); } void PrtCnvBroadcastMgr::incTickAndSetTrafficLoad(const bool a_isHighLoad, const bool a_isFullLoad) { if (e_ST_COLLECT == m_State) ++m_TickCounter; m_IsFullLoad = a_isFullLoad; if (a_isHighLoad) m_ActClaimWindow = m_HighLoadFactor * m_ClaimWindow; else m_ActClaimWindow = m_ClaimWindow; } bool PrtCnvBroadcastMgr::isEffectSimulationIdDeactivated(const uint16_t effectsimulationId) const { INFO_LOG(m_logger) << "Checking deactivation for Id " << effectsimulationId; return m_deactivatedAesArea2bcIndex.contains(effectsimulationId); } }