GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/*------------------------------------------------------------------------------ |
||
2 |
-- Solar Orbiter's Low Frequency Receiver Flight Software (LFR FSW), |
||
3 |
-- This file is a part of the LFR FSW |
||
4 |
-- Copyright (C) 2012-2018, Plasma Physics Laboratory - CNRS |
||
5 |
-- |
||
6 |
-- This program is free software; you can redistribute it and/or modify |
||
7 |
-- it under the terms of the GNU General Public License as published by |
||
8 |
-- the Free Software Foundation; either version 2 of the License, or |
||
9 |
-- (at your option) any later version. |
||
10 |
-- |
||
11 |
-- This program is distributed in the hope that it will be useful, |
||
12 |
-- but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
13 |
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
14 |
-- GNU General Public License for more details. |
||
15 |
-- |
||
16 |
-- You should have received a copy of the GNU General Public License |
||
17 |
-- along with this program; if not, write to the Free Software |
||
18 |
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||
19 |
-------------------------------------------------------------------------------*/ |
||
20 |
/*-- Author : Paul Leroy |
||
21 |
-- Contact : Alexis Jeandet |
||
22 |
-- Mail : alexis.jeandet@lpp.polytechnique.fr |
||
23 |
----------------------------------------------------------------------------*/ |
||
24 |
/** Functions related to TeleCommand acceptance. |
||
25 |
* |
||
26 |
* @file |
||
27 |
* @author P. LEROY |
||
28 |
* |
||
29 |
* A group of functions to handle TeleCommands parsing.\n |
||
30 |
* |
||
31 |
*/ |
||
32 |
|||
33 |
#include "tc_acceptance.h" |
||
34 |
#include <stdio.h> |
||
35 |
|||
36 |
unsigned int lookUpTableForCRC[CONST_256] = {0}; |
||
37 |
|||
38 |
//********************** |
||
39 |
// GENERAL USE FUNCTIONS |
||
40 |
22 |
unsigned int Crc_opt( unsigned char D, unsigned int Chk) |
|
41 |
{ |
||
42 |
/** This function generate the CRC for one byte and returns the value of the new syndrome. |
||
43 |
* |
||
44 |
* @param D is the current byte of data. |
||
45 |
* @param Chk is the current syndrom value. |
||
46 |
* |
||
47 |
* @return the value of the new syndrome on two bytes. |
||
48 |
* |
||
49 |
*/ |
||
50 |
|||
51 |
22 |
return(((Chk << SHIFT_1_BYTE) & BYTE0_MASK)^lookUpTableForCRC [(((Chk >> SHIFT_1_BYTE)^D) & BYTE1_MASK)]); |
|
52 |
} |
||
53 |
|||
54 |
1 |
void initLookUpTableForCRC( void ) |
|
55 |
{ |
||
56 |
/** This function is used to initiates the look-up table for fast CRC computation. |
||
57 |
* |
||
58 |
* The global table lookUpTableForCRC[256] is initiated. |
||
59 |
* |
||
60 |
*/ |
||
61 |
|||
62 |
unsigned int i; |
||
63 |
unsigned int tmp; |
||
64 |
|||
65 |
✓✓ | 257 |
for (i=0; i<CONST_256; i++) |
66 |
{ |
||
67 |
256 |
tmp = 0; |
|
68 |
✓✓ | 256 |
if((i & BIT_0) != 0) { |
69 |
128 |
tmp = tmp ^ CONST_CRC_0; |
|
70 |
} |
||
71 |
✓✓ | 256 |
if((i & BIT_1) != 0) { |
72 |
128 |
tmp = tmp ^ CONST_CRC_1; |
|
73 |
} |
||
74 |
✓✓ | 256 |
if((i & BIT_2) != 0) { |
75 |
128 |
tmp = tmp ^ CONST_CRC_2; |
|
76 |
} |
||
77 |
✓✓ | 256 |
if((i & BIT_3) != 0) { |
78 |
128 |
tmp = tmp ^ CONST_CRC_3; |
|
79 |
} |
||
80 |
✓✓ | 256 |
if((i & BIT_4) != 0) { |
81 |
128 |
tmp = tmp ^ CONST_CRC_4; |
|
82 |
} |
||
83 |
✓✓ | 256 |
if((i & BIT_5) != 0) { |
84 |
128 |
tmp = tmp ^ CONST_CRC_5; |
|
85 |
} |
||
86 |
✓✓ | 256 |
if((i & BIT_6) != 0) { |
87 |
128 |
tmp = tmp ^ CONST_CRC_6; |
|
88 |
} |
||
89 |
✓✓ | 256 |
if((i & BIT_7) != 0) { |
90 |
128 |
tmp = tmp ^ CONST_CRC_7; |
|
91 |
} |
||
92 |
256 |
lookUpTableForCRC[i] = tmp; |
|
93 |
} |
||
94 |
1 |
} |
|
95 |
|||
96 |
2 |
void GetCRCAsTwoBytes(unsigned char* data, unsigned char* crcAsTwoBytes, unsigned int sizeOfData) |
|
97 |
{ |
||
98 |
/** This function calculates a two bytes Cyclic Redundancy Code. |
||
99 |
* |
||
100 |
* @param data points to a buffer containing the data on which to compute the CRC. |
||
101 |
* @param crcAsTwoBytes points points to a two bytes buffer in which the CRC is stored. |
||
102 |
* @param sizeOfData is the number of bytes of *data* used to compute the CRC. |
||
103 |
* |
||
104 |
* The specification of the Cyclic Redundancy Code is described in the following document: ECSS-E-70-41-A. |
||
105 |
* |
||
106 |
*/ |
||
107 |
|||
108 |
unsigned int Chk; |
||
109 |
int j; |
||
110 |
2 |
Chk = CRC_RESET; // reset the syndrom to all ones |
|
111 |
✓✓ | 24 |
for (j=0; j<sizeOfData; j++) { |
112 |
22 |
Chk = Crc_opt(data[j], Chk); |
|
113 |
} |
||
114 |
2 |
crcAsTwoBytes[0] = (unsigned char) (Chk >> SHIFT_1_BYTE); |
|
115 |
2 |
crcAsTwoBytes[1] = (unsigned char) (Chk & BYTE1_MASK); |
|
116 |
2 |
} |
|
117 |
|||
118 |
//********************* |
||
119 |
// ACCEPTANCE FUNCTIONS |
||
120 |
2 |
int tc_parser(ccsdsTelecommandPacket_t * TCPacket, unsigned int estimatedPacketLength, unsigned char *computed_CRC) |
|
121 |
{ |
||
122 |
/** This function parses TeleCommands. |
||
123 |
* |
||
124 |
* @param TC points to the TeleCommand that will be parsed. |
||
125 |
* @param estimatedPacketLength is the PACKET_LENGTH field calculated from the effective length of the received packet. |
||
126 |
* |
||
127 |
* @return Status code of the parsing. |
||
128 |
* |
||
129 |
* The parsing checks: |
||
130 |
* - process id |
||
131 |
* - category |
||
132 |
* - length: a global check is performed and a per subtype check also |
||
133 |
* - type |
||
134 |
* - subtype |
||
135 |
* - crc |
||
136 |
* |
||
137 |
*/ |
||
138 |
|||
139 |
int status; |
||
140 |
int status_crc; |
||
141 |
unsigned char pid; |
||
142 |
unsigned char category; |
||
143 |
unsigned int packetLength; |
||
144 |
unsigned char packetType; |
||
145 |
unsigned char packetSubtype; |
||
146 |
unsigned char sid; |
||
147 |
|||
148 |
2 |
status = CCSDS_TM_VALID; |
|
149 |
|||
150 |
// APID check *** APID on 2 bytes |
||
151 |
4 |
pid = ((TCPacket->packetID[0] & BITS_PID_0) << SHIFT_4_BITS) |
|
152 |
2 |
+ ( (TCPacket->packetID[1] >> SHIFT_4_BITS) & BITS_PID_1 ); // PID = 11 *** 7 bits xxxxx210 7654xxxx |
|
153 |
2 |
category = (TCPacket->packetID[1] & BITS_CAT); // PACKET_CATEGORY = 12 *** 4 bits xxxxxxxx xxxx3210 |
|
154 |
2 |
packetLength = (TCPacket->packetLength[0] * CONST_256) + TCPacket->packetLength[1]; |
|
155 |
2 |
packetType = TCPacket->serviceType; |
|
156 |
2 |
packetSubtype = TCPacket->serviceSubType; |
|
157 |
2 |
sid = TCPacket->sourceID; |
|
158 |
|||
159 |
✗✓ | 2 |
if ( pid != CCSDS_PROCESS_ID ) // CHECK THE PROCESS ID |
160 |
{ |
||
161 |
status = ILLEGAL_APID; |
||
162 |
} |
||
163 |
✓✗ | 2 |
if (status == CCSDS_TM_VALID) // CHECK THE CATEGORY |
164 |
{ |
||
165 |
✗✓ | 2 |
if ( category != CCSDS_PACKET_CATEGORY ) |
166 |
{ |
||
167 |
status = ILLEGAL_APID; |
||
168 |
} |
||
169 |
} |
||
170 |
✓✗ | 2 |
if (status == CCSDS_TM_VALID) // CHECK THE PACKET_LENGTH FIELD AND THE ESTIMATED PACKET_LENGTH COMPLIANCE |
171 |
{ |
||
172 |
✗✓ | 2 |
if (packetLength != estimatedPacketLength ) { |
173 |
status = WRONG_LEN_PKT; |
||
174 |
} |
||
175 |
} |
||
176 |
✓✗ | 2 |
if (status == CCSDS_TM_VALID) // CHECK THAT THE PACKET DOES NOT EXCEED THE MAX SIZE |
177 |
{ |
||
178 |
✗✓ | 2 |
if ( packetLength > CCSDS_TC_PKT_MAX_SIZE ) { |
179 |
status = WRONG_LEN_PKT; |
||
180 |
} |
||
181 |
} |
||
182 |
✓✗ | 2 |
if (status == CCSDS_TM_VALID) // CHECK THE TYPE |
183 |
{ |
||
184 |
2 |
status = tc_check_type( packetType ); |
|
185 |
} |
||
186 |
✓✗ | 2 |
if (status == CCSDS_TM_VALID) // CHECK THE SUBTYPE |
187 |
{ |
||
188 |
2 |
status = tc_check_type_subtype( packetType, packetSubtype ); |
|
189 |
} |
||
190 |
✓✗ | 2 |
if (status == CCSDS_TM_VALID) // CHECK THE SID |
191 |
{ |
||
192 |
2 |
status = tc_check_sid( sid ); |
|
193 |
} |
||
194 |
✓✗ | 2 |
if (status == CCSDS_TM_VALID) // CHECK THE SUBTYPE AND LENGTH COMPLIANCE |
195 |
{ |
||
196 |
2 |
status = tc_check_length( packetSubtype, packetLength ); |
|
197 |
} |
||
198 |
2 |
status_crc = tc_check_crc( TCPacket, estimatedPacketLength, computed_CRC ); |
|
199 |
✓✓ | 2 |
if (status == CCSDS_TM_VALID ) // CHECK CRC |
200 |
{ |
||
201 |
1 |
status = status_crc; |
|
202 |
} |
||
203 |
|||
204 |
2 |
return status; |
|
205 |
} |
||
206 |
|||
207 |
2 |
int tc_check_type( unsigned char packetType ) |
|
208 |
{ |
||
209 |
/** This function checks that the type of a TeleCommand is valid. |
||
210 |
* |
||
211 |
* @param packetType is the type to check. |
||
212 |
* |
||
213 |
* @return Status code CCSDS_TM_VALID or ILL_TYPE. |
||
214 |
* |
||
215 |
*/ |
||
216 |
|||
217 |
int status; |
||
218 |
|||
219 |
2 |
status = ILL_TYPE; |
|
220 |
|||
221 |
✓✗ | 2 |
if ( (packetType == TC_TYPE_GEN) || (packetType == TC_TYPE_TIME)) |
222 |
{ |
||
223 |
2 |
status = CCSDS_TM_VALID; |
|
224 |
} |
||
225 |
else |
||
226 |
{ |
||
227 |
status = ILL_TYPE; |
||
228 |
} |
||
229 |
|||
230 |
2 |
return status; |
|
231 |
} |
||
232 |
|||
233 |
2 |
int tc_check_type_subtype( unsigned char packetType, unsigned char packetSubType ) |
|
234 |
{ |
||
235 |
/** This function checks that the subtype of a TeleCommand is valid and coherent with the type. |
||
236 |
* |
||
237 |
* @param packetType is the type of the TC. |
||
238 |
* @param packetSubType is the subtype to check. |
||
239 |
* |
||
240 |
* @return Status code CCSDS_TM_VALID or ILL_SUBTYPE. |
||
241 |
* |
||
242 |
*/ |
||
243 |
|||
244 |
int status; |
||
245 |
|||
246 |
✓✗✗ | 2 |
switch(packetType) |
247 |
{ |
||
248 |
case TC_TYPE_GEN: |
||
249 |
✓✓✓✗ ✓✗✓✗ ✓✗✗✓ ✗✗✗✗ |
11 |
if ( (packetSubType == TC_SUBTYPE_RESET) |
250 |
2 |
|| (packetSubType == TC_SUBTYPE_LOAD_COMM) |
|
251 |
3 |
|| (packetSubType == TC_SUBTYPE_LOAD_NORM) || (packetSubType == TC_SUBTYPE_LOAD_BURST) |
|
252 |
1 |
|| (packetSubType == TC_SUBTYPE_LOAD_SBM1) || (packetSubType == TC_SUBTYPE_LOAD_SBM2) |
|
253 |
1 |
|| (packetSubType == TC_SUBTYPE_DUMP) |
|
254 |
1 |
|| (packetSubType == TC_SUBTYPE_ENTER) |
|
255 |
1 |
|| (packetSubType == TC_SUBTYPE_UPDT_INFO) |
|
256 |
2 |
|| (packetSubType == TC_SUBTYPE_EN_CAL) || (packetSubType == TC_SUBTYPE_DIS_CAL) |
|
257 |
1 |
|| (packetSubType == TC_SUBTYPE_LOAD_K) || (packetSubType == TC_SUBTYPE_DUMP_K) |
|
258 |
|| (packetSubType == TC_SUBTYPE_LOAD_FBINS) |
||
259 |
|| (packetSubType == TC_SUBTYPE_LOAD_FILTER_PAR)) |
||
260 |
{ |
||
261 |
2 |
status = CCSDS_TM_VALID; |
|
262 |
} |
||
263 |
else |
||
264 |
{ |
||
265 |
status = ILL_SUBTYPE; |
||
266 |
} |
||
267 |
break; |
||
268 |
|||
269 |
case TC_TYPE_TIME: |
||
270 |
if (packetSubType == TC_SUBTYPE_UPDT_TIME) |
||
271 |
{ |
||
272 |
status = CCSDS_TM_VALID; |
||
273 |
} |
||
274 |
else |
||
275 |
{ |
||
276 |
status = ILL_SUBTYPE; |
||
277 |
} |
||
278 |
break; |
||
279 |
|||
280 |
default: |
||
281 |
status = ILL_SUBTYPE; |
||
282 |
break; |
||
283 |
} |
||
284 |
|||
285 |
2 |
return status; |
|
286 |
} |
||
287 |
|||
288 |
2 |
int tc_check_sid( unsigned char sid ) |
|
289 |
{ |
||
290 |
/** This function checks that the sid of a TeleCommand is valid. |
||
291 |
* |
||
292 |
* @param sid is the sid to check. |
||
293 |
* |
||
294 |
* @return Status code CCSDS_TM_VALID or CORRUPTED. |
||
295 |
* |
||
296 |
*/ |
||
297 |
|||
298 |
int status; |
||
299 |
|||
300 |
2 |
status = WRONG_SRC_ID; |
|
301 |
|||
302 |
✓✓✓✗ ✓✗✓✗ |
7 |
if ( (sid == SID_TC_MISSION_TIMELINE) || (sid == SID_TC_TC_SEQUENCES) || (sid == SID_TC_RECOVERY_ACTION_CMD) |
303 |
|| (sid == SID_TC_BACKUP_MISSION_TIMELINE) |
||
304 |
3 |
|| (sid == SID_TC_DIRECT_CMD) || (sid == SID_TC_SPARE_GRD_SRC1) || (sid == SID_TC_SPARE_GRD_SRC2) |
|
305 |
2 |
|| (sid == SID_TC_OBCP) || (sid == SID_TC_SYSTEM_CONTROL) || (sid == SID_TC_AOCS) |
|
306 |
1 |
|| (sid == SID_TC_RPW_INTERNAL)) |
|
307 |
{ |
||
308 |
2 |
status = CCSDS_TM_VALID; |
|
309 |
} |
||
310 |
else |
||
311 |
{ |
||
312 |
status = WRONG_SRC_ID; |
||
313 |
} |
||
314 |
|||
315 |
2 |
return status; |
|
316 |
} |
||
317 |
|||
318 |
2 |
int tc_check_length( unsigned char packetSubType, unsigned int length ) |
|
319 |
{ |
||
320 |
/** This function checks that the subtype and the length are compliant. |
||
321 |
* |
||
322 |
* @param packetSubType is the subtype to check. |
||
323 |
* @param length is the length to check. |
||
324 |
* |
||
325 |
* @return Status code CCSDS_TM_VALID or ILL_TYPE. |
||
326 |
* |
||
327 |
*/ |
||
328 |
|||
329 |
int status; |
||
330 |
|||
331 |
2 |
status = LFR_SUCCESSFUL; |
|
332 |
|||
333 |
✓✗✗✗ ✗✗✗✗ ✗✗✓✗ ✗✗✗✗ ✗ |
2 |
switch(packetSubType) |
334 |
{ |
||
335 |
case TC_SUBTYPE_RESET: |
||
336 |
✗✓ | 1 |
if (length!=(TC_LEN_RESET-CCSDS_TC_TM_PACKET_OFFSET)) { |
337 |
status = WRONG_LEN_PKT; |
||
338 |
} |
||
339 |
else { |
||
340 |
1 |
status = CCSDS_TM_VALID; |
|
341 |
} |
||
342 |
break; |
||
343 |
case TC_SUBTYPE_LOAD_COMM: |
||
344 |
if (length!=(TC_LEN_LOAD_COMM-CCSDS_TC_TM_PACKET_OFFSET)) { |
||
345 |
status = WRONG_LEN_PKT; |
||
346 |
} |
||
347 |
else { |
||
348 |
status = CCSDS_TM_VALID; |
||
349 |
} |
||
350 |
break; |
||
351 |
case TC_SUBTYPE_LOAD_NORM: |
||
352 |
if (length!=(TC_LEN_LOAD_NORM-CCSDS_TC_TM_PACKET_OFFSET)) { |
||
353 |
status = WRONG_LEN_PKT; |
||
354 |
} |
||
355 |
else { |
||
356 |
status = CCSDS_TM_VALID; |
||
357 |
} |
||
358 |
break; |
||
359 |
case TC_SUBTYPE_LOAD_BURST: |
||
360 |
if (length!=(TC_LEN_LOAD_BURST-CCSDS_TC_TM_PACKET_OFFSET)) { |
||
361 |
status = WRONG_LEN_PKT; |
||
362 |
} |
||
363 |
else { |
||
364 |
status = CCSDS_TM_VALID; |
||
365 |
} |
||
366 |
break; |
||
367 |
case TC_SUBTYPE_LOAD_SBM1: |
||
368 |
if (length!=(TC_LEN_LOAD_SBM1-CCSDS_TC_TM_PACKET_OFFSET)) { |
||
369 |
status = WRONG_LEN_PKT; |
||
370 |
} |
||
371 |
else { |
||
372 |
status = CCSDS_TM_VALID; |
||
373 |
} |
||
374 |
break; |
||
375 |
case TC_SUBTYPE_LOAD_SBM2: |
||
376 |
if (length!=(TC_LEN_LOAD_SBM2-CCSDS_TC_TM_PACKET_OFFSET)) { |
||
377 |
status = WRONG_LEN_PKT; |
||
378 |
} |
||
379 |
else { |
||
380 |
status = CCSDS_TM_VALID; |
||
381 |
} |
||
382 |
break; |
||
383 |
case TC_SUBTYPE_DUMP: |
||
384 |
if (length!=(TC_LEN_DUMP-CCSDS_TC_TM_PACKET_OFFSET)) { |
||
385 |
status = WRONG_LEN_PKT; |
||
386 |
} |
||
387 |
else { |
||
388 |
status = CCSDS_TM_VALID; |
||
389 |
} |
||
390 |
break; |
||
391 |
case TC_SUBTYPE_ENTER: |
||
392 |
if (length!=(TC_LEN_ENTER-CCSDS_TC_TM_PACKET_OFFSET)) { |
||
393 |
status = WRONG_LEN_PKT; |
||
394 |
} |
||
395 |
else { |
||
396 |
status = CCSDS_TM_VALID; |
||
397 |
} |
||
398 |
break; |
||
399 |
case TC_SUBTYPE_UPDT_INFO: |
||
400 |
if (length!=(TC_LEN_UPDT_INFO-CCSDS_TC_TM_PACKET_OFFSET)) { |
||
401 |
status = WRONG_LEN_PKT; |
||
402 |
} |
||
403 |
else { |
||
404 |
status = CCSDS_TM_VALID; |
||
405 |
} |
||
406 |
break; |
||
407 |
case TC_SUBTYPE_EN_CAL: |
||
408 |
if (length!=(TC_LEN_EN_CAL-CCSDS_TC_TM_PACKET_OFFSET)) { |
||
409 |
status = WRONG_LEN_PKT; |
||
410 |
} |
||
411 |
else { |
||
412 |
status = CCSDS_TM_VALID; |
||
413 |
} |
||
414 |
break; |
||
415 |
case TC_SUBTYPE_DIS_CAL: |
||
416 |
✓✗ | 1 |
if (length!=(TC_LEN_DIS_CAL-CCSDS_TC_TM_PACKET_OFFSET)) { |
417 |
1 |
status = WRONG_LEN_PKT; |
|
418 |
} |
||
419 |
else { |
||
420 |
status = CCSDS_TM_VALID; |
||
421 |
} |
||
422 |
break; |
||
423 |
case TC_SUBTYPE_LOAD_K: |
||
424 |
if (length!=(TC_LEN_LOAD_K-CCSDS_TC_TM_PACKET_OFFSET)) { |
||
425 |
status = WRONG_LEN_PKT; |
||
426 |
} |
||
427 |
else { |
||
428 |
status = CCSDS_TM_VALID; |
||
429 |
} |
||
430 |
break; |
||
431 |
case TC_SUBTYPE_DUMP_K: |
||
432 |
if (length!=(TC_LEN_DUMP_K-CCSDS_TC_TM_PACKET_OFFSET)) { |
||
433 |
status = WRONG_LEN_PKT; |
||
434 |
} |
||
435 |
else { |
||
436 |
status = CCSDS_TM_VALID; |
||
437 |
} |
||
438 |
break; |
||
439 |
case TC_SUBTYPE_LOAD_FBINS: |
||
440 |
if (length!=(TC_LEN_LOAD_FBINS-CCSDS_TC_TM_PACKET_OFFSET)) { |
||
441 |
status = WRONG_LEN_PKT; |
||
442 |
} |
||
443 |
else { |
||
444 |
status = CCSDS_TM_VALID; |
||
445 |
} |
||
446 |
break; |
||
447 |
case TC_SUBTYPE_LOAD_FILTER_PAR: |
||
448 |
if (length!=(TC_LEN_LOAD_FILTER_PAR-CCSDS_TC_TM_PACKET_OFFSET)) { |
||
449 |
status = WRONG_LEN_PKT; |
||
450 |
} |
||
451 |
else { |
||
452 |
status = CCSDS_TM_VALID; |
||
453 |
} |
||
454 |
break; |
||
455 |
case TC_SUBTYPE_UPDT_TIME: |
||
456 |
if (length!=(TC_LEN_UPDT_TIME-CCSDS_TC_TM_PACKET_OFFSET)) { |
||
457 |
status = WRONG_LEN_PKT; |
||
458 |
} |
||
459 |
else { |
||
460 |
status = CCSDS_TM_VALID; |
||
461 |
} |
||
462 |
break; |
||
463 |
default: // if the subtype is not a legal value, return ILL_SUBTYPE |
||
464 |
status = ILL_SUBTYPE; |
||
465 |
break ; |
||
466 |
} |
||
467 |
|||
468 |
2 |
return status; |
|
469 |
} |
||
470 |
|||
471 |
2 |
int tc_check_crc( ccsdsTelecommandPacket_t * TCPacket, unsigned int length, unsigned char *computed_CRC ) |
|
472 |
{ |
||
473 |
/** This function checks the CRC validity of the corresponding TeleCommand packet. |
||
474 |
* |
||
475 |
* @param TCPacket points to the TeleCommand packet to check. |
||
476 |
* @param length is the length of the TC packet. |
||
477 |
* |
||
478 |
* @return Status code CCSDS_TM_VALID or INCOR_CHECKSUM. |
||
479 |
* |
||
480 |
*/ |
||
481 |
|||
482 |
int status; |
||
483 |
unsigned char * CCSDSContent; |
||
484 |
|||
485 |
2 |
status = INCOR_CHECKSUM; |
|
486 |
|||
487 |
2 |
CCSDSContent = (unsigned char*) TCPacket->packetID; |
|
488 |
2 |
GetCRCAsTwoBytes(CCSDSContent, computed_CRC, length + CCSDS_TC_TM_PACKET_OFFSET - BYTES_PER_CRC); // 2 CRC bytes removed from the calculation of the CRC |
|
489 |
|||
490 |
✗✓ | 2 |
if (computed_CRC[0] != CCSDSContent[length + CCSDS_TC_TM_PACKET_OFFSET - BYTES_PER_CRC]) { |
491 |
status = INCOR_CHECKSUM; |
||
492 |
} |
||
493 |
✗✓ | 2 |
else if (computed_CRC[1] != CCSDSContent[length + CCSDS_TC_TM_PACKET_OFFSET -1]) { |
494 |
status = INCOR_CHECKSUM; |
||
495 |
} |
||
496 |
else { |
||
497 |
2 |
status = CCSDS_TM_VALID; |
|
498 |
} |
||
499 |
|||
500 |
2 |
return status; |
|
501 |
} |
||
502 |
|||
503 |
|||
504 |
Generated by: GCOVR (Version 4.1) |