GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/tm_lfr_tc_exe.c Lines: 74 239 31.0 %
Date: 2018-10-05 11:31:25 Branches: 2 15 13.3 %

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
25
/** Functions to send TM packets related to TC parsing and execution.
26
 *
27
 * @file
28
 * @author P. LEROY
29
 *
30
 * A group of functions to send appropriate TM packets after parsing and execution:
31
 * - TM_LFR_TC_EXE_SUCCESS
32
 * - TM_LFR_TC_EXE_INCONSISTENT
33
 * - TM_LFR_TC_EXE_NOT_EXECUTABLE
34
 * - TM_LFR_TC_EXE_NOT_IMPLEMENTED
35
 * - TM_LFR_TC_EXE_ERROR
36
 * - TM_LFR_TC_EXE_CORRUPTED
37
 *
38
 */
39
40
#include "tm_lfr_tc_exe.h"
41
42
61
int send_tm_lfr_tc_exe_success( ccsdsTelecommandPacket_t *TC, rtems_id queue_id )
43
{
44
    /** This function sends a TM_LFR_TC_EXE_SUCCESS packet in the dedicated RTEMS message queue.
45
     *
46
     * @param TC points to the TeleCommand packet that is being processed
47
     * @param queue_id is the id of the queue which handles TM
48
     *
49
     * @return RTEMS directive status code:
50
     * - RTEMS_SUCCESSFUL - message sent successfully
51
     * - RTEMS_INVALID_ID - invalid queue id
52
     * - RTEMS_INVALID_SIZE - invalid message size
53
     * - RTEMS_INVALID_ADDRESS - buffer is NULL
54
     * - RTEMS_UNSATISFIED - out of message buffers
55
     * - RTEMS_TOO_MANY - queue s limit has been reached
56
     *
57
     */
58
59
    rtems_status_code status;
60
    Packet_TM_LFR_TC_EXE_SUCCESS_t TM;
61
    unsigned char messageSize;
62
63
61
    TM.targetLogicalAddress = CCSDS_DESTINATION_ID;
64
61
    TM.protocolIdentifier = CCSDS_PROTOCOLE_ID;
65
61
    TM.reserved = DEFAULT_RESERVED;
66
61
    TM.userApplication = CCSDS_USER_APP;
67
    // PACKET HEADER
68
61
    TM.packetID[0] = (unsigned char) (APID_TM_TC_EXE >> SHIFT_1_BYTE);
69
61
    TM.packetID[1] = (unsigned char) (APID_TM_TC_EXE     );
70
61
    increment_seq_counter_destination_id( TM.packetSequenceControl, TC->sourceID );
71
61
    TM.packetLength[0] = (unsigned char) (PACKET_LENGTH_TC_EXE_SUCCESS >> SHIFT_1_BYTE);
72
61
    TM.packetLength[1] = (unsigned char) (PACKET_LENGTH_TC_EXE_SUCCESS     );
73
    // DATA FIELD HEADER
74
61
    TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
75
61
    TM.serviceType = TM_TYPE_TC_EXE;
76
61
    TM.serviceSubType = TM_SUBTYPE_EXE_OK;
77
61
    TM.destinationID = TC->sourceID;
78
61
    TM.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
79
61
    TM.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
80
61
    TM.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
81
61
    TM.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
82
61
    TM.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
83
61
    TM.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
84
    //
85
61
    TM.telecommand_pkt_id[0] = TC->packetID[0];
86
61
    TM.telecommand_pkt_id[1] = TC->packetID[1];
87
61
    TM.pkt_seq_control[0] = TC->packetSequenceControl[0];
88
61
    TM.pkt_seq_control[1] = TC->packetSequenceControl[1];
89
90
61
    messageSize = PACKET_LENGTH_TC_EXE_SUCCESS + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
91
92
    // SEND DATA
93
61
    status =  rtems_message_queue_send( queue_id, &TM, messageSize);
94
    if (status != RTEMS_SUCCESSFUL) {
95
        PRINTF("in send_tm_lfr_tc_exe_success *** ERR\n")
96
    }
97
98
    // UPDATE HK FIELDS
99
61
    update_last_TC_exe( TC, TM.time );
100
101
61
    return status;
102
}
103
104
int send_tm_lfr_tc_exe_inconsistent( ccsdsTelecommandPacket_t *TC, rtems_id queue_id,
105
                                    unsigned char byte_position, unsigned char rcv_value )
