| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // ====================================================================== | ||
| 2 | // \title TlmPacketizerImpl.cpp | ||
| 3 | // \author tcanham | ||
| 4 | // \brief cpp file for TlmPacketizer 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 | #include <Fw/Com/ComPacket.hpp> | ||
| 12 | #include <Fw/FPrimeBasicTypes.hpp> | ||
| 13 | #include <Fw/Prm/ParamValid.hpp> | ||
| 14 | #include <Svc/TlmPacketizer/TlmPacketizer.hpp> | ||
| 15 | #include <TlmPacketizerConfig/FppConstantsAc.hpp> | ||
| 16 | #include <cstring> | ||
| 17 | #include <limits> | ||
| 18 | |||
| 19 | namespace Svc { | ||
| 20 | |||
| 21 | const TlmPacketizer_TelemetrySendPortMap TlmPacketizer::TELEMETRY_SEND_PORT_MAP = {}; | ||
| 22 | |||
| 23 | static_assert(Svc::TelemetrySection::NUM_SECTIONS >= 1, "At least one telemetry section is required"); | ||
| 24 | |||
| 25 | // Keeps every offset a ComBuffer can hold representable in the offset type; setPacketList additionally asserts | ||
| 26 | // at runtime that no offset equals the NOT_IN_PACKET sentinel (the type's maximum) | ||
| 27 | static_assert(FW_COM_BUFFER_MAX_SIZE <= std::numeric_limits<FwTlmPacketizeOffsetType>::max(), | ||
| 28 | "FwTlmPacketizeOffsetType must span an entire ComBuffer"); | ||
| 29 | |||
| 30 | static_assert(static_cast<U8>(Fw::FW_DESERIALIZE_BUFFER_EMPTY) == Fw::DeserialStatus::BUFFER_EMPTY and | ||
| 31 | static_cast<U8>(Fw::FW_DESERIALIZE_FORMAT_ERROR) == Fw::DeserialStatus::FORMAT_ERROR and | ||
| 32 | static_cast<U8>(Fw::FW_DESERIALIZE_SIZE_MISMATCH) == Fw::DeserialStatus::SIZE_MISMATCH and | ||
| 33 | static_cast<U8>(Fw::FW_DESERIALIZE_TYPE_MISMATCH) == Fw::DeserialStatus::TYPE_MISMATCH, | ||
| 34 | "Fw::DeserialStatus must mirror Fw::SerializeStatus values"); | ||
| 35 | |||
| 36 | // ---------------------------------------------------------------------- | ||
| 37 | // Construction, initialization, and destruction | ||
| 38 | // ---------------------------------------------------------------------- | ||
| 39 | |||
| 40 | 35 | TlmPacketizer ::TlmPacketizer(const char* const compName) | |
| 41 |
12/18✓ Branch 20 taken 1750 times.
✓ Branch 23 taken 1750 times.
✓ Branch 24 taken 35 times.
✓ Branch 30 taken 35 times.
✓ Branch 41 taken 35 times.
✓ Branch 48 taken 35 times.
✓ Branch 55 taken 35 times.
✓ Branch 63 taken 3430 times.
✓ Branch 64 taken 70 times.
✓ Branch 65 taken 35 times.
✓ Branch 66 taken 35 times.
✓ Branch 75 taken 35 times.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✗ Branch 101 not taken.
✗ Branch 102 not taken.
|
5250 | : TlmPacketizerComponentBase(compName), m_numPackets(0), m_configured(false), m_numChannels(0) { |
| 42 | // Register self as parameter delegate | ||
| 43 |
1/1✓ Branch 7 taken 35 times.
|
35 | this->registerExternalParameters(this); |
| 44 | // clear missing tlm channel check | ||
| 45 |
2/2✓ Branch 0 taken 875 times.
✓ Branch 1 taken 35 times.
|
910 | for (FwChanIdType entry = 0; entry < TLMPACKETIZER_MAX_MISSING_TLM_CHECK; entry++) { |
| 46 | 875 | this->m_missTlmCheck[entry].checked = false; | |
| 47 | 875 | this->m_missTlmCheck[entry].id = 0; | |
| 48 | } | ||
| 49 | |||
| 50 | // clear packet buffers | ||
| 51 |
2/2✓ Branch 0 taken 1750 times.
✓ Branch 1 taken 35 times.
|
1785 | for (FwChanIdType buffer = 0; buffer < MAX_PACKETIZER_PACKETS; buffer++) { |
| 52 | 1750 | this->m_fillBuffers[buffer].updated = false; | |
| 53 | } | ||
| 54 | |||
| 55 | static_assert(NUM_CONFIGURABLE_TLMPACKETIZER_GROUPS == MAX_CONFIGURABLE_TLMPACKETIZER_GROUP + 1, | ||
| 56 | "NUM_CONFIGURABLE_TLMPACKETIZER_GROUPS MUST BE MAX_CONFIGURABLE_TLMPACKETIZER_GROUP + 1"); | ||
| 57 | 35 | } | |
| 58 | |||
| 59 |
3/4✓ Branch 37 taken 35 times.
✗ Branch 38 not taken.
✓ Branch 44 taken 1750 times.
✓ Branch 45 taken 35 times.
|
3570 | TlmPacketizer ::~TlmPacketizer() {} |
| 60 | |||
| 61 | 27 | void TlmPacketizer::setPacketList(const TlmPacketizerPacketList& packetList, | |
| 62 | const Svc::TlmPacketizerPacket& ignoreList, | ||
| 63 | const FwChanIdType startLevel) { | ||
| 64 | // Ignore list may be nullptr as long as numEntries is 0. Providing an ignore list with numEntries 0 disables | ||
| 65 | // functionality for two reasons: | ||
| 66 | // 1. There are no ignored channels as configured by FPP. | ||
| 67 | // 2. Ignore functionality is intentionally disabled by project where nullptr was intentionally supplied. | ||
| 68 | 27 | FW_ASSERT(ignoreList.list || ignoreList.numEntries == 0); | |
| 69 | 27 | FW_ASSERT(packetList.numEntries <= MAX_PACKETIZER_PACKETS, static_cast<FwAssertArgType>(packetList.numEntries)); | |
| 70 | |||
| 71 | // Reset key data members incase of reentrant calls | ||
| 72 | 27 | this->m_numChannels = 0; | |
| 73 | 27 | this->m_channelIndices.clear(); | |
| 74 | 27 | this->m_configured = false; | |
| 75 | |||
| 76 | // validate packet sizes against maximum com buffer size and populate hash | ||
| 77 | // table | ||
| 78 | 27 | FwChanIdType maxLevel = 0; | |
| 79 |
2/2✓ Branch 2 taken 105 times.
✓ Branch 3 taken 27 times.
|
132 | for (FwChanIdType pktEntry = 0; pktEntry < packetList.numEntries; pktEntry++) { |
| 80 | // Initial size is packetized telemetry descriptor + size of time tag + sizeof packet ID | ||
| 81 | 105 | FwSizeType packetLen = | |
| 82 | sizeof(FwPacketDescriptorType) + Fw::Time::SERIALIZED_SIZE + sizeof(FwTlmPacketizeIdType); | ||
| 83 | // A packet with no channels is autocoded with a nullptr list and is permitted | ||
| 84 | 105 | FW_ASSERT(packetList.list[pktEntry]->list != nullptr || packetList.list[pktEntry]->numEntries == 0, | |
| 85 | static_cast<FwAssertArgType>(pktEntry)); | ||
| 86 | // add up entries for each defined packet | ||
| 87 |
2/2✓ Branch 5 taken 226 times.
✓ Branch 6 taken 105 times.
|
331 | for (FwChanIdType tlmEntry = 0; tlmEntry < packetList.list[pktEntry]->numEntries; tlmEntry++) { |
| 88 | 226 | FwChanIdType id = packetList.list[pktEntry]->list[tlmEntry].id; | |
| 89 | 226 | const FwSizeType channelSize = packetList.list[pktEntry]->list[tlmEntry].size; | |
| 90 | 226 | FwSizeType entryIndex = 0; | |
| 91 |
3/3✓ Branch 4 taken 226 times.
✓ Branch 13 taken 151 times.
✓ Branch 14 taken 75 times.
|
226 | if (this->m_channelIndices.find(id, entryIndex) != Fw::Success::SUCCESS) { |
| 92 | // New channel - allocate a slot and initialize offsets to NOT_IN_PACKET | ||
| 93 | 151 | entryIndex = this->m_numChannels++; | |
| 94 |
1/1✓ Branch 4 taken 151 times.
|
151 | this->m_channels[entryIndex].id = id; |
| 95 |
1/1✓ Branch 4 taken 151 times.
|
151 | this->m_channels[entryIndex].hasValue = false; |
| 96 |
1/1✓ Branch 4 taken 151 times.
|
151 | this->m_channels[entryIndex].channelSize = channelSize; |
| 97 |
2/2✓ Branch 0 taken 7550 times.
✓ Branch 1 taken 151 times.
|
7701 | for (FwChanIdType pktOffsetEntry = 0; pktOffsetEntry < MAX_PACKETIZER_PACKETS; pktOffsetEntry++) { |
| 98 |
1/1✓ Branch 4 taken 7550 times.
|
7550 | this->m_channels[entryIndex].packetOffset[pktOffsetEntry] = NOT_IN_PACKET; |
| 99 | } | ||
| 100 |
1/1✓ Branch 4 taken 151 times.
|
151 | const Fw::Success insertStatus = this->m_channelIndices.insert(id, entryIndex); |
| 101 | 151 | FW_ASSERT(insertStatus == Fw::Success::SUCCESS, static_cast<FwAssertArgType>(insertStatus)); | |
| 102 | 151 | } else { | |
| 103 | // Existing channel - a channel ID may repeat across packets, but its definition (size) must match. | ||
| 104 | // A conflicting size would corrupt the packet offsets computed from the earlier definition and | ||
| 105 | // overflow the fill buffer during TlmRecv/TlmGet copies, so reject the misconfiguration here. | ||
| 106 | 75 | FW_ASSERT(this->m_channels[entryIndex].channelSize == channelSize, static_cast<FwAssertArgType>(id), | |
| 107 | static_cast<FwAssertArgType>(channelSize), | ||
| 108 | static_cast<FwAssertArgType>(this->m_channels[entryIndex].channelSize)); | ||
| 109 | } | ||
| 110 | // not ignored channel - update entry in place via reference | ||
| 111 |
1/1✓ Branch 4 taken 226 times.
|
226 | TlmEntry& entry = this->m_channels[entryIndex]; |
| 112 | 226 | entry.ignored = false; | |
| 113 | 226 | entry.channelSize = channelSize; | |
| 114 | // the offset into the buffer will be the current packet length | ||
| 115 | // the offset must fit within FwTlmPacketizeOffsetType and must not equal NOT_IN_PACKET | ||
| 116 | 226 | FW_ASSERT(packetLen < NOT_IN_PACKET, static_cast<FwAssertArgType>(packetLen)); | |
| 117 | 226 | entry.packetOffset[pktEntry] = static_cast<FwTlmPacketizeOffsetType>(packetLen); | |
| 118 | |||
| 119 | 226 | packetLen += entry.channelSize; | |
| 120 | |||
| 121 | } // end channel in packet | ||
| 122 | 105 | FW_ASSERT(packetLen <= FW_COM_BUFFER_MAX_SIZE, static_cast<FwAssertArgType>(packetLen), | |
| 123 | static_cast<FwAssertArgType>(pktEntry)); | ||
| 124 | // clear contents | ||
| 125 |
1/2✗ Branch 7 not taken.
✓ Branch 8 taken 105 times.
|
105 | (void)memset(this->m_fillBuffers[pktEntry].buffer.getBuffAddr(), 0, static_cast<size_t>(packetLen)); |
| 126 | // serialize packet descriptor and packet ID now since it will always be the same | ||
| 127 | 105 | Fw::SerializeStatus stat = this->m_fillBuffers[pktEntry].buffer.serializeFrom( | |
| 128 | static_cast<FwPacketDescriptorType>(Fw::ComPacketType::FW_PACKET_PACKETIZED_TLM)); | ||
| 129 | 105 | FW_ASSERT(Fw::FW_SERIALIZE_OK == stat, stat); | |
| 130 | 105 | stat = this->m_fillBuffers[pktEntry].buffer.serializeFrom(packetList.list[pktEntry]->id); | |
| 131 | 105 | FW_ASSERT(Fw::FW_SERIALIZE_OK == stat, stat); | |
| 132 | // set packet buffer length | ||
| 133 | 105 | stat = this->m_fillBuffers[pktEntry].buffer.setBuffLen(packetLen); | |
| 134 | 105 | FW_ASSERT(Fw::FW_SERIALIZE_OK == stat, stat); | |
| 135 | // save ID | ||
| 136 | 105 | this->m_fillBuffers[pktEntry].id = packetList.list[pktEntry]->id; | |
| 137 | // save level | ||
| 138 | 105 | this->m_fillBuffers[pktEntry].level = packetList.list[pktEntry]->level; | |
| 139 | // store max level | ||
| 140 |
2/2✓ Branch 5 taken 52 times.
✓ Branch 6 taken 53 times.
|
105 | if (packetList.list[pktEntry]->level > maxLevel) { |
| 141 | 52 | maxLevel = packetList.list[pktEntry]->level; | |
| 142 | } | ||
| 143 | |||
| 144 | } // end packet list | ||
| 145 | 27 | FW_ASSERT(maxLevel <= MAX_CONFIGURABLE_TLMPACKETIZER_GROUP, static_cast<FwAssertArgType>(maxLevel)); | |
| 146 | |||
| 147 | // This section adds entries in the map for channels that are intended to be ignored. When the user supplies | ||
| 148 | // a list with no length, this loop is skipped. To turn-off ignoring of channels, the user can provide a null | ||
| 149 | // list with 0 length. | ||
| 150 |
2/2✓ Branch 2 taken 44 times.
✓ Branch 3 taken 27 times.
|
71 | for (FwChanIdType channelEntry = 0; channelEntry < ignoreList.numEntries; channelEntry++) { |
| 151 | 44 | FwChanIdType id = ignoreList.list[channelEntry].id; | |
| 152 | 44 | FwSizeType entryIndex = 0; | |
| 153 |
2/3✓ Branch 4 taken 44 times.
✓ Branch 13 taken 44 times.
✗ Branch 14 not taken.
|
44 | if (this->m_channelIndices.find(id, entryIndex) != Fw::Success::SUCCESS) { |
| 154 | // New channel - allocate a slot and initialize offsets to NOT_IN_PACKET | ||
| 155 | 44 | entryIndex = this->m_numChannels++; | |
| 156 |
1/1✓ Branch 4 taken 44 times.
|
44 | this->m_channels[entryIndex].id = id; |
| 157 |
1/1✓ Branch 4 taken 44 times.
|
44 | this->m_channels[entryIndex].hasValue = false; |
| 158 |
2/2✓ Branch 0 taken 2200 times.
✓ Branch 1 taken 44 times.
|
2244 | for (FwChanIdType pktOffsetEntry = 0; pktOffsetEntry < MAX_PACKETIZER_PACKETS; pktOffsetEntry++) { |
| 159 |
1/1✓ Branch 4 taken 2200 times.
|
2200 | this->m_channels[entryIndex].packetOffset[pktOffsetEntry] = NOT_IN_PACKET; |
| 160 | } | ||
| 161 |
1/1✓ Branch 4 taken 44 times.
|
44 | const Fw::Success insertStatus = this->m_channelIndices.insert(id, entryIndex); |
| 162 | 44 | FW_ASSERT(insertStatus == Fw::Success::SUCCESS, static_cast<FwAssertArgType>(insertStatus)); | |
| 163 | 44 | } else { | |
| 164 | // Ensure it is a duplicate in the ignore list, not a duplicate of a valid channel | ||
| 165 | ✗ | FW_ASSERT(this->m_channels[entryIndex].ignored, static_cast<FwAssertArgType>(id)); | |
| 166 | } | ||
| 167 | // is ignored channel - update entry in place via reference | ||
| 168 |
1/1✓ Branch 4 taken 44 times.
|
44 | TlmEntry& entry = this->m_channels[entryIndex]; |
| 169 | 44 | entry.ignored = true; | |
| 170 | 44 | entry.channelSize = ignoreList.list[channelEntry].size; | |
| 171 | } // end ignore list | ||
| 172 | |||
| 173 | // store number of packets | ||
| 174 | 27 | this->m_numPackets = packetList.numEntries; | |
| 175 | |||
| 176 | // indicate configured | ||
| 177 | 27 | this->m_configured = true; | |
| 178 | 27 | } | |
| 179 | |||
| 180 | // ---------------------------------------------------------------------- | ||
| 181 | // Handler implementations for user-defined typed input ports | ||
| 182 | // ---------------------------------------------------------------------- | ||
| 183 | |||
| 184 | 200 | void TlmPacketizer ::TlmRecv_handler(const FwIndexType portNum, | |
| 185 | FwChanIdType id, | ||
| 186 | Fw::Time& timeTag, | ||
| 187 | Fw::TlmBuffer& val) { | ||
| 188 | 200 | FW_ASSERT(this->m_configured); | |
| 189 | 200 | FwSizeType entryIndex = 0; | |
| 190 | |||
| 191 | // Search to see if the channel is being tracked | ||
| 192 |
3/3✓ Branch 4 taken 200 times.
✓ Branch 13 taken 51 times.
✓ Branch 14 taken 149 times.
|
200 | if (this->m_channelIndices.find(id, entryIndex) != Fw::Success::SUCCESS) { |
| 193 | // channel not part of a packet and not ignored | ||
| 194 |
1/1✓ Branch 4 taken 51 times.
|
51 | this->missingChannel(id); |
| 195 | 51 | return; | |
| 196 | } | ||
| 197 | |||
| 198 |
1/1✓ Branch 4 taken 149 times.
|
149 | TlmEntry& entry = this->m_channels[entryIndex]; |
| 199 | |||
| 200 | // check to see if the channel is ignored. If so, just return. | ||
| 201 |
3/4✗ Branch 1 not taken.
✓ Branch 2 taken 149 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 148 times.
|
149 | if (entry.ignored) { |
| 202 | 1 | return; | |
| 203 | } | ||
| 204 | |||
| 205 | // An update larger than the configured channel size would overrun the packet | ||
| 206 | // fill buffer. Values may arrive from external sources (e.g. a hub bridging | ||
| 207 | // another address space), so reject rather than assert. | ||
| 208 |
3/3✓ Branch 5 taken 148 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 147 times.
|
148 | if (val.getSize() > entry.channelSize) { |
| 209 |
2/2✓ Branch 11 taken 1 times.
✓ Branch 14 taken 1 times.
|
1 | this->log_WARNING_HI_OversizedChannel(id, val.getSize(), entry.channelSize); |
| 210 | 1 | return; | |
| 211 | } | ||
| 212 | |||
| 213 | // copy telemetry value into active buffers; hasValue written in-place via reference | ||
| 214 |
2/2✓ Branch 0 taken 7350 times.
✓ Branch 1 taken 147 times.
|
7497 | for (FwChanIdType pkt = 0; pkt < MAX_PACKETIZER_PACKETS; pkt++) { |
| 215 | // check if current packet has this channel | ||
| 216 |
2/2✓ Branch 3 taken 226 times.
✓ Branch 4 taken 7124 times.
|
7350 | if (entry.packetOffset[pkt] != NOT_IN_PACKET) { |
| 217 | // get destination address | ||
| 218 |
1/1✓ Branch 5 taken 226 times.
|
226 | Os::ScopeLock lock(this->m_lock); |
| 219 | 226 | this->m_fillBuffers[pkt].updated = true; | |
| 220 |
1/1✓ Branch 8 taken 226 times.
|
226 | this->m_fillBuffers[pkt].latestTime = timeTag; |
| 221 | 226 | U8* ptr = &this->m_fillBuffers[pkt].buffer.getBuffAddr()[entry.packetOffset[pkt]]; | |
| 222 | |||
| 223 |
3/5✓ Branch 5 taken 226 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 226 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 226 times.
|
226 | (void)memcpy(ptr, val.getBuffAddr(), static_cast<size_t>(val.getSize())); |
| 224 | // set under the lock, after the copy, so TlmGet cannot see a value-less VALID entry | ||
| 225 | 226 | entry.hasValue = true; | |
| 226 | 226 | } | |
| 227 | } | ||
| 228 | } | ||
| 229 | |||
| 230 | 1 | void TlmPacketizer ::configureSectionGroupRate_handler(FwIndexType portNum, | |
| 231 | const Svc::TelemetrySection& section, | ||
| 232 | FwChanIdType tlmGroup, | ||
| 233 | const Svc::RateLogic& rateLogic, | ||
| 234 | U32 minDelta, | ||
| 235 | U32 maxDelta) { | ||
| 236 | 1 | this->configureSectionGroupRate(section, tlmGroup, rateLogic, minDelta, maxDelta); | |
| 237 | 1 | } | |
| 238 | |||
| 239 | //! Handler for input port TlmGet | ||
| 240 | 7 | Fw::TlmValid TlmPacketizer ::TlmGet_handler(FwIndexType portNum, //!< The port number | |
| 241 | FwChanIdType id, //!< Telemetry Channel ID | ||
| 242 | Fw::Time& timeTag, //!< Time Tag | ||
| 243 | Fw::TlmBuffer& val //!< Buffer containing serialized telemetry value. | ||
| 244 | //!< Size set to 0 if channel not found. | ||
| 245 | ) { | ||
| 246 | 7 | FW_ASSERT(this->m_configured); | |
| 247 | 7 | FwSizeType entryIndex = 0; | |
| 248 | |||
| 249 | // Search to see if the channel is being tracked | ||
| 250 |
3/3✓ Branch 4 taken 7 times.
✓ Branch 13 taken 1 times.
✓ Branch 14 taken 6 times.
|
7 | if (this->m_channelIndices.find(id, entryIndex) != Fw::Success::SUCCESS) { |
| 251 | // channel not part of a packet and not ignored | ||
| 252 |
1/1✓ Branch 4 taken 1 times.
|
1 | this->missingChannel(id); |
| 253 |
1/1✓ Branch 5 taken 1 times.
|
1 | val.resetSer(); |
| 254 |
1/1✓ Branch 1 taken 1 times.
|
1 | return Fw::TlmValid::INVALID; |
| 255 | } | ||
| 256 |
1/1✓ Branch 4 taken 6 times.
|
6 | const TlmEntry& entry = this->m_channels[entryIndex]; |
| 257 | |||
| 258 | // check to see if the channel is ignored. If so, just return, as | ||
| 259 | // we don't store the bytes of ignored channels | ||
| 260 |
3/4✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 5 times.
|
6 | if (entry.ignored) { |
| 261 |
1/1✓ Branch 5 taken 1 times.
|
1 | val.resetSer(); |
| 262 |
1/1✓ Branch 1 taken 1 times.
|
1 | return Fw::TlmValid::INVALID; |
| 263 | } | ||
| 264 | |||
| 265 |
3/4✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 4 times.
|
5 | if (!entry.hasValue) { |
| 266 | // haven't received a value yet for this entry. | ||
| 267 |
1/1✓ Branch 5 taken 1 times.
|
1 | val.resetSer(); |
| 268 |
1/1✓ Branch 1 taken 1 times.
|
1 | return Fw::TlmValid::INVALID; |
| 269 | } | ||
| 270 | |||
| 271 | // make sure we have enough space to store this entry in our buf | ||
| 272 | 4 | FW_ASSERT(entry.channelSize <= val.getCapacity(), static_cast<FwAssertArgType>(entry.channelSize), | |
| 273 | static_cast<FwAssertArgType>(val.getCapacity())); | ||
| 274 | |||
| 275 | // okay, we have the matching entry. | ||
| 276 | // go over each packet and find the first one which stores this channel | ||
| 277 | |||
| 278 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | for (FwChanIdType pkt = 0; pkt < MAX_PACKETIZER_PACKETS; pkt++) { |
| 279 | // check if current packet has this channel | ||
| 280 |
2/2✓ Branch 3 taken 4 times.
✓ Branch 4 taken 1 times.
|
5 | if (entry.packetOffset[pkt] != NOT_IN_PACKET) { |
| 281 | // okay, it has the channel. copy chan val into the tlm buf | ||
| 282 |
1/1✓ Branch 5 taken 4 times.
|
4 | Os::ScopeLock lock(this->m_lock); |
| 283 |
1/1✓ Branch 8 taken 4 times.
|
4 | timeTag = this->m_fillBuffers[pkt].latestTime; |
| 284 | 4 | U8* ptr = &this->m_fillBuffers[pkt].buffer.getBuffAddr()[entry.packetOffset[pkt]]; | |
| 285 |
2/4✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4 times.
|
4 | (void)memcpy(val.getBuffAddr(), ptr, static_cast<size_t>(entry.channelSize)); |
| 286 | // set buf len to the channelSize. keep in mind, this is the MAX serialized size of the channel. | ||
| 287 | // so we may actually be filling val with some junk after the value of the channel. | ||
| 288 |
1/1✓ Branch 7 taken 4 times.
|
4 | const Fw::SerializeStatus setStatus = val.setBuffLen(entry.channelSize); |
| 289 | 4 | FW_ASSERT(setStatus == Fw::SerializeStatus::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(setStatus)); | |
| 290 |
1/1✓ Branch 1 taken 4 times.
|
4 | return Fw::TlmValid::VALID; |
| 291 | 4 | } | |
| 292 | } | ||
| 293 | |||
| 294 | // did not find a packet which stores this channel. | ||
| 295 | // coding error, this was not an ignored channel so it must be in a packet somewhere | ||
| 296 | ✗ | FW_ASSERT(false, static_cast<FwAssertArgType>(entry.id)); | |
| 297 | // TPP (tim paranoia principle) | ||
| 298 | ✗ | val.resetSer(); | |
| 299 | ✗ | return Fw::TlmValid::INVALID; | |
| 300 | } | ||
| 301 | |||
| 302 | 51 | void TlmPacketizer ::Run_handler(const FwIndexType portNum, U32 context) { | |
| 303 | 51 | FW_ASSERT(this->m_configured); | |
| 304 | |||
| 305 |
2/2✓ Branch 4 taken 167 times.
✓ Branch 5 taken 51 times.
|
218 | for (FwChanIdType pkt = 0; pkt < this->m_numPackets; pkt++) { |
| 306 | // Local flags to track which sections require a packet dispatch | ||
| 307 | 167 | bool sectionNeedsSend[TelemetrySection::NUM_SECTIONS] = {false}; | |
| 308 | 167 | bool anySectionNeedsSend = false; | |
| 309 | |||
| 310 | // Lock only to capture the update status and group, and reset the fill buffer flag. | ||
| 311 | 167 | bool isNewData = false; | |
| 312 | 167 | FwChanIdType entryGroup = 0; | |
| 313 | { | ||
| 314 |
1/1✓ Branch 5 taken 167 times.
|
167 | Os::ScopeLock lock(this->m_lock); |
| 315 |
1/2✗ Branch 4 not taken.
✓ Branch 5 taken 167 times.
|
167 | isNewData = this->m_fillBuffers[pkt].updated; |
| 316 | 167 | entryGroup = this->m_fillBuffers[pkt].level; | |
| 317 | 167 | this->m_fillBuffers[pkt].updated = false; | |
| 318 | 167 | } | |
| 319 | |||
| 320 |
2/2✓ Branch 0 taken 334 times.
✓ Branch 1 taken 167 times.
|
501 | for (FwIndexType section = 0; section < TelemetrySection::NUM_SECTIONS; section++) { |
| 321 | 334 | PktSendCounters& pktEntryFlags = this->m_packetFlags[static_cast<FwSizeType>(section)][pkt]; | |
| 322 | // Group policy with the packet's overridden fields copied in | ||
| 323 |
1/1✓ Branch 2 taken 334 times.
|
334 | const Svc::TlmSendConfig effectiveEntryConfig = this->effectiveConfig(section, pkt); |
| 324 | |||
| 325 | // Packet is updated and not REQUESTED (Keep REQUESTED marking to bypass disable checks) | ||
| 326 |
4/4✓ Branch 0 taken 236 times.
✓ Branch 1 taken 98 times.
✓ Branch 4 taken 233 times.
✓ Branch 5 taken 3 times.
|
334 | if (isNewData && pktEntryFlags.updateFlag != UpdateFlag::REQUESTED) { |
| 327 | 233 | pktEntryFlags.updateFlag = UpdateFlag::NEW; | |
| 328 | } | ||
| 329 | |||
| 330 | /* Base conditions for sending | ||
| 331 | 1. Output port is connected | ||
| 332 | 2. The packet was requested (Override Checks). | ||
| 333 | |||
| 334 | If the packet wasn't requested: | ||
| 335 | 3. The effective send state allows sending (packet -> group -> section enable) | ||
| 336 | 4. The packet has data (marked updated in the past or new) | ||
| 337 | */ | ||
| 338 |
3/4✓ Branch 5 taken 334 times.
✓ Branch 8 taken 334 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 334 times.
|
334 | if (!this->isConnected_PktSend_OutputPort(this->sectionGroupToPort(section, entryGroup))) { |
| 339 | ✗ | continue; | |
| 340 | } | ||
| 341 | |||
| 342 |
2/2✓ Branch 2 taken 3 times.
✓ Branch 3 taken 331 times.
|
334 | if (pktEntryFlags.updateFlag == UpdateFlag::REQUESTED) { |
| 343 | 3 | sectionNeedsSend[section] = true; | |
| 344 | } else { | ||
| 345 |
4/4✓ Branch 7 taken 331 times.
✓ Branch 11 taken 331 times.
✓ Branch 17 taken 73 times.
✓ Branch 18 taken 258 times.
|
331 | if (not this->sendAllowed(effectiveEntryConfig.get_sendState(), section)) { |
| 346 | 73 | continue; | |
| 347 | } | ||
| 348 |
2/2✓ Branch 2 taken 10 times.
✓ Branch 3 taken 248 times.
|
258 | if (pktEntryFlags.updateFlag == UpdateFlag::NEVER_UPDATED) { |
| 349 | 10 | continue; // Avoid No Data | |
| 350 | } | ||
| 351 | } | ||
| 352 | |||
| 353 | // Update Counter, prevent overflow. | ||
| 354 |
2/2✓ Branch 2 taken 100 times.
✓ Branch 3 taken 151 times.
|
251 | if (pktEntryFlags.prevSentCounter < std::numeric_limits<U32>::max()) { |
| 355 | 100 | pktEntryFlags.prevSentCounter++; | |
| 356 | } | ||
| 357 | |||
| 358 | /* | ||
| 359 | 1. Packet has been updated | ||
| 360 | 2. Group Logic includes checking MIN | ||
| 361 | 3. Packet sent counter at MIN | ||
| 362 | */ | ||
| 363 |
1/2✓ Branch 2 taken 201 times.
✗ Branch 3 not taken.
|
452 | if (pktEntryFlags.updateFlag == UpdateFlag::NEW and |
| 364 |
5/6✓ Branch 0 taken 201 times.
✓ Branch 1 taken 50 times.
✓ Branch 8 taken 201 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 201 times.
✓ Branch 11 taken 50 times.
|
452 | effectiveEntryConfig.get_rates().get_rateLogic() != Svc::RateLogic::EVERY_MAX and |
| 365 | 201 | pktEntryFlags.prevSentCounter >= effectiveEntryConfig.get_rates().get_min()) { | |
| 366 | 201 | sectionNeedsSend[section] = true; | |
| 367 | } | ||
| 368 | |||
| 369 | /* | ||
| 370 | 1. Group Logic includes checking MAX | ||
| 371 | 2. Packet set counter is at MAX | ||
| 372 | */ | ||
| 373 |
5/6✓ Branch 6 taken 3 times.
✓ Branch 7 taken 248 times.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3 times.
✓ Branch 11 taken 248 times.
|
254 | if (effectiveEntryConfig.get_rates().get_rateLogic() != Svc::RateLogic::ON_CHANGE_MIN and |
| 374 | 3 | pktEntryFlags.prevSentCounter >= effectiveEntryConfig.get_rates().get_max()) { | |
| 375 | 3 | sectionNeedsSend[section] = true; | |
| 376 | } | ||
| 377 | |||
| 378 |
3/4✗ Branch 1 not taken.
✓ Branch 2 taken 251 times.
✓ Branch 3 taken 207 times.
✓ Branch 4 taken 44 times.
|
251 | if (sectionNeedsSend[section]) { |
| 379 | 207 | anySectionNeedsSend = true; | |
| 380 | } | ||
| 381 | 334 | } | |
| 382 | |||
| 383 | // Only perform the buffer copy if at least one section needs to send. | ||
| 384 |
2/2✓ Branch 0 taken 113 times.
✓ Branch 1 taken 54 times.
|
167 | if (anySectionNeedsSend) { |
| 385 | // Snapshot only the packet data under the lock | ||
| 386 |
1/1✓ Branch 2 taken 113 times.
|
113 | Fw::ComBuffer sendBuffer; |
| 387 |
1/1✓ Branch 2 taken 113 times.
|
113 | Fw::Time sendTime; |
| 388 | { | ||
| 389 |
1/1✓ Branch 5 taken 113 times.
|
113 | Os::ScopeLock lock(this->m_lock); |
| 390 |
1/1✓ Branch 6 taken 113 times.
|
113 | sendBuffer = this->m_fillBuffers[pkt].buffer; |
| 391 |
1/1✓ Branch 6 taken 113 times.
|
113 | sendTime = this->m_fillBuffers[pkt].latestTime; |
| 392 | 113 | } | |
| 393 | |||
| 394 | // serialize time into time offset in packet | ||
| 395 | 113 | Fw::ExternalSerializeBuffer buff( | |
| 396 | 113 | &sendBuffer.getBuffAddr()[sizeof(FwPacketDescriptorType) + sizeof(FwTlmPacketizeIdType)], | |
| 397 |
1/1✓ Branch 2 taken 113 times.
|
113 | Fw::Time::SERIALIZED_SIZE); |
| 398 |
1/1✓ Branch 2 taken 113 times.
|
113 | const Fw::SerializeStatus timeStatus = buff.serializeFrom(sendTime); |
| 399 | 113 | FW_ASSERT(Fw::FW_SERIALIZE_OK == timeStatus, static_cast<FwAssertArgType>(timeStatus)); | |
| 400 | |||
| 401 |
2/2✓ Branch 0 taken 226 times.
✓ Branch 1 taken 113 times.
|
339 | for (FwIndexType section = 0; section < TelemetrySection::NUM_SECTIONS; section++) { |
| 402 |
3/4✗ Branch 1 not taken.
✓ Branch 2 taken 226 times.
✓ Branch 3 taken 207 times.
✓ Branch 4 taken 19 times.
|
226 | if (sectionNeedsSend[section]) { |
| 403 | 207 | PktSendCounters& pktEntryFlags = this->m_packetFlags[section][pkt]; | |
| 404 |
1/1✓ Branch 1 taken 207 times.
|
207 | FwIndexType outIndex = this->sectionGroupToPort(section, entryGroup); |
| 405 | |||
| 406 |
1/1✓ Branch 6 taken 207 times.
|
207 | this->PktSend_out(outIndex, sendBuffer, pktEntryFlags.prevSentCounter); |
| 407 | |||
| 408 | 207 | pktEntryFlags.prevSentCounter = 0; | |
| 409 | 207 | pktEntryFlags.updateFlag = UpdateFlag::PAST; | |
| 410 | } | ||
| 411 | } | ||
| 412 | 113 | } | |
| 413 | } | ||
| 414 | 51 | } | |
| 415 | |||
| 416 | 2 | void TlmPacketizer ::controlIn_handler(FwIndexType portNum, | |
| 417 | const Svc::TelemetrySection& section, | ||
| 418 | const Fw::Enabled& enabled) { | ||
| 419 | // NUM_SECTIONS is an enum constant (not a standalone constant), so isValid() accepts it. | ||
| 420 | // The explicit bounds check prevents an out-of-bounds write to m_sectionEnabled. | ||
| 421 |
4/8✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 2 times.
✗ Branch 19 not taken.
|
2 | if (section.isValid() && section < TelemetrySection::NUM_SECTIONS && enabled.isValid()) { |
| 422 | 2 | (void)(this->m_sectionEnabled[static_cast<FwSizeType>(section)] = enabled); | |
| 423 | } else { | ||
| 424 | ✗ | this->log_WARNING_LO_SectionUnconfigurable(section, enabled); | |
| 425 | } | ||
| 426 | 2 | } | |
| 427 | |||
| 428 | 1 | void TlmPacketizer ::pingIn_handler(const FwIndexType portNum, U32 key) { | |
| 429 | // return key | ||
| 430 | 1 | this->pingOut_out(0, key); | |
| 431 | 1 | } | |
| 432 | |||
| 433 | // ---------------------------------------------------------------------- | ||
| 434 | // Command handler implementations | ||
| 435 | // ---------------------------------------------------------------------- | ||
| 436 | |||
| 437 | 3 | void TlmPacketizer ::SET_LEVEL_cmdHandler(const FwOpcodeType opCode, const U32 cmdSeq, FwChanIdType level) { | |
| 438 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
|
3 | if (level > MAX_CONFIGURABLE_TLMPACKETIZER_GROUP) { |
| 439 | 1 | this->log_WARNING_LO_MaxLevelExceed(level, MAX_CONFIGURABLE_TLMPACKETIZER_GROUP); | |
| 440 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
|
1 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR); |
| 441 | 1 | return; | |
| 442 | } | ||
| 443 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
|
6 | for (FwIndexType section = 0; section < TelemetrySection::NUM_SECTIONS; section++) { |
| 444 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 4 times.
|
20 | for (FwChanIdType group = 0; group < NUM_CONFIGURABLE_TLMPACKETIZER_GROUPS; group++) { |
| 445 |
2/2✓ Branch 13 taken 8 times.
✓ Branch 14 taken 8 times.
|
16 | this->m_groupConfigs[static_cast<FwSizeType>(section)][group].set_sendState( |
| 446 | group <= level ? Svc::TlmSendState::INHERIT_FROM_PARENT : Svc::TlmSendState::SEND_NEVER); | ||
| 447 | } | ||
| 448 | } | ||
| 449 |
2/2✓ Branch 6 taken 2 times.
✓ Branch 12 taken 2 times.
|
2 | this->tlmWrite_GroupConfigs(this->m_groupConfigs); |
| 450 | 2 | this->log_ACTIVITY_HI_LevelSet(level); | |
| 451 |
2/2✓ Branch 6 taken 2 times.
✓ Branch 9 taken 2 times.
|
2 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); |
| 452 | } | ||
| 453 | |||
| 454 | 4 | void TlmPacketizer ::SEND_PKT_cmdHandler(const FwOpcodeType opCode, | |
| 455 | const U32 cmdSeq, | ||
| 456 | const U32 id, | ||
| 457 | const Svc::TelemetrySection& section) { | ||
| 458 | 4 | FwChanIdType pkt = 0; | |
| 459 |
3/3✓ Branch 4 taken 4 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 3 times.
|
4 | if (this->resolvePacket(section, id, pkt) != PacketStatus::OK) { |
| 460 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
|
1 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR); |
| 461 | 1 | return; | |
| 462 | } | ||
| 463 | |||
| 464 | { | ||
| 465 |
1/1✓ Branch 5 taken 3 times.
|
3 | Os::ScopeLock lock(this->m_lock); |
| 466 | 3 | this->m_fillBuffers[pkt].updated = true; | |
| 467 |
2/2✓ Branch 3 taken 3 times.
✓ Branch 13 taken 3 times.
|
3 | this->m_fillBuffers[pkt].latestTime = this->getTime(); |
| 468 | 3 | } | |
| 469 | |||
| 470 | 3 | this->m_packetFlags[section][pkt].updateFlag = UpdateFlag::REQUESTED; | |
| 471 | |||
| 472 |
1/1✓ Branch 5 taken 3 times.
|
3 | this->log_ACTIVITY_HI_PacketSent(id); |
| 473 |
2/2✓ Branch 6 taken 3 times.
✓ Branch 9 taken 3 times.
|
3 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); |
| 474 | } | ||
| 475 | |||
| 476 | 75 | void TlmPacketizer ::ENABLE_SECTION_cmdHandler(FwOpcodeType opCode, | |
| 477 | U32 cmdSeq, | ||
| 478 | const Svc::TelemetrySection& section, | ||
| 479 | const Fw::Enabled& enable) { | ||
| 480 | 75 | FW_ASSERT(section.isValid()); | |
| 481 | 75 | FW_ASSERT(enable.isValid()); | |
| 482 |
3/6✓ Branch 4 taken 75 times.
✗ Branch 5 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 75 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 75 times.
|
75 | if (section < 0 or section >= TelemetrySection::NUM_SECTIONS) { |
| 483 | ✗ | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR); | |
| 484 | ✗ | return; | |
| 485 | } | ||
| 486 | 75 | (void)(this->m_sectionEnabled[section] = enable); | |
| 487 |
2/2✓ Branch 6 taken 75 times.
✓ Branch 12 taken 75 times.
|
75 | this->tlmWrite_SectionEnabled(this->m_sectionEnabled); |
| 488 |
2/2✓ Branch 6 taken 75 times.
✓ Branch 9 taken 75 times.
|
75 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); |
| 489 | } | ||
| 490 | |||
| 491 | 292 | void TlmPacketizer ::CONFIGURE_GROUP_SEND_cmdHandler(FwOpcodeType opCode, | |
| 492 | U32 cmdSeq, | ||
| 493 | const Svc::TelemetrySection& section, | ||
| 494 | FwChanIdType tlmGroup, | ||
| 495 | const Svc::TlmSendState& sendState) { | ||
| 496 | 292 | FW_ASSERT(section.isValid()); | |
| 497 |
6/8✓ Branch 4 taken 292 times.
✗ Branch 5 not taken.
✓ Branch 10 taken 292 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 291 times.
✓ Branch 14 taken 1 times.
✓ Branch 15 taken 291 times.
|
292 | if (section < 0 or section >= TelemetrySection::NUM_SECTIONS or tlmGroup > MAX_CONFIGURABLE_TLMPACKETIZER_GROUP) { |
| 498 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
|
1 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR); |
| 499 | 1 | return; | |
| 500 | } | ||
| 501 | 291 | this->m_groupConfigs[section][tlmGroup].set_sendState(sendState); | |
| 502 |
2/2✓ Branch 6 taken 291 times.
✓ Branch 12 taken 291 times.
|
291 | this->tlmWrite_GroupConfigs(this->m_groupConfigs); |
| 503 | 291 | this->log_ACTIVITY_HI_GroupSendStateSet(section, tlmGroup, sendState); | |
| 504 |
2/2✓ Branch 6 taken 291 times.
✓ Branch 9 taken 291 times.
|
291 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); |
| 505 | } | ||
| 506 | |||
| 507 | 282 | void TlmPacketizer ::CONFIGURE_GROUP_RATES_cmdHandler(FwOpcodeType opCode, | |
| 508 | U32 cmdSeq, | ||
| 509 | const Svc::TelemetrySection& section, | ||
| 510 | FwChanIdType tlmGroup, | ||
| 511 | const Svc::RateLogic& rateLogic, | ||
| 512 | U32 minDelta, | ||
| 513 | U32 maxDelta) { | ||
| 514 | 282 | FW_ASSERT(section.isValid()); | |
| 515 | 282 | FW_ASSERT(rateLogic.isValid()); | |
| 516 |
4/8✓ Branch 4 taken 282 times.
✗ Branch 5 not taken.
✓ Branch 10 taken 282 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 282 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 282 times.
|
282 | if (section < 0 or section >= TelemetrySection::NUM_SECTIONS or tlmGroup > MAX_CONFIGURABLE_TLMPACKETIZER_GROUP) { |
| 517 | ✗ | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR); | |
| 518 | ✗ | return; | |
| 519 | } | ||
| 520 | 282 | this->configureSectionGroupRate(section, tlmGroup, rateLogic, minDelta, maxDelta); | |
| 521 |
2/2✓ Branch 6 taken 282 times.
✓ Branch 9 taken 282 times.
|
282 | this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); |
| 522 | } | ||
| 523 | |||
| 524 | 5 | void TlmPacketizer ::GET_PACKET_CONFIG_cmdHandler(FwOpcodeType opCode, | |
| 525 | U32 cmdSeq, | ||
| 526 | const Svc::TelemetrySection& section, | ||
| 527 | U32 packetId) { | ||
| 528 | 5 | FwChanIdType pkt = 0; | |
| 529 |
1/1✓ Branch 4 taken 5 times.
|
5 | const PacketStatus status = this->resolvePacket(section, packetId, pkt); |
| 530 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
|
5 | if (status == PacketStatus::OK) { |
| 531 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
|
3 | const FwSizeType sectionIndex = static_cast<FwSizeType>(section.e); |
| 532 |
3/3✓ Branch 10 taken 3 times.
✓ Branch 16 taken 3 times.
✓ Branch 20 taken 3 times.
|
6 | this->log_ACTIVITY_HI_PacketConfigReport(section, packetId, this->m_packetOverrides[sectionIndex][pkt], |
| 533 |
2/3✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✓ Branch 7 taken 3 times.
|
6 | this->effectiveConfig(static_cast<FwIndexType>(section.e), pkt)); |
| 534 | } | ||
| 535 |
2/2✓ Branch 6 taken 5 times.
✓ Branch 9 taken 5 times.
|
5 | this->cmdResponse_out(opCode, cmdSeq, TlmPacketizer::toCmdResponse(status)); |
| 536 | 5 | } | |
| 537 | |||
| 538 | 16 | void TlmPacketizer ::OVERRIDE_PACKET_SEND_cmdHandler(FwOpcodeType opCode, | |
| 539 | U32 cmdSeq, | ||
| 540 | const Svc::TelemetrySection& section, | ||
| 541 | U32 packetId, | ||
| 542 | const Svc::TlmSendState& sendState) { | ||
| 543 | 16 | const Svc::PacketOverrideConfig requested(Svc::PacketOverrideType::OVERRIDE_SEND, | |
| 544 |
3/3✓ Branch 3 taken 16 times.
✓ Branch 11 taken 16 times.
✓ Branch 15 taken 16 times.
|
16 | Svc::TlmSendConfig(sendState, Svc::RateConfig())); |
| 545 |
1/1✓ Branch 6 taken 16 times.
|
32 | this->cmdResponse_out(opCode, cmdSeq, |
| 546 |
2/2✓ Branch 4 taken 16 times.
✓ Branch 7 taken 16 times.
|
32 | TlmPacketizer::toCmdResponse(this->overridePacket(section, packetId, requested))); |
| 547 | 32 | } | |
| 548 | |||
| 549 | 3 | void TlmPacketizer ::OVERRIDE_PACKET_RATES_cmdHandler(FwOpcodeType opCode, | |
| 550 | U32 cmdSeq, | ||
| 551 | const Svc::TelemetrySection& section, | ||
| 552 | U32 packetId, | ||
| 553 | const Svc::RateLogic& rateLogic, | ||
| 554 | U32 minDelta, | ||
| 555 | U32 maxDelta) { | ||
| 556 | 3 | const Svc::PacketOverrideConfig requested( | |
| 557 | Svc::PacketOverrideType::OVERRIDE_RATES, | ||
| 558 |
3/3✓ Branch 7 taken 3 times.
✓ Branch 11 taken 3 times.
✓ Branch 15 taken 3 times.
|
3 | Svc::TlmSendConfig(Svc::TlmSendState::INHERIT_FROM_PARENT, Svc::RateConfig(rateLogic, minDelta, maxDelta))); |
| 559 |
1/1✓ Branch 6 taken 3 times.
|
6 | this->cmdResponse_out(opCode, cmdSeq, |
| 560 |
2/2✓ Branch 4 taken 3 times.
✓ Branch 7 taken 3 times.
|
6 | TlmPacketizer::toCmdResponse(this->overridePacket(section, packetId, requested))); |
| 561 | 6 | } | |
| 562 | |||
| 563 | 5 | void TlmPacketizer ::CLEAR_PACKET_OVERRIDE_cmdHandler(FwOpcodeType opCode, | |
| 564 | U32 cmdSeq, | ||
| 565 | const Svc::TelemetrySection& section, | ||
| 566 | U32 packetId) { | ||
| 567 |
2/2✓ Branch 3 taken 5 times.
✓ Branch 7 taken 5 times.
|
5 | const Svc::PacketOverrideConfig requested(Svc::PacketOverrideType::GROUP_DEFAULT, Svc::TlmSendConfig()); |
| 568 |
1/1✓ Branch 6 taken 5 times.
|
10 | this->cmdResponse_out(opCode, cmdSeq, |
| 569 |
2/2✓ Branch 4 taken 5 times.
✓ Branch 7 taken 5 times.
|
10 | TlmPacketizer::toCmdResponse(this->overridePacket(section, packetId, requested))); |
| 570 | 10 | } | |
| 571 | |||
| 572 | 283 | void TlmPacketizer::configureSectionGroupRate( | |
| 573 | const Svc::TelemetrySection& section, //!< Section grouping | ||
| 574 | FwChanIdType tlmGroup, //!< Group Identifier | ||
| 575 | const Svc::RateLogic& rateLogic, //!< Rate Logic | ||
| 576 | U32 minDelta, //!< Minimum Sched Ticks to send packets on updates when using ON_CHANGE logic | ||
| 577 | U32 maxDelta //!< Maximum Sched Ticks between packets to send when using EVERY_MAX logic | ||
| 578 | ) { | ||
| 579 | 283 | FW_ASSERT(section.isValid()); | |
| 580 | 283 | FW_ASSERT(rateLogic.isValid()); | |
| 581 | // These two asserts are an "if" statement in a command so they will no assert on bad user data | ||
| 582 | 283 | FW_ASSERT(section >= 0 and section < TelemetrySection::NUM_SECTIONS); | |
| 583 | 283 | FW_ASSERT(tlmGroup <= MAX_CONFIGURABLE_TLMPACKETIZER_GROUP); | |
| 584 | |||
| 585 |
2/2✓ Branch 23 taken 283 times.
✓ Branch 27 taken 283 times.
|
283 | this->m_groupConfigs[section][tlmGroup].set_rates(Svc::RateConfig(rateLogic, minDelta, maxDelta)); |
| 586 |
2/2✓ Branch 6 taken 283 times.
✓ Branch 12 taken 283 times.
|
283 | this->tlmWrite_GroupConfigs(this->m_groupConfigs); |
| 587 | 283 | } | |
| 588 | |||
| 589 | 646 | FwIndexType TlmPacketizer::sectionGroupToPort(const FwIndexType section, const FwSizeType group) { | |
| 590 | // Confirm the indices will not overflow the size of the array | ||
| 591 | 646 | FW_ASSERT(group < TlmPacketizer_TelemetrySendSection::SIZE, static_cast<FwAssertArgType>(group)); | |
| 592 | 646 | FW_ASSERT(section < TlmPacketizer_TelemetrySendPortMap::SIZE, static_cast<FwAssertArgType>(section)); | |
| 593 | |||
| 594 | 646 | const FwIndexType outIndex = TlmPacketizer::TELEMETRY_SEND_PORT_MAP[static_cast<FwSizeType>(section)][group]; | |
| 595 | |||
| 596 | // Confirm the output port index is within the valid number of telemetry send ports | ||
| 597 | 646 | FW_ASSERT(outIndex < TELEMETRY_SEND_PORTS, static_cast<FwAssertArgType>(outIndex)); | |
| 598 | 646 | return outIndex; | |
| 599 | } | ||
| 600 | |||
| 601 | 29 | Fw::CmdResponse TlmPacketizer::toCmdResponse(PacketStatus status) { | |
| 602 |
3/3✓ Branch 0 taken 23 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 5 times.
|
29 | switch (status) { |
| 603 | 23 | case PacketStatus::OK: | |
| 604 | 23 | return Fw::CmdResponse::OK; | |
| 605 | 1 | case PacketStatus::MIRROR_FAILED: | |
| 606 | 1 | return Fw::CmdResponse::EXECUTION_ERROR; | |
| 607 | 5 | default: | |
| 608 | 5 | return Fw::CmdResponse::VALIDATION_ERROR; | |
| 609 | } | ||
| 610 | } | ||
| 611 | |||
| 612 | 337 | Svc::TlmSendConfig TlmPacketizer::effectiveConfig(FwIndexType section, FwChanIdType pkt) const { | |
| 613 | 337 | const FwSizeType sectionIndex = static_cast<FwSizeType>(section); | |
| 614 | // Start from the group policy, then copy in the fields the packet overrides | ||
| 615 |
3/3✓ Branch 16 taken 337 times.
✓ Branch 22 taken 337 times.
✓ Branch 26 taken 337 times.
|
337 | Svc::TlmSendConfig effective = this->m_groupConfigs[sectionIndex][this->m_fillBuffers[pkt].level]; |
| 616 |
2/2✓ Branch 11 taken 337 times.
✓ Branch 17 taken 337 times.
|
337 | const Svc::PacketOverrideConfig& packetOverride = this->m_packetOverrides[sectionIndex][pkt]; |
| 617 |
1/1✓ Branch 6 taken 337 times.
|
337 | const Svc::PacketOverrideType overrideType = packetOverride.get_overrideType(); |
| 618 |
3/4✓ Branch 2 taken 319 times.
✓ Branch 3 taken 18 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 319 times.
|
656 | const bool overridesSend = (overrideType == Svc::PacketOverrideType::OVERRIDE_SEND) or |
| 619 | 319 | (overrideType == Svc::PacketOverrideType::OVERRIDE_SEND_AND_RATES); | |
| 620 |
3/4✓ Branch 2 taken 336 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 336 times.
|
673 | const bool overridesRates = (overrideType == Svc::PacketOverrideType::OVERRIDE_RATES) or |
| 621 | 336 | (overrideType == Svc::PacketOverrideType::OVERRIDE_SEND_AND_RATES); | |
| 622 | // A packet-level INHERIT_FROM_PARENT means "use the group's state", so it is not copied | ||
| 623 |
6/6✓ Branch 0 taken 18 times.
✓ Branch 1 taken 319 times.
✓ Branch 10 taken 17 times.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 17 times.
✓ Branch 13 taken 320 times.
|
337 | if (overridesSend and packetOverride.get_sendConfig().get_sendState() != Svc::TlmSendState::INHERIT_FROM_PARENT) { |
| 624 |
1/1✓ Branch 11 taken 17 times.
|
17 | effective.set_sendState(packetOverride.get_sendConfig().get_sendState()); |
| 625 | } | ||
| 626 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 336 times.
|
337 | if (overridesRates) { |
| 627 |
1/1✓ Branch 11 taken 1 times.
|
1 | effective.set_rates(packetOverride.get_sendConfig().get_rates()); |
| 628 | } | ||
| 629 | 674 | return effective; | |
| 630 | 337 | } | |
| 631 | |||
| 632 | 331 | bool TlmPacketizer::sendAllowed(const Svc::TlmSendState& sendState, FwIndexType section) const { | |
| 633 |
4/6✗ Branch 3 not taken.
✓ Branch 4 taken 331 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 70 times.
✓ Branch 7 taken 258 times.
✗ Branch 8 not taken.
|
331 | switch (sendState.e) { |
| 634 | 3 | case Svc::TlmSendState::SEND_ALWAYS: | |
| 635 | 3 | return true; | |
| 636 | 70 | case Svc::TlmSendState::SEND_NEVER: | |
| 637 | 70 | return false; | |
| 638 | // INHERIT_FROM_PARENT here is a group-level state, whose parent is the section. Fall-through intended. | ||
| 639 | 258 | case Svc::TlmSendState::SEND_WHEN_SECTION_ENABLED: | |
| 640 | case Svc::TlmSendState::INHERIT_FROM_PARENT: | ||
| 641 | 258 | return this->m_sectionEnabled[static_cast<FwSizeType>(section)] == Fw::Enabled::ENABLED; | |
| 642 | ✗ | default: | |
| 643 | ✗ | FW_ASSERT(0, static_cast<FwAssertArgType>(sendState.e)); | |
| 644 | ✗ | return false; | |
| 645 | } | ||
| 646 | } | ||
| 647 | |||
| 648 | 36 | Fw::Success TlmPacketizer::findPacketIndexById(U32 packetId, FwChanIdType& pkt) const { | |
| 649 |
2/2✓ Branch 4 taken 46 times.
✓ Branch 5 taken 5 times.
|
51 | for (FwChanIdType p = 0; p < this->m_numPackets; p++) { |
| 650 |
2/2✓ Branch 5 taken 31 times.
✓ Branch 6 taken 15 times.
|
46 | if (this->m_fillBuffers[p].id == packetId) { |
| 651 | 31 | pkt = p; | |
| 652 | 31 | return Fw::Success::SUCCESS; | |
| 653 | } | ||
| 654 | } | ||
| 655 | 5 | return Fw::Success::FAILURE; | |
| 656 | } | ||
| 657 | |||
| 658 | 33 | TlmPacketizer::PacketStatus TlmPacketizer::resolvePacket(const Svc::TelemetrySection& section, | |
| 659 | U32 packetId, | ||
| 660 | FwChanIdType& pkt) { | ||
| 661 |
6/8✓ Branch 4 taken 33 times.
✗ Branch 5 not taken.
✓ Branch 10 taken 33 times.
✗ Branch 11 not taken.
✓ Branch 16 taken 2 times.
✓ Branch 17 taken 31 times.
✓ Branch 18 taken 2 times.
✓ Branch 19 taken 31 times.
|
33 | if (not section.isValid() or section < 0 or section >= TelemetrySection::NUM_SECTIONS) { |
| 662 | 2 | this->log_WARNING_LO_InvalidPacketConfig(packetId); | |
| 663 | 2 | return PacketStatus::INVALID_SECTION; | |
| 664 | } | ||
| 665 |
3/3✓ Branch 2 taken 31 times.
✓ Branch 11 taken 4 times.
✓ Branch 12 taken 27 times.
|
31 | if (this->findPacketIndexById(packetId, pkt) != Fw::Success::SUCCESS) { |
| 666 | 4 | this->log_WARNING_LO_PacketNotFound(packetId); | |
| 667 | 4 | return PacketStatus::UNKNOWN_PACKET; | |
| 668 | } | ||
| 669 | 27 | return PacketStatus::OK; | |
| 670 | } | ||
| 671 | |||
| 672 | 17 | Svc::PacketOverrideType TlmPacketizer::mergeOverrideType(const Svc::PacketOverrideType& current, | |
| 673 | const Svc::PacketOverrideType& requested) { | ||
| 674 |
6/6✓ Branch 4 taken 4 times.
✓ Branch 5 taken 13 times.
✓ Branch 14 taken 3 times.
✓ Branch 15 taken 1 times.
✓ Branch 16 taken 16 times.
✓ Branch 17 taken 1 times.
|
17 | if (current == Svc::PacketOverrideType::GROUP_DEFAULT or current == requested) { |
| 675 | 16 | return requested; | |
| 676 | } | ||
| 677 | // Different fields already overridden: both apply | ||
| 678 | 1 | return Svc::PacketOverrideType::OVERRIDE_SEND_AND_RATES; | |
| 679 | } | ||
| 680 | |||
| 681 | 21 | TlmPacketizer::PacketStatus TlmPacketizer::applyPacketOverride(const Svc::TelemetrySection& section, | |
| 682 | FwChanIdType pkt, | ||
| 683 | const Svc::PacketOverrideConfig& requested) { | ||
| 684 |
3/4✗ Branch 3 not taken.
✓ Branch 4 taken 21 times.
✓ Branch 11 taken 21 times.
✓ Branch 17 taken 21 times.
|
21 | Svc::PacketOverrideConfig& stored = this->m_packetOverrides[static_cast<FwSizeType>(section.e)][pkt]; |
| 685 | // Snapshot so a failed mirror can roll back and the persisted copy never diverges | ||
| 686 |
1/1✓ Branch 3 taken 21 times.
|
21 | const Svc::PacketOverrideConfig previous = stored; |
| 687 | // Fields not (yet) overridden hold neutral values: INHERIT_FROM_PARENT and default rates | ||
| 688 | 21 | Svc::TlmSendConfig merged = (previous.get_overrideType() == Svc::PacketOverrideType::GROUP_DEFAULT) | |
| 689 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 8 times.
|
21 | ? Svc::TlmSendConfig() |
| 690 |
2/2✓ Branch 1 taken 13 times.
✓ Branch 9 taken 8 times.
|
21 | : stored.get_sendConfig(); |
| 691 |
3/4✓ Branch 4 taken 14 times.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
|
21 | switch (requested.get_overrideType()) { |
| 692 | 14 | case Svc::PacketOverrideType::OVERRIDE_SEND: | |
| 693 |
1/1✓ Branch 10 taken 14 times.
|
14 | merged.set_sendState(requested.get_sendConfig().get_sendState()); |
| 694 | 14 | break; | |
| 695 | 3 | case Svc::PacketOverrideType::OVERRIDE_RATES: | |
| 696 |
1/1✓ Branch 10 taken 3 times.
|
3 | merged.set_rates(requested.get_sendConfig().get_rates()); |
| 697 | 3 | break; | |
| 698 | ✗ | case Svc::PacketOverrideType::OVERRIDE_SEND_AND_RATES: | |
| 699 | ✗ | merged = requested.get_sendConfig(); | |
| 700 | ✗ | break; | |
| 701 | 4 | default: | |
| 702 | // GROUP_DEFAULT: clearing keeps no policy of its own | ||
| 703 |
2/2✓ Branch 2 taken 4 times.
✓ Branch 7 taken 4 times.
|
4 | merged = Svc::TlmSendConfig(); |
| 704 | 4 | break; | |
| 705 | } | ||
| 706 |
1/1✓ Branch 4 taken 21 times.
|
21 | stored.set_sendConfig(merged); |
| 707 |
1/1✓ Branch 8 taken 21 times.
|
42 | stored.set_overrideType( |
| 708 | 21 | requested.get_overrideType() == Svc::PacketOverrideType::GROUP_DEFAULT | |
| 709 |
14/22✓ Branch 0 taken 4 times.
✓ Branch 1 taken 17 times.
✓ Branch 3 taken 4 times.
✓ Branch 8 taken 17 times.
✓ Branch 14 taken 17 times.
✓ Branch 18 taken 17 times.
✓ Branch 23 taken 17 times.
✓ Branch 24 taken 4 times.
✓ Branch 28 taken 17 times.
✓ Branch 29 taken 4 times.
✓ Branch 31 taken 17 times.
✓ Branch 32 taken 4 times.
✓ Branch 36 taken 17 times.
✓ Branch 37 taken 4 times.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
|
76 | ? Svc::PacketOverrideType(Svc::PacketOverrideType::GROUP_DEFAULT) |
| 710 | 34 | : TlmPacketizer::mergeOverrideType(previous.get_overrideType(), requested.get_overrideType())); | |
| 711 |
3/3✓ Branch 2 taken 21 times.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 20 times.
|
21 | if (this->mirrorOverride(section, pkt) != Fw::Success::SUCCESS) { |
| 712 |
1/1✓ Branch 4 taken 1 times.
|
1 | stored = previous; |
| 713 | 1 | return PacketStatus::MIRROR_FAILED; | |
| 714 | } | ||
| 715 | 20 | return PacketStatus::OK; | |
| 716 | 21 | } | |
| 717 | |||
| 718 | 24 | TlmPacketizer::PacketStatus TlmPacketizer::overridePacket(const Svc::TelemetrySection& section, | |
| 719 | U32 packetId, | ||
| 720 | const Svc::PacketOverrideConfig& requested) { | ||
| 721 | 24 | FwChanIdType pkt = 0; | |
| 722 |
1/1✓ Branch 4 taken 24 times.
|
24 | PacketStatus status = this->resolvePacket(section, packetId, pkt); |
| 723 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 21 times.
|
24 | if (status != PacketStatus::OK) { |
| 724 | 3 | return status; | |
| 725 | } | ||
| 726 |
1/1✓ Branch 4 taken 21 times.
|
21 | status = this->applyPacketOverride(section, pkt, requested); |
| 727 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 20 times.
|
21 | if (status != PacketStatus::OK) { |
| 728 | 1 | return status; | |
| 729 | } | ||
| 730 |
2/2✓ Branch 4 taken 4 times.
✓ Branch 5 taken 16 times.
|
20 | if (requested.get_overrideType() == Svc::PacketOverrideType::GROUP_DEFAULT) { |
| 731 |
1/1✓ Branch 5 taken 4 times.
|
4 | this->log_ACTIVITY_HI_PacketOverrideCleared(section, packetId); |
| 732 | } else { | ||
| 733 |
1/1✓ Branch 5 taken 16 times.
|
32 | this->log_ACTIVITY_HI_PacketOverrideSet(section, packetId, |
| 734 |
3/4✗ Branch 3 not taken.
✓ Branch 4 taken 16 times.
✓ Branch 11 taken 16 times.
✓ Branch 17 taken 16 times.
|
16 | this->m_packetOverrides[static_cast<FwSizeType>(section.e)][pkt]); |
| 735 | } | ||
| 736 | 20 | return PacketStatus::OK; | |
| 737 | } | ||
| 738 | |||
| 739 | 6 | void TlmPacketizer ::packetOverrideIn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer) { | |
| 740 | // Reload per-packet overrides from the persistence component: one PacketConfigEntry record after another | ||
| 741 |
2/2✓ Branch 4 taken 5 times.
✓ Branch 5 taken 1 times.
|
6 | if (fwBuffer.isValid()) { |
| 742 |
1/1✓ Branch 2 taken 5 times.
|
5 | auto deserializer = fwBuffer.getDeserializer(); |
| 743 | 5 | const FwSizeType recordSize = static_cast<FwSizeType>(Svc::PacketConfigEntry::SERIALIZED_SIZE); | |
| 744 |
1/1✓ Branch 4 taken 5 times.
|
5 | const FwSizeType maxRecords = static_cast<FwSizeType>(fwBuffer.getSize()) / recordSize; |
| 745 | 5 | Fw::SerializeStatus status = Fw::FW_SERIALIZE_OK; | |
| 746 |
3/4✓ Branch 0 taken 7 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
|
11 | for (FwSizeType record = 0; (record < maxRecords) and (status == Fw::FW_SERIALIZE_OK); record++) { |
| 747 |
1/1✓ Branch 2 taken 7 times.
|
7 | Svc::PacketConfigEntry entry; |
| 748 |
1/1✓ Branch 2 taken 7 times.
|
7 | status = deserializer.deserializeTo(entry); |
| 749 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
|
7 | if (status != Fw::FW_SERIALIZE_OK) { |
| 750 | 1 | break; | |
| 751 | } | ||
| 752 |
1/1✓ Branch 4 taken 6 times.
|
6 | const Svc::TelemetrySection section = entry.get_section(); |
| 753 | 6 | FwChanIdType pkt = 0; | |
| 754 | // Enum values were validated by deserialization; only the section range remains to check | ||
| 755 |
5/6✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 5 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 5 times.
|
6 | if (section < 0 or section >= TelemetrySection::NUM_SECTIONS) { |
| 756 |
1/1✓ Branch 7 taken 1 times.
|
1 | this->log_WARNING_LO_ReloadRecordInvalid(entry.get_packetId()); |
| 757 |
3/3✓ Branch 4 taken 5 times.
✓ Branch 13 taken 1 times.
✓ Branch 14 taken 4 times.
|
5 | } else if (this->findPacketIndexById(entry.get_packetId(), pkt) != Fw::Success::SUCCESS) { |
| 758 |
1/1✓ Branch 7 taken 1 times.
|
1 | this->log_WARNING_LO_ReloadRecordUnknownPacket(entry.get_packetId()); |
| 759 | } else { | ||
| 760 |
4/5✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✓ Branch 13 taken 4 times.
✓ Branch 19 taken 4 times.
✓ Branch 25 taken 4 times.
|
4 | this->m_packetOverrides[static_cast<FwSizeType>(section.e)][pkt] = entry.get_override(); |
| 761 | } | ||
| 762 | 7 | } | |
| 763 | // Trailing bytes that do not form a whole record are a malformed buffer | ||
| 764 |
7/7✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 4 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 2 times.
✓ Branch 9 taken 3 times.
|
5 | if ((status == Fw::FW_SERIALIZE_OK) and (deserializer.getDeserializeSizeLeft() != 0)) { |
| 765 | 2 | status = Fw::FW_DESERIALIZE_FORMAT_ERROR; | |
| 766 | } | ||
| 767 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
|
5 | if (status != Fw::FW_SERIALIZE_OK) { |
| 768 |
1/1✓ Branch 2 taken 3 times.
|
3 | Fw::DeserialStatus reported(static_cast<Fw::DeserialStatus::T>(status)); |
| 769 |
2/3✓ Branch 2 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
|
3 | if (not reported.isValid()) { |
| 770 | ✗ | reported = Fw::DeserialStatus::FORMAT_ERROR; | |
| 771 | } | ||
| 772 |
1/1✓ Branch 5 taken 3 times.
|
3 | this->log_WARNING_HI_ConfigReloadFailed(reported); |
| 773 | 3 | } | |
| 774 | 5 | } else { | |
| 775 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 10 taken 1 times.
|
1 | this->log_WARNING_HI_ConfigReloadFailed(Fw::DeserialStatus::BUFFER_EMPTY); |
| 776 | } | ||
| 777 | 6 | this->packetOverrideReturnOut_out(0, fwBuffer); | |
| 778 | 6 | } | |
| 779 | |||
| 780 | 1 | void TlmPacketizer ::packetOverrideReturnIn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer) { | |
| 781 | // Mirror buffers come from allocate and go back to the same pool; the SDD requires the whole | ||
| 782 | // mirror path (packetOverrideOut, allocate, deallocate, packetOverrideReturnIn) wired or none of it | ||
| 783 | 1 | FW_ASSERT(this->isConnected_deallocate_OutputPort(0)); | |
| 784 | 1 | this->deallocate_out(0, fwBuffer); | |
| 785 | 1 | } | |
| 786 | |||
| 787 | 21 | Fw::Success TlmPacketizer::mirrorOverride(const Svc::TelemetrySection& section, FwChanIdType pkt) { | |
| 788 | // persistent storage component should mirror this state; skip if not wired | ||
| 789 |
2/3✓ Branch 5 taken 21 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 21 times.
|
21 | if (not this->isConnected_packetOverrideOut_OutputPort(0)) { |
| 790 | ✗ | return Fw::Success::SUCCESS; | |
| 791 | } | ||
| 792 | // A mirror port without an allocator cannot persist anything, and without a deallocator the returned | ||
| 793 | // mirror buffers could never be freed; the SDD requires the whole mirror path wired or none of it | ||
| 794 | 21 | FW_ASSERT(this->isConnected_allocate_OutputPort(0)); | |
| 795 | 21 | FW_ASSERT(this->isConnected_deallocate_OutputPort(0)); | |
| 796 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 21 times.
|
21 | const FwSizeType sectionIndex = static_cast<FwSizeType>(section.e); |
| 797 | 42 | const Svc::PacketConfigEntry entry(static_cast<U32>(this->m_fillBuffers[pkt].id), section, | |
| 798 |
3/3✓ Branch 6 taken 21 times.
✓ Branch 12 taken 21 times.
✓ Branch 20 taken 21 times.
|
42 | this->m_packetOverrides[sectionIndex][pkt]); |
| 799 | 21 | const FwSizeType entrySize = static_cast<FwSizeType>(Svc::PacketConfigEntry::SERIALIZED_SIZE); | |
| 800 |
1/1✓ Branch 3 taken 21 times.
|
21 | Fw::Buffer buffer = this->allocate_out(0, entrySize); |
| 801 |
3/3✓ Branch 2 taken 21 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 20 times.
|
21 | if (not buffer.isValid()) { |
| 802 |
1/1✓ Branch 5 taken 1 times.
|
1 | this->log_WARNING_HI_ConfigMirrorAllocFailed(); |
| 803 |
1/1✓ Branch 1 taken 1 times.
|
1 | return Fw::Success::FAILURE; |
| 804 | } | ||
| 805 | // Fw.BufferGet contract: a valid buffer is at least the requested size | ||
| 806 | 20 | FW_ASSERT(static_cast<FwSizeType>(buffer.getSize()) >= entrySize, static_cast<FwAssertArgType>(buffer.getSize())); | |
| 807 |
1/1✓ Branch 2 taken 20 times.
|
20 | auto serializer = buffer.getSerializer(); |
| 808 |
1/1✓ Branch 2 taken 20 times.
|
20 | const Fw::SerializeStatus status = serializer.serializeFrom(entry); |
| 809 | 20 | FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status)); | |
| 810 |
1/1✓ Branch 2 taken 20 times.
|
20 | buffer.setSize(static_cast<Fw::Buffer::SizeType>(entrySize)); |
| 811 |
1/1✓ Branch 5 taken 20 times.
|
20 | this->packetOverrideOut_out(0, buffer); |
| 812 |
1/1✓ Branch 1 taken 20 times.
|
20 | return Fw::Success::SUCCESS; |
| 813 | 21 | } | |
| 814 | |||
| 815 | 52 | void TlmPacketizer::missingChannel(FwChanIdType id) { | |
| 816 | // search to see if missing channel has already been sent | ||
| 817 |
2/2✓ Branch 0 taken 676 times.
✓ Branch 1 taken 1 times.
|
677 | for (FwChanIdType slot = 0; slot < TLMPACKETIZER_MAX_MISSING_TLM_CHECK; slot++) { |
| 818 | // if it's been checked, return | ||
| 819 |
5/6✗ Branch 4 not taken.
✓ Branch 5 taken 676 times.
✓ Branch 6 taken 650 times.
✓ Branch 7 taken 26 times.
✓ Branch 13 taken 25 times.
✓ Branch 14 taken 625 times.
|
676 | if (this->m_missTlmCheck[slot].checked and (this->m_missTlmCheck[slot].id == id)) { |
| 820 | 25 | return; | |
| 821 |
3/4✗ Branch 4 not taken.
✓ Branch 5 taken 651 times.
✓ Branch 6 taken 26 times.
✓ Branch 7 taken 625 times.
|
651 | } else if (not this->m_missTlmCheck[slot].checked) { |
| 822 | 26 | this->m_missTlmCheck[slot].checked = true; | |
| 823 | 26 | this->m_missTlmCheck[slot].id = id; | |
| 824 | 26 | this->log_WARNING_LO_NoChan(id); | |
| 825 | 26 | return; | |
| 826 | } | ||
| 827 | } | ||
| 828 | } | ||
| 829 | |||
| 830 | 78 | Fw::SerializeStatus TlmPacketizer::deserializeParam(const FwPrmIdType base_id, | |
| 831 | const FwPrmIdType local_id, | ||
| 832 | const Fw::ParamValid prmStat, | ||
| 833 | Fw::SerialBufferBase& buff) { | ||
| 834 |
4/6✓ Branch 3 taken 6 times.
✓ Branch 4 taken 72 times.
✓ Branch 8 taken 6 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 78 times.
✗ Branch 11 not taken.
|
78 | if (FW_PARAM_OK(prmStat)) { |
| 835 |
2/3✓ Branch 0 taken 38 times.
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
78 | switch (local_id) { |
| 836 | // A stored value of a different shape (e.g. saved by a previous FSW load) must not load as a scrambled | ||
| 837 | // table | ||
| 838 | 38 | case PARAMID_SECTION_ENABLED: { | |
| 839 |
1/1✓ Branch 2 taken 38 times.
|
38 | Svc::TlmPacketizer_SectionEnabled loaded; |
| 840 |
1/1✓ Branch 7 taken 38 times.
|
38 | Fw::SerializeStatus status = buff.deserializeTo(loaded); |
| 841 |
6/7✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
✓ Branch 9 taken 38 times.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 37 times.
✓ Branch 13 taken 1 times.
✓ Branch 14 taken 37 times.
|
38 | if ((status == Fw::FW_SERIALIZE_OK) and (buff.getDeserializeSizeLeft() != 0)) { |
| 842 | 1 | status = Fw::FW_DESERIALIZE_SIZE_MISMATCH; | |
| 843 | } | ||
| 844 |
2/2✓ Branch 0 taken 37 times.
✓ Branch 1 taken 1 times.
|
38 | if (status == Fw::FW_SERIALIZE_OK) { |
| 845 |
1/1✓ Branch 6 taken 37 times.
|
37 | this->m_sectionEnabled = loaded; |
| 846 | } | ||
| 847 | 38 | return status; | |
| 848 | 38 | } | |
| 849 | 40 | case PARAMID_SECTION_CONFIGS: { | |
| 850 |
1/1✓ Branch 2 taken 40 times.
|
40 | Svc::TlmPacketizer_SectionConfigs loaded; |
| 851 |
1/1✓ Branch 7 taken 40 times.
|
40 | Fw::SerializeStatus status = buff.deserializeTo(loaded); |
| 852 |
7/7✓ Branch 0 taken 39 times.
✓ Branch 1 taken 1 times.
✓ Branch 9 taken 39 times.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 38 times.
✓ Branch 13 taken 1 times.
✓ Branch 14 taken 39 times.
|
40 | if ((status == Fw::FW_SERIALIZE_OK) and (buff.getDeserializeSizeLeft() != 0)) { |
| 853 | 1 | status = Fw::FW_DESERIALIZE_SIZE_MISMATCH; | |
| 854 | } | ||
| 855 |
2/2✓ Branch 0 taken 38 times.
✓ Branch 1 taken 2 times.
|
40 | if (status == Fw::FW_SERIALIZE_OK) { |
| 856 |
1/1✓ Branch 6 taken 38 times.
|
38 | this->m_groupConfigs = loaded; |
| 857 | } | ||
| 858 | 40 | return status; | |
| 859 | 40 | } | |
| 860 | ✗ | default: | |
| 861 | ✗ | FW_ASSERT(false, static_cast<FwAssertArgType>(local_id)); | |
| 862 | } | ||
| 863 | } | ||
| 864 | ✗ | return Fw::SerializeStatus::FW_DESERIALIZE_TYPE_MISMATCH; | |
| 865 | } | ||
| 866 | |||
| 867 | 2 | Fw::SerializeStatus TlmPacketizer::serializeParam(const FwPrmIdType base_id, | |
| 868 | const FwPrmIdType local_id, | ||
| 869 | Fw::SerialBufferBase& buff) const { | ||
| 870 |
2/3✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | switch (local_id) { |
| 871 | 1 | case PARAMID_SECTION_ENABLED: | |
| 872 | 1 | return buff.serializeFrom(this->m_sectionEnabled); | |
| 873 | 1 | case PARAMID_SECTION_CONFIGS: | |
| 874 | 1 | return buff.serializeFrom(this->m_groupConfigs); | |
| 875 | ✗ | default: | |
| 876 | ✗ | FW_ASSERT(false, static_cast<FwAssertArgType>(local_id)); | |
| 877 | } | ||
| 878 | ✗ | return Fw::SerializeStatus::FW_SERIALIZE_FORMAT_ERROR; | |
| 879 | } | ||
| 880 | |||
| 881 | } // end namespace Svc | ||
| 882 |