| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // ====================================================================== | ||
| 2 | // \title BufferRepeater.cpp | ||
| 3 | // \author lestarch | ||
| 4 | // \brief cpp file for GenericRepeater component implementation class | ||
| 5 | // | ||
| 6 | // \copyright | ||
| 7 | // Copyright 2009-2015, by the California Institute of Technology. | ||
| 8 | // ALL RIGHTS RESERVED. United States Government Sponsorship | ||
| 9 | // acknowledged. | ||
| 10 | // | ||
| 11 | // ====================================================================== | ||
| 12 | |||
| 13 | #include <Fw/FPrimeBasicTypes.hpp> | ||
| 14 | #include <Svc/BufferRepeater/BufferRepeater.hpp> | ||
| 15 | #include <cstring> | ||
| 16 | |||
| 17 | namespace Svc { | ||
| 18 | |||
| 19 | // ---------------------------------------------------------------------- | ||
| 20 | // Construction, initialization, and destruction | ||
| 21 | // ---------------------------------------------------------------------- | ||
| 22 | |||
| 23 | ✗ | BufferRepeater ::BufferRepeater(const char* const compName) | |
| 24 | : BufferRepeaterComponentBase(compName), | ||
| 25 | ✗ | m_allocation_failure_response(BufferRepeater::NUM_BUFFER_REPEATER_FAILURE_OPTIONS) {} | |
| 26 | |||
| 27 | ✗ | BufferRepeater ::~BufferRepeater() {} | |
| 28 | |||
| 29 | ✗ | void BufferRepeater ::configure(BufferRepeater::BufferRepeaterFailureOption allocation_failure_response) { | |
| 30 | ✗ | this->m_allocation_failure_response = allocation_failure_response; | |
| 31 | ✗ | } | |
| 32 | |||
| 33 | ✗ | bool BufferRepeater ::check_allocation(FwIndexType index, | |
| 34 | const Fw::Buffer& new_allocation, | ||
| 35 | const Fw::Buffer& incoming_buffer) { | ||
| 36 | ✗ | FW_ASSERT(index < NUM_PORTOUT_OUTPUT_PORTS, static_cast<FwAssertArgType>(index)); | |
| 37 | ✗ | bool is_valid = (new_allocation.getData() != nullptr) && (new_allocation.getSize() >= incoming_buffer.getSize()); | |
| 38 | |||
| 39 | // Respond to invalid buffer allocation | ||
| 40 | ✗ | if (!is_valid) { | |
| 41 | ✗ | switch (this->m_allocation_failure_response) { | |
| 42 | ✗ | case NO_RESPONSE_ON_OUT_OF_MEMORY: | |
| 43 | // No response intended | ||
| 44 | ✗ | break; | |
| 45 | ✗ | case WARNING_ON_OUT_OF_MEMORY: | |
| 46 | ✗ | this->log_WARNING_HI_AllocationSoftFailure(index, incoming_buffer.getSize()); | |
| 47 | ✗ | break; | |
| 48 | ✗ | case FATAL_ON_OUT_OF_MEMORY: | |
| 49 | ✗ | this->log_FATAL_AllocationHardFailure(index, incoming_buffer.getSize()); | |
| 50 | ✗ | break; | |
| 51 | ✗ | default: | |
| 52 | ✗ | FW_ASSERT(false); | |
| 53 | ✗ | break; | |
| 54 | } | ||
| 55 | } | ||
| 56 | ✗ | return is_valid; | |
| 57 | } | ||
| 58 | |||
| 59 | // ---------------------------------------------------------------------- | ||
| 60 | // Handler implementations for user-defined serial input ports | ||
| 61 | // ---------------------------------------------------------------------- | ||
| 62 | |||
| 63 | ✗ | void BufferRepeater ::portIn_handler(FwIndexType portNum, /*!< The port number*/ | |
| 64 | Fw::Buffer& buffer /*!< The serialization buffer*/ | ||
| 65 | ) { | ||
| 66 | ✗ | FW_ASSERT(this->m_allocation_failure_response < NUM_BUFFER_REPEATER_FAILURE_OPTIONS); | |
| 67 | ✗ | for (FwIndexType i = 0; i < NUM_PORTOUT_OUTPUT_PORTS; i++) { | |
| 68 | ✗ | if (isConnected_portOut_OutputPort(i)) { | |
| 69 | ✗ | Fw::Buffer new_allocation = this->allocate_out(0, buffer.getSize()); | |
| 70 | ✗ | const bool allocationValid = this->check_allocation(i, new_allocation, buffer); | |
| 71 | ✗ | if (allocationValid) { | |
| 72 | // Clone the data and send it | ||
| 73 | ✗ | FW_ASSERT_NO_OVERFLOW(buffer.getSize(), size_t); | |
| 74 | ✗ | (void)::memcpy(new_allocation.getData(), buffer.getData(), static_cast<size_t>(buffer.getSize())); | |
| 75 | ✗ | new_allocation.setSize(buffer.getSize()); | |
| 76 | ✗ | this->portOut_out(i, new_allocation); | |
| 77 | ✗ | } else if (new_allocation.getData() != nullptr) { | |
| 78 | // Return an undersized but valid allocation rather than leaking it | ||
| 79 | ✗ | this->deallocate_out(0, new_allocation); | |
| 80 | } | ||
| 81 | ✗ | } | |
| 82 | } | ||
| 83 | ✗ | this->deallocate_out(0, buffer); | |
| 84 | ✗ | } | |
| 85 | } // end namespace Svc | ||
| 86 |