diff --git a/container/FIFO.h b/container/FIFO.h index 670a50d7..134da9b8 100644 --- a/container/FIFO.h +++ b/container/FIFO.h @@ -21,7 +21,7 @@ public: readIndex(0), writeIndex(0), currentSize(0) { } - bool emtpy() { + bool empty() { return (currentSize == 0); } @@ -45,7 +45,7 @@ public: } ReturnValue_t retrieve(T *value) { - if (emtpy()) { + if (empty()) { return EMPTY; } else { *value = data[readIndex]; diff --git a/container/IndexedRingMemoryArray.h b/container/IndexedRingMemoryArray.h index eacfe3e5..992b7489 100644 --- a/container/IndexedRingMemoryArray.h +++ b/container/IndexedRingMemoryArray.h @@ -2,10 +2,10 @@ #define FRAMEWORK_CONTAINER_INDEXEDRINGMEMORY_H_ #include +#include #include #include #include -#include #include template diff --git a/datalinklayer/DataLinkLayer.cpp b/datalinklayer/DataLinkLayer.cpp index 1ee546c1..70999403 100644 --- a/datalinklayer/DataLinkLayer.cpp +++ b/datalinklayer/DataLinkLayer.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include DataLinkLayer::DataLinkLayer(uint8_t* set_frame_buffer, ClcwIF* setClcw, @@ -60,7 +60,7 @@ ReturnValue_t DataLinkLayer::frameValidationCheck() { } ReturnValue_t DataLinkLayer::frameCheckCRC() { - uint16_t checkValue = ::Calculate_CRC(this->currentFrame.getFullFrame(), + uint16_t checkValue = CRC::crc16ccitt(this->currentFrame.getFullFrame(), this->currentFrame.getFullSize()); if (checkValue == 0) { return RETURN_OK; diff --git a/datalinklayer/TcTransferFrameLocal.cpp b/datalinklayer/TcTransferFrameLocal.cpp index a53c5b28..7362a6ae 100644 --- a/datalinklayer/TcTransferFrameLocal.cpp +++ b/datalinklayer/TcTransferFrameLocal.cpp @@ -6,7 +6,7 @@ */ #include -#include +#include #include #include @@ -25,7 +25,7 @@ TcTransferFrameLocal::TcTransferFrameLocal(bool bypass, bool controlCommand, uin uint16_t totalSize = sizeof(TcTransferFramePrimaryHeader) + dataSize + FRAME_CRC_SIZE -1; frame->header.vcidAndLength_h |= (totalSize & 0x0300) >> 8; frame->header.length_l = (totalSize & 0x00FF); - uint16_t crc = ::Calculate_CRC(getFullFrame(), getFullSize() -2); + uint16_t crc = CRC::crc16ccitt(getFullFrame(), getFullSize() -2); this->getFullFrame()[getFullSize()-2] = (crc & 0xFF00) >> 8; this->getFullFrame()[getFullSize()-1] = (crc & 0x00FF); } else if (dataSize <= 1016) { @@ -33,7 +33,7 @@ TcTransferFrameLocal::TcTransferFrameLocal(bool bypass, bool controlCommand, uin uint16_t dataCrcSize = sizeof(TcTransferFramePrimaryHeader) + 1 + dataSize + FRAME_CRC_SIZE -1; frame->header.vcidAndLength_h |= (dataCrcSize & 0x0300) >> 8; frame->header.length_l = (dataCrcSize & 0x00FF); - uint16_t crc = ::Calculate_CRC(getFullFrame(), getFullSize() -2); + uint16_t crc = CRC::crc16ccitt(getFullFrame(), getFullSize() -2); this->getFullFrame()[getFullSize()-2] = (crc & 0xFF00) >> 8; this->getFullFrame()[getFullSize()-1] = (crc & 0x00FF); } else { diff --git a/globalfunctions/crc_ccitt.cpp b/globalfunctions/CRC.cpp similarity index 92% rename from globalfunctions/crc_ccitt.cpp rename to globalfunctions/CRC.cpp index 2fbebd07..ecd0b675 100644 --- a/globalfunctions/crc_ccitt.cpp +++ b/globalfunctions/CRC.cpp @@ -1,7 +1,7 @@ -#include +#include #include -static const uint16_t crc_table[256] = { +const uint16_t CRC::crc16ccitt_table[256] = { 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, @@ -38,19 +38,18 @@ static const uint16_t crc_table[256] = { // CRC implementation -uint16_t Calculate_CRC(uint8_t const input[], uint32_t length) +uint16_t CRC::crc16ccitt(uint8_t const input[], uint32_t length, uint16_t startingCrc) { - uint16_t crc = 0xFFFF; uint8_t *data = (uint8_t *)input; unsigned int tbl_idx; while (length--) { - tbl_idx = ((crc >> 8) ^ *data) & 0xff; - crc = (crc_table[tbl_idx] ^ (crc << 8)) & 0xffff; + tbl_idx = ((startingCrc >> 8) ^ *data) & 0xff; + startingCrc = (crc16ccitt_table[tbl_idx] ^ (startingCrc << 8)) & 0xffff; data++; } - return crc & 0xffff; + return startingCrc & 0xffff; //The part below is not used! // bool temr[16]; diff --git a/globalfunctions/CRC.h b/globalfunctions/CRC.h new file mode 100644 index 00000000..4200f94f --- /dev/null +++ b/globalfunctions/CRC.h @@ -0,0 +1,16 @@ +#ifndef CRC_CCITT_H_ +#define CRC_CCITT_H_ + +#include + +class CRC { +public: + static uint16_t crc16ccitt(uint8_t const input[], uint32_t length, + uint16_t startingCrc = 0xffff); +private: + CRC(); + + static const uint16_t crc16ccitt_table[256]; +}; + +#endif /* CRC_H_ */ diff --git a/globalfunctions/crc_ccitt.h b/globalfunctions/crc_ccitt.h deleted file mode 100644 index 6310f184..00000000 --- a/globalfunctions/crc_ccitt.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef CRC_CCITT_H_ -#define CRC_CCITT_H_ - -#include - -uint16_t Calculate_CRC(uint8_t const input[], uint32_t length); - - -#endif /* CRC_H_ */ diff --git a/memory/MemoryHelper.cpp b/memory/MemoryHelper.cpp index 4905875e..69830084 100644 --- a/memory/MemoryHelper.cpp +++ b/memory/MemoryHelper.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -98,7 +98,7 @@ void MemoryHelper::completeDump(ReturnValue_t errorCode, break; } case MemoryMessage::CMD_MEMORY_CHECK: { - uint16_t crc = ::Calculate_CRC(reservedSpaceInIPC, size); + uint16_t crc = CRC::crc16ccitt(reservedSpaceInIPC, size); //Delete data immediately, was temporary. ipcStore->deleteData(ipcAddress); MemoryMessage::setMemoryCheckReply(&reply, crc); diff --git a/osal/FreeRTOS/MessageQueue.cpp b/osal/FreeRTOS/MessageQueue.cpp index f3aebcd1..887df392 100644 --- a/osal/FreeRTOS/MessageQueue.cpp +++ b/osal/FreeRTOS/MessageQueue.cpp @@ -38,7 +38,9 @@ ReturnValue_t MessageQueue::reply(MessageQueueMessage* message) { ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message, MessageQueueId_t* receivedFrom) { ReturnValue_t status = this->receiveMessage(message); - *receivedFrom = this->lastPartner; + if(status == HasReturnvaluesIF::RETURN_OK) { + *receivedFrom = this->lastPartner; + } return status; } @@ -89,23 +91,24 @@ MessageQueueId_t MessageQueue::getDefaultDestination() const { bool MessageQueue::isDefaultDestinationSet() const { return 0; } + ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, MessageQueueMessage *message, MessageQueueId_t sentFrom, bool ignoreFault) { message->setSender(sentFrom); - BaseType_t result = xQueueSendToBack(reinterpret_cast(sendTo),reinterpret_cast(message->getBuffer()), 0); - if (result != pdPASS) { - if (!ignoreFault) { - InternalErrorReporterIF* internalErrorReporter = objectManager->get( - objects::INTERNAL_ERROR_REPORTER); - if (internalErrorReporter != NULL) { - internalErrorReporter->queueMessageNotSent(); - } + BaseType_t result = xQueueSendToBack(reinterpret_cast(sendTo),reinterpret_cast(message->getBuffer()), 0); + if (result != pdPASS) { + if (!ignoreFault) { + InternalErrorReporterIF* internalErrorReporter = objectManager->get( + objects::INTERNAL_ERROR_REPORTER); + if (internalErrorReporter != NULL) { + internalErrorReporter->queueMessageNotSent(); } - return MessageQueueIF::FULL; } - return HasReturnvaluesIF::RETURN_OK; + return MessageQueueIF::FULL; + } + return HasReturnvaluesIF::RETURN_OK; } diff --git a/osal/FreeRTOS/QueueFactory.cpp b/osal/FreeRTOS/QueueFactory.cpp index 5c7087de..eaf245d3 100644 --- a/osal/FreeRTOS/QueueFactory.cpp +++ b/osal/FreeRTOS/QueueFactory.cpp @@ -1,6 +1,6 @@ #include -#include "../FreeRTOS/MessageQueue.h" +#include QueueFactory* QueueFactory::factoryInstance = NULL; diff --git a/osal/FreeRTOS/TaskFactory.cpp b/osal/FreeRTOS/TaskFactory.cpp index 7b2f70a3..753da60f 100644 --- a/osal/FreeRTOS/TaskFactory.cpp +++ b/osal/FreeRTOS/TaskFactory.cpp @@ -15,6 +15,7 @@ TaskFactory* TaskFactory::instance() { } /*** * Keep in Mind that you need to call before this vTaskStartScheduler()! + * High taskPriority_ number means high priority. */ PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_, diff --git a/tcdistribution/TcPacketCheck.cpp b/tcdistribution/TcPacketCheck.cpp index b942e6b6..90a1167f 100644 --- a/tcdistribution/TcPacketCheck.cpp +++ b/tcdistribution/TcPacketCheck.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -8,7 +8,7 @@ TcPacketCheck::TcPacketCheck( uint16_t set_apid ) : apid(set_apid) { } ReturnValue_t TcPacketCheck::checkPacket( TcPacketStored* current_packet ) { - uint16_t calculated_crc = ::Calculate_CRC ( current_packet->getWholeData(), current_packet->getFullSize() ); + uint16_t calculated_crc = CRC::crc16ccitt( current_packet->getWholeData(), current_packet->getFullSize() ); if ( calculated_crc != 0 ) { return INCORRECT_CHECKSUM; } diff --git a/tmtcpacket/pus/TcPacketBase.cpp b/tmtcpacket/pus/TcPacketBase.cpp index 630394f8..c81e06b7 100644 --- a/tmtcpacket/pus/TcPacketBase.cpp +++ b/tmtcpacket/pus/TcPacketBase.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -40,7 +40,7 @@ uint16_t TcPacketBase::getErrorControl() { void TcPacketBase::setErrorControl() { uint32_t full_size = getFullSize(); - uint16_t crc = ::Calculate_CRC(getWholeData(), full_size - CRC_SIZE); + uint16_t crc = CRC::crc16ccitt(getWholeData(), full_size - CRC_SIZE); uint32_t size = getApplicationDataSize(); (&tcData->data)[size] = (crc & 0XFF00) >> 8; // CRCH (&tcData->data)[size + 1] = (crc) & 0X00FF; // CRCL diff --git a/tmtcpacket/pus/TmPacketBase.cpp b/tmtcpacket/pus/TmPacketBase.cpp index 1599f79e..74bc9b8a 100644 --- a/tmtcpacket/pus/TmPacketBase.cpp +++ b/tmtcpacket/pus/TmPacketBase.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -39,7 +39,7 @@ uint16_t TmPacketBase::getErrorControl() { void TmPacketBase::setErrorControl() { uint32_t full_size = getFullSize(); - uint16_t crc = ::Calculate_CRC(getWholeData(), full_size - CRC_SIZE); + uint16_t crc = CRC::crc16ccitt(getWholeData(), full_size - CRC_SIZE); uint32_t size = getSourceDataSize(); getSourceData()[size] = (crc & 0XFF00) >> 8; // CRCH getSourceData()[size + 1] = (crc) & 0X00FF; // CRCL diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index ee59ffe4..bf2e8242 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -64,7 +64,7 @@ public: virtual ~CommandingServiceBase(); /*** - * This is the periodic called function + * This is the periodically called function. * Handle request queue for external commands. * Handle command Queue for internal commands. * @param opCode is unused here at the moment @@ -104,6 +104,69 @@ public: }; protected: + /** + * Check the target subservice + * @param subservice[in] + * @return -@c RETURN_OK on success + * -@c INVALID_SUBSERVICE if service is not known + */ + virtual ReturnValue_t isValidSubservice(uint8_t subservice) = 0; + + /** + * Once a TC Request is valid, the existence of the destination and its target interface is checked and retrieved. + * The target message queue ID can then be acquired by using the target interface. + * @param subservice + * @param tcData Application Data of TC Packet + * @param tcDataLen + * @param id MessageQueue ID is stored here + * @param objectId Object ID is extracted and stored here + * @return - @c RETURN_OK on success + * - @c RETURN_FAILED + * - @c CSB or implementation specific return codes + */ + virtual ReturnValue_t getMessageQueueAndObject(uint8_t subservice, + const uint8_t *tcData, uint32_t tcDataLen, MessageQueueId_t *id, + object_id_t *objectId) = 0; + + /** + * After the Message Queue and Object ID are determined, + * the command is prepared by using an implementation specific CommandMessage type + * which is sent to the target object. + * It contains all necessary information for the device to execute telecommands. + * @param message[out] message to be sent to the object + * @param subservice[in] Subservice of the current communication + * @param tcData Additional data of the command + * @param tcDataLen Length of the additional data + * @param state[out] Setable state of the communication + * @param objectId Target object ID + * @return - @c RETURN_OK on success + * - @c EXECUTION_COMPLETE if exectuin is finished + * - any other return code will be part of (1,4) start failure + */ + virtual ReturnValue_t prepareCommand(CommandMessage *message, + uint8_t subservice, const uint8_t *tcData, uint32_t tcDataLen, + uint32_t *state, object_id_t objectId) = 0; + + /** + * This function is responsible for the communication between the Command Service Base + * and the respective PUS Commanding Service once the execution has started. + * The PUS Commanding Service receives replies from the target device and forwards them by calling this function. + * There are different translations of these replies to specify how the Command Service proceeds. + * @param reply Command Message which contains information about the command + * @param previousCommand Command_t of last command + * @param state state of the communication + * @param optionalNextCommand[out] An optional next command which can be set in this function + * @param objectId Source object ID + * @param isStep Flag value to mark steps of command execution + * @return - @c RETURN_OK, @c EXECUTION_COMPLETE or @c NO_STEP_MESSAGE to generate TC verification success + * - @c INVALID_REPLY can handle unrequested replies + * - Anything else triggers a TC verification failure + */ + virtual ReturnValue_t handleReply(const CommandMessage *reply, + Command_t previousCommand, uint32_t *state, + CommandMessage *optionalNextCommand, object_id_t objectId, + bool *isStep) = 0; + struct CommandInfo { struct tcInfo { uint8_t ackFlags; @@ -180,20 +243,6 @@ protected: */ void sendTmPacket(uint8_t subservice, SerializeIF* content, SerializeIF* header = NULL); - virtual ReturnValue_t isValidSubservice(uint8_t subservice) = 0; - - virtual ReturnValue_t prepareCommand(CommandMessage *message, - uint8_t subservice, const uint8_t *tcData, uint32_t tcDataLen, - uint32_t *state, object_id_t objectId) = 0; - - virtual ReturnValue_t handleReply(const CommandMessage *reply, - Command_t previousCommand, uint32_t *state, - CommandMessage *optionalNextCommand, object_id_t objectId, - bool *isStep) = 0; - - virtual ReturnValue_t getMessageQueueAndObject(uint8_t subservice, - const uint8_t *tcData, uint32_t tcDataLen, MessageQueueId_t *id, - object_id_t *objectId) = 0; virtual void handleUnrequestedReply(CommandMessage *reply); @@ -209,7 +258,8 @@ private: * It handles replies generated by the devices and relayed by the specific service implementation. * This means that it determines further course of action depending on the return values specified * in the service implementation. - * This includes the generation of TC verification messages: + * This includes the generation of TC verification messages. Note that + * the static framework object ID @c VerificationReporter::messageReceiver needs to be set. * - TM[1,5] Step Successs * - TM[1,6] Step Failure * - TM[1,7] Completion Success diff --git a/tmtcservices/PusServiceBase.cpp b/tmtcservices/PusServiceBase.cpp index c8f6accf..6e105325 100644 --- a/tmtcservices/PusServiceBase.cpp +++ b/tmtcservices/PusServiceBase.cpp @@ -23,14 +23,14 @@ ReturnValue_t PusServiceBase::performOperation(uint8_t opCode) { TmTcMessage message; for (uint8_t count = 0; count < PUS_SERVICE_MAX_RECEPTION; count++) { ReturnValue_t status = this->requestQueue->receiveMessage(&message); - // debug << "PusServiceBase::performOperation: Receiving from MQ ID: " << std::hex << this->requestQueue.getId() << std::dec << " returned: " << status << std::endl; + // debug << "PusServiceBase::performOperation: Receiving from MQ ID: " << std::hex << this->requestQueue.getId() + // << std::dec << " returned: " << status << std::endl; if (status == RETURN_OK) { this->currentPacket.setStoreAddress(message.getStorageId()); -// info << "Service " << (uint16_t) this->serviceId << ": new packet!" -// << std::endl; + // info << "Service " << (uint16_t) this->serviceId << ": new packet!" << std::endl; ReturnValue_t return_code = this->handleRequest(); - // debug << "Service " << (uint16_t)this->serviceId << ": handleRequest returned: " << (int)return_code << std::endl; + // debug << "Service " << (uint16_t)this->serviceId << ": handleRequest returned: " << (int)return_code << std::endl; if (return_code == RETURN_OK) { this->verifyReporter.sendSuccessReport( TC_VERIFY::COMPLETION_SUCCESS, &this->currentPacket); @@ -44,7 +44,7 @@ ReturnValue_t PusServiceBase::performOperation(uint8_t opCode) { errorParameter2 = 0; } else if (status == MessageQueueIF::EMPTY) { status = RETURN_OK; - // debug << "PusService " << (uint16_t)this->serviceId << ": no new packet." << std::endl; + // debug << "PusService " << (uint16_t)this->serviceId << ": no new packet." << std::endl; break; } else { diff --git a/tmtcservices/PusServiceBase.h b/tmtcservices/PusServiceBase.h index 782d375f..d318ff1e 100644 --- a/tmtcservices/PusServiceBase.h +++ b/tmtcservices/PusServiceBase.h @@ -46,13 +46,20 @@ public: */ virtual ~PusServiceBase(); /** - * The handleRequest method shall handle any kind of Telecommand Request immediately. + * @brief The handleRequest method shall handle any kind of Telecommand Request immediately. + * @details * Implemetations can take the Telecommand in currentPacket and perform any kind of operation. * They may send additional "Start Success (1,3)" messages with the verifyReporter, but Completion * Success or Failure Reports are generated automatically after execution of this method. - * If a Telecommand can not be executed within one call cycle, this Base class is not the right parent. - * The child class may add additional error information in #errorParameters which are attached to the generated - * verification message. + * + * If a Telecommand can not be executed within one call cycle, + * this Base class is not the right parent. + * + * The child class may add additional error information by setting #errorParameters which are + * attached to the generated verification message. + * + * Subservice checking should be implemented in this method. + * * @return The returned status_code is directly taken as main error code in the Verification Report. * On success, RETURN_OK shall be returned. */ @@ -68,8 +75,8 @@ public: * It checks for new requests, and, if found, calls handleRequest, sends completion verification messages and deletes * the TC requests afterwards. * performService is always executed afterwards. - * @return - \c RETURN_OK if the periodic performService was successful. - * - \c RETURN_FAILED else. + * @return \c RETURN_OK if the periodic performService was successful. + * \c RETURN_FAILED else. */ ReturnValue_t performOperation(uint8_t opCode); virtual uint16_t getIdentifier(); @@ -91,7 +98,7 @@ protected: /** * One of two error parameters for additional error information. */ - uint8_t errorParameter2; + uint32_t errorParameter2; /** * This is a complete instance of the Telecommand reception queue of the class. * It is initialized on construction of the class.