106
{
107
    /** This function sends a TM_LFR_TC_EXE_INCONSISTENT packet in the dedicated RTEMS message queue.
108
     *
109
     * @param TC points to the TeleCommand packet that is being processed
110
     * @param queue_id is the id of the queue which handles TM
111
     * @param byte_position is the byte position of the MSB of the parameter that has been seen as inconsistent
112
     * @param rcv_value  is the value of the LSB of the parameter that has been detected as inconsistent
113
     *
114
     * @return RTEMS directive status code:
115
     * - RTEMS_SUCCESSFUL - message sent successfully
116
     * - RTEMS_INVALID_ID - invalid queue id
117
     * - RTEMS_INVALID_SIZE - invalid message size
118
     * - RTEMS_INVALID_ADDRESS - buffer is NULL
119
     * - RTEMS_UNSATISFIED - out of message buffers
120
     * - RTEMS_TOO_MANY - queue s limit has been reached
121
     *
122
     */
123
124
    rtems_status_code status;
125
    Packet_TM_LFR_TC_EXE_INCONSISTENT_t TM;
126
    unsigned char messageSize;
127
128
    TM.targetLogicalAddress = CCSDS_DESTINATION_ID;
129
    TM.protocolIdentifier = CCSDS_PROTOCOLE_ID;
130
    TM.reserved = DEFAULT_RESERVED;
131
    TM.userApplication = CCSDS_USER_APP;
132
    // PACKET HEADER
133
    TM.packetID[0] = (unsigned char) (APID_TM_TC_EXE >> SHIFT_1_BYTE);
134
    TM.packetID[1] = (unsigned char) (APID_TM_TC_EXE     );
135
    increment_seq_counter_destination_id( TM.packetSequenceControl, TC->sourceID );
136
    TM.packetLength[0] = (unsigned char) (PACKET_LENGTH_TC_EXE_INCONSISTENT >> SHIFT_1_BYTE);
137
    TM.packetLength[1] = (unsigned char) (PACKET_LENGTH_TC_EXE_INCONSISTENT     );
138
    // DATA FIELD HEADER
139
    TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
140
    TM.serviceType = TM_TYPE_TC_EXE;
141
    TM.serviceSubType = TM_SUBTYPE_EXE_NOK;
142
    TM.destinationID = TC->sourceID;
143
    TM.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
144
    TM.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
145
    TM.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
146
    TM.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
147
    TM.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
148
    TM.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
149
    //
150
    TM.tc_failure_code[0] = (char) (WRONG_APP_DATA >> SHIFT_1_BYTE);
151
    TM.tc_failure_code[1] = (char) (WRONG_APP_DATA     );
152
    TM.telecommand_pkt_id[0] = TC->packetID[0];
153
    TM.telecommand_pkt_id[1] = TC->packetID[1];
154
    TM.pkt_seq_control[0] = TC->packetSequenceControl[0];
155
    TM.pkt_seq_control[1] = TC->packetSequenceControl[1];
156
    TM.tc_service = TC->serviceType;      // type of the rejected TC
157
    TM.tc_subtype = TC->serviceSubType;   // subtype of the rejected TC
158
    TM.byte_position = byte_position;
159
    TM.rcv_value = (unsigned char) rcv_value;
160
161
    messageSize = PACKET_LENGTH_TC_EXE_INCONSISTENT + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
162
163
    // SEND DATA
164
    status =  rtems_message_queue_send( queue_id, &TM, messageSize);
165
    if (status != RTEMS_SUCCESSFUL) {
166
        PRINTF("in send_tm_lfr_tc_exe_inconsistent *** ERR\n")
167
    }
168
169
    // UPDATE HK FIELDS
170
    update_last_TC_rej( TC, TM.time );
171
172
    return status;
173
}
174
175
2
int send_tm_lfr_tc_exe_not_executable( ccsdsTelecommandPacket_t *TC, rtems_id queue_id )
176
{
177
    /** This function sends a TM_LFR_TC_EXE_NOT_EXECUTABLE packet in the dedicated RTEMS message queue.
178
     *
179
     * @param TC points to the TeleCommand packet that is being processed
180
     * @param queue_id is the id of the queue which handles TM
181
     *
182
     * @return RTEMS directive status code:
183
     * - RTEMS_SUCCESSFUL - message sent successfully
184
     * - RTEMS_INVALID_ID - invalid queue id
185
     * - RTEMS_INVALID_SIZE - invalid message size
186
     * - RTEMS_INVALID_ADDRESS - buffer is NULL
187
     * - RTEMS_UNSATISFIED - out of message buffers
188
     * - RTEMS_TOO_MANY - queue s limit has been reached
189
     *
190
     */
191
192
    rtems_status_code status;
193
    Packet_TM_LFR_TC_EXE_NOT_EXECUTABLE_t TM;
194
    unsigned char messageSize;
195
196
2
    TM.targetLogicalAddress = CCSDS_DESTINATION_ID;
197
2
    TM.protocolIdentifier = CCSDS_PROTOCOLE_ID;
198
2
    TM.reserved = DEFAULT_RESERVED;
199
2
    TM.userApplication = CCSDS_USER_APP;
200
    // PACKET HEADER
201
2
    TM.packetID[0] = (unsigned char) (APID_TM_TC_EXE >> SHIFT_1_BYTE);
202
2
    TM.packetID[1] = (unsigned char) (APID_TM_TC_EXE     );
203
2
    increment_seq_counter_destination_id( TM.packetSequenceControl, TC->sourceID );
204
2
    TM.packetLength[0] = (unsigned char) (PACKET_LENGTH_TC_EXE_NOT_EXECUTABLE >> SHIFT_1_BYTE);
205
2
    TM.packetLength[1] = (unsigned char) (PACKET_LENGTH_TC_EXE_NOT_EXECUTABLE     );
206
    // DATA FIELD HEADER
207
2
    TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
208
2
    TM.serviceType = TM_TYPE_TC_EXE;
209
2
    TM.serviceSubType = TM_SUBTYPE_EXE_NOK;
210
2
    TM.destinationID = TC->sourceID;    // default destination id
211
2
    TM.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
212
2
    TM.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
213
2
    TM.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
214
2
    TM.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
215
2
    TM.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
216
2
    TM.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
217
    //
218
2
    TM.tc_failure_code[0] = (char) (TC_NOT_EXE >> SHIFT_1_BYTE);
219
2
    TM.tc_failure_code[1] = (char) (TC_NOT_EXE     );
220
2
    TM.telecommand_pkt_id[0] = TC->packetID[0];
221
2
    TM.telecommand_pkt_id[1] = TC->packetID[1];
222
2
    TM.pkt_seq_control[0] = TC->packetSequenceControl[0];
223
2
    TM.pkt_seq_control[1] = TC->packetSequenceControl[1];
224
2
    TM.tc_service = TC->serviceType;      // type of the rejected TC
225
2
    TM.tc_subtype = TC->serviceSubType;   // subtype of the rejected TC
226
2
    TM.lfr_status_word[0] = housekeeping_packet.lfr_status_word[0];
227
2
    TM.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1];
