#include "PlocHandler.h" #include #include #include #include PlocHandler::PlocHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie) : DeviceHandlerBase(objectId, comIF, comCookie) { if (comCookie == NULL) { sif::error << "PlocHandler: Invalid com cookie" << std::endl; } } PlocHandler::~PlocHandler() { } void PlocHandler::doStartUp(){ if(mode == _MODE_START_UP){ setMode(MODE_ON); } } void PlocHandler::doShutDown(){ } ReturnValue_t PlocHandler::buildNormalDeviceCommand( DeviceCommandId_t * id) { return RETURN_OK; } ReturnValue_t PlocHandler::buildTransitionDeviceCommand( DeviceCommandId_t * id){ return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t PlocHandler::buildCommandFromCommand( DeviceCommandId_t deviceCommand, const uint8_t * commandData, size_t commandDataLen) { switch(deviceCommand) { case(PLOC::TC_MEM_WRITE): { const uint32_t memoryAddress = *(commandData) << 24 | *(commandData + 1) << 16 | *(commandData + 2) << 8 | *(commandData + 3); const uint32_t memoryData = *(commandData + 4) << 24 | *(commandData + 5) << 16 | *(commandData + 6) << 8 | *(commandData + 7); PLOC::TcMemWrite tcMemWrite(memoryAddress, memoryData); rawPacket = tcMemWrite.getWholeData(); rawPacketLen = tcMemWrite.getFullSize(); rememberCommandId = PLOC::TC_MEM_WRITE; return RETURN_OK; } case(PLOC::TC_MEM_READ): { const uint32_t memoryAddress = *(commandData) << 24 | *(commandData + 1) << 16 | *(commandData + 2) << 8 | *(commandData + 3); PLOC::TcMemRead tcMemRead(memoryAddress); rawPacket = tcMemRead.getWholeData(); rawPacketLen = tcMemRead.getFullSize(); rememberCommandId = PLOC::TC_MEM_READ; return RETURN_OK; } default: sif::debug << "PlocHandler::buildCommandFromCommand: Command not implemented" << std::endl; return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; } return HasReturnvaluesIF::RETURN_FAILED; } void PlocHandler::fillCommandAndReplyMap() { this->insertInCommandAndReplyMap(PLOC::TC_MEM_WRITE, 1, nullptr, PLOC::SIZE_ACK_REPORT); this->insertInCommandAndReplyMap(PLOC::TC_MEM_READ, 1, nullptr, PLOC::SIZE_ACK_REPORT); this->insertInReplyMap(PLOC::ACK_SUCCESS, 1); this->insertInReplyMap(PLOC::ACK_FAILURE, 1); } ReturnValue_t PlocHandler::scanForReply(const uint8_t *start, size_t remainingSize, DeviceCommandId_t *foundId, size_t *foundLen) { ReturnValue_t result = RETURN_OK; *foundId = (*(start) << 8 | *(start + 1)) & APID_MASK; switch(*foundId) { case(PLOC::ACK_SUCCESS): *foundLen = PLOC::SIZE_ACK_REPORT; break; case(PLOC::ACK_FAILURE): *foundLen = PLOC::SIZE_ACK_REPORT; break; default: sif::debug << "PlocHandler::scanForReply: Reply has invalid apid" << std::endl; result = IGNORE_REPLY_DATA; break; } result = verifyPacket(start, foundLen); return result; } ReturnValue_t PlocHandler::verifyPacket(const uint8_t* start, size_t* foundLen) { uint16_t receivedCrc = *(start + *foundLen - 2) << 8 | *(start + *foundLen - 1); if (receivedCrc != CRC::crc16ccitt(start, *foundLen, 0)) { return CRC_FAILURE; } return RETURN_OK; } ReturnValue_t PlocHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { switch (id) { case (PLOC::ACK_SUCCESS): receiveTm(); receiveExecutionReport(); break; case (PLOC::ACK_FAILURE): //TODO: Interpretation of status field in ack reply. sif::error << "PlocHandler::interpretDeviceReply: Received ack failure reply" << std::endl; triggerEvent(ACK_FAILURE, rememberCommandId); break; default: { sif::debug << "PlocHandler::interpretDeviceReply: Unknown device reply id" << std::endl; return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; } } return RETURN_OK; } void PlocHandler::receiveTm() { switch (rememberCommandId) { case (PLOC::TC_MEM_WRITE): break; case (PLOC::TC_MEM_READ): receiveTmMemoryReadReport(); break; default: sif::debug << "PlocHandler::receiveTm: Rembered unknown command id" << std::endl; break; } } void PlocHandler::receiveExecutionReport() { size_t receivedDataLen = 0; uint8_t *receivedData = nullptr; communicationInterface->requestReceiveMessage(comCookie, PLOC::SIZE_EXE_REPORT); communicationInterface->readReceivedMessage(comCookie, &receivedData, &receivedDataLen); if(!verifyPacket(receivedData, &receivedDataLen)) { replyRawData(receivedData, receivedDataLen, defaultRawReceiver); triggerEvent(EXE_RPT_INVALID_CRC); sif::error << "PlocHandler::receiveExecutionReport: Execution report has invalid crc" << std::endl; return; } handleExecutionReport(receivedData, receivedDataLen); } void PlocHandler::handleExecutionReport(const uint8_t* receivedData, size_t receivedDataLen) { uint16_t apid = (*(receivedData) << 8 | *(receivedData + 1)) & APID_MASK; switch (apid) { case (PLOC::APID_EXE_SUCCESS): { return; } case (PLOC::APID_EXE_FAILURE): { //TODO: Interpretation of status field in execution report sif::error << "PlocHandler::handleExecutionReport: Received execution failure report" << std::endl; triggerEvent(EXE_FAILURE, rememberCommandId); return; } } return; } void PlocHandler::receiveTmMemoryReadReport() { size_t receivedDataLen = 0; uint8_t *receivedData = nullptr; /* Receiving the telemetry packet */ ReturnValue_t result = communicationInterface->requestReceiveMessage(comCookie, PLOC::SIZE_TM_MEM_READ_REPORT); if (result != RETURN_OK) { sif::error << "PlocHandler::receiveExecutionReport: Failed to request memory read telemetry " << std::endl; triggerEvent(REQUESTING_TM_READ_REPORT_FAILED, result); return; } result = communicationInterface->readReceivedMessage(comCookie, &receivedData, &receivedDataLen); if (result != RETURN_OK) { sif::error << "PlocHandler::receiveExecutionReport: Failed to request memory read telemetry " << std::endl; return; } uint16_t apid = (*(receivedData) << 8 | *(receivedData + 1)) & APID_MASK; if (apid != PLOC::APID_TM_READ_REPORT) { sif::error << "PlocHandler::receiveTmReadReport: Tm read report has invalid apid" << std::endl; return; } if(!verifyPacket(receivedData, &receivedDataLen)) { replyRawData(receivedData, receivedDataLen, defaultRawReceiver); triggerEvent(TM_READ_RPT_INVALID_CRC); sif::error << "PlocHandler::receiveTmReadReport: TM read report has invalid crc" << std::endl; return; } handleDeviceTM(receivedData, receivedDataLen, PLOC::TC_MEM_READ); } void PlocHandler::handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCommandId_t replyId) { ReturnValue_t result = RETURN_OK; DeviceReplyMap::iterator iter = deviceReplyMap.find(replyId); if (iter == deviceReplyMap.end()) { sif::debug << "PlocHandler::handleDeviceTM: Unknown reply id" << std::endl; return; } MessageQueueId_t queueId = iter->second.command->second.sendReplyTo; if (queueId == NO_COMMANDER) { return; } result = actionHelper.reportData(queueId, replyId, data, dataSize); if (result != RETURN_OK) { sif::debug << "PlocHandler::handleDeviceTM: Failed to report data" << std::endl; } } void PlocHandler::setNormalDatapoolEntriesInvalid(){ } uint32_t PlocHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo){ return 500; } ReturnValue_t PlocHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) { return HasReturnvaluesIF::RETURN_OK; } void PlocHandler::setModeNormal() { mode = MODE_NORMAL; }