GCC Code Coverage Report


Directory: /home/runner/work/fprime/fprime/Svc/Version/
File: Version.cpp
Date: 2026-11-03 22:12:04
Exec Total Coverage
Lines: 35 172 20.3%
Functions: 7 14 50.0%
Branches: 24 142 16.9%

Line Branch Exec Source
1 // ======================================================================
2 // \title Version.cpp
3 // \author sreddy
4 // \brief cpp file for Version component implementation class
5 // ======================================================================
6
7 #include "Svc/Version/Version.hpp"
8 #include "Fw/FPrimeBasicTypes.hpp"
9
10 #include "versions/version.hpp" //autogenerated file containing hardcoded project and framework versions
11
12 namespace Svc {
13
14 // ----------------------------------------------------------------------
15 // Component construction and destruction
16 // ----------------------------------------------------------------------
17
18 1 Version ::Version(const char* const compName)
19
3/9
✓ Branch 2 taken 10 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
11 : VersionComponentBase(compName), m_enable(false), m_num_custom_elements(0) {
20
1/1
✓ Branch 1 taken 1 times.
1 Fw::String version_string = "no_ver";
21 // initialize all custom entries
22
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 times.
11 for (FwIndexType id = 0; id < Svc::VersionCfg::VersionEnum::NUM_CONSTANTS; id++) {
23 // setVersion_enum is by default set to the first enum value, so not setting it here
24
1/1
✓ Branch 1 taken 10 times.
10 this->verId_db[id].set_version_value(version_string);
25
1/1
✓ Branch 1 taken 10 times.
10 this->verId_db[id].set_version_status(VersionStatus::FAILURE);
26 }
27 1 }
28
29
3/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 1 times.
22 Version ::~Version() {}
30
31 1 void Version::config(bool enable) {
32 // Set Verbosity for custom versions
33 1 this->m_enable = enable;
34 1 }
35
36 1 void Version::start() {
37 // Send startup TLM and EVENTS
38 1 this->fwVersion_tlm();
39 1 this->projectVersion_tlm();
40 1 this->libraryVersion_tlm();
41 1 }
42 // ----------------------------------------------------------------------
43 // Handler implementations for user-defined typed input ports
44 // ----------------------------------------------------------------------
45
46 ✗ void Version ::getVersion_handler(FwIndexType portNum,
47 const Svc::VersionCfg::VersionEnum& version_id,
48 Fw::StringBase& version_string,
49 Svc::VersionStatus& status) {
50 ✗ FW_ASSERT(version_id.isValid(), version_id.e);
51 ✗ FW_ASSERT(static_cast<Svc::VersionCfg::VersionEnum::SerialType>(version_id.e) <
52 Svc::VersionCfg::VersionEnum::NUM_CONSTANTS,
53 version_id.e);
54 ✗ U8 version_slot = VersionSlot(version_id.e);
55 ✗ version_string = static_cast<const Fw::StringBase&>(this->verId_db[version_slot].get_version_value());
56 ✗ status = this->verId_db[version_slot].get_version_status();
57 ✗ }
58
59 ✗ void Version ::setVersion_handler(FwIndexType portNum,
60 const Svc::VersionCfg::VersionEnum& version_id,
61 Fw::StringBase& version_string,
62 Svc::VersionStatus& status) {
63 ✗ FW_ASSERT(version_id.isValid(), version_id.e);
64 ✗ FW_ASSERT(static_cast<Svc::VersionCfg::VersionEnum::SerialType>(version_id.e) <
65 Svc::VersionCfg::VersionEnum::NUM_CONSTANTS,
66 version_id.e);
67 ✗ auto ver_slot = VersionSlot(version_id.e);
68 // Count each slot once: rewrites of a populated slot must not grow the count
69 ✗ if ((this->verId_db[ver_slot].get_version_value() == "no_ver") &&
70 ✗ (this->m_num_custom_elements < Svc::VersionCfg::VersionEnum::NUM_CONSTANTS)) {
71 ✗ this->m_num_custom_elements++;
72 }
73 ✗ this->verId_db[ver_slot].set_version_enum(version_id);
74 ✗ this->verId_db[ver_slot].set_version_value(version_string);
75 ✗ this->verId_db[ver_slot].set_version_status(status);
76 ✗ this->customVersion_tlm(ver_slot);
77 ✗ }
78
79 // Scheduled handler to periodically re-emit all version information (without event spamming)
80 ✗ void Version ::schedIn_handler(FwIndexType portNum, U32 context) {
81 ✗ this->projectVersion_tlm(/* sendEvent = */ false);
82 ✗ this->fwVersion_tlm(/* sendEvent = */ false);
83 ✗ this->libraryVersion_tlm(/* sendEvent = */ false);
84 ✗ this->customVersion_tlm_all(/* sendEvent = */ false);
85 ✗ }
86
87 // ----------------------------------------------------------------------
88 // Handler implementations for commands
89 // ----------------------------------------------------------------------
90
91 ✗ void Version ::ENABLE_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, const Svc::VersionEnabled& enable) {
92 ✗ this->m_enable = (enable == VersionEnabled::ENABLED);
93
94 ✗ this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
95 ✗ }
96
97 // Command handler to event versions
98 ✗ void Version ::VERSION_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, const Svc::VersionType& version_type) {
99 ✗ FW_ASSERT(version_type.isValid(), version_type.e);
100
101 ✗ switch (version_type) {
102 ✗ case (Svc::VersionType::PROJECT):
103 ✗ this->projectVersion_tlm();
104 ✗ break;
105
106 ✗ case (Svc::VersionType::FRAMEWORK):
107 ✗ this->fwVersion_tlm();
108 ✗ break;
109
110 ✗ case (Svc::VersionType::LIBRARY):
111 ✗ this->libraryVersion_tlm();
112 ✗ break;
113
114 ✗ case (Svc::VersionType::CUSTOM):
115 ✗ this->customVersion_tlm_all();
116 ✗ break;
117
118 ✗ case (Svc::VersionType::ALL):
119 ✗ this->projectVersion_tlm();
120 ✗ this->fwVersion_tlm();
121 ✗ this->libraryVersion_tlm();
122 ✗ this->customVersion_tlm_all();
123 ✗ break;
124 ✗ default:
125 ✗ FW_ASSERT(false, version_type);
126 ✗ break;
127 }
128
129 ✗ this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
130 ✗ }
131 // ----------------------------------------------------------------------
132 // implementations for internal functions
133 // ----------------------------------------------------------------------
134 // Write framework version tlm; also emit the event when sendEvent is true (default in Version.hpp)
135 1 void Version ::fwVersion_tlm(bool sendEvent) {
136
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (sendEvent) {
137
1/1
✓ Branch 1 taken 1 times.
1 Fw::LogStringArg fw_event = (Project::Version::FRAMEWORK_VERSION);
138
1/1
✓ Branch 1 taken 1 times.
1 this->log_ACTIVITY_LO_FrameworkVersion(fw_event);
139 1 }
140
1/1
✓ Branch 1 taken 1 times.
1 Fw::TlmString fw_tlm = (Project::Version::FRAMEWORK_VERSION);
141
2/2
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
1 this->tlmWrite_FrameworkVersion(fw_tlm);
142 1 }
143 // Write project version tlm; also emit the event when sendEvent is true (default in Version.hpp)
144 1 void Version ::projectVersion_tlm(bool sendEvent) {
145
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (sendEvent) {
146
1/1
✓ Branch 1 taken 1 times.
1 Fw::LogStringArg proj_event = Project::Version::PROJECT_VERSION;
147
1/1
✓ Branch 1 taken 1 times.
1 this->log_ACTIVITY_LO_ProjectVersion(proj_event);
148 1 }
149
1/1
✓ Branch 1 taken 1 times.
1 Fw::TlmString proj_tlm = Project::Version::PROJECT_VERSION;
150
2/2
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
1 this->tlmWrite_ProjectVersion(proj_tlm);
151 1 }
152 // Write library version tlm; also emit the event when sendEvent is true (default in Version.hpp)
153 1 void Version ::libraryVersion_tlm(bool sendEvent) {
154 // Process libraries array
155
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 for (FwIndexType i = 0; i < Project::Version::LIBRARY_VERSIONS_COUNT; i++) {
156 ✗ FW_ASSERT(Project::Version::LIBRARY_VERSIONS[i] != nullptr, static_cast<FwAssertArgType>(i));
157 // Write to Events, if enabled via sendEvent function argument
158 ✗ if (sendEvent) {
159 ✗ this->log_ACTIVITY_LO_LibraryVersions(Fw::LogStringArg(Project::Version::LIBRARY_VERSIONS[i]));
160 }
161
162 // Emit TLM on library versions
163 ✗ switch (i) {
164 ✗ case VER_SLOT_00:
165 ✗ this->tlmWrite_LibraryVersion01(Fw::TlmString(Project::Version::LIBRARY_VERSIONS[i]));
166 ✗ break;
167 ✗ case VER_SLOT_01:
168 ✗ this->tlmWrite_LibraryVersion02(Fw::TlmString(Project::Version::LIBRARY_VERSIONS[i]));
169 ✗ break;
170 ✗ case VER_SLOT_02:
171 ✗ this->tlmWrite_LibraryVersion03(Fw::TlmString(Project::Version::LIBRARY_VERSIONS[i]));
172 ✗ break;
173 ✗ case VER_SLOT_03:
174 ✗ this->tlmWrite_LibraryVersion04(Fw::TlmString(Project::Version::LIBRARY_VERSIONS[i]));
175 ✗ break;
176 ✗ case VER_SLOT_04:
177 ✗ this->tlmWrite_LibraryVersion05(Fw::TlmString(Project::Version::LIBRARY_VERSIONS[i]));
178 ✗ break;
179 ✗ case VER_SLOT_05:
180 ✗ this->tlmWrite_LibraryVersion06(Fw::TlmString(Project::Version::LIBRARY_VERSIONS[i]));
181 ✗ break;
182 ✗ case VER_SLOT_06:
183 ✗ this->tlmWrite_LibraryVersion07(Fw::TlmString(Project::Version::LIBRARY_VERSIONS[i]));
184 ✗ break;
185 ✗ case VER_SLOT_07:
186 ✗ this->tlmWrite_LibraryVersion08(Fw::TlmString(Project::Version::LIBRARY_VERSIONS[i]));
187 ✗ break;
188 ✗ case VER_SLOT_08:
189 ✗ this->tlmWrite_LibraryVersion09(Fw::TlmString(Project::Version::LIBRARY_VERSIONS[i]));
190 ✗ break;
191 ✗ case VER_SLOT_09:
192 ✗ this->tlmWrite_LibraryVersion10(Fw::TlmString(Project::Version::LIBRARY_VERSIONS[i]));
193 ✗ break;
194 ✗ default:
195 // It is possible to have more than 10 library versions; however design agreed to only
196 // provide 10 TLM channels for it
197 ✗ break;
198 }
199 }
200 1 }
201 // Write all custom version tlm; also emit the event when sendEvent is true (default in Version.hpp)
202 ✗ void Version ::customVersion_tlm_all(bool sendEvent) {
203 // projects may define a maximum of 10 custom slots
204 static_assert(Svc::VersionCfg::VersionEnum::NUM_CONSTANTS <= VER_SLOT_09 + 1,
205 "Svc::Version supports at most 10 custom version slots");
206 ✗ for (U8 i = 0; (m_num_custom_elements != 0) && (i < Svc::VersionCfg::VersionEnum::NUM_CONSTANTS); i++) {
207 ✗ this->customVersion_tlm(static_cast<VersionSlot>(i), sendEvent);
208 }
209 ✗ }
210 // Write custom version tlm; also emit the event when sendEvent is true (default in Version.hpp)
211 ✗ void Version ::customVersion_tlm(VersionSlot custom_slot, bool sendEvent) {
212 // Process custom version TLM only if verbosity is enabled and there are any valid writes to it;
213 // it doesn't necessarily have to be consecutive
214 ✗ if ((this->verId_db[custom_slot].get_version_value() != "no_ver") &&
215 ✗ (this->m_num_custom_elements > 0)) { // Write TLM for valid writes
216
217 // Write to Events, if enabled via sendEvent function argument
218 ✗ if (sendEvent) {
219 ✗ this->log_ACTIVITY_LO_CustomVersions(this->verId_db[custom_slot].get_version_enum(),
220 ✗ this->verId_db[custom_slot].get_version_value());
221 }
222
223 ✗ if (m_enable == true) { // Send TLM only if verbosity is enabled
224 // Write to TLM
225 ✗ switch (custom_slot) {
226 ✗ case VER_SLOT_00:
227 ✗ this->tlmWrite_CustomVersion01(verId_db[custom_slot]);
228 ✗ break;
229 ✗ case VER_SLOT_01:
230 ✗ this->tlmWrite_CustomVersion02(verId_db[custom_slot]);
231 ✗ break;
232 ✗ case VER_SLOT_02:
233 ✗ this->tlmWrite_CustomVersion03(verId_db[custom_slot]);
234 ✗ break;
235 ✗ case VER_SLOT_03:
236 ✗ this->tlmWrite_CustomVersion04(verId_db[custom_slot]);
237 ✗ break;
238 ✗ case VER_SLOT_04:
239 ✗ this->tlmWrite_CustomVersion05(verId_db[custom_slot]);
240 ✗ break;
241 ✗ case VER_SLOT_05:
242 ✗ this->tlmWrite_CustomVersion06(verId_db[custom_slot]);
243 ✗ break;
244 ✗ case VER_SLOT_06:
245 ✗ this->tlmWrite_CustomVersion07(verId_db[custom_slot]);
246 ✗ break;
247 ✗ case VER_SLOT_07:
248 ✗ this->tlmWrite_CustomVersion08(verId_db[custom_slot]);
249 ✗ break;
250 ✗ case VER_SLOT_08:
251 ✗ this->tlmWrite_CustomVersion09(verId_db[custom_slot]);
252 ✗ break;
253 ✗ case VER_SLOT_09:
254 ✗ this->tlmWrite_CustomVersion10(verId_db[custom_slot]);
255 ✗ break;
256 ✗ default:
257 // There are only 10 custom slots available
258 ✗ FW_ASSERT(false, custom_slot);
259 ✗ break;
260 }
261 }
262 }
263 ✗ }
264
265 } // namespace Svc
266