228
229
2
    messageSize = PACKET_LENGTH_TC_EXE_NOT_EXECUTABLE + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
230
231
    // SEND DATA
232
2
    status =  rtems_message_queue_send( queue_id, &TM, messageSize);
233
    if (status != RTEMS_SUCCESSFUL) {
234
        PRINTF("in send_tm_lfr_tc_exe_not_executable *** ERR\n")
235
    }
236
237
    // UPDATE HK FIELDS
238
2
    update_last_TC_rej( TC, TM.time );
239
240
2
    return status;
241
}
242
243
int send_tm_lfr_tc_exe_not_implemented( ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time )
244
{
245
    /** This function sends a TM_LFR_TC_EXE_NOT_IMPLEMENTED packet in the dedicated RTEMS message queue.
246
     *
247
     * @param TC points to the TeleCommand packet that is being processed
248
     * @param queue_id is the id of the queue which handles TM
249
     *
250
     * @return RTEMS directive status code:
251
     * - RTEMS_SUCCESSFUL - message sent successfully
252
     * - RTEMS_INVALID_ID - invalid queue id
253
     * - RTEMS_INVALID_SIZE - invalid message size
254
     * - RTEMS_INVALID_ADDRESS - buffer is NULL
255
     * - RTEMS_UNSATISFIED - out of message buffers
256
     * - RTEMS_TOO_MANY - queue s limit has been reached
257
     *
258
     */
259
260
    rtems_status_code status;
261
    Packet_TM_LFR_TC_EXE_NOT_IMPLEMENTED_t TM;
262
    unsigned char messageSize;
263
264
    TM.targetLogicalAddress = CCSDS_DESTINATION_ID;
265
    TM.protocolIdentifier = CCSDS_PROTOCOLE_ID;
266
    TM.reserved = DEFAULT_RESERVED;
267
    TM.userApplication = CCSDS_USER_APP;
268
    // PACKET HEADER
269
    TM.packetID[0] = (unsigned char) (APID_TM_TC_EXE >> SHIFT_1_BYTE);
270
    TM.packetID[1] = (unsigned char) (APID_TM_TC_EXE     );
271
    increment_seq_counter_destination_id( TM.packetSequenceControl, TC->sourceID );
272
    TM.packetLength[0] = (unsigned char) (PACKET_LENGTH_TC_EXE_NOT_IMPLEMENTED >> SHIFT_1_BYTE);
273
    TM.packetLength[1] = (unsigned char) (PACKET_LENGTH_TC_EXE_NOT_IMPLEMENTED     );
274
    // DATA FIELD HEADER
275
    TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
276
    TM.serviceType = TM_TYPE_TC_EXE;
277
    TM.serviceSubType = TM_SUBTYPE_EXE_NOK;
278
    TM.destinationID = TC->sourceID;    // default destination id
279
    TM.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
280
    TM.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
281
    TM.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
282
    TM.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
283
    TM.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
284
    TM.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
285
    //
286
    TM.tc_failure_code[0] = (char) (FUNCT_NOT_IMPL >> SHIFT_1_BYTE);
287
    TM.tc_failure_code[1] = (char) (FUNCT_NOT_IMPL     );
288
    TM.telecommand_pkt_id[0] = TC->packetID[0];
289
    TM.telecommand_pkt_id[1] = TC->packetID[1];
290
    TM.pkt_seq_control[0] = TC->packetSequenceControl[0];
291
    TM.pkt_seq_control[1] = TC->packetSequenceControl[1];
292
    TM.tc_service = TC->serviceType;      // type of the rejected TC
293
    TM.tc_subtype = TC->serviceSubType;   // subtype of the rejected TC
294
295
    messageSize = PACKET_LENGTH_TC_EXE_NOT_IMPLEMENTED + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
296
297
    // SEND DATA
298
    status =  rtems_message_queue_send( queue_id, &TM, messageSize);
299
    if (status != RTEMS_SUCCESSFUL) {
300
        PRINTF("in send_tm_lfr_tc_exe_not_implemented *** ERR\n")
301
    }
302
303
    // UPDATE HK FIELDS
304
    update_last_TC_rej( TC, TM.time );
305
306
    return status;
307
}
308
309
int send_tm_lfr_tc_exe_error( ccsdsTelecommandPacket_t *TC, rtems_id queue_id )
310
{
311
    /** This function sends a TM_LFR_TC_EXE_ERROR packet in the dedicated RTEMS message queue.
312
     *
313
     * @param TC points to the TeleCommand packet that is being processed
314
     * @param queue_id is the id of the queue which handles TM
315
     *
316
     * @return RTEMS directive status code:
317
     * - RTEMS_SUCCESSFUL - message sent successfully
318
     * - RTEMS_INVALID_ID - invalid queue id
319
     * - RTEMS_INVALID_SIZE - invalid message size
320
     * - RTEMS_INVALID_ADDRESS - buffer is NULL
321
     * - RTEMS_UNSATISFIED - out of message buffers
322
     * - RTEMS_TOO_MANY - queue s limit has been reached
323
     *
324
     */
325
326
    rtems_status_code status;
327
    Packet_TM_LFR_TC_EXE_ERROR_t TM;
328
    unsigned char messageSize;
329
330
    TM.targetLogicalAddress = CCSDS_DESTINATION_ID;
331
    TM.protocolIdentifier = CCSDS_PROTOCOLE_ID;
332
    TM.reserved = DEFAULT_RESERVED;
333
    TM.userApplication = CCSDS_USER_APP;
334
    // PACKET HEADER
335
    TM.packetID[0] = (unsigned char) (APID_TM_TC_EXE >> SHIFT_1_BYTE);
336
    TM.packetID[1] = (unsigned char) (APID_TM_TC_EXE     );
337
    increment_seq_counter_destination_id( TM.packetSequenceControl, TC->sourceID );
338
    TM.packetLength[0] = (unsigned char) (PACKET_LENGTH_TC_EXE_ERROR >> SHIFT_1_BYTE);
339
    TM.packetLength[1] = (unsigned char) (PACKET_LENGTH_TC_EXE_ERROR     );
340
    // DATA FIELD HEADER
341
    TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
342
    TM.serviceType = TM_TYPE_TC_EXE;
343
    TM.serviceSubType = TM_SUBTYPE_EXE_NOK;
344
    TM.destinationID = TC->sourceID;    // default destination id
345
    TM.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
346
    TM.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
347
    TM.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
348
    TM.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
349
    TM.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
350
    TM.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
351
    //
352
    TM.tc_failure_code[0] = (char) (FAIL_DETECTED >> SHIFT_1_BYTE);
353
    TM.tc_failure_code[1] = (char) (FAIL_DETECTED     );
354
    TM.telecommand_pkt_id[0] = TC->packetID[0];
355
    TM.telecommand_pkt_id[1] = TC->packetID[1];
356
    TM.pkt_seq_control[0] = TC->packetSequenceControl[0];
357
    TM.pkt_seq_control[1] = TC->packetSequenceControl[1];
358
    TM.tc_service = TC->serviceType;      // type of the rejected TC
359
    TM.tc_subtype = TC->serviceSubType;   // subtype of the rejected TC
360
361
    messageSize = PACKET_LENGTH_TC_EXE_ERROR + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
362
363
    // SEND DATA
364
    status =  rtems_message_queue_send( queue_id, &TM, messageSize);
365
    if (status != RTEMS_SUCCESSFUL) {
366
        PRINTF("in send_tm_lfr_tc_exe_error *** ERR\n")
367
    }
368
369
    // UPDATE HK FIELDS
370
    update_last_TC_rej( TC, TM.time );
371
372
    return status;
373
}
374
375
int send_tm_lfr_tc_exe_corrupted(ccsdsTelecommandPacket_t *TC, rtems_id queue_id,
376
                                 unsigned char *computed_CRC, unsigned char *currentTC_LEN_RCV,
377
                                 unsigned char destinationID )
