/** * The BiteHandler class manages everything todo with bite requests. * $Id$ * $HeadURL$ * $Author$ * Created by Hannes Baeuerle, SLSE, 2016-06-06 */ #include "bite_handler.h" #include "ParticipantHandling/participant.h" #include "ParticipantHandling/participant_donator.h" #include "main_handler.h" #include namespace ParticipantManagement { namespace BiteHandling { BiteHandler::BiteHandler(MainHandler *mainHandler) : QObject() , Interface::Fts::CallBiteRequestHandler(mainHandler->fts()) , m_mainHandler(mainHandler) , m_logger(getLogger("BiteHandler")) { } bool BiteHandler::init() { return true; } void BiteHandler::onDemandBiteReply(const Core::FunctionReplyObject &replyObject) { if (replyObject.error()) WARNING_LOG(m_logger) << "Got an demandBiteError: " << replyObject(); auto it = m_demandedBiteParticipantRequests.find(replyObject.id()); if (it != m_demandedBiteParticipantRequests.end()) { const DemandedParticipants &dp = it.value(); m_mainHandler->fts()->callBiteReply(dp.cookie, replyObject); dp.timer->deleteLater(); m_demandedBiteParticipants -= dp.demandedBiteParticipants; m_demandedBiteParticipantRequests.erase(it); } else WARNING_LOG(m_logger) << "Bite request with request id " << replyObject.id() << " was not replied to by the proxy"; } void BiteHandler::onCallBiteRequest(const rti::core::SampleIdentity &cookie, const CallBiteRequest &request) { DEBUG_LOG(m_logger) << "onCallBiteRequest: " << request; auto ret = callBiteRequest(cookie, request); if (ret.error() || ret.id()) { WARNING_LOG(m_logger) << ret(); m_mainHandler->fts()->callBiteReply(cookie, ret); } // delayed answer in non-error case } Core::FunctionReplyObject BiteHandler::callBiteRequest(const rti::core::SampleIdentity &cookie, const CallBiteRequest &request) { TrainingAreaBase::DemandBiteRequest req; req.equipmentNumbers().reserve(request.participantIds().size()); req.withSelfTest(request.withSelfTest()); bool bOneFound = false; bool bAlreadyDemandedFound = false; QSet currentDemandedParticipants; for (const int participantId : request.participantIds()) { if (m_demandedBiteParticipants.contains(participantId)) { DEBUG_LOG(m_logger) << "demandBiteRequest for participant Id " << participantId << " already triggered - reply is still to be done"; bAlreadyDemandedFound = true; continue; } const ParticipantHandling::Participant *participant = m_mainHandler->participantHandler()->participantById(participantId); if (participant == nullptr) { WARNING_LOG(m_logger) << "Got BITE request for non existing participant id " << participantId; continue; } if (participant->equipmentNumber() == 0) { WARNING_LOG(m_logger) << "Got BITE request participant id " << participantId << " but has no equipment number set"; continue; } bOneFound = true; m_demandedBiteParticipants.insert(participant->id()); currentDemandedParticipants.insert(participant->id()); req.equipmentNumbers().push_back(participant->equipmentNumber()); } if (req.equipmentNumbers().size() == 0 && bAlreadyDemandedFound) return Core::FunctionReplyObject(req.requestId()); if (req.equipmentNumbers().size() != 0) { static int s_requestId = 1; req.requestId(s_requestId++); if (!m_mainHandler->tabFtc()->demandBiteRequest(req, this)) return Core::FunctionReplyObject(req.requestId(), tr_lts("dds", "Error passing the BITE request to the proxy")); QTimer *timeoutTimer = new QTimer(this); timeoutTimer->setSingleShot(true); timeoutTimer->setInterval(5000); const int requestId = req.requestId(); m_demandedBiteParticipantRequests.insert(requestId, {currentDemandedParticipants, cookie, timeoutTimer}); auto cb = [this, requestId]() { onBiteRequestTimeout(requestId); }; connect(timeoutTimer, &QTimer::timeout, this, cb); return Core::FunctionReplyObject(); } // at least one found but this was already requested and we're waiting for answer -> don't answer with error if (bOneFound) return Core::FunctionReplyObject(); return Core::FunctionReplyObject(req.requestId(), tr_lts("dds", "Got no valid participants for BITE request")); } void BiteHandler::onBiteRequestTimeout(int requestId) { INFO_LOG(m_logger) << "onBiteRequestTimeout for " << requestId; onDemandBiteReply(Core::FunctionReplyObject(requestId, tr_lts("dds", "Timeout while waiting for the proxy"))); } } // namespace BiteHandling } // namespace ParticipantManagement