| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // \title AMPCSSequence.cpp | ||
| 2 | // \author Rob Bocchino | ||
| 3 | // \brief AMPCSSequence implementation | ||
| 4 | // | ||
| 5 | // \copyright | ||
| 6 | // Copyright (C) 2009-2018 California Institute of Technology. | ||
| 7 | // ALL RIGHTS RESERVED. United States Government Sponsorship | ||
| 8 | // acknowledged. | ||
| 9 | // | ||
| 10 | // ====================================================================== | ||
| 11 | |||
| 12 | #include "Svc/CmdSequencer/formats/AMPCSSequence.hpp" | ||
| 13 | #include <Utils/Hash/Hash.hpp> | ||
| 14 | #include "Fw/Com/ComPacket.hpp" | ||
| 15 | #include "Fw/Types/Assert.hpp" | ||
| 16 | #include "Os/FileSystem.hpp" | ||
| 17 | |||
| 18 | namespace Svc { | ||
| 19 | |||
| 20 |
3/3✓ Branch 10 taken 87 times.
✓ Branch 16 taken 87 times.
✓ Branch 22 taken 87 times.
|
87 | AMPCSSequence ::AMPCSSequence(CmdSequencerComponentImpl& component) : CmdSequencerComponentImpl::Sequence(component) {} |
| 21 | |||
| 22 | 46 | bool AMPCSSequence ::loadFile(const Fw::ConstStringBase& fileName) { | |
| 23 | // Make sure there is a buffer allocated | ||
| 24 | 46 | FW_ASSERT(this->m_buffer.getBuffAddr() != nullptr); | |
| 25 | |||
| 26 |
1/1✓ Branch 2 taken 46 times.
|
46 | Fw::FileNameString crcFileName; |
| 27 |
2/2✓ Branch 8 taken 46 times.
✓ Branch 11 taken 46 times.
|
46 | const Fw::FormatStatus formatStatus = crcFileName.format("%s.CRC32", fileName.toChar()); |
| 28 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 45 times.
|
46 | if (formatStatus != Fw::FormatStatus::SUCCESS) { |
| 29 | // format() failed; OVERFLOWED when the .CRC32 suffix does not fit in FileNameStringSize | ||
| 30 |
1/1✓ Branch 5 taken 1 times.
|
1 | this->setFileName(fileName); |
| 31 |
1/1✓ Branch 4 taken 1 times.
|
1 | this->m_events.fileInvalid(CmdSequencer_FileReadStage::READ_SEQ_CRC, static_cast<I32>(formatStatus)); |
| 32 | 1 | return false; | |
| 33 | } | ||
| 34 | |||
| 35 |
1/1✓ Branch 6 taken 45 times.
|
45 | this->m_header.m_timeBase = TimeBase::TB_DONT_CARE; |
| 36 | 45 | this->m_header.m_timeContext = FW_CONTEXT_DONT_CARE; | |
| 37 | |||
| 38 |
4/4✓ Branch 4 taken 45 times.
✓ Branch 10 taken 42 times.
✓ Branch 12 taken 40 times.
✓ Branch 13 taken 2 times.
|
87 | const bool status = this->readCRCFile(crcFileName) and this->getFileSize(fileName) and |
| 39 |
6/6✓ Branch 4 taken 40 times.
✓ Branch 6 taken 36 times.
✓ Branch 7 taken 4 times.
✓ Branch 12 taken 36 times.
✓ Branch 14 taken 35 times.
✓ Branch 15 taken 1 times.
|
40 | this->readSequenceFile(fileName) and this->validateCRC() and |
| 40 |
7/8✓ Branch 0 taken 42 times.
✓ Branch 1 taken 3 times.
✓ Branch 11 taken 35 times.
✓ Branch 13 taken 35 times.
✗ Branch 14 not taken.
✓ Branch 19 taken 35 times.
✓ Branch 21 taken 31 times.
✓ Branch 22 taken 4 times.
|
87 | this->m_header.validateTime(this->m_component) and this->validateRecords(); |
| 41 | |||
| 42 | 45 | return status; | |
| 43 | 46 | } | |
| 44 | |||
| 45 | 45 | bool AMPCSSequence ::readCRCFile(const Fw::ConstStringBase& crcFileName) { | |
| 46 | bool result; | ||
| 47 | |||
| 48 | 45 | this->setFileName(crcFileName); | |
| 49 | |||
| 50 | 45 | Os::File::Status status = this->m_crcFile.open(crcFileName.toChar(), Os::File::OPEN_READ); | |
| 51 | |||
| 52 |
2/2✓ Branch 0 taken 42 times.
✓ Branch 1 taken 3 times.
|
45 | if (status == Os::File::OP_OK) { |
| 53 |
2/4✓ Branch 4 taken 42 times.
✗ Branch 5 not taken.
✓ Branch 10 taken 42 times.
✗ Branch 11 not taken.
|
42 | result = this->readCRC() and this->deserializeCRC(); |
| 54 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
|
3 | } else if (status == Os::File::DOESNT_EXIST) { |
| 55 | 2 | this->m_events.fileNotFound(); | |
| 56 | 2 | result = false; | |
| 57 | } else { | ||
| 58 | 1 | this->m_events.fileReadError(); | |
| 59 | 1 | result = false; | |
| 60 | } | ||
| 61 | |||
| 62 | 45 | this->m_crcFile.close(); | |
| 63 | 45 | return result; | |
| 64 | } | ||
| 65 | |||
| 66 | 42 | bool AMPCSSequence ::getFileSize(const Fw::ConstStringBase& seqFileName) { | |
| 67 | 42 | bool status = true; | |
| 68 | 42 | FwSizeType fileSize; | |
| 69 |
1/1✓ Branch 5 taken 42 times.
|
42 | this->setFileName(seqFileName); |
| 70 |
1/1✓ Branch 7 taken 42 times.
|
42 | const Os::FileSystem::Status fileStatus = Os::FileSystem::getFileSize(this->m_fileName.toChar(), fileSize); |
| 71 |
4/4✓ Branch 0 taken 41 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 40 times.
✓ Branch 3 taken 1 times.
|
42 | if (fileStatus == Os::FileSystem::OP_OK and fileSize >= static_cast<FwSizeType>(sizeof(this->m_sequenceHeader))) { |
| 72 | 80 | this->m_header.m_fileSize = | |
| 73 | 80 | static_cast<U32>(fileSize - static_cast<FwSizeType>(sizeof(this->m_sequenceHeader))); | |
| 74 | } else { | ||
| 75 |
1/1✓ Branch 4 taken 2 times.
|
2 | this->m_events.fileInvalid(CmdSequencer_FileReadStage::READ_HEADER_SIZE, fileStatus); |
| 76 | 2 | status = false; | |
| 77 | } | ||
| 78 | 42 | return status; | |
| 79 | } | ||
| 80 | |||
| 81 | 40 | bool AMPCSSequence ::readSequenceFile(const Fw::ConstStringBase& seqFileName) { | |
| 82 | bool result; | ||
| 83 | |||
| 84 | 40 | this->setFileName(seqFileName); | |
| 85 | 40 | Os::File::Status status = this->m_sequenceFile.open(this->m_fileName.toChar(), Os::File::OPEN_READ); | |
| 86 | |||
| 87 |
1/2✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
|
40 | if (status == Os::File::OP_OK) { |
| 88 | 40 | result = this->readOpenSequenceFile(); | |
| 89 | ✗ | } else if (status == Os::File::DOESNT_EXIST) { | |
| 90 | ✗ | this->m_events.fileNotFound(); | |
| 91 | ✗ | result = false; | |
| 92 | } else { | ||
| 93 | ✗ | this->m_events.fileReadError(); | |
| 94 | ✗ | result = false; | |
| 95 | } | ||
| 96 | |||
| 97 | 40 | this->m_sequenceFile.close(); | |
| 98 | 40 | return result; | |
| 99 | } | ||
| 100 | |||
| 101 | 36 | bool AMPCSSequence ::validateCRC() { | |
| 102 | 36 | bool result = true; | |
| 103 | 36 | U32 computed = this->m_crc.finalize(); | |
| 104 |
2/2✓ Branch 4 taken 1 times.
✓ Branch 5 taken 35 times.
|
36 | if (this->m_crc.m_stored != computed) { |
| 105 | 1 | this->m_events.fileCRCFailure(this->m_crc.m_stored, computed); | |
| 106 | 1 | result = false; | |
| 107 | } | ||
| 108 | 36 | return result; | |
| 109 | } | ||
| 110 | |||
| 111 | 35 | bool AMPCSSequence ::validateRecords() { | |
| 112 | 35 | Fw::LinearBufferBase& buffer = this->m_buffer; | |
| 113 |
1/1✓ Branch 2 taken 35 times.
|
35 | Sequence::Record record; |
| 114 | |||
| 115 | // Deserialize all records and count the records | ||
| 116 |
1/1✓ Branch 7 taken 35 times.
|
35 | const U32 loopBound = static_cast<U32>(buffer.getDeserializeSizeLeft()); |
| 117 | 35 | U32 numRecords = 0; | |
| 118 |
2/2✓ Branch 0 taken 173 times.
✓ Branch 1 taken 2 times.
|
175 | for (; numRecords < loopBound; ++numRecords) { |
| 119 |
3/3✓ Branch 7 taken 173 times.
✓ Branch 9 taken 31 times.
✓ Branch 10 taken 142 times.
|
173 | if (not this->hasMoreRecords()) { |
| 120 | 31 | break; | |
| 121 | } | ||
| 122 |
1/1✓ Branch 4 taken 142 times.
|
142 | Fw::SerializeStatus status = this->deserializeRecord(record); |
| 123 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 140 times.
|
142 | if (status != Fw::FW_SERIALIZE_OK) { |
| 124 |
1/1✓ Branch 4 taken 2 times.
|
2 | this->m_events.recordInvalid(numRecords, status); |
| 125 | 2 | return false; | |
| 126 | } | ||
| 127 | } | ||
| 128 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 31 times.
|
33 | if (numRecords == 0) { |
| 129 |
1/1✓ Branch 4 taken 2 times.
|
2 | this->m_events.noRecords(); |
| 130 | 2 | return false; | |
| 131 | } | ||
| 132 | // Set the number of records | ||
| 133 | 31 | this->m_header.m_numRecords = numRecords; | |
| 134 | // Reset deserialization | ||
| 135 |
1/1✓ Branch 7 taken 31 times.
|
31 | this->reset(); |
| 136 | |||
| 137 | 31 | return true; | |
| 138 | 35 | } | |
| 139 | |||
| 140 | 233 | bool AMPCSSequence ::hasMoreRecords() const { | |
| 141 | 233 | return this->m_buffer.getDeserializeSizeLeft() > 0; | |
| 142 | } | ||
| 143 | |||
| 144 | 56 | void AMPCSSequence ::nextRecord(Sequence::Record& record) { | |
| 145 | 56 | Fw::SerializeStatus status = this->deserializeRecord(record); | |
| 146 | 56 | FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status); | |
| 147 | 56 | } | |
| 148 | |||
| 149 | 34 | void AMPCSSequence ::reset() { | |
| 150 | 34 | this->m_buffer.resetDeser(); | |
| 151 | 34 | } | |
| 152 | |||
| 153 | 44 | void AMPCSSequence ::clear() { | |
| 154 | 44 | this->m_buffer.resetSer(); | |
| 155 | 44 | } | |
| 156 | |||
| 157 | 42 | bool AMPCSSequence ::readCRC() { | |
| 158 | 42 | Os::File& file = this->m_crcFile; | |
| 159 | 42 | Fw::LinearBufferBase& buffer = this->m_buffer; | |
| 160 | 42 | bool status = true; | |
| 161 | Fw::SerializeStatus ser_status; | ||
| 162 | |||
| 163 | 42 | FwSizeType readLen = static_cast<FwSizeType>(sizeof(U32)); | |
| 164 |
1/1✓ Branch 7 taken 42 times.
|
42 | ser_status = buffer.setBuffLen(static_cast<Fw::Serializable::SizeType>(readLen)); |
| 165 | 42 | FW_ASSERT(ser_status == Fw::FW_SERIALIZE_OK, ser_status); | |
| 166 | |||
| 167 | 42 | U8* const addr = buffer.getBuffAddr(); | |
| 168 |
1/1✓ Branch 4 taken 42 times.
|
42 | Os::File::Status fileStatus = file.read(addr, readLen); |
| 169 | |||
| 170 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
|
42 | if (fileStatus != Os::File::OP_OK) { |
| 171 | ✗ | this->m_events.fileInvalid(CmdSequencer_FileReadStage::READ_SEQ_CRC, fileStatus); | |
| 172 | ✗ | status = false; | |
| 173 | } | ||
| 174 | |||
| 175 | 42 | return status; | |
| 176 | } | ||
| 177 | |||
| 178 | 42 | bool AMPCSSequence ::deserializeCRC() { | |
| 179 | 42 | bool status = true; | |
| 180 | 42 | Fw::SerializeStatus serializeStatus = this->m_buffer.deserializeTo(this->m_crc.m_stored); | |
| 181 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
|
42 | if (serializeStatus != Fw::FW_SERIALIZE_OK) { |
| 182 | ✗ | this->m_events.fileInvalid(CmdSequencer_FileReadStage::READ_SEQ_CRC, serializeStatus); | |
| 183 | ✗ | status = false; | |
| 184 | } | ||
| 185 | 42 | return status; | |
| 186 | } | ||
| 187 | |||
| 188 | 40 | bool AMPCSSequence ::readOpenSequenceFile() { | |
| 189 | 40 | this->m_buffer.resetSer(); | |
| 190 | 40 | this->m_crc.init(); | |
| 191 | 40 | bool status = this->readSequenceHeader(); | |
| 192 |
2/2✓ Branch 0 taken 39 times.
✓ Branch 1 taken 1 times.
|
40 | if (status) { |
| 193 | 39 | this->m_crc.update(this->m_sequenceHeader, sizeof(this->m_sequenceHeader)); | |
| 194 | 39 | status = this->readRecords(); | |
| 195 | } | ||
| 196 |
2/2✓ Branch 0 taken 36 times.
✓ Branch 1 taken 4 times.
|
40 | if (status) { |
| 197 | 36 | U8* const buffAddr = this->m_buffer.getBuffAddr(); | |
| 198 | 36 | const FwSizeType buffLen = this->m_buffer.getSize(); | |
| 199 | 36 | FW_ASSERT(buffLen == this->m_header.m_fileSize, static_cast<FwAssertArgType>(buffLen), | |
| 200 | static_cast<FwAssertArgType>(this->m_header.m_fileSize)); | ||
| 201 | 36 | this->m_crc.update(buffAddr, buffLen); | |
| 202 | } | ||
| 203 | 40 | return status; | |
| 204 | } | ||
| 205 | |||
| 206 | 40 | bool AMPCSSequence ::readSequenceHeader() { | |
| 207 | 40 | Os::File& file = this->m_sequenceFile; | |
| 208 | |||
| 209 | 40 | bool status = true; | |
| 210 | |||
| 211 | 40 | FwSizeType readLen = sizeof this->m_sequenceHeader; | |
| 212 |
1/1✓ Branch 6 taken 40 times.
|
40 | const Os::File::Status fileStatus = file.read(this->m_sequenceHeader, readLen); |
| 213 | |||
| 214 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 39 times.
|
40 | if (fileStatus != Os::File::OP_OK) { |
| 215 |
1/1✓ Branch 4 taken 1 times.
|
1 | this->m_events.fileInvalid(CmdSequencer_FileReadStage::READ_HEADER, fileStatus); |
| 216 | 1 | status = false; | |
| 217 | } | ||
| 218 | |||
| 219 |
3/4✓ Branch 0 taken 39 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 39 times.
|
40 | if (status and readLen != sizeof this->m_sequenceHeader) { |
| 220 | ✗ | this->m_events.fileInvalid(CmdSequencer_FileReadStage::READ_HEADER_SIZE, static_cast<I32>(readLen)); | |
| 221 | ✗ | status = false; | |
| 222 | } | ||
| 223 | |||
| 224 | 40 | return status; | |
| 225 | } | ||
| 226 | |||
| 227 | 39 | bool AMPCSSequence ::readRecords() { | |
| 228 | 39 | Os::File& file = this->m_sequenceFile; | |
| 229 | 39 | const FwSizeType size = this->m_header.m_fileSize; | |
| 230 | 39 | Fw::LinearBufferBase& buffer = this->m_buffer; | |
| 231 | 39 | U8* const addr = buffer.getBuffAddr(); | |
| 232 | |||
| 233 | // Check file size | ||
| 234 |
2/2✓ Branch 6 taken 1 times.
✓ Branch 7 taken 38 times.
|
39 | if (size > this->m_buffer.getCapacity()) { |
| 235 |
1/1✓ Branch 4 taken 1 times.
|
1 | this->m_events.fileSizeError(static_cast<U32>(size)); |
| 236 | 1 | return false; | |
| 237 | } | ||
| 238 | |||
| 239 | 38 | FwSizeType readLen = size; | |
| 240 |
1/1✓ Branch 4 taken 38 times.
|
38 | const Os::File::Status fileStatus = file.read(addr, readLen); |
| 241 | // Check read status | ||
| 242 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 37 times.
|
38 | if (fileStatus != Os::File::OP_OK) { |
| 243 |
1/1✓ Branch 4 taken 1 times.
|
1 | this->m_events.fileInvalid(CmdSequencer_FileReadStage::READ_SEQ_DATA, fileStatus); |
| 244 | 1 | return false; | |
| 245 | } | ||
| 246 | // Check read size | ||
| 247 | 37 | const FwSizeType readLenUint = static_cast<FwSizeType>(readLen); | |
| 248 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 36 times.
|
37 | if (readLenUint != size) { |
| 249 |
1/1✓ Branch 4 taken 1 times.
|
1 | this->m_events.fileInvalid(CmdSequencer_FileReadStage::READ_SEQ_DATA_SIZE, static_cast<I32>(readLen)); |
| 250 | 1 | return false; | |
| 251 | } | ||
| 252 | // set buffer size | ||
| 253 |
1/1✓ Branch 7 taken 36 times.
|
36 | const Fw::SerializeStatus serializeStatus = buffer.setBuffLen(size); |
| 254 | 36 | FW_ASSERT(serializeStatus == Fw::FW_SERIALIZE_OK, serializeStatus); | |
| 255 | 36 | return true; | |
| 256 | } | ||
| 257 | |||
| 258 | 198 | Fw::SerializeStatus AMPCSSequence ::deserializeRecord(Sequence::Record& record) { | |
| 259 | 198 | Record::CmdLength::t cmdLength; | |
| 260 | |||
| 261 |
1/1✓ Branch 6 taken 198 times.
|
198 | Fw::SerializeStatus status = this->deserializeTimeFlag(record.m_descriptor); |
| 262 | |||
| 263 |
2/2✓ Branch 0 taken 196 times.
✓ Branch 1 taken 2 times.
|
198 | if (status == Fw::FW_SERIALIZE_OK) { |
| 264 |
1/1✓ Branch 7 taken 196 times.
|
196 | status = this->deserializeTime(record.m_timeTag); |
| 265 | } | ||
| 266 |
2/2✓ Branch 0 taken 196 times.
✓ Branch 1 taken 2 times.
|
198 | if (status == Fw::FW_SERIALIZE_OK) { |
| 267 |
1/1✓ Branch 4 taken 196 times.
|
196 | status = this->deserializeCmdLength(cmdLength); |
| 268 | } | ||
| 269 |
2/2✓ Branch 0 taken 196 times.
✓ Branch 1 taken 2 times.
|
198 | if (status == Fw::FW_SERIALIZE_OK) { |
| 270 |
1/1✓ Branch 7 taken 196 times.
|
196 | status = this->translateCommand(record.m_command, cmdLength); |
| 271 | } | ||
| 272 | |||
| 273 | 198 | return status; | |
| 274 | } | ||
| 275 | |||
| 276 | 198 | Fw::SerializeStatus AMPCSSequence ::deserializeTimeFlag(Sequence::Record::Descriptor& descriptor) { | |
| 277 | 198 | Fw::LinearBufferBase& buffer = this->m_buffer; | |
| 278 | 198 | Record::TimeFlag::Serial::t timeFlagSerial; | |
| 279 |
1/1✓ Branch 7 taken 198 times.
|
198 | Fw::SerializeStatus status = buffer.deserializeTo(timeFlagSerial); |
| 280 |
1/2✓ Branch 0 taken 198 times.
✗ Branch 1 not taken.
|
198 | if (status == Fw::FW_SERIALIZE_OK) { |
| 281 |
3/3✓ Branch 0 taken 4 times.
✓ Branch 1 taken 192 times.
✓ Branch 2 taken 2 times.
|
198 | switch (timeFlagSerial) { |
| 282 | 4 | case Record::TimeFlag::ABSOLUTE: | |
| 283 | 4 | descriptor = Sequence::Record::ABSOLUTE; | |
| 284 | 4 | break; | |
| 285 | 192 | case Record::TimeFlag::RELATIVE: | |
| 286 | 192 | descriptor = Sequence::Record::RELATIVE; | |
| 287 | 192 | break; | |
| 288 | 2 | default: | |
| 289 | 2 | status = Fw::FW_DESERIALIZE_FORMAT_ERROR; | |
| 290 | 2 | break; | |
| 291 | } | ||
| 292 | } | ||
| 293 | 198 | return status; | |
| 294 | } | ||
| 295 | |||
| 296 | 196 | Fw::SerializeStatus AMPCSSequence ::deserializeTime(Fw::Time& timeTag) { | |
| 297 | 196 | Record::Time::t time; | |
| 298 | 196 | Fw::LinearBufferBase& buffer = this->m_buffer; | |
| 299 |
1/1✓ Branch 7 taken 196 times.
|
196 | Fw::SerializeStatus status = buffer.deserializeTo(time); |
| 300 |
1/2✓ Branch 0 taken 196 times.
✗ Branch 1 not taken.
|
196 | if (status == Fw::FW_SERIALIZE_OK) { |
| 301 |
1/1✓ Branch 4 taken 196 times.
|
196 | timeTag.set(time, 0); |
| 302 | } | ||
| 303 | 196 | return status; | |
| 304 | } | ||
| 305 | |||
| 306 | 196 | Fw::SerializeStatus AMPCSSequence ::deserializeCmdLength(Record::CmdLength::t& cmdLength) { | |
| 307 | 196 | Fw::LinearBufferBase& buffer = this->m_buffer; | |
| 308 | 196 | Fw::SerializeStatus status = buffer.deserializeTo(cmdLength); | |
| 309 |
3/6✓ Branch 0 taken 196 times.
✗ Branch 1 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 196 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 196 times.
|
196 | if (status == Fw::FW_SERIALIZE_OK and cmdLength > buffer.getDeserializeSizeLeft()) { |
| 310 | // Not enough data left | ||
| 311 | ✗ | status = Fw::FW_DESERIALIZE_SIZE_MISMATCH; | |
| 312 | } | ||
| 313 | // The translated record occupies the packet descriptor, the zero-extension bytes prepended to | ||
| 314 | // the two-byte AMPCS opcode, and the record body. It must fit the ComBuffer capacity: | ||
| 315 | // SERIALIZED_SIZE is the capacity plus the stored length, and comparing against it admits | ||
| 316 | // records that setBuffLen then rejects, asserting in translateCommand | ||
| 317 | 196 | const FwSizeType translatedSize = | |
| 318 | 196 | sizeof(FwPacketDescriptorType) + (sizeof(FwOpcodeType) - 2) + static_cast<FwSizeType>(cmdLength); | |
| 319 |
2/4✓ Branch 0 taken 196 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 196 times.
|
196 | if (status == Fw::FW_SERIALIZE_OK and translatedSize > FW_COM_BUFFER_MAX_SIZE) { |
| 320 | // Record size is too big for com buffer | ||
| 321 | ✗ | status = Fw::FW_DESERIALIZE_SIZE_MISMATCH; | |
| 322 | } | ||
| 323 | 196 | return status; | |
| 324 | } | ||
| 325 | |||
| 326 | 196 | Fw::SerializeStatus AMPCSSequence ::translateCommand(Fw::ComBuffer& comBuffer, const Record::CmdLength::t cmdLength) { | |
| 327 | 196 | Fw::LinearBufferBase& buffer = this->m_buffer; | |
| 328 |
1/1✓ Branch 5 taken 196 times.
|
196 | comBuffer.resetSer(); |
| 329 | // Serialize the command packet descriptor | ||
| 330 | 196 | const FwPacketDescriptorType cmdDescriptor = Fw::ComPacketType::FW_PACKET_COMMAND; | |
| 331 |
1/1✓ Branch 5 taken 196 times.
|
196 | Fw::SerializeStatus status = comBuffer.serializeFrom(cmdDescriptor); |
| 332 | 196 | FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status); | |
| 333 | // Zero-extend the two-byte AMPCS opcode by (sizeof(FwOpcodeType) - 2) bytes | ||
| 334 | static_assert(sizeof(FwOpcodeType) >= 2, "FwOpcodeType must be at least two bytes wide"); | ||
| 335 | 196 | U32 sizeOfZeros = 0; | |
| 336 | 196 | const FwIndexType bytesToExtend = sizeof(FwOpcodeType) - 2; | |
| 337 | 196 | const U8 zeros = 0; | |
| 338 |
2/2✓ Branch 0 taken 392 times.
✓ Branch 1 taken 196 times.
|
588 | for (FwIndexType i = 0; i < bytesToExtend; i++) { |
| 339 |
1/1✓ Branch 5 taken 392 times.
|
392 | status = comBuffer.serializeFrom(zeros); |
| 340 | 392 | FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status); | |
| 341 | 392 | sizeOfZeros += static_cast<U32>(sizeof(zeros)); | |
| 342 | } | ||
| 343 | // Set the buffer length | ||
| 344 |
1/1✓ Branch 5 taken 196 times.
|
196 | const U32 fixedBuffLen = static_cast<U32>(comBuffer.getSize()); |
| 345 | 196 | FW_ASSERT(fixedBuffLen == sizeof(cmdDescriptor) + sizeOfZeros, static_cast<FwAssertArgType>(fixedBuffLen)); | |
| 346 | 196 | const U32 totalBuffLen = fixedBuffLen + cmdLength; | |
| 347 |
1/1✓ Branch 5 taken 196 times.
|
196 | status = comBuffer.setBuffLen(totalBuffLen); |
| 348 | 196 | FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status); | |
| 349 | // Copy the opcode and argument bytes | ||
| 350 | 196 | FwSizeType size = cmdLength; | |
| 351 | 196 | U8* const addr = comBuffer.getBuffAddr(); | |
| 352 | 196 | FW_ASSERT(addr != nullptr); | |
| 353 | // true means "don't serialize the length" | ||
| 354 |
1/1✓ Branch 8 taken 196 times.
|
196 | status = buffer.deserializeTo(&addr[fixedBuffLen], size, Fw::Serialization::OMIT_LENGTH); |
| 355 | 196 | return status; | |
| 356 | } | ||
| 357 | |||
| 358 | } // namespace Svc | ||
| 359 |