1 |
#ident "$Header: /home/cvsuser/cvsroot/IRIS/proj/lev0/apps/decode_hk_vcdu.c,v 1.2 2012/05/29 19:04:40 jim Exp $" |
2 |
/***************************************************************************** |
3 |
* Filename: decode_hk_vcdu.c * |
4 |
* Author: Carl * |
5 |
* Create Date: February, 2, 2008 * |
6 |
* Description: This file contains modules to process housekeeping packets * |
7 |
* from high speed bus. * |
8 |
* (C) Stanford University, 2008 * |
9 |
****************************************************************************/ |
10 |
#include <stdio.h> |
11 |
#include "decode_hk.h" |
12 |
#include "packets.h" |
13 |
#include "decode_hk_vcdu.h" |
14 |
#include "save_packet_to_dayfile.h" |
15 |
#include <sys/time.h> |
16 |
#include <time.h> |
17 |
#include "timeio.h" |
18 |
#include <dirent.h> |
19 |
#include "printk.h" |
20 |
|
21 |
/*********** static function prototypes **************/ |
22 |
static unsigned short *decode_im_pdu(unsigned short *w, IM_PDU_Packet_t *p); |
23 |
static unsigned short *decode_ccsds(unsigned short *w, CCSDS_Packet_t *p); |
24 |
|
25 |
/************* function prototypes ******************/ |
26 |
int lookup_fsn(CCSDS_Packet_t **ptr, unsigned int *Fsn); |
27 |
int save_packet_to_dayfile(unsigned short *word_ptr, int apid, HK_Dayfile_Data_t **df_head); |
28 |
int write_packet_to_dayfile(HK_Dayfile_Data_t **df_head); |
29 |
int filter_out_non_isps(CCSDS_Packet_t **ptr); |
30 |
int write_hk_to_drms(DRMS_Record_t *record, CCSDS_Packet_t **ccsds_pkt); |
31 |
int get_status( int lz_status[100], int status_count); |
32 |
|
33 |
/*********** extern function prototypes **************/ |
34 |
extern int free_dayfile_data( HK_Dayfile_Data_t **df_head); |
35 |
extern int free_dayfile_pkt_data( HK_Dayfile_Data_t **df_head); |
36 |
|
37 |
/********** High level hk telemetry routines **************/ |
38 |
|
39 |
/* Receive the next VCDU in the telemetry stream. The following |
40 |
action is taken depending on the contents of the VCDU. |
41 |
|
42 |
A) If the vcdu contains a single science data packet |
43 |
it skipped |
44 |
|
45 |
B) If the vcdu contains one or more housekeeping packets each |
46 |
one is APID value checked and based on APID the following |
47 |
three cases of processing is carried out |
48 |
|
49 |
a) decode hk keyword in structure and pass back structure |
50 |
|
51 |
b) skip decode of hk kywords and pass back null hk structure |
52 |
and save packet to dayfile (i.e., OBT and Sequencer packets) |
53 |
|
54 |
c) decode hk keyword in structure and pass back structure and |
55 |
also save packet to dayfile(i.e., ISP, etc) |
56 |
|
57 |
d) skip decode of hk keywords and skip save of packet to dayfile |
58 |
for APID not requiring processing. |
59 |
|
60 |
Overall Status value: |
61 |
|
62 |
0: HK_SUCCESS_HK_ALL: All hk packets where decoded successfully |
63 |
or saved to dayfiles successfully with no |
64 |
errors. Successfully skipped processing of |
65 |
hk packets that are not on list to be |
66 |
processed. Successfully skipped if found |
67 |
Image Packets. When this occurs a CCSDS |
68 |
link list is probably returned. So probably |
69 |
need to check structure and if available |
70 |
write HK Structure (within CCSDS structure) |
71 |
of keyword names and values to DRMS. |
72 |
|
73 |
1: HK_SUCCESS_HK_SOME: Some errors found when doing HK Processing |
74 |
but did successfully decode and return a |
75 |
structure or successfully saved dayfiles. |
76 |
When this occurs a CCSDS link list is |
77 |
probably returned. So probably need to check |
78 |
structure and if available write HK Structure |
79 |
(within CCSDS structure) of keyword names and |
80 |
values to DRMS. |
81 |
|
82 |
4: SUCCESS_SKIP_IMAGE: Detected Image and successfully skipped processing. |
83 |
|
84 |
5: SUCCESS_SKIP_PROCESSING_APID: Detected ALL APIDS in VCDU that are not |
85 |
normally processed. Successfully skipped |
86 |
processing and returned this value. |
87 |
|
88 |
< 0: See Macro definitions: All errors found when doing HK Processing for |
89 |
a single VCDU. The last error code occurrance |
90 |
is returned, since cannot return all error |
91 |
codes for every hk packet in VCDU. Consult |
92 |
log file for full display of all errors that |
93 |
occurred. Consult decode_hk_vcdu.h for macro |
94 |
definitions of negative error codes. The |
95 |
returned CCSDS structure has no items to |
96 |
write to DRMS when this occurs. |
97 |
|
98 |
Returned Values to Level 0 Top Module: See .h file |
99 |
*/ |
100 |
|
101 |
/************************* decode next hk vcdu ****************************/ |
102 |
int decode_next_hk_vcdu(unsigned short vcdu[PACKETWORDS], CCSDS_Packet_t **hk_packets, unsigned int *Fsn) |
103 |
{ |
104 |
/* declarations */ |
105 |
CCSDS_Packet_t ccsds, *p, *p_hk; |
106 |
IM_PDU_Packet_t im_pdu; |
107 |
int spfd; |
108 |
int i, j, k; |
109 |
unsigned char *p1,*p2; |
110 |
static unsigned short buffer[PACKETWORDS]; |
111 |
unsigned short *w, *hkstart; |
112 |
int lz_status[100]; |
113 |
int hk_status = ERROR_NODATA; |
114 |
int wdf_status; |
115 |
int wd_status; |
116 |
int foni_status; |
117 |
int decode_status; |
118 |
int lev0_status; |
119 |
int fsn_status=1; |
120 |
DRMS_Record_t *record=NULL; |
121 |
static short writeFlag= HK_INIT_WRITE_FLAG; |
122 |
static HK_Dayfile_Data_t *dfd=NULL; |
123 |
|
124 |
/* init variables */ |
125 |
j=0; |
126 |
lev0_status=ERROR_NODATA; /* -13 */ |
127 |
|
128 |
/* init lz_status array */ |
129 |
for (k=0;k<100;k++) lz_status[k]=99; |
130 |
|
131 |
/****** |
132 |
Copy the raw telem data to a buffer. The incoming telemetry stream is in |
133 |
big endian format. Swap the byte order if we are doing the processing on |
134 |
a little endian machine. |
135 |
******/ |
136 |
#if __BYTE_ORDER == __LITTLE_ENDIAN |
137 |
p1 = (unsigned char *)vcdu; |
138 |
p2 = (unsigned char *)buffer; |
139 |
for (i=0; i<PACKETWORDS; i++) |
140 |
{ |
141 |
*(p2+1) = *p1; |
142 |
*p2 = *(p1+1); |
143 |
p1 += 2; |
144 |
p2 += 2; |
145 |
} |
146 |
#else |
147 |
memcpy(buffer, vcdu, PACKETBYTES); |
148 |
#endif |
149 |
|
150 |
/* Decode IM_PDU headers. */ |
151 |
w = decode_im_pdu(buffer, &im_pdu); |
152 |
|
153 |
/* Loop over all CCSDS packet in the packet zone. */ |
154 |
*hk_packets = p_hk = NULL; |
155 |
do |
156 |
{ |
157 |
/* Decode the CCSDS header. */ |
158 |
hkstart = vcdu + (w-buffer); |
159 |
w = decode_ccsds(w, &ccsds); |
160 |
|
161 |
#ifdef DEBUG_DECODE_HK_VCDU |
162 |
printkerr("DEBUG Message at %s, line %d: Looping thru vcdu for packet." |
163 |
"\n",__FILE__, __LINE__, ccsds.apid); |
164 |
#else |
165 |
#endif |
166 |
|
167 |
/* Branch depending on the APID. */ |
168 |
switch(ccsds.apid) |
169 |
{ |
170 |
/*************************************/ |
171 |
/*** Case of Finding End of VCDU ***/ |
172 |
/*************************************/ |
173 |
case 0: |
174 |
/* We have reached the end of the VCDU */ |
175 |
if (hk_status != ERROR_NODATA) |
176 |
{ |
177 |
hk_status=HK_SUCCESS_REACHED_END_VCDU; |
178 |
} |
179 |
lz_status[j++] = hk_status; |
180 |
break; |
181 |
|
182 |
/******************************************/ |
183 |
/*** Case of Finding Image Packet-skip ***/ |
184 |
/******************************************/ |
185 |
case APID_IRIS_SCIENCE: |
186 |
case APID_HMI_SCIENCE_1: |
187 |
case APID_HMI_SCIENCE_2: |
188 |
case APID_AIA_SCIENCE_1: |
189 |
case APID_AIA_SCIENCE_2: |
190 |
hk_status=HK_SUCCESS_SKIP_IMAGE; |
191 |
lz_status[j++] = hk_status; |
192 |
break; |
193 |
|
194 |
/*********************************************/ |
195 |
/*** Case of Finding HK Time packet-skip ***/ |
196 |
/********************************************/ |
197 |
case APID_IRIS_TIME: |
198 |
case APID_HMI_TIME_1: |
199 |
case APID_HMI_TIME_2: |
200 |
case APID_AIA_TIME_1: |
201 |
case APID_AIA_TIME_2: |
202 |
/* This is an empty timestamp packet. Do nothing. */ |
203 |
hk_status=HK_SUCCESS_HKTIME; |
204 |
lz_status[j++] = hk_status; |
205 |
break; |
206 |
|
207 |
/***********************************************************************/ |
208 |
/*** Case of Decoding to CCSDS_Packet_t struct and Writing Day File ***/ |
209 |
/***********************************************************************/ |
210 |
case APID_HMI_IMSTAT_1: |
211 |
case APID_HMI_IMSTAT_2: |
212 |
case APID_AIA_IMSTAT_1: |
213 |
case APID_AIA_IMSTAT_2: |
214 |
case APID_HMI_SEQ_1: |
215 |
case APID_HMI_SEQ_2: |
216 |
case APID_AIA_SEQ_1: |
217 |
case APID_AIA_SEQ_2: |
218 |
case APID_IRIS_ISP: |
219 |
|
220 |
#ifdef DEBUG_DECODE_HK_VCDU |
221 |
printkerr("DEBUG Message at %s, line %d: Processing hk packet for apid <%d>." |
222 |
"\n",__FILE__, __LINE__, ccsds.apid); |
223 |
#else |
224 |
#endif |
225 |
/* This is an image status, or maybe sequencer or maybe obt packet. */ |
226 |
decode_status = decode_hk_keywords(hkstart, ccsds.apid, &ccsds.keywords); |
227 |
|
228 |
/* set status based on decode status */ |
229 |
if (decode_status != 0) |
230 |
{ |
231 |
/* if did have error or warning use value in decode_status*/ |
232 |
hk_status=decode_status; |
233 |
} |
234 |
else |
235 |
{ |
236 |
/* if passed then map to success values */ |
237 |
hk_status=HK_SUCCESS_DECODING; |
238 |
} |
239 |
lz_status[j++] = hk_status; |
240 |
|
241 |
/* create ccsds note and add HK_Keyword_t structure to CCSDS node */ |
242 |
if (hk_status==HK_SUCCESS_DECODING) |
243 |
{ |
244 |
/* Allocate a CCSDS packet. */ |
245 |
p = malloc(sizeof(CCSDS_Packet_t)); |
246 |
if(!p) |
247 |
{ |
248 |
printkerr("ERROR at %s, line %d: Cannot malloc space!\n",__FILE__, __LINE__); |
249 |
} |
250 |
|
251 |
memcpy(p, &ccsds, sizeof(CCSDS_Packet_t)); |
252 |
|
253 |
/* Append to output list. */ |
254 |
if (*hk_packets == NULL) |
255 |
{ |
256 |
*hk_packets = p_hk = p; |
257 |
} |
258 |
else |
259 |
{ |
260 |
p_hk->next = p; |
261 |
p_hk = p_hk->next; |
262 |
} |
263 |
p_hk->next = NULL; |
264 |
} |
265 |
/* write packet to dayfile */ |
266 |
spfd = save_packet_to_dayfile(hkstart ,ccsds.apid, &dfd) ; |
267 |
hk_status=spfd; |
268 |
if (hk_status == ERROR_HK_ENVIRONMENT_VARS_NOT_SET) |
269 |
{ |
270 |
/* never got a chance to save packets */ |
271 |
lev0_status= ERROR_HK_ENVIRONMENT_VARS_NOT_SET; |
272 |
lz_status[j++] = hk_status; |
273 |
return (lev0_status); |
274 |
} |
275 |
|
276 |
// take out if SOME means only decoded some and |
277 |
// does not mean decoded and wrote-dayfile some |
278 |
lz_status[j++] = hk_status; |
279 |
break; |
280 |
/*************************************/ |
281 |
/*** Case of Writing Day File Only ***/ |
282 |
/*************************************/ |
283 |
case APID_HMI_OBT_1: |
284 |
case APID_HMI_OBT_2: |
285 |
case APID_AIA_OBT_1: |
286 |
case APID_AIA_OBT_2: |
287 |
if (hk_status == HK_SUCCESS_HKTIME || |
288 |
hk_status == HK_SUCCESS_DECODING || |
289 |
hk_status == HK_SUCCESS_WRITE_DAYFILE) |
290 |
{ |
291 |
|
292 |
/* write packet to dayfile */ |
293 |
spfd = save_packet_to_dayfile(hkstart ,ccsds.apid, &dfd) ; |
294 |
hk_status=spfd; |
295 |
if (hk_status == ERROR_HK_ENVIRONMENT_VARS_NOT_SET) |
296 |
{ |
297 |
/* never got a chance to save packets */ |
298 |
lev0_status= ERROR_HK_ENVIRONMENT_VARS_NOT_SET; |
299 |
lz_status[j++] = hk_status; |
300 |
return (lev0_status); |
301 |
} |
302 |
} |
303 |
|
304 |
// take out if SOME means only decoded some and |
305 |
// does not mean decoded and wrote-dayfile some |
306 |
lz_status[j++] = hk_status; |
307 |
break; |
308 |
|
309 |
/*********************************/ |
310 |
/*** All Other Non-Valid cases ***/ |
311 |
/*********************************/ |
312 |
default: |
313 |
/* This is not known HK PACKET to process */ |
314 |
hk_status=HK_SUCCESS_SKIP_PROCESSING_APID; |
315 |
lz_status[j++] = hk_status; |
316 |
break; |
317 |
}// switch |
318 |
#ifdef DEBUG_DECODE_HK_VCDU |
319 |
printkerr("DEBUG Message at %s, line %d: Processing packet for apid <%d>." |
320 |
"\n",__FILE__, __LINE__, ccsds.apid); |
321 |
#else |
322 |
#endif |
323 |
w += ccsds.length/2; |
324 |
} while ( ccsds.apid>0 && (int)(w-buffer) < PACKETWORDS); |
325 |
|
326 |
|
327 |
#ifdef DEBUG_DECODE_HK_VCDU |
328 |
/* check level 0 processing status */ |
329 |
/* O = Processing HK TIME packet */ |
330 |
/* 1 = Processing HK Decoding */ |
331 |
/* 2 = Processing Saving of packet to dayfile */ |
332 |
/* 3 = Processing end of VCDU */ |
333 |
printkerr("DEBUG Message at %s, line %d: Level O by APID processing type" |
334 |
" number when processing packets for above apids", __FILE__, __LINE__); |
335 |
for (i=0; i < j ;i++) |
336 |
{ |
337 |
printkerr(":%d:",lz_status[i]); |
338 |
} |
339 |
printkerr("\n"); |
340 |
#else |
341 |
#endif |
342 |
|
343 |
/* finished VCDU, now write saved dayfile packets to filesystem |
344 |
and free dayfile structure. Currentily write out dayfile after each VCDU. |
345 |
Also keeps using initial packet times filename to write packets too.*/ |
346 |
if(dfd && hk_status != HK_SUCCESS_SKIP_IMAGE ) |
347 |
{ |
348 |
if (writeFlag == HK_WRITE_AFTER_VCDU_COUNT) |
349 |
{ |
350 |
wdf_status = write_packet_to_dayfile( &dfd); |
351 |
if (HK_SUCCESS_WRITE_DAYFILE != wdf_status ) |
352 |
{ |
353 |
printkerr("ERROR at %s, line %d: Return status failed for " |
354 |
"write_packet_to_dayfile. Probably can't open dayfile.\n", |
355 |
__FILE__, __LINE__); |
356 |
return (ERROR_HK_FAILED_OPEN_DAYFILE); |
357 |
} |
358 |
wdf_status=free_dayfile_pkt_data( &dfd); |
359 |
if (HK_SUCCESS_WRITE_DAYFILE != wdf_status) |
360 |
{ |
361 |
printkerr("Warning at %s, line %d: Return status failed for " |
362 |
"free_dayfile_pkt_data\n", __FILE__, __LINE__); |
363 |
} |
364 |
writeFlag= HK_INIT_WRITE_FLAG; |
365 |
} |
366 |
else writeFlag++; |
367 |
} |
368 |
if(*hk_packets && hk_status != HK_SUCCESS_SKIP_IMAGE) |
369 |
{ |
370 |
//printk("Call write_hk_to_drms() in decode_next_hk_vcdu() != HK_SUCCESS_SKIP_IMAGE\n"); //!!TEMP |
371 |
/* write Keywords to DRMS in Level 0 Data Series by APID */ |
372 |
wd_status = write_hk_to_drms(record, hk_packets); |
373 |
//printk("write_hk_to_drms() status wd_status=%d\n", wd_status); //!!TEMP |
374 |
|
375 |
/* check wd_status value */ |
376 |
if (wd_status == HK_SUCCESS_WROTE_TO_DRMS) |
377 |
{ |
378 |
/* wrote successfully to drms -now free CCSDS_Packet_t nodes */ |
379 |
lev0_status= SUCCESS_HK_NEED_TO_CTD; /* set to 0 */ |
380 |
} |
381 |
else if (wd_status == SUCCESS_HK_SKIP_WTD_REC_EXISTS) |
382 |
{ |
383 |
/* found record in data series, so skip writing this record to drms again*/ |
384 |
lev0_status= SUCCESS_HK_SKIP_WTD_REC_EXISTS; //orig Carl stuff |
385 |
//lev0_status= SUCCESS_HK_NEED_TO_CTD; /* treat as successful write */ |
386 |
} |
387 |
else if (wd_status == SUCCESS_HK_SKIP_WTD_REC_TIME_OOR) |
388 |
{ |
389 |
/* found record not within time range of --not-- greater than 12 hrs */ |
390 |
/* of current date and time, so skip writing this record to drms again */ |
391 |
lev0_status= SUCCESS_HK_SKIP_WTD_REC_TIME_OOR; |
392 |
} |
393 |
else if (wd_status == ERROR_HK_ENVIRONMENT_VARS_NOT_SET) |
394 |
{ |
395 |
/* never got a chance to write to DRMS */ |
396 |
lev0_status= ERROR_HK_ENVIRONMENT_VARS_NOT_SET; |
397 |
} |
398 |
else if (wd_status == ERROR_HK_FAILED_TO_FIND_TIMECODES) |
399 |
{ |
400 |
/* never got a chance to write to DRMS */ |
401 |
lev0_status= ERROR_HK_FAILED_TO_FIND_TIMECODES; |
402 |
} |
403 |
else if (wd_status == ERROR_HK_FAILED_CLOSE_DRMS_RECORD) |
404 |
{ |
405 |
lev0_status= ERROR_HK_FAILED_CLOSE_DRMS_RECORD; |
406 |
} |
407 |
else if (wd_status == ERROR_HK_FAILED_OPEN_DRMS_RECORD) |
408 |
{ |
409 |
lev0_status= ERROR_HK_FAILED_OPEN_DRMS_RECORD; |
410 |
} |
411 |
else if (wd_status == ERROR_HK_FAILED_UNKNOWNSERIES) |
412 |
{ |
413 |
// the success of write of level 0 by APID data series should |
414 |
// not effect setting of lev0_status which is returned to ingest_lev0 |
415 |
printkerr("ERROR at %s, line %d: Return status code <%d> " |
416 |
"for write_hk_to_drms function. Unknown data series " |
417 |
"when writing to Level0 by APID series. Create Series.\n" |
418 |
, __FILE__, __LINE__, wd_status); |
419 |
} |
420 |
else |
421 |
{ |
422 |
printkerr("Warning at %s, line %d: Return status <%d> unexpected " |
423 |
"for write_hk_to_drms. Check status code in " |
424 |
"drms_statuscodes.h.\n", __FILE__, __LINE__, wd_status); |
425 |
} |
426 |
}/* if time to write hk packets to DRMS */ |
427 |
|
428 |
#ifdef DEBUG_DECODE_HK_VCDU |
429 |
if (get_status( lz_status, j) != 4) |
430 |
{ |
431 |
printkerr("DEBUG Message at %s, line %d: Overall hk by apid processing " |
432 |
"status for saving packets, decoding packets <%d> and writing " |
433 |
"to drms lev0 hk series <%d>\n", |
434 |
__FILE__, __LINE__, get_status( lz_status, j), lev0_status); |
435 |
} |
436 |
#else |
437 |
#endif |
438 |
|
439 |
/* determine structure to pass back to LEV0 top module -note only want ISPs */ |
440 |
/* first should not free ccsds nodes if ISPs there */ |
441 |
/* Filter out non-isp nodes in CCSDS_Packet_t link list */ |
442 |
/* if there is a isp node return back success values */ |
443 |
/* if there are no isp nodes return back status meaning no isp's found */ |
444 |
if(hk_packets && hk_status != HK_SUCCESS_SKIP_IMAGE && lev0_status >= ERROR_NODATA) |
445 |
{ |
446 |
/* filters out non-isps and free node that are not isp's */ |
447 |
foni_status = filter_out_non_isps(hk_packets); |
448 |
//printk("foni_status = %d\n", foni_status); //!!TEMP |
449 |
if(foni_status == 1) |
450 |
{ |
451 |
/*got a ISP node in CCSDS_Packet_t link list so set to value for |
452 |
lev0 top module to know to write to level0 data series*/ |
453 |
/* lookup FSN value to pass back */ |
454 |
fsn_status= lookup_fsn(hk_packets, Fsn); |
455 |
if(fsn_status) |
456 |
{ |
457 |
lev0_status = ERROR_HK_FAILED_GETTING_FSN; /* set to -27 */ |
458 |
} |
459 |
else |
460 |
{ |
461 |
/* successfully got FSN value */ |
462 |
lev0_status = SUCCESS_HK_NEED_TO_WTD_CTD; /* set to 1 */ |
463 |
} |
464 |
} |
465 |
} |
466 |
|
467 |
/* Set status returned for lev0 top module by evaluation of */ |
468 |
/* errors when writing to dayfile, decoding hk, etc. */ |
469 |
return (lev0_status); |
470 |
} |
471 |
|
472 |
|
473 |
/******************* Packet header routines ********************/ |
474 |
|
475 |
/* Extract fields from IM_PDU packet header. */ |
476 |
static unsigned short *decode_im_pdu(unsigned short *w, IM_PDU_Packet_t *p) |
477 |
{ |
478 |
/* Word 0 */ |
479 |
p->im_pdu_count = ((long long) (*w & 0x3ff)) << 32; |
480 |
p->im_pdu_id = (unsigned char)(*w++ >> 10); |
481 |
/* Word 1 */ |
482 |
p->im_pdu_count |= *w++ << 16; |
483 |
/* Word 2 */ |
484 |
p->im_pdu_count |= *w++; |
485 |
/* Word 3 */ |
486 |
p->fhp = (unsigned short)((*w++) & 0x7ff); |
487 |
return w; |
488 |
} |
489 |
|
490 |
/************ Extract fields from CCSDS packet header **************/ |
491 |
static unsigned short *decode_ccsds(unsigned short *w, CCSDS_Packet_t *p) |
492 |
{ |
493 |
/* Word 4 */ |
494 |
p->version = (unsigned char)((*w >> 13) & 0x7); |
495 |
p->type = (unsigned char)((*w >> 12) & 1); |
496 |
p->shf = (unsigned char)((*w >> 11) & 1); |
497 |
p->apid = (unsigned short)((*w++) & 0x7ff); |
498 |
/* Word 5 */ |
499 |
p->sf = (unsigned char)((*w >> 14) & 0x3); |
500 |
p->ssc = (unsigned short)((*w++) & 0x3fff); |
501 |
/* Word 6 */ |
502 |
/* According to the CCSDS spec the packet length field contains |
503 |
"total number of octets - header octets - 1". |
504 |
Add 1 to get length of data field in bytes. */ |
505 |
p->length = (unsigned short)(*w++ + 1); |
506 |
return w; |
507 |
} |
508 |
|
509 |
/********************** hk_ccsds_free function ******************/ |
510 |
void hk_ccsds_free(CCSDS_Packet_t **ptr) |
511 |
{ |
512 |
CCSDS_Packet_t *tmp, *p; |
513 |
p= *ptr; |
514 |
while(p) |
515 |
{ |
516 |
if (p->keywords) |
517 |
{ |
518 |
deallocate_hk_keyword(p->keywords); |
519 |
} |
520 |
tmp = p->next; |
521 |
free(p); |
522 |
p = tmp; |
523 |
} |
524 |
} |
525 |
|
526 |
|
527 |
/********************** filter out non isps function ******************/ |
528 |
int filter_out_non_isps(CCSDS_Packet_t **ptr) |
529 |
{ |
530 |
/* declarations */ |
531 |
CCSDS_Packet_t *tmp, *p, *prev; |
532 |
int isp_count=0; |
533 |
|
534 |
/* initialized variables */ |
535 |
p= *ptr; |
536 |
prev=p; |
537 |
|
538 |
/* locate non-isps and free node*/ |
539 |
while(p) |
540 |
{ |
541 |
|
542 |
if (p->apid != APID_HMI_IMSTAT_1 && p->apid != APID_HMI_IMSTAT_2 && |
543 |
p->apid != APID_AIA_IMSTAT_1 && p->apid != APID_AIA_IMSTAT_2 && |
544 |
p->apid != APID_IRIS_ISP) |
545 |
{ |
546 |
if (p->keywords) |
547 |
{ |
548 |
deallocate_hk_keyword(p->keywords); |
549 |
} |
550 |
prev->next=p->next; |
551 |
tmp = p->next; |
552 |
free(p); |
553 |
p = tmp; |
554 |
} |
555 |
else |
556 |
{ /* if is isp */ |
557 |
isp_count++; |
558 |
if(isp_count == 1) |
559 |
{ |
560 |
/*set new head once*/ |
561 |
*ptr=p; |
562 |
} |
563 |
prev=p; |
564 |
p=p->next; |
565 |
} |
566 |
} |
567 |
return (isp_count); |
568 |
} |
569 |
|
570 |
|
571 |
/********************** lookup FSN function ******************/ |
572 |
int lookup_fsn(CCSDS_Packet_t **ptr, unsigned int *Fsn) |
573 |
{ |
574 |
/* declarations */ |
575 |
CCSDS_Packet_t *p; |
576 |
HK_Keyword_t *kw; |
577 |
unsigned int fsn=0; |
578 |
int status=1; //not found case |
579 |
|
580 |
/* initialized variables */ |
581 |
p= *ptr; |
582 |
kw=p->keywords; |
583 |
|
584 |
/* locate Fsn */ |
585 |
while(kw) |
586 |
{ |
587 |
|
588 |
if (strstr(kw->name, "FILTERGRAM_SN") || strstr(kw->name, "FRAME_SN")) |
589 |
{ |
590 |
fsn=kw->eng_value.uint32_val; |
591 |
status = 0; |
592 |
*Fsn=fsn; |
593 |
break; |
594 |
} |
595 |
else |
596 |
{ |
597 |
kw=kw->next; |
598 |
} |
599 |
} |
600 |
return (status); |
601 |
} |
602 |
|
603 |
|
604 |
|
605 |
/*********************** get status ************************************/ |
606 |
int get_status( int lz[], int jj) |
607 |
{ |
608 |
/* declarations */ |
609 |
int k, count_errors, last_error, skip_apids; |
610 |
|
611 |
/* Set status returned to lev0 top module by evaluation of */ |
612 |
/* errors when writing to dayfile, decoding hk, etc. */ |
613 |
for (k=0, count_errors=0,skip_apids=0, last_error=0; k < jj; k++) |
614 |
{ |
615 |
/* count errors and apids skipped*/ |
616 |
if (lz[k] < 0 ) |
617 |
{ |
618 |
count_errors+=1; |
619 |
last_error= lz[k]; |
620 |
} |
621 |
else if (lz[k] == SUCCESS_SKIP_PROCESSING_APID) |
622 |
{ |
623 |
skip_apids+=1; |
624 |
} |
625 |
} |
626 |
|
627 |
/* if no errors return status HK_SUCCESS_SKIP_IMAGE, |
628 |
HK_SUCCESS_SKIP_PROCESSING_APID, or HK_SUCCESS_HK_ALL */ |
629 |
if (!count_errors) |
630 |
{ |
631 |
if (lz[0] == HK_SUCCESS_SKIP_IMAGE) return HK_SUCCESS_SKIP_IMAGE; |
632 |
else if (skip_apids == (jj - 2 )) |
633 |
{ |
634 |
return HK_SUCCESS_SKIP_PROCESSING_APID; |
635 |
} |
636 |
else return HK_SUCCESS_HK_ALL; |
637 |
} |
638 |
/* if count errors equal to total process then return |
639 |
HK error-status of last item processed */ |
640 |
else if ( count_errors == jj - 2) |
641 |
{ |
642 |
return last_error; |
643 |
} |
644 |
/* if got some errors and some sucessful processing return HK_SUCCESS_HK_SOME */ |
645 |
else if ( count_errors < jj - 2) |
646 |
{ |
647 |
return HK_SUCCESS_HK_SOME; |
648 |
} |
649 |
else return lz[0]; |
650 |
} |