| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // ====================================================================== | ||
| 2 | // \title FprimeRouter.cpp | ||
| 3 | // \author thomas-bc | ||
| 4 | // \brief cpp file for FprimeRouter component implementation class | ||
| 5 | // ====================================================================== | ||
| 6 | |||
| 7 | #include "Svc/FprimeRouter/FprimeRouter.hpp" | ||
| 8 | #include "Fw/Com/ComPacket.hpp" | ||
| 9 | #include "Fw/FPrimeBasicTypes.hpp" | ||
| 10 | #include "Fw/Logger/Logger.hpp" | ||
| 11 | #include "config/ApidEnumAc.hpp" | ||
| 12 | |||
| 13 | namespace Svc { | ||
| 14 | |||
| 15 | // ---------------------------------------------------------------------- | ||
| 16 | // Component construction and destruction | ||
| 17 | // ---------------------------------------------------------------------- | ||
| 18 | |||
| 19 |
3/9✓ Branch 10 taken 500 times.
✓ Branch 13 taken 500 times.
✓ Branch 14 taken 10 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
|
510 | FprimeRouter ::FprimeRouter(const char* const compName) : FprimeRouterComponentBase(compName) { |
| 20 | // Mark every table entry unused | ||
| 21 |
2/2✓ Branch 1 taken 500 times.
✓ Branch 2 taken 10 times.
|
510 | for (FwSizeType i = 0; i < FW_NUM_ARRAY_ELEMENTS(this->m_bufferContextTable); i++) { |
| 22 |
1/1✓ Branch 6 taken 500 times.
|
500 | this->m_bufferContextTable[i].state = Fw::Active::INACTIVE; |
| 23 | } | ||
| 24 | 10 | } | |
| 25 | |||
| 26 |
3/4✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✓ Branch 11 taken 500 times.
✓ Branch 12 taken 10 times.
|
1020 | FprimeRouter ::~FprimeRouter() {} |
| 27 | |||
| 28 | // ---------------------------------------------------------------------- | ||
| 29 | // Handler implementations for user-defined typed input ports | ||
| 30 | // ---------------------------------------------------------------------- | ||
| 31 | |||
| 32 | 109 | void FprimeRouter ::dataIn_handler(FwIndexType portNum, Fw::Buffer& packetBuffer, const ComCfg::FrameContext& context) { | |
| 33 | Fw::SerializeStatus status; | ||
| 34 | 109 | Fw::ComPacketType packetType = context.get_apid(); | |
| 35 | // Route based on received APID (packet type) | ||
| 36 |
3/3✓ Branch 0 taken 1 times.
✓ Branch 1 taken 55 times.
✓ Branch 2 taken 53 times.
|
109 | switch (packetType) { |
| 37 | // Handle a command packet | ||
| 38 | 1 | case Fw::ComPacketType::FW_PACKET_COMMAND: { | |
| 39 | // Allocate a com buffer on the stack | ||
| 40 |
1/1✓ Branch 2 taken 1 times.
|
1 | Fw::ComBuffer com; |
| 41 | // Copy the contents of the packet buffer into the com buffer | ||
| 42 |
3/3✓ Branch 5 taken 1 times.
✓ Branch 11 taken 1 times.
✓ Branch 14 taken 1 times.
|
1 | status = com.setBuff(packetBuffer.getData(), packetBuffer.getSize()); |
| 43 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (status == Fw::FW_SERIALIZE_OK) { |
| 44 | // Send the com buffer - critical functionality so it is considered an error not to | ||
| 45 | // have the port connected. This is why we don't check isConnected() before sending. | ||
| 46 |
1/1✓ Branch 5 taken 1 times.
|
1 | this->commandOut_out(0, com, 0); |
| 47 | } else { | ||
| 48 | ✗ | this->log_WARNING_HI_SerializationError(status); | |
| 49 | } | ||
| 50 | // The command buffer was copied into the com buffer above, so ownership of the | ||
| 51 | // incoming packetBuffer is returned immediately with the context it was received with. | ||
| 52 |
1/1✓ Branch 5 taken 1 times.
|
1 | this->dataReturnOut_out(0, packetBuffer, context); |
| 53 | 1 | break; | |
| 54 | 1 | } | |
| 55 | // Handle a file packet | ||
| 56 | 55 | case Fw::ComPacketType::FW_PACKET_FILE: { | |
| 57 | // If the file uplink output port is connected, send the file packet directly. | ||
| 58 | // Ownership is passed to the receiver and will come back on fileBufferReturnIn, | ||
| 59 | // at which point we return it to the deframer via dataReturnOut. fileOut carries | ||
| 60 | // only Fw::Buffer, so remember the context here to restore it on return. | ||
| 61 |
1/2✓ Branch 5 taken 55 times.
✗ Branch 6 not taken.
|
55 | if (this->isConnected_fileOut_OutputPort(0)) { |
| 62 |
3/3✓ Branch 3 taken 55 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 54 times.
|
55 | if (this->insertContext(packetBuffer, context) == Fw::Success::FAILURE) { |
| 63 | 1 | this->log_WARNING_HI_FileOutContextTableFull(); | |
| 64 | } | ||
| 65 | 55 | this->fileOut_out(0, packetBuffer); | |
| 66 | } else { | ||
| 67 | // Port not connected, return the buffer immediately with its context | ||
| 68 | ✗ | this->dataReturnOut_out(0, packetBuffer, context); | |
| 69 | } | ||
| 70 | 55 | break; | |
| 71 | } | ||
| 72 | 53 | default: { | |
| 73 | // Packet type is not known to the F Prime protocol. If the unknownDataOut port is | ||
| 74 | // connected, forward packet and context for further processing. | ||
| 75 | // Ownership is passed to the receiver and will come back on fileBufferReturnIn, | ||
| 76 | // at which point we return it to the deframer via dataReturnOut. The return path | ||
| 77 | // (fileBufferReturnIn) carries no context, so remember it here to restore on return. | ||
| 78 |
2/2✓ Branch 5 taken 52 times.
✓ Branch 6 taken 1 times.
|
53 | if (this->isConnected_unknownDataOut_OutputPort(0)) { |
| 79 |
3/3✓ Branch 3 taken 52 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 51 times.
|
52 | if (this->insertContext(packetBuffer, context) == Fw::Success::FAILURE) { |
| 80 | 1 | this->log_WARNING_HI_UnknownDataOutContextTableFull(); | |
| 81 | } | ||
| 82 | 52 | this->unknownDataOut_out(0, packetBuffer, context); | |
| 83 | } else { | ||
| 84 | // Port not connected, return the buffer immediately with its context | ||
| 85 | 1 | this->dataReturnOut_out(0, packetBuffer, context); | |
| 86 | } | ||
| 87 | 53 | break; | |
| 88 | } | ||
| 89 | } | ||
| 90 | 109 | } | |
| 91 | |||
| 92 | 1 | void FprimeRouter ::cmdResponseIn_handler(FwIndexType portNum, | |
| 93 | FwOpcodeType opcode, | ||
| 94 | U32 cmdSeq, | ||
| 95 | const Fw::CmdResponse& response) { | ||
| 96 | // Nothing to do | ||
| 97 | 1 | } | |
| 98 | |||
| 99 | 6 | void FprimeRouter ::fileBufferReturnIn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer) { | |
| 100 | // Restore the context that was saved when this buffer was handed off on | ||
| 101 | // fileOut/unknownDataOut | ||
| 102 |
1/1✓ Branch 2 taken 6 times.
|
6 | ComCfg::FrameContext context; |
| 103 |
3/3✓ Branch 3 taken 6 times.
✓ Branch 12 taken 3 times.
✓ Branch 13 taken 3 times.
|
6 | if (this->takeContext(fwBuffer, context) == Fw::Success::FAILURE) { |
| 104 | // Buffer not found in the table: return with an empty context (already default) | ||
| 105 |
1/1✓ Branch 5 taken 3 times.
|
3 | this->log_WARNING_HI_BufferContextNotFound(); |
| 106 | } | ||
| 107 |
1/1✓ Branch 5 taken 6 times.
|
6 | this->dataReturnOut_out(0, fwBuffer, context); |
| 108 | 12 | } | |
| 109 | |||
| 110 | // ---------------------------------------------------------------------- | ||
| 111 | // Buffer-to-context association table helpers | ||
| 112 | // ---------------------------------------------------------------------- | ||
| 113 | |||
| 114 | 107 | Fw::Success FprimeRouter ::insertContext(const Fw::Buffer& buffer, const ComCfg::FrameContext& context) { | |
| 115 | 107 | const U8* key = buffer.getData(); | |
| 116 |
2/2✓ Branch 1 taken 2656 times.
✓ Branch 2 taken 2 times.
|
2658 | for (FwSizeType i = 0; i < FW_NUM_ARRAY_ELEMENTS(this->m_bufferContextTable); i++) { |
| 117 |
2/2✓ Branch 6 taken 105 times.
✓ Branch 7 taken 2551 times.
|
2656 | if (this->m_bufferContextTable[i].state == Fw::Active::INACTIVE) { |
| 118 | 105 | this->m_bufferContextTable[i].state = Fw::Active::ACTIVE; | |
| 119 | 105 | this->m_bufferContextTable[i].key = key; | |
| 120 | 105 | this->m_bufferContextTable[i].context = context; | |
| 121 | 105 | return Fw::Success::SUCCESS; | |
| 122 | } | ||
| 123 | } | ||
| 124 | // Table full | ||
| 125 | 2 | return Fw::Success::FAILURE; | |
| 126 | } | ||
| 127 | |||
| 128 | 6 | Fw::Success FprimeRouter ::takeContext(const Fw::Buffer& buffer, ComCfg::FrameContext& context) { | |
| 129 | 6 | const U8* key = buffer.getData(); | |
| 130 |
2/2✓ Branch 1 taken 154 times.
✓ Branch 2 taken 3 times.
|
157 | for (FwSizeType i = 0; i < FW_NUM_ARRAY_ELEMENTS(this->m_bufferContextTable); i++) { |
| 131 |
6/6✓ Branch 6 taken 104 times.
✓ Branch 7 taken 50 times.
✓ Branch 12 taken 3 times.
✓ Branch 13 taken 101 times.
✓ Branch 14 taken 3 times.
✓ Branch 15 taken 151 times.
|
154 | if (this->m_bufferContextTable[i].state == Fw::Active::ACTIVE && this->m_bufferContextTable[i].key == key) { |
| 132 | 3 | context = this->m_bufferContextTable[i].context; | |
| 133 | 3 | this->m_bufferContextTable[i].state = Fw::Active::INACTIVE; | |
| 134 | 3 | return Fw::Success::SUCCESS; | |
| 135 | } | ||
| 136 | } | ||
| 137 | // Not found | ||
| 138 | 3 | return Fw::Success::FAILURE; | |
| 139 | } | ||
| 140 | |||
| 141 | } // namespace Svc | ||
| 142 |