378
{
379
    /** This function sends a TM_LFR_TC_EXE_CORRUPTED packet in the dedicated RTEMS message queue.
380
     *
381
     * @param TC points to the TeleCommand packet that is being processed
382
     * @param queue_id is the id of the queue which handles TM
383
     * @param computed_CRC points to a buffer of two bytes containing the CRC computed during the parsing of the TeleCommand
384
     * @param currentTC_LEN_RCV points to a buffer of two bytes containing a packet size field computed on the received data
385
     *
386
     * @return RTEMS directive status code:
387
     * - RTEMS_SUCCESSFUL - message sent successfully
388
     * - RTEMS_INVALID_ID - invalid queue id
389
     * - RTEMS_INVALID_SIZE - invalid message size
390
     * - RTEMS_INVALID_ADDRESS - buffer is NULL
391
     * - RTEMS_UNSATISFIED - out of message buffers
392
     * - RTEMS_TOO_MANY - queue s limit has been reached
393
     *
394
     */
395
396
    rtems_status_code status;
397
    Packet_TM_LFR_TC_EXE_CORRUPTED_t TM;
398
    unsigned char messageSize;
399
    unsigned int packetLength;
400
    unsigned int estimatedPacketLength;
401
    unsigned char *packetDataField;
402
403
    packetLength = (TC->packetLength[0] * CONST_256) + TC->packetLength[1];   // compute the packet length parameter written in the TC
404
    estimatedPacketLength = (unsigned int) ((currentTC_LEN_RCV[0] * CONST_256) + currentTC_LEN_RCV[1]);
405
    packetDataField = (unsigned char *) &TC->headerFlag_pusVersion_Ack; // get the beginning of the data field
406
407
    TM.targetLogicalAddress = CCSDS_DESTINATION_ID;
408
    TM.protocolIdentifier = CCSDS_PROTOCOLE_ID;
409
    TM.reserved = DEFAULT_RESERVED;
410
    TM.userApplication = CCSDS_USER_APP;
411
    // PACKET HEADER
412
    TM.packetID[0] = (unsigned char) (APID_TM_TC_EXE >> SHIFT_1_BYTE);
413
    TM.packetID[1] = (unsigned char) (APID_TM_TC_EXE     );
414
    increment_seq_counter_destination_id( TM.packetSequenceControl, TC->sourceID );
415
    TM.packetLength[0] = (unsigned char) (PACKET_LENGTH_TC_EXE_CORRUPTED >> SHIFT_1_BYTE);
416
    TM.packetLength[1] = (unsigned char) (PACKET_LENGTH_TC_EXE_CORRUPTED     );
417
    // DATA FIELD HEADER
418
    TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
419
    TM.serviceType = TM_TYPE_TC_EXE;
420
    TM.serviceSubType = TM_SUBTYPE_EXE_NOK;
421
    TM.destinationID = destinationID;
422
    TM.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
423
    TM.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
424
    TM.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
425
    TM.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
426
    TM.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
427
    TM.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
428
    //
429
    TM.tc_failure_code[0] = (unsigned char) (CORRUPTED >> SHIFT_1_BYTE);
430
    TM.tc_failure_code[1] = (unsigned char) (CORRUPTED     );
431
    TM.telecommand_pkt_id[0] = TC->packetID[0];
432
    TM.telecommand_pkt_id[1] = TC->packetID[1];
433
    TM.pkt_seq_control[0] = TC->packetSequenceControl[0];
434
    TM.pkt_seq_control[1] = TC->packetSequenceControl[1];
435
    TM.tc_service = TC->serviceType;      // type of the rejected TC
436
    TM.tc_subtype = TC->serviceSubType;   // subtype of the rejected TC
437
    TM.pkt_len_rcv_value[0] = TC->packetLength[0];
438
    TM.pkt_len_rcv_value[1] = TC->packetLength[1];
439
    TM.pkt_datafieldsize_cnt[0] = currentTC_LEN_RCV[0];
440
    TM.pkt_datafieldsize_cnt[1] = currentTC_LEN_RCV[1];
441
    TM.rcv_crc[0] = packetDataField[ estimatedPacketLength - 1 ];
442
    TM.rcv_crc[1] = packetDataField[ estimatedPacketLength     ];
443
    TM.computed_crc[0] = computed_CRC[0];
444
    TM.computed_crc[1] = computed_CRC[1];
445
446
    messageSize = PACKET_LENGTH_TC_EXE_CORRUPTED + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
447
448
    // SEND DATA
449
    status =  rtems_message_queue_send( queue_id, &TM, messageSize);
450
    if (status != RTEMS_SUCCESSFUL) {
451
        PRINTF("in send_tm_lfr_tc_exe_error *** ERR\n")
452
    }
453
454
    // UPDATE HK FIELDS
455
    update_last_TC_rej( TC, TM.time );
456
457
    return status;
458
}
459
460
63
void increment_seq_counter_destination_id( unsigned char *packet_sequence_control, unsigned char destination_id )
461
{
462
    /** This function increment the packet sequence control parameter of a TC, depending on its destination ID.
463
     *
464
     * @param packet_sequence_control points to the packet sequence control which will be incremented
465
     * @param destination_id is the destination ID of the TM, there is one counter by destination ID
466
     *
467
     * If the destination ID is not known, a dedicated counter is incremented.
468
     *
469
     */
470
471
    unsigned short sequence_cnt;
472
    unsigned short segmentation_grouping_flag;
473
    unsigned short new_packet_sequence_control;
474
    unsigned char i;
475
476



63
    switch (destination_id)
477
    {
478
    case SID_TC_GROUND:
479
        i = GROUND;
480
        break;
481
    case SID_TC_MISSION_TIMELINE:
482
63
        i = MISSION_TIMELINE;
483
63
        break;
484
    case SID_TC_TC_SEQUENCES:
485
        i = TC_SEQUENCES;
486
        break;
487
    case SID_TC_RECOVERY_ACTION_CMD:
488
        i = RECOVERY_ACTION_CMD;
489
        break;
490
    case SID_TC_BACKUP_MISSION_TIMELINE:
491
        i = BACKUP_MISSION_TIMELINE;
492
        break;
493
    case SID_TC_DIRECT_CMD:
494
        i = DIRECT_CMD;
495
        break;
496
    case SID_TC_SPARE_GRD_SRC1:
497
        i = SPARE_GRD_SRC1;
498
        break;
499
    case SID_TC_SPARE_GRD_SRC2:
500
        i = SPARE_GRD_SRC2;
501
        break;
502
    case SID_TC_OBCP:
503
        i = OBCP;
504
        break;
505
    case SID_TC_SYSTEM_CONTROL:
506
        i = SYSTEM_CONTROL;
507
        break;
508
    case SID_TC_AOCS:
509
        i = AOCS;
510
        break;
511
    case SID_TC_RPW_INTERNAL:
512
        i = RPW_INTERNAL;
513
        break;
514
    default:
515
        i = GROUND;
516
        break;
517
    }
518
519
63
    segmentation_grouping_flag  = TM_PACKET_SEQ_CTRL_STANDALONE << SHIFT_1_BYTE;
520
63
    sequence_cnt                = sequenceCounters_TC_EXE[ i ] & SEQ_CNT_MASK;
521
522
63
    new_packet_sequence_control = segmentation_grouping_flag | sequence_cnt ;
523
524
63
    packet_sequence_control[0] = (unsigned char) (new_packet_sequence_control >> SHIFT_1_BYTE);
525
63
    packet_sequence_control[1] = (unsigned char) (new_packet_sequence_control     );
526
527
    // increment the sequence counter
528
63
    if ( sequenceCounters_TC_EXE[ i ] < SEQ_CNT_MAX )
529
    {
530
63
        sequenceCounters_TC_EXE[ i ] = sequenceCounters_TC_EXE[ i ] + 1;
531
    }
532
    else
533
    {
534
        sequenceCounters_TC_EXE[ i ] = 0;
535
    }
536
63
}