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