00001
00002
00003
00004
00005 #include <inttypes.h>
00006 #include <dirent.h>
00007 #include "jsoc.h"
00008 #include "egsehmicomp.h"
00009
00010 typedef struct APID_Pointer_HK_Configs_struct
00011 {
00012 int apid;
00013
00014 struct HK_Config_Files_struct *ptr_hk_configs;
00015
00016 struct APID_Pointer_HK_Configs_struct *next;
00017 } APID_Pointer_HK_Configs;
00018
00019 typedef struct HK_Config_Files_struct
00020 {
00021 int apid_number;
00022 char packet_id_type[MAX_PACKET_ID_TYPE];
00023 char file_version_number[MAX_CHAR_VERSION_NUMBER];
00024
00025 char parameter_version_number[MAX_CHAR_VERSION_NUMBER];
00026
00027 char date[MAX_DATE_SIZE];
00028 int number_bytes_used;
00029 struct Keyword_Parameter_struct *keywords;
00030
00031 struct HK_Config_Files_struct *next;
00032 } HK_Config_Files;
00033
00034 typedef struct APID_HKPFD_Files_struct
00035 {
00036 char version_number[MAX_CHAR_VERSION_NUMBER];
00037 int apid;
00038 char directory_name[MAX_DIRECTORY_NAME];
00039 char filename[MAX_FILE_NAME];
00040 struct APID_HKPFD_Files_struct *next;
00041 } APID_HKPFD_Files;
00042
00043 typedef struct GTCIDS_Version_Number_struct
00044 {
00045 char file_version_number[MAX_CHAR_VERSION_NUMBER];
00046 char hmi_id_version_number[MAX_CHAR_VERSION_NUMBER];
00047 char aia_id_version_number[MAX_CHAR_VERSION_NUMBER];
00048 char change_date[MAX_SIZE_CHANGE_DATE];
00049 char change_time[MAX_SIZE_CHANGE_TIME];
00050 struct GTCIDS_Version_Number_struct *next;
00051 } GTCIDS_Version_Number;
00052
00053 typedef struct ALG_Conversion_struct
00054 {
00055 int number_of_coeffs;
00056 double coeff [MAX_NUMBER_COFFICIENTS];
00057 } ALG_Conversion;
00058
00059 typedef struct Keyword_Parameter_struct {
00060 char telemetry_mnemonic_name[MAX_HK_MNM];
00061
00062
00063 char keyword_name[MAX_HK_KYWD];
00064
00065
00066 int start_byte;
00067 int start_bit_number;
00068 int bit_length;
00069
00070 char conv_type;
00071 char type[MAX_HK_VALUE_TYPE];
00072
00073 struct ALG_Conversion_struct *alg_ptr;
00074 struct DSC_Conversion_struct *dsc_ptr;
00075 struct Keyword_Parameter_struct *next;
00076 } Keyword_Parameter;
00077
00078
00079 typedef struct IM_PDU_Packet_struct
00080 {
00081
00082 uint8_t im_pdu_id;
00083 uint64_t im_pdu_count;
00084
00085 uint8_t spare;
00086 uint16_t fhp;
00087
00088
00089 struct CCSDS_Packet_struct *packets;
00090
00091 } IM_PDU_Packet_t;
00092
00093 typedef struct HK_Keywords_Format_struct
00094 {
00095 char keyword_name[KEYWORD_NAME_SIZE];
00096
00097
00098 unsigned int keyword_value;
00099
00100
00101 char type[KEYWORD_TYPE_SIZE] ;
00102
00103
00104
00105 char telemetry_mnemonic_name[TELEMETRY_MNEMONIC_SIZE];
00106 int start_byte ;
00107
00108
00109
00110
00111 int start_bit;
00112 int bit_length;
00113 char conv_type;
00114 struct ALG_Conversion_struct *alg;
00115 struct DSC_Conversion_struct *dsc;
00116 struct HK_Keywords_Format_struct *next;
00117
00118
00119 } HK_Keywords_Format;
00120
00121 typedef struct DSC_Conversion_struct
00122 {
00123 int low_range;
00124 int high_range;
00125 char dsc_value[MAX_VALUE_DSC];
00126 struct DSC_Conversion_struct *next;
00127 } DSC_Conversion;
00128
00129
00130 #define ERRMSG(__msg__) printkerr("ERROR at %s, line %d: " #__msg__"\n",__FILE__,__LINE__);
00131
00132
00133
00134 int numcontexts=0;
00135 Decompress_Context_t *Context[MAXCONTEXTS];
00136 APID_Pointer_HK_Configs *global_apid_configs;
00137 GTCIDS_Version_Number *global_gtcids_vn;
00138 static int isHMI = 0;
00139
00140
00141 static int fits_copy_header(char *out, char *in, int headlen)
00142 {
00143 int newlen=0;
00144
00145 while (headlen>0)
00146 {
00147 if (strncmp(in, "SIMPLE =", 9) &&
00148 strncmp(in, "BITPIX =", 9) &&
00149 strncmp(in, "NAXIS =", 9) &&
00150 strncmp(in, "NAXIS1 =", 9) &&
00151 strncmp(in, "NAXIS2 =", 9) &&
00152 strncmp(in, "DATE =", 9) &&
00153 strncmp(in, "END ", 8))
00154 {
00155 memcpy(out, in, 80);
00156 out += 80;
00157 newlen += 80;
00158 }
00159 in += 80;
00160 headlen -= 80;
00161 }
00162 return newlen;
00163 }
00164
00165 #define WRITE(fh,buf,len) (fwrite(buf, len, 1, fh)==1)
00166 #define CLOSE(fh) fclose(fh)
00167
00168 int fits_writeimage_raw(const char* file, int compress, int headlen,
00169 char *header, int width, int height,short *data)
00170 {
00171 time_t t;
00172 struct tm tm;
00173 FILE *fh;
00174 int i, rem, hl,nzhead, nzdata;
00175 unsigned char *zdata;
00176 char *head;
00177 char date[20], *p, tmp;
00178 unsigned int npix,buflen;
00179 int ndata_blocks, nhead_blocks, len;
00180 char buf[1024];
00181
00182 if (headlen % 80)
00183 {
00184 printkerr("Error: Fits header length must be a multiple of 80.\n");
00185 return 1;
00186 }
00187
00188 if (!(fh=fopen(file,"w")))
00189 {
00190 printkerr("Couldn't open file %s.\n",file);
00191 return 1;
00192 }
00193
00194
00195
00196 head = malloc(headlen+2*2880);
00197 memset(head,' ',headlen+2*2880);
00198 p = head;
00199 snprintf(p,80,"SIMPLE = T");
00200 p += 80;
00201 snprintf(p,80,"BITPIX = 16 / Number of bits per data pixel");
00202 p += 80;
00203 snprintf(p,80,"NAXIS = 2 / Number of data axes");
00204 p += 80;
00205 snprintf(p,80,"NAXIS1 = %6d",width);
00206 p += 80;
00207 snprintf(p,80,"NAXIS2 = %6d",height);
00208 p += 80;
00209 snprintf(p,80,"BLANK = %6d",-32768);
00210 p += 80;
00211
00212 t = time(NULL);
00213 gmtime_r(&t, &tm);
00214 strftime(date,20,"%F %T",&tm);
00215
00216 snprintf(p,80,"DATE = '%s'",date);
00217 p += 80;
00218 if (headlen>0 && header !=NULL)
00219 p += fits_copy_header(p,header,headlen);
00220 snprintf(p,80,"END");
00221 p += 80;
00222
00223 while ((p-head)%2880)
00224 {
00225 memset(p,' ',80);
00226 p += 80;
00227 }
00228 hl = p-head;
00229 nhead_blocks = hl/2880;
00230 for(i=0; i<hl; i++)
00231 if (head[i]=='\0')
00232 head[i] = ' ';
00233
00234
00235 if (!WRITE(fh,head,hl))
00236 {
00237 printkerr( "Failed to write header data to file %s\n",file);
00238 goto bailout;
00239 }
00240
00241 npix = width*height;
00242
00243 if (compress)
00244 {
00245
00246 buflen = 3*npix;
00247 if ((zdata= malloc(buflen))==NULL)
00248 {
00249 printkerr("Could't allocate zdata buffer\n");
00250 goto bailout;
00251 }
00252
00253
00254 nzdata = rice_encode2(data, npix, zdata, buflen, 64);
00255 if (nzdata < 0)
00256 {
00257 printkerr( "Data compression failed with error code %d\n",
00258 nzhead);
00259 free(zdata);
00260 goto bailout;
00261 }
00262
00263
00264 fprintf(fh, "%d %d %d %d\n", 16, 64, 2*npix, nzdata);
00265
00266
00267 if (!WRITE(fh, zdata, nzdata))
00268 {
00269 printkerr( "Failed to write compressed data to file %s\n",file);
00270 free(zdata);
00271 goto bailout;
00272 }
00273 free(zdata);
00274 }
00275 else
00276 {
00277
00278 #if __BYTE_ORDER == __LITTLE_ENDIAN
00279 p = (char *)data;
00280 for (i=0; i<npix; i++)
00281 {
00282 tmp = *(p+1); *(p+1) = *p; *p = tmp;
00283 p += 2;
00284 }
00285 #endif
00286
00287
00288 if (!WRITE(fh,data,sizeof(unsigned short)*npix))
00289 {
00290 printkerr( "Failed to write data to file %s\n",file);
00291 goto bailout;
00292 }
00293
00294
00295 memset(head,0,2880);
00296 rem = 2880 - ((sizeof(unsigned short)*npix) % 2880);
00297 if (!WRITE(fh, head, rem))
00298 {
00299 printkerr( "Failed to write zero padding to file %s\n",file);
00300 goto bailout;
00301 }
00302
00303
00304 #if __BYTE_ORDER == __LITTLE_ENDIAN
00305 p = (char *)data;
00306 for (i=0; i<npix; i++)
00307 {
00308 tmp = *(p+1); *(p+1) = *p; *p = tmp;
00309 p += 2;
00310 }
00311 #endif
00312 }
00313
00314
00315 free(head);
00316 CLOSE(fh);
00317 return 0;
00318
00319
00320 bailout:
00321
00322
00323 free(head);
00324 CLOSE(fh);
00325 unlink(file);
00326 return 1;
00327 }
00328 #undef WRITE
00329 #undef CLOSE
00330
00331
00332
00333
00334
00335 void printk_set(int (*std)(const char *fmt, ...),
00336 int (*err)(const char *fmt, ...))
00337 {
00338 printk = std;
00339 printkerr = err;
00340 }
00341
00342
00343 static int fprintf_wrap(const char *fmt, ...)
00344 {
00345 int val;
00346 va_list args;
00347
00348 va_start(args,fmt);
00349 val = vfprintf(stderr,fmt,args);
00350 va_end(args);
00351 return val;
00352 }
00353
00354
00355 static int printf_wrap(const char *fmt, ...)
00356 {
00357 int val;
00358 va_list args;
00359
00360 va_start(args,fmt);
00361 val = vprintf(fmt,args);
00362 va_end(args);
00363 return val;
00364 }
00365
00366 int (*printk)(const char *fmt, ...) = &printf_wrap;
00367 int (*printkerr)(const char *fmt, ...) = &fprintf_wrap;
00368
00369
00370
00371 static void get_version_number(unsigned short *wd_ptr, char *ptr_vn)
00372 {
00373
00374 unsigned short w;
00375 w = wd_ptr[7];
00376
00377 sprintf(ptr_vn, "%d.%d", w & 0x00FF, w >> 8 & 0x00FF );
00378 }
00379
00380 static int load_engr_values(HK_Keywords_Format *hk_keywords, HK_Keyword_t **kw_head)
00381 {
00382
00383 HK_Keyword_t *kwt=NULL;
00384 DSC_Conversion *dsc;
00385 int i;
00386
00387
00388 while(hk_keywords)
00389 {
00390 if (!kwt)
00391 *kw_head = kwt = (HK_Keyword_t*) malloc (sizeof (HK_Keyword_t));
00392 else
00393 {
00394 kwt->next = (HK_Keyword_t*) malloc (sizeof (HK_Keyword_t));
00395 kwt = kwt->next;
00396 }
00397 memset(kwt,0,sizeof(HK_Keyword_t));
00398 kwt->next = NULL;
00399
00400 strcpy(kwt->fitsname, hk_keywords->keyword_name);
00401 strcpy(kwt->name, hk_keywords->telemetry_mnemonic_name);
00402
00403 kwt->raw_value = hk_keywords->keyword_value;
00404
00405 if ( hk_keywords->conv_type == 'R')
00406 {
00407 if (!strcmp( hk_keywords->type , "UB"))
00408 {
00409 kwt->eng_type = DRMS_TYPE_UINT8;
00410 kwt->eng_value.uint8_val = hk_keywords->keyword_value;
00411 }
00412 else if (!strcmp( hk_keywords->type , "SB"))
00413 {
00414 kwt->eng_type = DRMS_TYPE_INT8;
00415 kwt->eng_value.int8_val = hk_keywords->keyword_value;
00416 }
00417 else if (!strcmp( hk_keywords->type , "IU1"))
00418 {
00419 kwt->eng_type = DRMS_TYPE_UINT16;
00420 kwt->eng_value.uint16_val = hk_keywords->keyword_value;
00421
00422 }
00423 else if (!strcmp( hk_keywords->type , "IS1"))
00424 {
00425 kwt->eng_type = DRMS_TYPE_INT16;
00426 kwt->eng_value.int16_val = hk_keywords->keyword_value;
00427 }
00428 else if (!strcmp( hk_keywords->type , "IL1"))
00429 {
00430 kwt->eng_type = DRMS_TYPE_INT32;
00431 kwt->eng_value.int32_val = hk_keywords->keyword_value;
00432 }
00433 else if (!strcmp( hk_keywords->type , "UL1"))
00434 {
00435 kwt->eng_type = DRMS_TYPE_UINT32;
00436 kwt->eng_value.uint32_val = hk_keywords->keyword_value;
00437 }
00438 else
00439 {
00440 printkerr("ERROR at %s, line %d: Type '%s' not handled.\n", __FILE__, __LINE__, hk_keywords->type);
00441 return ERROR_HK_UNHANDLED_TYPE;
00442 }
00443 }
00444 else if ( hk_keywords->conv_type == 'D')
00445 {
00446 if (!strcmp( hk_keywords->type,"UB") || !strcmp( hk_keywords->type ,"IU1") || !strcmp( hk_keywords->type,"UL1"))
00447 {
00448 kwt->eng_type = DRMS_TYPE_STRING;
00449 for (dsc = hk_keywords->dsc; dsc ; dsc= dsc->next)
00450 {
00451 if ( hk_keywords->keyword_value >= dsc->low_range &&
00452 hk_keywords->keyword_value <= dsc->high_range )
00453 {
00454 kwt->eng_value.string_val =(char *) malloc(sizeof(dsc->dsc_value) + 1);
00455 strcpy( kwt->eng_value.string_val , dsc->dsc_value);
00456 break;
00457 }
00458 }
00459 if ( !kwt->eng_value.string_val)
00460 {
00461 kwt->eng_value.string_val =(char *) malloc(sizeof("NO_VALUE") + 1);
00462 strcpy( kwt->eng_value.string_val , "NO_VALUE");
00463 printkerr("WARNING at %s, line %d: There are no DSC data lines to set digital type keyword '%s'.\n"
00464 "Setting value to NO_VALUE. Check config files and run script to update config files.\n",
00465 __FILE__, __LINE__, hk_keywords->keyword_name);
00466 }
00467 }
00468 else
00469 {
00470 printkerr("ERROR at %s, line %d: Type '%s' not handled.\n", __FILE__, __LINE__, hk_keywords->type);
00471 return ERROR_HK_UNHANDLED_TYPE;
00472 }
00473 }
00474 else if (hk_keywords->conv_type == 'A')
00475 {
00476
00477
00478
00479
00480
00481
00482 if (!strcmp( hk_keywords->type,"UB") || !strcmp( hk_keywords->type ,"IU1") || !strcmp( hk_keywords->type,"UL1"))
00483 {
00484 if(hk_keywords->alg)
00485 {
00486 for (i=0; i < hk_keywords->alg->number_of_coeffs; i++)
00487 {
00488 kwt->eng_value.double_val += hk_keywords->alg->coeff[i] * pow(hk_keywords->keyword_value, i);
00489 }
00490 }
00491 else
00492 {
00493 kwt->eng_value.double_val = 0;
00494 printkerr("WARNING at %s, line %d: Missing ACON line for keyword '%s'."
00495 " Default engr.value set to zero.\n"
00496 "Check config files for missing ACON lines for keyword.\n",
00497 __FILE__, __LINE__, hk_keywords->keyword_name);
00498 }
00499 kwt->eng_type = DRMS_TYPE_DOUBLE;
00500 }
00501 else
00502 {
00503 printkerr("ERROR at %s, line %d: Engr Type '%s' not handled.\n", __FILE__, __LINE__, hk_keywords->type);
00504 return ERROR_HK_UNHANDLED_TYPE;
00505 }
00506 }
00507 else
00508 {
00509 printkerr("ERROR at %c, line %d: Conversion Type '%s' not handled.\n", __FILE__, __LINE__, hk_keywords->conv_type);
00510 return ERROR_HK_UNHANDLED_TYPE;
00511 }
00512 hk_keywords = hk_keywords->next;
00513 }
00514 return SUCCESSFUL;
00515 }
00516
00517 HK_Keywords_Format *load_hk_configs(HK_Config_Files *config)
00518 {
00519 HK_Keywords_Format *new_kw, *new_kw_head;
00520 Keyword_Parameter *config_kw;
00521 DSC_Conversion *config_dsc, *prev_new_dsc, *new_dsc;
00522 ALG_Conversion *config_alg, *new_alg;
00523 int i;
00524
00525 config_kw=config->keywords;
00526
00527 if (config_kw == NULL)
00528 {
00529 ERRMSG("Null pointer input.");
00530 return NULL;
00531 }
00532
00533 new_kw_head = new_kw = NULL;
00534 while (config_kw)
00535 {
00536 if (!new_kw)
00537 new_kw = new_kw_head = malloc(sizeof(HK_Keywords_Format));
00538 else
00539 {
00540 new_kw->next = malloc(sizeof(HK_Keywords_Format));
00541 new_kw = new_kw->next;
00542 }
00543 new_kw->next = NULL;
00544
00545 strcpy(new_kw->keyword_name, config_kw->keyword_name);
00546
00547 strcpy(new_kw->telemetry_mnemonic_name,
00548 config_kw->telemetry_mnemonic_name);
00549
00550 new_kw->start_byte = config_kw->start_byte;
00551 new_kw->start_bit = config_kw->start_bit_number;
00552
00553 strcpy( new_kw->type, config_kw->type);
00554
00555 new_kw->bit_length = config_kw->bit_length;
00556 new_kw->conv_type = config_kw->conv_type;
00557
00558 if( config_kw->conv_type == 'D')
00559 {
00560 new_kw->dsc = (DSC_Conversion*)NULL;
00561 config_dsc=config_kw->dsc_ptr;
00562 prev_new_dsc=NULL;
00563 while (config_dsc)
00564 {
00565
00566 new_dsc=(DSC_Conversion*) malloc(sizeof(DSC_Conversion));
00567 if (!prev_new_dsc)
00568 {
00569 new_kw->dsc= new_dsc;
00570 }
00571 new_dsc->low_range = config_dsc->low_range;
00572 new_dsc->high_range = config_dsc->high_range;
00573 strcpy(new_dsc->dsc_value,config_dsc->dsc_value);
00574 new_dsc->next = (DSC_Conversion *)NULL;
00575 if(prev_new_dsc)
00576 {
00577 prev_new_dsc->next = new_dsc;
00578 }
00579
00580 config_dsc= config_dsc->next;
00581 prev_new_dsc=new_dsc;
00582 new_dsc= new_kw->dsc->next;
00583 }
00584 }
00585 else
00586 {
00587 new_kw->dsc = (DSC_Conversion*)NULL;
00588 }
00589
00590 if( config_kw->conv_type == 'A')
00591 {
00592 config_alg=config_kw->alg_ptr;
00593 if (config_alg)
00594 {
00595
00596 new_alg = (ALG_Conversion*) malloc(sizeof(ALG_Conversion));
00597 new_kw->alg= new_alg;
00598 new_alg->number_of_coeffs = config_alg->number_of_coeffs;
00599 for(i=0; i < new_alg->number_of_coeffs; i++)
00600 {
00601 new_alg->coeff[i] = config_alg->coeff[i];
00602 }
00603 }
00604 else
00605 {
00606
00607 new_kw->alg= (ALG_Conversion*)NULL;
00608 }
00609
00610 }
00611 else
00612 {
00613 new_kw->alg = (ALG_Conversion*)NULL;
00614 }
00615
00616
00617
00618 config_kw = config_kw->next;
00619 }
00620 return new_kw_head;
00621 }
00622
00623 static int load_hk_values(unsigned short *word_ptr, HK_Keywords_Format *ptr_hk_keywords)
00624 {
00625
00626 HK_Keywords_Format *top_hk_keywords;
00627 unsigned int *w;
00628 unsigned char *byte_ptr;
00629 top_hk_keywords = ptr_hk_keywords;
00630 unsigned int keep_bits;
00631 int i;
00632
00633 byte_ptr= (unsigned char*)(word_ptr+3);
00634
00635 while ( ptr_hk_keywords != NULL )
00636 {
00637 if(!strcmp(ptr_hk_keywords->type, "UB") || !strcmp(ptr_hk_keywords->type, "SB") )
00638 {
00639
00640 keep_bits=0;
00641
00642 w = (unsigned int*) &(byte_ptr[ptr_hk_keywords->start_byte]);
00643
00644 keep_bits = (unsigned int) (pow( 2, ptr_hk_keywords->bit_length) - 1) ;
00645
00646 ptr_hk_keywords->keyword_value = (unsigned char)(( *w >> (8 - (ptr_hk_keywords->start_bit + ptr_hk_keywords->bit_length))) & keep_bits);
00647 }
00648 else if( (!strcmp(ptr_hk_keywords->type, "IS1") || !strcmp(ptr_hk_keywords->type, "IU1")) && ptr_hk_keywords->bit_length <= 16)
00649 {
00650
00651 keep_bits=0;
00652
00653 w = (unsigned int*) &(byte_ptr[ptr_hk_keywords->start_byte]);
00654
00655 keep_bits = (unsigned int) (pow( 2, ptr_hk_keywords->bit_length) - 1) ;
00656
00657 ptr_hk_keywords->keyword_value = (unsigned short int) (( (*w ) >> 8) & 0x00FF );
00658
00659 ptr_hk_keywords->keyword_value |= (unsigned short int) (( (*w ) << 8 ) & 0xFF00 );
00660
00661 ptr_hk_keywords->keyword_value = (unsigned int) (( ptr_hk_keywords->keyword_value >> (16 - (ptr_hk_keywords->start_bit + ptr_hk_keywords->bit_length))) & keep_bits);
00662 }
00663 else if (!strcmp(ptr_hk_keywords->type, "UL1") || !strcmp(ptr_hk_keywords->type, "IL1"))
00664 {
00665
00666 keep_bits=0;
00667
00668 keep_bits = (unsigned int) (pow( 2, ptr_hk_keywords->bit_length ) - 1 ) ;
00669
00670 w = (unsigned int*) &(byte_ptr[ptr_hk_keywords->start_byte]);
00671
00672 ptr_hk_keywords->keyword_value = (unsigned int) ( (*w) >> 24 & 0x000000FF);
00673
00674 ptr_hk_keywords->keyword_value |= (unsigned int) ( (*w) >> 8 & 0x0000FF00);
00675
00676 ptr_hk_keywords->keyword_value |= (unsigned int) ( (*w) << 24 & 0xFF000000);
00677
00678 ptr_hk_keywords->keyword_value |= (unsigned int) ( (*w) << 8 & 0x00FF0000);
00679
00680 ptr_hk_keywords->keyword_value = (ptr_hk_keywords->keyword_value >> (32 - (ptr_hk_keywords->start_bit + ptr_hk_keywords->bit_length ))) & keep_bits ;
00681 }
00682 else
00683 {
00684 printkerr("ERROR at %s, line %d: Did not find this bit length for keyword %s\n",
00685 __FILE__, __LINE__, ptr_hk_keywords->keyword_name );
00686
00687 }
00688 ptr_hk_keywords = ptr_hk_keywords->next;
00689 }
00690 ptr_hk_keywords= top_hk_keywords;
00691 return (SUCCESSFUL);
00692 }
00693
00694 static void deallocate_hk_keywords_format(HK_Keywords_Format *head)
00695 {
00696 HK_Keywords_Format *tmp;
00697 DSC_Conversion *d_tmp, *d_head;
00698
00699 while(head)
00700 {
00701
00702 d_head=head->dsc;
00703 while (d_head)
00704 {
00705 d_tmp=d_head->next;
00706 free(d_head);
00707 d_head= d_tmp;
00708 }
00709
00710
00711 if (head->alg)
00712 {
00713 free(head->alg);
00714 }
00715
00716
00717 tmp = head->next;
00718 free(head);
00719 head = tmp;
00720 }
00721 }
00722
00723 void deallocate_hk_keyword(HK_Keyword_t *head)
00724 {
00725 HK_Keyword_t *tmp;
00726
00727 while(head)
00728 {
00729 tmp = head->next;
00730 if (head->eng_type == DRMS_TYPE_STRING && head->eng_value.string_val)
00731 {
00732 free(head->eng_value.string_val);
00733 }
00734 free(head);
00735 head = tmp;
00736 }
00737 }
00738
00739 GTCIDS_Version_Number * read_gtcids_hk_file(APID_Pointer_HK_Configs *top_apid_ptr)
00740 {
00741
00742 char *hk_gtcids_directory ;
00743 char *hk_gtcids_filename;
00744 char hk_gtcids_directory_filename[MAX_FILE_NAME];
00745 FILE *file_ptr;
00746 char line[MAXLINE_IN_FILE];
00747 GTCIDS_Version_Number *top_ptr_gtcids_vn;
00748 GTCIDS_Version_Number *ptr_gtcids_vn;
00749
00750
00751 hk_gtcids_directory = getenv("HK_CONFIG_DIRECTORY");
00752 hk_gtcids_filename= getenv("HK_GTCIDS_FILE");
00753 if(hk_gtcids_filename == NULL)
00754 hk_gtcids_filename = "gtcids.txt";
00755 if(hk_gtcids_directory == NULL)
00756 hk_gtcids_directory = "../../tables/hk_config_file";
00757 sprintf(hk_gtcids_directory_filename, "%s/%s", hk_gtcids_directory,
00758 hk_gtcids_filename);
00759
00760 file_ptr = fopen(hk_gtcids_directory_filename, "r");
00761 if(!file_ptr)
00762 {
00763 printkerr("Error:Couldn't open Ground To Code IDS file %s.\n",hk_gtcids_directory_filename);
00764 printkerr("Set the enviroment variables HK_CONFIG_DIRECTORY"
00765 " to point to config directory and HK_GTCIDS_FILE"
00766 " environment variable to point to the correct file name\n");
00767
00768 return NULL;
00769 }
00770 top_ptr_gtcids_vn = NULL;
00771 while( fgets(line, MAXLINE_IN_FILE, file_ptr) != NULL )
00772 {
00773 if(line[0] == '#')
00774 continue;
00775 else
00776 {
00777 if (top_ptr_gtcids_vn == NULL)
00778 {
00779 top_ptr_gtcids_vn = ptr_gtcids_vn = malloc(sizeof(GTCIDS_Version_Number));
00780 ptr_gtcids_vn->next = (GTCIDS_Version_Number*)NULL;
00781 }
00782 else
00783 {
00784 ptr_gtcids_vn->next = malloc(sizeof(GTCIDS_Version_Number));
00785 ptr_gtcids_vn = ptr_gtcids_vn->next;
00786 ptr_gtcids_vn->next = (GTCIDS_Version_Number*)NULL;
00787 }
00788 ptr_gtcids_vn->next= NULL;
00789
00790
00791
00792
00793
00794 sscanf( line,
00795 "%s %s |%*s | %*s | %s | %s | %*s | %s | %*s",
00796 ptr_gtcids_vn->change_date,
00797 ptr_gtcids_vn->change_time,
00798 ptr_gtcids_vn->hmi_id_version_number,
00799 ptr_gtcids_vn->aia_id_version_number,
00800 ptr_gtcids_vn->file_version_number);
00801 }
00802 }
00803 fclose(file_ptr);
00804
00805 global_gtcids_vn = top_ptr_gtcids_vn;
00806 return(top_ptr_gtcids_vn);
00807 }
00808
00809 char * find_file_version_number(GTCIDS_Version_Number *top, char p_version_number[])
00810 {
00811
00812 GTCIDS_Version_Number *tmp_ptr;
00813
00814 for(tmp_ptr=top;tmp_ptr;tmp_ptr=tmp_ptr->next)
00815 {
00816 if( !strcmp(tmp_ptr->hmi_id_version_number, p_version_number))
00817 {
00818 return tmp_ptr->file_version_number;
00819 }
00820 }
00821 return ("");
00822 }
00823
00824 APID_HKPFD_Files* read_all_hk_config_files(char f_version_number[])
00825 {
00826
00827 char dirname[200];
00828 char *dn;
00829 APID_HKPFD_Files *top, *p;
00830 DIR *dir_p;
00831 struct dirent *dir_entry_p;
00832
00833
00834 int file_loaded_flag=0;
00835 memset(dirname, 0x0, sizeof(dirname));
00836
00837
00838 dn = getenv("HK_CONFIG_DIRECTORY");
00839 if(dn == NULL)
00840 {
00841 printkerr("Error at %s, line %d: Could not get directory environment\n"
00842 "variable:<HK_CONFIG_DIRECTORY>. Set the env variable "
00843 "HK_CONFIG_DIRECTORY to point to the config file directory.\n",
00844 __FILE__,__LINE__,dn);
00845 return NULL;
00846 }
00847
00848 strcpy( dirname, dn);
00849 strcat(dirname, f_version_number);
00850 strcat(dirname,"\0");
00851
00852
00853 if ((dir_p = opendir(dirname)) == NULL)
00854 {
00855 printkerr("Error at %s, line %d: Could not open directory <%s>. "
00856 "The directory with < %s > version number does not exist. "
00857 "Run make_hkpdf.pl script to create directory and config files.\n",
00858 __FILE__,__LINE__,dirname, f_version_number);
00859 return NULL;
00860 }
00861
00862 top = NULL;
00863 while( (dir_entry_p = readdir(dir_p)) != NULL )
00864 {
00865 if( strncmp(dir_entry_p->d_name,"apid",4) )
00866 continue;
00867 if( top == NULL )
00868 top = p = malloc(sizeof(APID_HKPFD_Files));
00869 else
00870 {
00871 p->next = malloc(sizeof(APID_HKPFD_Files));
00872 p = p->next;
00873 }
00874 p->next = NULL;
00875
00876 strcpy(p->filename, dir_entry_p->d_name);
00877 strcpy(p->directory_name, dirname);
00878
00879 sscanf(p->filename, "%*4s-%x-%*7s-%d",
00880 &p->apid, p->version_number);
00881 file_loaded_flag=1;
00882 }
00883 closedir(dir_p);
00884
00885 if ( !file_loaded_flag)
00886 {
00887 printkerr("Error at %s, line %d: Could not find config file(s) "
00888 "in directory < %s >. Check if file(s) exist, if "
00889 "don't exist, then run make_hkpdf.pl script to "
00890 "create config files.\n", __FILE__,__LINE__,dirname);
00891 }
00892 return top;
00893 }
00894
00895 Keyword_Parameter* create_hdpf_keyword_nodes(HK_Config_Files *ptr_hk_config,
00896 int number_of_lines)
00897 {
00898
00899 Keyword_Parameter *p;
00900 int k;
00901
00902
00903 p = ptr_hk_config->keywords = NULL;
00904
00905 for( k=0; k<number_of_lines; k++)
00906 {
00907 if(ptr_hk_config->keywords == NULL)
00908 {
00909
00910 p = ptr_hk_config->keywords = malloc( sizeof(Keyword_Parameter) );
00911 }
00912 else
00913 {
00914
00915 p->next = malloc(sizeof(Keyword_Parameter ));
00916 p = p->next;
00917 }
00918 p->next = NULL;
00919 }
00920 return (ptr_hk_config->keywords);
00921 }
00922
00923 DSC_Conversion* create_hdpf_dsc_nodes(Keyword_Parameter *ptr_hk_keyword)
00924 {
00925
00926 DSC_Conversion *p;
00927 int k;
00928
00929
00930 p = ptr_hk_keyword->dsc_ptr ;
00931
00932 if ( p == NULL)
00933 {
00934
00935 p = (DSC_Conversion *) malloc(sizeof(DSC_Conversion));
00936 ptr_hk_keyword->dsc_ptr= p;
00937 }
00938 else
00939 {
00940 while ( p->next != (DSC_Conversion *)(NULL))
00941 {
00942 p= p->next;
00943 }
00944
00945 p->next = (DSC_Conversion *) malloc (sizeof(DSC_Conversion));
00946 p=p->next;
00947 }
00948 p->next= NULL;
00949 return(p);
00950 }
00951
00952 int load_hdpf_keyword_lines(char keyword_lines[MAX_NUM_KW_LINES][MAXLINE_IN_FILE],int number_of_lines,HK_Config_Files *ptr_hk_config_node)
00953 {
00954
00955 Keyword_Parameter *keyword_node;
00956 int k=0;
00957
00958
00959 keyword_node= create_hdpf_keyword_nodes( ptr_hk_config_node, number_of_lines );
00960
00961 for(k=0; keyword_lines[k][0] != '\0';
00962 k++,keyword_node=keyword_node->next)
00963 {
00964 sscanf(keyword_lines[k]," %*s %s %s %d %d %d %s %c %*s",
00965 keyword_node->keyword_name,
00966 keyword_node->telemetry_mnemonic_name,
00967 &(keyword_node->start_byte),
00968 &(keyword_node->start_bit_number),
00969 &(keyword_node->bit_length),
00970 keyword_node->type,
00971 &keyword_node->conv_type);
00972 keyword_node->dsc_ptr = (DSC_Conversion *)NULL;
00973 keyword_node->alg_ptr = (ALG_Conversion *)NULL;
00974 }
00975 return SUCCESSFUL;
00976 }
00977
00978 int load_hdpf_dsc_lines(char dsc_lines[MAX_NUM_DCON_LINES][MAXLINE_DCON_IN_FILE ], int number_of_lines, HK_Config_Files *ptr_hk_config_node)
00979 {
00980
00981 DSC_Conversion *dsc_node;
00982 int i=0;
00983 int k=0;
00984 char tlm_name[HK_MAX_TLM_NAME];
00985 Keyword_Parameter *kw;
00986
00987
00988
00989
00990
00991
00992 for ( kw= ptr_hk_config_node->keywords ; kw; kw=kw->next)
00993 {
00994
00995 if ( kw->conv_type == 'D')
00996 {
00997 kw->dsc_ptr=(DSC_Conversion*)NULL;
00998
00999 for (i=0; i < number_of_lines; i++)
01000 {
01001 sscanf ( dsc_lines[i], "%*s %s %*d %*d %*d %*d %*d %*d", tlm_name);
01002 strcat( tlm_name, "");
01003 if( !strcmp( kw->telemetry_mnemonic_name, tlm_name))
01004 {
01005
01006 dsc_node = create_hdpf_dsc_nodes( kw);
01007
01008 sscanf(dsc_lines[i]," %*s %*s %d %d %s %*s",
01009 &(dsc_node->low_range), &(dsc_node->high_range),
01010 dsc_node->dsc_value);
01011 dsc_node->next = NULL;
01012 }
01013 }
01014 }
01015 }
01016 return 0;
01017 }
01018
01019 int load_hdpf_alg_lines(char alg_lines[MAX_NUM_ACON_LINES][MAXLINE_ACON_IN_FILE],int number_of_lines,HK_Config_Files *ptr_hk_config_node)
01020 {
01021
01022 ALG_Conversion *alg_node;
01023 int i, k;
01024 char tlm_name[HK_MAX_TLM_NAME];
01025 Keyword_Parameter *kw;
01026
01027
01028
01029
01030
01031
01032 for ( kw= ptr_hk_config_node->keywords ; kw; kw=kw->next)
01033 {
01034
01035 if ( kw->conv_type == 'A')
01036 {
01037
01038 for (i=0; i < number_of_lines; i++)
01039 {
01040
01041 sscanf ( alg_lines[i], "%*s %s %*d %*d %*d %*d %*d %*d %*d", tlm_name);
01042 strcat( tlm_name, "");
01043 if( !strncmp( kw->telemetry_mnemonic_name, tlm_name, sizeof(tlm_name)))
01044 {
01045
01046 kw->alg_ptr = (ALG_Conversion*)malloc (sizeof (ALG_Conversion));
01047 alg_node= kw->alg_ptr;
01048
01049
01050 k=0;
01051 sscanf(alg_lines[i]," %*s %*s %d %lf %lf %lf %lf %lf %*lf %*s",
01052 &(alg_node->number_of_coeffs), &(alg_node->coeff[k++]),
01053 &(alg_node->coeff[k++]), &(alg_node->coeff[k++]),
01054 &(alg_node->coeff[k++]), &(alg_node->coeff[k]) );
01055 break;
01056 }
01057 }
01058 }
01059 }
01060 return SUCCESSFUL;
01061 }
01062
01063 int save_hdpf_new_formats(FILE* file_ptr,APID_Pointer_HK_Configs *p_apid_ptr_hk_configs)
01064 {
01065
01066 int err_status[3];
01067 HK_Config_Files *ptr_config_node;
01068 HK_Config_Files *previous_ptr_config_node;
01069 int status;
01070 int i, j, k;
01071 char line[MAXLINE_IN_FILE];
01072 char keyword_lines[MAX_NUM_KW_LINES][MAXLINE_IN_FILE];
01073 char acon_lines[MAX_NUM_ACON_LINES][MAXLINE_ACON_IN_FILE];
01074 char dcon_lines[MAX_NUM_DCON_LINES][MAXLINE_DCON_IN_FILE];
01075
01076
01077
01078 if (p_apid_ptr_hk_configs->ptr_hk_configs == NULL)
01079 {
01080
01081 p_apid_ptr_hk_configs->ptr_hk_configs =malloc( sizeof(HK_Config_Files));
01082 ptr_config_node = p_apid_ptr_hk_configs->ptr_hk_configs;
01083 ptr_config_node->next = NULL;
01084 ptr_config_node->keywords = NULL;
01085 }
01086 else
01087 {
01088
01089 for(ptr_config_node = p_apid_ptr_hk_configs->ptr_hk_configs,
01090 previous_ptr_config_node = ptr_config_node;
01091 ptr_config_node;
01092 previous_ptr_config_node = ptr_config_node,
01093 ptr_config_node = ptr_config_node->next)
01094 {
01095 ;
01096 }
01097
01098 ptr_config_node = malloc( sizeof(HK_Config_Files));
01099 previous_ptr_config_node->next = ptr_config_node;
01100 ptr_config_node->next = NULL;
01101 ptr_config_node->keywords = NULL;
01102 }
01103
01104 for(i=0, j=0, k=0; fgets(line, MAXLINE_IN_FILE, file_ptr) != NULL; )
01105 {
01106 if (!strncmp(line, "#", 1))
01107 {
01108 continue;
01109 }
01110 else if (!strncmp(line, "KWD", 3))
01111 {
01112 strcpy( keyword_lines[i++], line);
01113 }
01114 else if (!strncmp(line, "DCON", 4))
01115 {
01116
01117 if(j >= MAX_NUM_DCON_LINES)
01118 {
01119 printkerr("WARNING: Maximum lines for array exceeded.\n"
01120 " Skipping saving DCON config data since array too small.\n"
01121 " Update define variable MAX_NUM_DCON_LINES. \n");
01122 }
01123 else
01124 {
01125 strncpy( dcon_lines[j++], line, MAXLINE_DCON_IN_FILE);
01126 }
01127 }
01128 else if (! strncmp(line, "ACON", 4))
01129 {
01130 if(k >= MAX_NUM_ACON_LINES)
01131 {
01132 printkerr("WARNING: Maximum lines for array exceeded.\n"
01133 " Skipping saving ACON config data since array too small.\n"
01134 " Update define variable MAX_NUM_ACON_LINES. \n");
01135 }
01136 else
01137 {
01138 strcpy( acon_lines[k++], line);
01139 }
01140 }
01141 else if (!strncmp(line, "FILE", 4))
01142 {
01143 sscanf(line," %*s %*s %s ", ptr_config_node->file_version_number);
01144 }
01145 else if (!strncmp(line, "APID", 4))
01146 {
01147 if( strstr(line, "HMI") )
01148 {
01149 sscanf( line,"%*s %x %d %s %s",
01150 &(ptr_config_node->apid_number),
01151 &(ptr_config_node->number_bytes_used),
01152 ptr_config_node->packet_id_type,
01153 ptr_config_node->date);
01154 }
01155 else if( strstr(line, "AIA") )
01156 {
01157 sscanf( line,"%*s %x %d %s %s",
01158 &(ptr_config_node->apid_number),
01159 &(ptr_config_node->number_bytes_used),
01160 ptr_config_node->packet_id_type,
01161 ptr_config_node->date);
01162 }
01163 else if( strstr(line, "SSIM") )
01164 {
01165 sscanf( line,"%*s %x %d %*s %s",
01166 &(ptr_config_node->apid_number),
01167 &(ptr_config_node->number_bytes_used),
01168 ptr_config_node->date);
01169
01170 strcpy(ptr_config_node->packet_id_type,"HMI");
01171 }
01172 else
01173 {
01174
01175
01176 sscanf( line,"%*s %x %d %s",
01177 &(ptr_config_node->apid_number),
01178 &(ptr_config_node->number_bytes_used),
01179 ptr_config_node->date);
01180
01181 strcpy(ptr_config_node->packet_id_type,"HMI");
01182 }
01183 }
01184 else
01185 {
01186 printkerr("WARNING: Could not find line with this keyword in apid-#-version-# file\n");
01187 printkerr("WARNING: Line tried to parse is < %s >\n", line);
01188 }
01189 }
01190
01191 strcpy(keyword_lines[i],"");
01192 strcpy(dcon_lines[j],"");
01193 strcpy(acon_lines[k],"");
01194
01195 err_status[0] = load_hdpf_keyword_lines(keyword_lines,i,ptr_config_node);
01196 err_status[1] = load_hdpf_dsc_lines(dcon_lines,j,ptr_config_node);
01197 err_status[2] = load_hdpf_alg_lines(acon_lines,k,ptr_config_node);
01198
01199
01200
01201
01202 for (int i=0; i < sizeof(err_status); i++)
01203 {
01204 if ( err_status[i] != ERROR_LOADING_HK_DATA )
01205 continue;
01206 else
01207 status= err_status[i];
01208 }
01209 return status;
01210 }
01211
01212 void load_config_data(APID_HKPFD_Files *hkpfd_files,
01213 APID_Pointer_HK_Configs *hk_configs)
01214 {
01215
01216 APID_HKPFD_Files* p;
01217 int apid;
01218 char filename[MAX_FILE_NAME];
01219 FILE* file_ptr;
01220
01221
01222 int err_status=0;
01223
01224
01225 apid = hk_configs->apid;
01226 p = hkpfd_files;
01227 while(p)
01228 {
01229 if ( p->apid == apid )
01230 {
01231 sprintf(filename,"%s/%s",p->directory_name, p->filename);
01232 file_ptr = fopen( filename ,"r");
01233 err_status = save_hdpf_new_formats(file_ptr, hk_configs);
01234 fclose(file_ptr);
01235 }
01236 p = p->next;
01237 }
01238 }
01239
01240 void load_gtcids_data( GTCIDS_Version_Number* top_ptr_gtcids_data,
01241 APID_Pointer_HK_Configs *top_apid_ptr_hk_configs)
01242 {
01243
01244 GTCIDS_Version_Number* tmp_ptr_gtcids_data;
01245 APID_Pointer_HK_Configs *tmp_apid_ptr_hk_configs;
01246 HK_Config_Files *tmp_ptr_hk_configs;
01247
01248
01249 tmp_ptr_gtcids_data= top_ptr_gtcids_data;
01250 tmp_apid_ptr_hk_configs= top_apid_ptr_hk_configs;
01251
01252
01253 for(tmp_apid_ptr_hk_configs = top_apid_ptr_hk_configs;
01254 tmp_apid_ptr_hk_configs ;
01255 tmp_apid_ptr_hk_configs= tmp_apid_ptr_hk_configs->next)
01256 {
01257
01258 for( tmp_ptr_hk_configs = tmp_apid_ptr_hk_configs->ptr_hk_configs;
01259 tmp_ptr_hk_configs ;
01260 tmp_ptr_hk_configs= tmp_ptr_hk_configs->next)
01261 {
01262 for (tmp_ptr_gtcids_data=top_ptr_gtcids_data;tmp_ptr_gtcids_data ;
01263 tmp_ptr_gtcids_data=tmp_ptr_gtcids_data->next)
01264 {
01265 if( !strcmp(tmp_ptr_gtcids_data->file_version_number,
01266 tmp_ptr_hk_configs->file_version_number))
01267 {
01268 if(!strcmp(tmp_ptr_hk_configs->packet_id_type, HMI_ID_TYPE))
01269 {
01270 strcpy(tmp_ptr_hk_configs->parameter_version_number,
01271 tmp_ptr_gtcids_data->hmi_id_version_number);
01272 }
01273 else if(!strcmp(tmp_ptr_hk_configs->packet_id_type, AIA_ID_TYPE))
01274 {
01275 strcpy(tmp_ptr_hk_configs->parameter_version_number,
01276 tmp_ptr_gtcids_data->aia_id_version_number);
01277 }
01278 else
01279 {
01280 strcpy(tmp_ptr_hk_configs->parameter_version_number,
01281 tmp_ptr_gtcids_data->hmi_id_version_number);
01282 }
01283 break;
01284 }
01285 }
01286 }
01287 }
01288 }
01289
01290 void deallocate_apid_hkpfd_files_nodes(APID_HKPFD_Files *ptr)
01291 {
01292
01293 APID_HKPFD_Files *tmp;
01294
01295 while(ptr)
01296 {
01297 tmp = ptr->next;
01298 free(ptr);
01299 ptr = tmp;
01300 }
01301 return;
01302 }
01303
01304 int load_all_apids_hk_configs(char version_number[])
01305 {
01306
01307 APID_Pointer_HK_Configs *apid_ptr_hk_configs;
01308 APID_Pointer_HK_Configs *top_apid_ptr_hk_configs;
01309 APID_HKPFD_Files *top_apid_hkpfd_files;
01310 APID_HKPFD_Files *hkpfd_files;
01311 GTCIDS_Version_Number *top_ptr_gtcids_data;
01312 int apid_array[MAX_APID_POINTERS];
01313 int number_of_apids, i;
01314 char file_version_number[50];
01315 char *ptr_fvn;
01316 HK_Config_Files *hk_configs;
01317 Keyword_Parameter *hk_keyword;
01318
01319
01320 ptr_fvn=file_version_number;
01321
01322 top_ptr_gtcids_data = read_gtcids_hk_file(top_apid_ptr_hk_configs);
01323
01324 ptr_fvn=find_file_version_number(top_ptr_gtcids_data, version_number);
01325
01326 if ((top_apid_hkpfd_files = read_all_hk_config_files(ptr_fvn)) == NULL)
01327 return ERROR_HK_NOSUCHDIR;
01328
01329 number_of_apids = 0;
01330 memset(apid_array, 0, sizeof(apid_array));
01331 for(hkpfd_files=top_apid_hkpfd_files; hkpfd_files;
01332 hkpfd_files=hkpfd_files->next)
01333 {
01334
01335 for (i=0; i<number_of_apids; i++)
01336 {
01337 if (apid_array[i] == hkpfd_files->apid)
01338 break;
01339 }
01340 if (i >= number_of_apids) \
01341 {
01342
01343 apid_array[i]= hkpfd_files->apid;
01344 number_of_apids++;
01345 }
01346 }
01347
01348 for ( i=0; i < number_of_apids; i++)
01349 {
01350 if ( i == 0)
01351 {
01352
01353 apid_ptr_hk_configs = (APID_Pointer_HK_Configs *)malloc(sizeof(APID_Pointer_HK_Configs));
01354 top_apid_ptr_hk_configs = apid_ptr_hk_configs;
01355 }
01356 else
01357 {
01358
01359 apid_ptr_hk_configs->next = (APID_Pointer_HK_Configs *)malloc(sizeof(APID_Pointer_HK_Configs));
01360 apid_ptr_hk_configs = apid_ptr_hk_configs->next;
01361 }
01362 apid_ptr_hk_configs->apid = apid_array[i];
01363 apid_ptr_hk_configs->next= NULL;
01364 apid_ptr_hk_configs->ptr_hk_configs= (HK_Config_Files*)NULL;
01365 }
01366
01367 apid_ptr_hk_configs = top_apid_ptr_hk_configs;
01368 for(i=0; i < number_of_apids; i++)
01369 {
01370 load_config_data( top_apid_hkpfd_files, apid_ptr_hk_configs);
01371 apid_ptr_hk_configs = apid_ptr_hk_configs->next;
01372 }
01373
01374 load_gtcids_data(top_ptr_gtcids_data, top_apid_ptr_hk_configs);
01375
01376 global_apid_configs = top_apid_ptr_hk_configs;
01377
01378 deallocate_apid_hkpfd_files_nodes(top_apid_hkpfd_files) ;
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405 return SUCCESS;
01406 }
01407
01408 HK_Config_Files* check_packet_version_number( HK_Config_Files *ptr_to_configs,
01409 char *version_number )
01410 {
01411 while(ptr_to_configs != NULL )
01412 {
01413 if(!strcmp(ptr_to_configs->parameter_version_number, version_number))
01414 {
01415 break;
01416 }
01417 ptr_to_configs = ptr_to_configs->next;
01418 }
01419 return ptr_to_configs;
01420 }
01421
01422 int check_free_configs_flag(void)
01423 {
01424
01425 int status;
01426 FILE *file_ptr;
01427 char *directory ;
01428 char *filename;
01429 char directory_filename[MAX_FILE_NAME];
01430
01431
01432 directory = getenv("HK_CONFIG_DIRECTORY");
01433 filename= getenv("HK_FREE_FLAG_FILE");
01434 if(filename == NULL)
01435 filename = "HK_FREE_CONFIG_FLAG_FILE";
01436 if(directory == NULL)
01437 directory = "../../tables/hk_config_file";
01438 sprintf(directory_filename, "%s/%s", directory, filename);
01439
01440 file_ptr = fopen(directory_filename, "r");
01441 if (file_ptr == NULL)
01442 {
01443 status =0;
01444 }
01445 else
01446 {
01447 status = 1;
01448 fclose(file_ptr);
01449 }
01450 return status;
01451 }
01452
01453 void deallocate_apid_ptr_hk_config_nodes(void)
01454 {
01455 extern APID_Pointer_HK_Configs *global_apid_configs;
01456 APID_Pointer_HK_Configs *tmp_apid_ptr_hk_configs;
01457 APID_Pointer_HK_Configs *prev_apid_ptr_hk_configs;
01458 HK_Config_Files *tmp_ptr_hk_configs;
01459 HK_Config_Files *prev_ptr_hk_configs;
01460 Keyword_Parameter *tmp_keyword_node;
01461 Keyword_Parameter *prev_keyword_node;
01462 DSC_Conversion *tmp_dsc_node;
01463 DSC_Conversion *prev_dsc_node;
01464 ALG_Conversion *tmp_alg_node;
01465 ALG_Conversion *prev_alg_node;
01466 int free_flag=0;
01467
01468
01469 if (!(free_flag= check_free_configs_flag()))
01470 {
01471
01472 return;
01473 }
01474
01475
01476 tmp_apid_ptr_hk_configs=global_apid_configs;
01477
01478
01479 for(prev_apid_ptr_hk_configs=tmp_apid_ptr_hk_configs;
01480 tmp_apid_ptr_hk_configs;
01481 prev_apid_ptr_hk_configs = tmp_apid_ptr_hk_configs )
01482 {
01483 for(prev_ptr_hk_configs=tmp_ptr_hk_configs=tmp_apid_ptr_hk_configs->ptr_hk_configs;
01484 tmp_ptr_hk_configs;
01485 prev_ptr_hk_configs =tmp_ptr_hk_configs)
01486 {
01487 for(prev_keyword_node=tmp_keyword_node=
01488 tmp_ptr_hk_configs->keywords;
01489 tmp_keyword_node;
01490 prev_keyword_node =tmp_keyword_node)
01491 {
01492
01493 for(prev_dsc_node=tmp_dsc_node=tmp_keyword_node->dsc_ptr;
01494 tmp_dsc_node; prev_dsc_node = tmp_dsc_node)
01495 {
01496 tmp_dsc_node= tmp_dsc_node->next;
01497 free( prev_dsc_node);
01498 }
01499
01500 tmp_alg_node=tmp_keyword_node->alg_ptr;
01501 if (tmp_keyword_node)
01502 {
01503 free( tmp_alg_node );
01504 }
01505 tmp_keyword_node=tmp_keyword_node->next;
01506 free(prev_keyword_node);
01507 }
01508 tmp_ptr_hk_configs =tmp_ptr_hk_configs->next;
01509 free(prev_ptr_hk_configs);
01510 }
01511 tmp_apid_ptr_hk_configs = tmp_apid_ptr_hk_configs->next ;
01512 free(prev_apid_ptr_hk_configs);
01513 }
01514
01515 global_apid_configs=NULL;
01516
01517 }
01518
01519 HK_Config_Files* reread_all_files(APID_Pointer_HK_Configs *apid_ptr_configs,char version_number[])
01520 {
01521
01522 int apid;
01523 APID_Pointer_HK_Configs *p, *prev_p;
01524 char file_version_number[50];
01525 char *ptr_fvn;
01526 int found_flag;
01527 GTCIDS_Version_Number *ptr_gtcids_data;
01528 APID_HKPFD_Files *top_hkpfd_files;
01529 APID_HKPFD_Files *hkpfd_files;
01530
01531
01532 ptr_fvn=file_version_number;
01533 ptr_gtcids_data = global_gtcids_vn;
01534
01535
01536 apid= apid_ptr_configs->apid;
01537
01538 ptr_fvn=find_file_version_number(ptr_gtcids_data, version_number);
01539
01540 if ((top_hkpfd_files = read_all_hk_config_files(ptr_fvn)) == NULL)
01541 return (HK_Config_Files*)NULL;
01542
01543 for(hkpfd_files=top_hkpfd_files; hkpfd_files;
01544 hkpfd_files=hkpfd_files->next)
01545 {
01546 found_flag=0;
01547 for(p=global_apid_configs; p ; p=p->next)
01548 {
01549 if ( p->apid == hkpfd_files->apid)
01550 {
01551 found_flag=1;
01552 break;
01553 }
01554 prev_p=p;
01555 }
01556 if (!found_flag)
01557 {
01558
01559 prev_p->next = (APID_Pointer_HK_Configs *) malloc (sizeof (APID_Pointer_HK_Configs));
01560 prev_p->next->next= NULL;
01561 prev_p->next->ptr_hk_configs= (HK_Config_Files*) NULL;
01562 prev_p->next->apid=hkpfd_files->apid;
01563 }
01564 }
01565
01566 for(p=global_apid_configs; p ; p=p->next)
01567 {
01568 load_config_data(top_hkpfd_files, p);
01569 }
01570
01571 p=global_apid_configs;
01572 load_gtcids_data(ptr_gtcids_data, p);
01573
01574 hkpfd_files=top_hkpfd_files;
01575 deallocate_apid_hkpfd_files_nodes(hkpfd_files) ;
01576
01577 p = global_apid_configs;
01578 while (p)
01579 {
01580 if( p->apid == apid )
01581 {
01582 return p->ptr_hk_configs;
01583 }
01584 p = p->next;
01585 }
01586
01587 return (HK_Config_Files*)NULL;
01588 }
01589
01590 int decode_hk_keywords(unsigned short *word_ptr, int apid, HK_Keyword_t **kw_head)
01591 {
01592
01593 HK_Keywords_Format *ptr_hk_keywords;
01594 HK_Keywords_Format *top_ptr_hk_keywords;
01595 APID_Pointer_HK_Configs *apid_configs;
01596 HK_Config_Files *config_files;
01597 int status;
01598 char version_number[MAX_CHAR_VERSION_NUMBER];
01599 HK_Config_Files *matching_config;
01600 char *init_hdr_apid;
01601 char *init_hdr_pkt_version;
01602
01603
01604 matching_config= (HK_Config_Files *)NULL;
01605
01606
01607 init_hdr_apid= getenv("HK_INITIAL_HEADER_APID");
01608 init_hdr_pkt_version= getenv("HK_INITIAL_HEADER_PKT_VERSION");
01609 if( !init_hdr_apid || !init_hdr_pkt_version)
01610 {
01611 ERRMSG("Please set. Could not find environment variables: <HK_INITIAL_HEADER_APID> <HK_INITIAL_HEADER_PKT_VERSION>");
01612 return HK_DECODER_ERROR_UNKNOWN_ENV_VARIABLE;
01613 }
01614
01615
01616 if (apid == 431)
01617 {
01618 strcpy(version_number,init_hdr_pkt_version);
01619 }
01620 else
01621 {
01622 get_version_number(word_ptr, version_number);
01623 }
01624
01625
01626 if (!global_apid_configs )
01627 {
01628 load_all_apids_hk_configs(version_number);
01629 }
01630
01631
01632 apid_configs = global_apid_configs;
01633 while(apid_configs)
01634 {
01635 if (apid_configs->apid == apid)
01636 break;
01637 else
01638 apid_configs = apid_configs->next;
01639 }
01640
01641 if ( apid_configs == NULL)
01642 {
01643
01644 printkerr("ERROR at %s, line %d: This apid <%x> does not have valid "
01645 "config data to decode packet. Check if config files exist. "
01646 "If don't exist, run make_hkpdf.pl script to create files.\n",
01647 __FILE__, __LINE__, apid);
01648 return HK_DECODER_ERROR_UNKNOWN_APID;
01649 }
01650
01651
01652 config_files = apid_configs->ptr_hk_configs;
01653
01654
01655
01656
01657
01658
01659
01660 matching_config = check_packet_version_number(config_files,version_number);
01661 if ( matching_config == NULL )
01662 {
01663
01664
01665
01666
01667
01668 config_files = reread_all_files(apid_configs, version_number);
01669 matching_config = check_packet_version_number(config_files,version_number);
01670 if ( matching_config != NULL )
01671 {
01672
01673
01674 ;
01675 }
01676 }
01677 if ( matching_config == NULL )
01678 {
01679
01680 ERRMSG("Could not find version number even after re-reading hk config files.");
01681 return HK_DECODER_ERROR_CANNOT_FIND_VER_NUM;
01682 }
01683
01684 if (ptr_hk_keywords = load_hk_configs( matching_config ))
01685 {
01686
01687 if (status = load_hk_values( word_ptr, ptr_hk_keywords))
01688 return status;
01689
01690 if (!( status = load_engr_values(ptr_hk_keywords, kw_head)))
01691 {
01692
01693 deallocate_hk_keywords_format(ptr_hk_keywords);
01694 status = HK_DECODER_SUCCESSFUL;
01695 deallocate_apid_ptr_hk_config_nodes();
01696 return status;
01697 }
01698 }
01699 else
01700 {
01701 ERRMSG("Could not find config data for this version number");
01702 status = HK_DECODER_ERROR_CANNOT_LOAD_HK_VALUES;
01703 }
01704 return status;
01705 }
01706
01707
01708
01709
01710
01711
01712
01713 HK_Keyword_t *copy_hk_keywords(HK_Keyword_t *head)
01714 {
01715 HK_Keyword_t *newhead, *p;
01716
01717 if (head)
01718 {
01719 newhead = malloc(sizeof(HK_Keyword_t));
01720 assert(newhead);
01721 p = newhead;
01722 memcpy(p, head, sizeof(HK_Keyword_t));
01723 if (head->eng_type == DRMS_TYPE_STRING)
01724 p->eng_value.string_val = strdup(head->eng_value.string_val);
01725 head = head->next;
01726 while(head)
01727 {
01728 p->next = malloc(sizeof(HK_Keyword_t));
01729 assert(p->next);
01730 p = p->next;
01731 memcpy(p, head, sizeof(HK_Keyword_t));
01732 if (head->eng_type == DRMS_TYPE_STRING)
01733 p->eng_value.string_val = strdup(head->eng_value.string_val);
01734 head = head->next;
01735 }
01736 }
01737 else
01738 newhead = NULL;
01739
01740 return newhead;
01741 }
01742
01743
01744
01745 CropTable_t croptables[MAX_CROPID+1];
01746 unsigned short *lutables[MAX_LUTID+1];
01747 unsigned short *ilutables[MAX_LUTID+1];
01748 static int table_initialized = 0;
01749 static unsigned char numzero16[1<<16];
01750
01751 static unsigned short *decode_im_pdu(unsigned short *w, IM_PDU_Packet_t *p)
01752 {
01753
01754 p->im_pdu_count = ((long long) (*w & 0x3ff)) << 32;
01755 p->im_pdu_id = *w++ >> 10;
01756
01757 p->im_pdu_count |= *w++ << 16;
01758
01759 p->im_pdu_count |= *w++;
01760
01761 p->fhp = (*w++) & 0x7ff;
01762 return w;
01763 }
01764
01765 static unsigned short *decode_ccsds(unsigned short *w, CCSDS_Packet_t *p)
01766 {
01767
01768 p->version = (*w >> 13) & 0x7;
01769 p->type = (*w >> 12) & 1;
01770 p->shf = (*w >> 11) & 1;
01771 p->apid = (*w++) & 0x7ff;
01772
01773 p->sf = (*w >> 14) & 0x3;
01774 p->ssc = (*w++) & 0x3fff;
01775
01776
01777
01778
01779 p->length = *w++ + 1;
01780 return w;
01781 }
01782
01783
01784 static unsigned short *decode_scidata(unsigned short *w, SciDataPacket_t *p)
01785 {
01786 int i;
01787
01788 p->shs = (*w++)<<16;
01789
01790 p->shs |= *w++;
01791
01792 p->shss = (*w++)<<16;
01793
01794 p->shss |= *w++;
01795
01796 for (i=0; i<4; i++)
01797 p->ccdhead[i] = *w++;
01798
01799 p->cropid = *w >> 4;
01800 p->romode = (*w >> 2) & 0x3;
01801 p->headererr = (*w >> 1) & 0x1;
01802 p->oflow = *w++ & 0x1;
01803
01804 p->tapcode = *w >> 12;
01805 p->bitselectid = (*w >> 8) & 0xf;
01806 p->compid = *w++ & 0xff;
01807
01808 p->lutid = *w >> 8;
01809 p->offset = (*w++ & 0xff) << 16;
01810
01811 p->offset |= *w++;
01812
01813 p->data = w;
01814 return w;
01815 }
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826 static int decompress_new_context(unsigned int FSN, unsigned int FID)
01827 {
01828 Decompress_Context_t *C;
01829
01830 if (numcontexts>=MAXCONTEXTS)
01831 {
01832 printkerr("Maximum number of contexts exceeded.\n"
01833 "More than %d images are being decoded simultaneously.\n",
01834 MAXCONTEXTS);
01835 return -1;
01836 }
01837 else
01838 {
01839 C = malloc(sizeof(Decompress_Context_t));
01840 memset(C,0,sizeof(Decompress_Context_t));
01841 C->ID = UNIQUEID(FSN,FID);
01842
01843
01844 C->image = malloc(sizeof(Image_t));
01845 C->image = memset(C->image,0,sizeof(Image_t));
01846 C->image->ID = C->ID;
01847 C->image->keywords = NULL;
01848 C->image->next = NULL;
01849
01850
01851
01852
01853
01854 C->image->firstpacket.cropid = -1;
01855
01856
01857 C->image->stat.ID = C->ID;
01858 C->image->stat.starttime = time(NULL);
01859
01860
01861 Context[numcontexts] = C;
01862 ++numcontexts;
01863
01864 return numcontexts-1;
01865 }
01866 }
01867
01868
01869
01870
01871
01872
01873
01874
01875 int decompress_status_all(Decompress_Stat_t **stat)
01876 {
01877 int i;
01878 if (numcontexts<=0)
01879 {
01880 *stat = NULL;
01881 return 0;
01882 }
01883 else
01884 {
01885 *stat = malloc(numcontexts*sizeof(Decompress_Stat_t));
01886 for (i=0; i<numcontexts; i++)
01887 (*stat)[i] = Context[i]->image->stat;
01888 return numcontexts;
01889 }
01890 }
01891
01892
01893
01894
01895
01896 void decompress_print_status( Decompress_Stat_t *stat)
01897 {
01898 if (stat==NULL)
01899 return;
01900
01901 printk(" ID = %llu = 0x%0llx\n (FSN,FID) = (%d, %d) = (0x%0x, 0x%0x).\n",
01902 stat->ID,stat->ID,ID2FSN(stat->ID),ID2FID(stat->ID),
01903 ID2FSN(stat->ID),ID2FID(stat->ID));
01904 printk(" %hu packets received.\n", stat->npackets);
01905 printk(" %u pixels (%d%%) out of %u received.\n",
01906 stat->numpix, (100*stat->numpix)/stat->totalpix,
01907 stat->totalpix);
01908 printk(" First packet received at %s",ctime(&(stat->starttime)));
01909 printk(" backup_occured = %hhu\n",stat->backup_occured);
01910 printk(" skip_occured = %hhu\n",stat->skip_occured);
01911 }
01912
01913
01914
01915 static int decompress_findcontext(unsigned int FSN, unsigned int FID)
01916 {
01917 int ctx;
01918 long long ID;
01919
01920 ID = UNIQUEID(FSN,FID);
01921 for (ctx=0; ctx<numcontexts; ctx++)
01922 if (Context[ctx] != NULL && Context[ctx]->ID == ID)
01923 break;
01924 return ctx;
01925 }
01926
01927
01928 void decompress_undotransform(const unsigned int N, const unsigned int R,
01929 const unsigned int ILUTID,
01930 const unsigned int numpix, unsigned short *pixels)
01931 {
01932 unsigned int i;
01933 unsigned short nmask;
01934 unsigned short *ILUT = ilutables[ILUTID];
01935
01936 assert(N>=NMIN && N<=NMAX);
01937 assert(R<=RMAX);
01938 nmask = (1<<N)-1;
01939
01940 if (ILUTID==0) {
01941 for (i=0; i<numpix; i++)
01942 if (pixels[i] != 0xffff)
01943 pixels[i] = (pixels[i] & nmask) << R;
01944 else
01945 pixels[i] = 0x8000;
01946 } else {
01947 for (i=0; i<numpix; i++)
01948 if (pixels[i] != 0xffff)
01949 pixels[i] = (ILUT[pixels[i]] & nmask) << R;
01950 else
01951 pixels[i] = 0x8000;
01952 }
01953 }
01954
01955
01956
01957 void decompress_uncrop(const unsigned int CROPID, const unsigned int numpix,
01958 unsigned short *pixels, Image_t *image)
01959 {
01960 unsigned int row, skip, take, total, width, height;
01961 unsigned short *table;
01962 short *data, *t;
01963 int tapcode;
01964 int i,j;
01965
01966 width = croptables[CROPID].width;
01967 height = croptables[CROPID].height;
01968 table = croptables[CROPID].table;
01969 data = image->data;
01970 tapcode = image->firstpacket.tapcode;
01971
01972 if (!CROPID) {
01973 memcpy(data, pixels, 2*numpix);
01974 } else {
01975 total = 0;
01976 for (row=0; row<height && total<numpix; row++)
01977 {
01978 skip = table[2*row];
01979 take = table[2*row+1];
01980 if (total+take>numpix)
01981 take = numpix-total;
01982 memcpy(&data[row*width + skip], &pixels[total],
01983 take*sizeof(unsigned short));
01984 total += take;
01985 }
01986 }
01987
01988
01989
01990
01991 width = image->width;
01992 height = image->height;
01993 switch (tapcode) {
01994 case 0:
01995 t = malloc(2*width*height);
01996 for (i=0; i<height/2; ++i) {
01997 memcpy(t+i*width, data+i*width/2, width);
01998 memcpy(t+(height-1-i)*width, data+(height+height/2+i)*width/2, width);
01999 for (j=0; j<width/2; ++j) {
02000 t[width-1-j+i*width] = data[j+(height/2+i)*width/2];
02001 t[width-1-j+(height-1-i)*width] = data[j+(height+i)*width/2];
02002 }
02003 }
02004 free(data);
02005 image->data = t;
02006 break;
02007 case 1:
02008 t = malloc(2*width*height);
02009 for (i=0; i<height; ++i) {
02010 memcpy(t+i*width, data+i*width/2, width);
02011 for (j=0; j<width/2; ++j)
02012 t[width-1-j+i*width] = data[j+(height+i)*width/2];
02013 }
02014 free(data);
02015 image->data = t;
02016 break;
02017 case 2:
02018 t = malloc(2*width*height);
02019 for (i=0; i<height/2; ++i)
02020 for (j=0; j<width; ++j) {
02021 t[j+i*width] = data[width-1-j+i*width];
02022 t[j+(height-1-i)*width] = data[width-1-j+(i+height/2)*width];
02023 }
02024 free(data);
02025 image->data = t;
02026 break;
02027 case 3:
02028 t = malloc(2*width*height);
02029 for (i=0; i<height; ++i) {
02030 memcpy(t+(height-1-i)*width, data+(i+height)*width/2, width);
02031 for (j=0; j<width/2; ++j)
02032 t[width-1-j+(height-1-i)*width] = data[j+i*width/2];
02033 }
02034 free(data);
02035 image->data = t;
02036 break;
02037 case 4:
02038 t = malloc(2*width*height);
02039 for (i=0; i<height/2; ++i) {
02040 memcpy(t+(height-1-i)*width, data+(i+height/2)*width, 2*width);
02041 memcpy(t+i*width, data+i*width, 2*width);
02042 }
02043 free(data);
02044 image->data = t;
02045 break;
02046 case 5:
02047
02048 break;
02049 case 6:
02050 t = malloc(2*width*height);
02051 for (i=0; i<height; ++i)
02052 for (j=0; j<width; ++j)
02053 t[j+i*width] = data[width-1-j+i*width];
02054 free(data);
02055 image->data = t;
02056 break;
02057 case 7:
02058 t = malloc(2*width*height);
02059 for (i=0; i<height; ++i)
02060 for (j=0; j<width; ++j)
02061 t[j+i*width] = data[width-1-j+(height-1-i)*width];
02062 free(data);
02063 image->data = t;
02064 break;
02065 case 8:
02066 t = malloc(2*width*height);
02067 for (i=0; i<height; ++i)
02068 memcpy(t+i*width, data+(height-1-i)*width, 2*width);
02069 free(data);
02070 image->data = t;
02071 break;
02072 }
02073 }
02074
02075
02076
02077
02078
02079 Image_t *decompress_free_context(unsigned int ctx, int discard_image)
02080 {
02081 Image_t *im;
02082 Decompress_Context_t *C;
02083 HK_Keyword_t *kw, *tmp;
02084
02085
02086 C = Context[ctx];
02087 Context[ctx] = Context[numcontexts-1];
02088 --numcontexts;
02089 Context[numcontexts] = NULL;
02090
02091 free(C->pixelbuf);
02092 if (discard_image)
02093 {
02094 deallocate_hk_keyword(C->image->keywords);
02095 free(C->image->data);
02096 free(C->image);
02097 im = NULL;
02098 }
02099 else
02100 im = C->image;
02101 free(C);
02102
02103 return im;
02104 }
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119 static Image_t *decompress_prepare_image(int ctx)
02120 {
02121 Image_t *im;
02122 unsigned int N, R;
02123 SciDataPacket_t *scipack;
02124 Decompress_Stat_t *stat;
02125
02126 im = Context[ctx]->image;
02127 scipack = &(im->firstpacket);
02128 stat = &im->stat;
02129 N = scipack->compid >> 3;
02130 if (N==0) N=16;
02131 R = scipack->bitselectid;
02132
02133 decompress_undotransform(N,R,scipack->lutid,stat->totalpix,Context[ctx]->pixelbuf);
02134 decompress_uncrop(scipack->cropid,stat->totalpix,Context[ctx]->pixelbuf, im);
02135
02136
02137 return decompress_free_context(ctx, 0);
02138 }
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150 int decompress_flush_image(unsigned int FSN, unsigned int FID,
02151 Image_t **image)
02152 {
02153 int ctx;
02154
02155 ctx = decompress_findcontext(FSN,FID);
02156 if (ctx>=numcontexts)
02157 {
02158 *image = NULL;
02159 return ERROR_NOSUCHIMAGE;
02160 }
02161 if (!Context[ctx]->pixelbuf) {
02162 *image = NULL;
02163 return ERROR_EMPTY_IMAGE_CONTEXT;
02164 }
02165 *image = decompress_prepare_image(ctx);
02166 return SUCCESS;
02167 }
02168
02169
02170
02171 int decompress_writefitsimage(const char* file, Image_t *image, int compress)
02172 {
02173 int n_kw, hlen;
02174 char *p, *head;
02175 SciDataPacket_t *h;
02176 HK_Keyword_t *kw;
02177 int npkts, missvals;
02178
02179 missvals = image->stat.totalpix - image->stat.numpix;
02180 npkts = image->stat.npackets;
02181
02182 kw = image->keywords;
02183 n_kw = 0;
02184 while(kw)
02185 {
02186 n_kw++;
02187 kw = kw->next;
02188 }
02189 hlen = ((n_kw+15+35)/36)*36*80;
02190 head = malloc(hlen);
02191 assert(head);
02192 memset(head,' ',hlen);
02193 p = head;
02194
02195 h = &image->firstpacket;
02196 snprintf(p,80,"SHS = %u",h->shs);
02197 p += 80;
02198 snprintf(p,80,"SHSS = %u",h->shss);
02199 p += 80;
02200 snprintf(p,80,"FSN = %u",ID2FSN(image->ID));
02201 p += 80;
02202
02203
02204
02205 snprintf(p,80,"CROPID = %d",h->cropid);
02206 p += 80;
02207 snprintf(p,80,"ROMODE = %d",h->romode);
02208 p += 80;
02209 snprintf(p,80,"HEADRERR= %d",h->headererr);
02210 p += 80;
02211 snprintf(p,80,"OVERFLOW= %d",h->oflow);
02212 p += 80;
02213 snprintf(p,80,"TAPCODE = %d",h->tapcode);
02214 p += 80;
02215 snprintf(p,80,"BITSELID= %d",h->bitselectid);
02216 p += 80;
02217 snprintf(p,80,"LUTID = %d",h->lutid);
02218 p += 80;
02219 snprintf(p,80,"COMPID = %d",h->compid);
02220 p += 80;
02221 snprintf(p,80,"OFFSET = %d",h->offset);
02222 p += 80;
02223 snprintf(p,80,"MISSVALS= %d",missvals);
02224 p += 80;
02225 snprintf(p,80,"NUMPKTS = %d",npkts);
02226 p += 80;
02227 kw = image->keywords;
02228 while(kw)
02229 {
02230 if(kw->eng_type == DRMS_TYPE_STRING)
02231 {
02232 snprintf(p,80,"%-8s= %s",kw->fitsname, kw->eng_value.string_val);
02233 }
02234 else if(kw->eng_type == DRMS_TYPE_UINT8)
02235 {
02236 snprintf(p,80,"%-8s= %"PRIu8,kw->fitsname, kw->eng_value.uint8_val);
02237 }
02238 else if (kw->eng_type == DRMS_TYPE_UINT16)
02239 {
02240 snprintf(p,80,"%-8s= %"PRIu16,kw->fitsname, kw->eng_value.uint16_val);
02241 }
02242 else if (kw->eng_type == DRMS_TYPE_UINT32)
02243 {
02244 snprintf(p,80,"%-8s= %"PRIu32,kw->fitsname, kw->eng_value.uint32_val);
02245 }
02246 else if (kw->eng_type == DRMS_TYPE_DOUBLE)
02247 {
02248 snprintf(p,80,"%-8s= %lf",kw->fitsname, kw->eng_value.double_val);
02249 }
02250 else if (kw->eng_type == DRMS_TYPE_INT8)
02251 {
02252 snprintf(p,80,"%-8s= %"PRId8,kw->fitsname, kw->eng_value.int8_val);
02253 }
02254 else if (kw->eng_type == DRMS_TYPE_INT16)
02255 {
02256 snprintf(p,80,"%-8s= %"PRId16,kw->fitsname, kw->eng_value.int16_val);
02257 }
02258 else if (kw->eng_type == DRMS_TYPE_INT32)
02259 {
02260 snprintf(p,80,"%-8s= %"PRId32,kw->fitsname, kw->eng_value.int32_val);
02261 }
02262 else
02263 {
02264 printkerr("Unexpected execution of else. All keywords should have type values. This one does not < %s>\n",kw->name);
02265 }
02266
02267 kw = kw->next;
02268 p += 80;
02269 }
02270
02271
02272 if (compress<=1)
02273 return fits_writeimage_raw(file, compress, (int) (p-head), head,
02274 image->width, image->height, image->data);
02275 else
02276 {
02277 printkerr("Invalid value (%d) for compress.\n",compress);
02278 return 1;
02279 }
02280 }
02281
02282 void decompress_free_hk(CCSDS_Packet_t *p)
02283 {
02284 CCSDS_Packet_t *tmp;
02285 while(p)
02286 {
02287 if (p->keywords)
02288 deallocate_hk_keyword(p->keywords);
02289 tmp = p->next;
02290 free(p);
02291 p = tmp;
02292 }
02293 }
02294
02295 void decompress_free_images(Image_t *image)
02296 {
02297 Image_t *ip;
02298 HK_Keyword_t *kw, *ktmp;
02299 while (image)
02300 {
02301 deallocate_hk_keyword(image->keywords);
02302 free(image->data);
02303 ip = image->next;
02304 free(image);
02305 image = ip;
02306 }
02307 }
02308
02309 static void decompress_initnonzerotables(void)
02310 {
02311 unsigned int i,nz,b;
02312
02313 for (i=0; i<=0xffff; i++)
02314 {
02315 b = i;
02316 nz = 0;
02317 while ((b&1) == 0 && nz<16)
02318 {
02319 ++nz;
02320 b = b>>1;
02321 }
02322 numzero16[i] = nz;
02323 }
02324 table_initialized = 1;
02325 }
02326
02327 static void decompress_initcroptables(void)
02328 {
02329 unsigned int i;
02330
02331
02332 for (i=0; i<MAX_CROPID; i++)
02333 {
02334 croptables[i].width = 0;
02335 croptables[i].height = 0;
02336 croptables[i].table = NULL;
02337 }
02338 #if 0
02339
02340 assert(MAX_CROPID>=5);
02341 decompress_square_croptable(&croptables[0],256);
02342 decompress_square_croptable(&croptables[1],1024);
02343 decompress_square_croptable(&croptables[2],4096);
02344 decompress_circular_croptable(&croptables[3],256);
02345 decompress_circular_croptable(&croptables[4],1024);
02346 decompress_circular_croptable(&croptables[5],4096);
02347 #endif
02348 }
02349
02350 static void decompress_initlookuptables(void)
02351 {
02352 unsigned int i;
02353 unsigned short maxval;
02354 double x, finv;
02355
02356
02357 for (i=0; i<MAX_LUTID; i++)
02358 {
02359 lutables[i] = NULL;
02360 ilutables[i] = NULL;
02361 }
02362 #if 0
02363 assert(MAX_LUTID>=2);
02364 maxval = (1<<NMAX)-1;
02365 lutables[0] = malloc((maxval+1)*sizeof(short));
02366 lutables[1] = malloc((maxval+1)*sizeof(short));
02367 lutables[2] = malloc((maxval+1)*sizeof(short));
02368 ilutables[0] = malloc((maxval+1)*sizeof(short));
02369 ilutables[1] = malloc((maxval+1)*sizeof(short));
02370 ilutables[2] = malloc((maxval+1)*sizeof(short));
02371 for (i=0, x=0; i<(1<<NMAX); i++, x += 1.0)
02372 {
02373
02374 lutables[0][i] = i;
02375 ilutables[0][i] = i;
02376
02377 lutables[1][i] = floor(sqrt(128*x)+0.5);
02378 finv = floor((x*x)/128+0.5);
02379 ilutables[1][i] = finv > (float)maxval ? maxval : (unsigned short) finv;
02380
02381 lutables[2][i] = floor(sqrt(1024*x)+0.5);
02382 finv = floor((x*x)/1024+0.5);
02383 ilutables[2][i] = finv > (float)maxval ? maxval : (unsigned short) finv;
02384 }
02385 #endif
02386 }
02387
02388 void decompress_inittables(void)
02389 {
02390 decompress_initnonzerotables();
02391 decompress_initcroptables();
02392 decompress_initlookuptables();
02393 }
02394
02395 int decompress_read_croptable(const char *filename, const int cropid, CropTable_t *C)
02396 {
02397 unsigned int row;
02398 FILE *fh;
02399 unsigned short skip, take;
02400 int id;
02401
02402 fh = fopen(filename,"r");
02403 if (fh == NULL)
02404 {
02405 printkerr("Failed to open crop table file %s.\n",filename);
02406 return ERROR_BAD_OR_MISSING_CROP_TABLE;
02407 }
02408 C->totalpix = 0;
02409 fscanf(fh,"%d",&id);
02410 if (id != cropid) {
02411 printkerr("Crop table with the wrong ID %d supplied.\n", id);
02412 return ERROR_BAD_OR_MISSING_CROP_TABLE;
02413 }
02414 fscanf(fh,"%u",&C->width);
02415 fscanf(fh,"%u",&C->height);
02416 C->table = malloc(2*C->height*sizeof(unsigned short));
02417 for (row=0; row<C->height; row++)
02418 {
02419 if (fscanf(fh,"%hu",&skip) != 1)
02420 {
02421 printk("Crop table file %s is too short.\n",filename);
02422 return ERROR_BAD_OR_MISSING_CROP_TABLE;
02423 }
02424 C->table[2*row] = skip;
02425 if (fscanf(fh,"%hu",&take) != 1)
02426 {
02427 printk("Crop table file %s is too short.\n",filename);
02428 return ERROR_BAD_OR_MISSING_CROP_TABLE;
02429 }
02430 C->table[2*row+1] = take;
02431 C->totalpix += take;
02432 }
02433 fclose(fh);
02434 return 0;
02435 }
02436
02437 int decompress_read_lutable(const char *filename, const int lutid, unsigned short *ILUT)
02438 {
02439 int i, id;
02440 FILE *fh;
02441
02442 fh = fopen(filename,"r");
02443 if (fh == NULL)
02444 {
02445 printkerr("Failed to open lookup table file %s.\n",filename);
02446 return ERROR_BAD_OR_MISSING_LOOKUP_TABLE;
02447 }
02448 fscanf(fh,"%d", &id);
02449 if (id != lutid) {
02450 printkerr("ILU table with the wrong ID %d supplied.\n", id);
02451 return ERROR_BAD_OR_MISSING_LOOKUP_TABLE;
02452 }
02453 for (i=0; i<(1<<14); i++)
02454 {
02455 fscanf(fh,"%hu",ILUT++);
02456 }
02457 fclose(fh);
02458 return 0;
02459 }
02460
02461 static int decompress_context_initimage(int ctx, SciDataPacket_t *scipack)
02462 {
02463 Decompress_Context_t *C;
02464 int cropid, lutid;
02465 unsigned int buflen;
02466 int pad=0;
02467 int errcode;
02468
02469 C = Context[ctx];
02470
02471
02472 memcpy(&(C->image->firstpacket), scipack, sizeof(SciDataPacket_t));
02473
02474
02475 cropid = scipack->cropid;
02476 if (cropid < 0 || cropid > MAX_CROPID)
02477 return ERROR_INVALIDCROPID;
02478
02479 if (cropid == 0) {
02480 croptables[cropid].totalpix = 4096*4096;
02481 switch (scipack->tapcode) {
02482 case 2:
02483 case 4:
02484 case 5:
02485 case 6:
02486 case 7:
02487 case 8:
02488 croptables[cropid].width = 4096;
02489 croptables[cropid].height = 4096;
02490 break;
02491 default:
02492 croptables[cropid].width = 2048;
02493 croptables[cropid].height = 8192;
02494 }
02495 } else if (croptables[cropid].width == 0) {
02496 char filename[64];
02497 if (isHMI)
02498 snprintf(filename, 64, "/home/production/cvs/EGSE/tables/crop/hmi/crop%d", cropid);
02499 else
02500 snprintf(filename, 64, "/home/production/cvs/EGSE/tables/crop/aia/crop%d", cropid);
02501 errcode=decompress_read_croptable(filename, cropid, &croptables[cropid]);
02502 if (errcode) return errcode;
02503 }
02504
02505 lutid = scipack->lutid;
02506 if (lutid && ilutables[lutid] == NULL) {
02507 char filename[64];
02508 ilutables[lutid] = malloc(16384*2);
02509 if (isHMI)
02510 snprintf(filename, 64, "/home/production/cvs/EGSE/tables/lu/hmi/ilu%d", lutid);
02511 else
02512 snprintf(filename, 64, "/home/production/cvs/EGSE/tables/lu/aia/ilu%d", lutid);
02513 errcode=decompress_read_lutable(filename, lutid, ilutables[lutid]);
02514 if (errcode) return errcode;
02515 }
02516
02517
02518 C->image->stat.totalpix = croptables[cropid].totalpix;
02519 buflen = croptables[cropid].width*croptables[cropid].height
02520 * sizeof(unsigned short);
02521
02522
02523 C->pixelbuf = malloc(buflen);
02524 memset(C->pixelbuf, 0xff, buflen);
02525
02526 C->image->width = croptables[cropid].width;
02527 C->image->height = croptables[cropid].height;
02528 if (scipack->tapcode ==0 || scipack->tapcode ==1 || scipack->tapcode ==3) {
02529 C->image->width *= 2;
02530 C->image->height /= 2;
02531 }
02532
02533 if (buflen % 2880)
02534 pad = 2880 - (buflen % 2880);
02535 C->image->data = malloc(buflen + pad);
02536 for (int i=0;i<buflen/2;++i) C->image->data[i] = -32768;
02537
02538 memset(((char *) C->image->data)+buflen, 0, pad);
02539 return SUCCESS;
02540 }
02541
02542 static int decompress_packet(const unsigned int N, const unsigned int K,
02543 const unsigned int SAT, unsigned short *pixels,
02544 int *new_count, unsigned short *indata)
02545 {
02546 unsigned int *in;
02547 unsigned int b, nz, sign, nbits, c31mk, c32mnmk;
02548 unsigned kmask, nmask;
02549 unsigned int diff, error;
02550 unsigned int pixcnt, nmk, wordcnt, newcnt=0;
02551 unsigned short oldval, val;
02552
02553 assert(N>=NMIN && N<=NMAX);
02554 assert(K>=KMIN && K<=KMAX);
02555 assert(SAT<=8);
02556 assert(table_initialized);
02557
02558
02559 kmask = (1<<K)-1;
02560 nmask = (1<<N)-1;
02561 nmk = N-K;
02562 c31mk = 31-K;
02563 c32mnmk = 32-nmk;
02564
02565
02566 in = (unsigned int *)indata;
02567 wordcnt = 0;
02568 b = *in++;
02569 oldval = (unsigned short) b;
02570 if (*pixels == 0xffff)
02571 newcnt++;
02572 *pixels++ = oldval;
02573 b = b >> 16;
02574 nbits = 16;
02575 pixcnt = 1;
02576
02577
02578
02579 while ((wordcnt <= PACKETDATAWORDS-3))
02580 {
02581
02582 diff = b & kmask;
02583 if (unlikely(nbits<K))
02584 {
02585 wordcnt += 2;
02586 if (wordcnt >= PACKETDATAWORDS-1)
02587 break;
02588 b = *in++;
02589 diff += (b << nbits) & kmask;
02590 b = b >> (K-nbits);
02591 nbits += c31mk;
02592
02593
02594 sign = b & 1;
02595 b = b>>1;
02596
02597
02598
02599
02600
02601 nz = numzero16[(unsigned short) b];
02602
02603
02604 b = b >> (nz+1);
02605 nbits -= nz+1;
02606 }
02607 else
02608 {
02609 if (likely(nbits>K+1))
02610 {
02611 nbits -= K+1;
02612 b = b >> K;
02613
02614 sign = b & 1;
02615 b = b>>1;
02616
02617
02618 if (likely(nbits<17))
02619 {
02620 nz = numzero16[b];
02621
02622 if (likely(nz<nbits))
02623 {
02624 b = b>>(nz+1);
02625 nbits -= nz+1;
02626
02627 }
02628 else
02629 {
02630 unsigned int tmp;
02631 wordcnt += 2;
02632 if (wordcnt >= PACKETDATAWORDS-1)
02633 break;
02634 b = *in++;
02635 tmp = numzero16[(unsigned short) b];
02636
02637
02638 b = b>>(tmp+1);
02639 nz = nbits + tmp;
02640 nbits = 31-tmp;
02641
02642 }
02643 }
02644 else
02645 {
02646 nz = numzero16[(unsigned short) b];
02647 b = b>>(nz+1);
02648 nbits -= nz+1;
02649
02650 }
02651 }
02652 else
02653 {
02654 if (nbits==K)
02655 {
02656 wordcnt += 2;
02657 if (wordcnt >= PACKETDATAWORDS-1)
02658 break;
02659 b = *in++;
02660
02661 sign = b & 1;
02662 b = b>>1;
02663
02664 nz = numzero16[(unsigned short) b];
02665 b = b>>(nz+1);
02666 nbits = 30 - nz;
02667 }
02668 else
02669 {
02670
02671 sign = (b >> K) & 1;
02672 wordcnt += 2;
02673 if (wordcnt >= PACKETDATAWORDS-1)
02674 break;
02675 b = *in++;
02676
02677 nz = numzero16[(unsigned short) b];
02678 b = b>>(nz+1);
02679 nbits = 31 - nz;
02680 }
02681 }
02682 }
02683
02684
02685 if (unlikely(nz >= 16))
02686 break;
02687 else if (unlikely(nz==SAT))
02688 {
02689 diff = (diff | (b<<K)) & nmask;
02690
02691 if (unlikely(nbits<nmk))
02692 {
02693 wordcnt += 2;
02694 if (wordcnt >= PACKETDATAWORDS-1)
02695 break;
02696 b = *in++;
02697 diff += (b<<(K+nbits)) & nmask;
02698 b = b >> (nmk-nbits);
02699 nbits += c32mnmk;
02700 }
02701 else
02702 {
02703 b = b >> nmk;
02704 nbits -= nmk;
02705 }
02706 }
02707 else
02708 diff += nz << K;
02709
02710
02711 if (*pixels == 0xffff)
02712 newcnt++;
02713 *pixels = (sign==1 ? oldval-diff : oldval+diff);
02714 oldval = *pixels++;
02715 ++pixcnt;
02716 }
02717
02718 error = 0;
02719 if (unlikely(nz==16))
02720 {
02721
02722
02723
02724
02725
02726
02727
02728 error = (diff != 0) || (sign!=0);
02729 ++wordcnt;
02730 while (wordcnt < PACKETDATAWORDS-1)
02731 {
02732 error |= (indata[wordcnt++]!= 0);
02733 }
02734 }
02735
02736 if (pixcnt==1)
02737 oldval=0;
02738
02739
02740
02741 val = indata[PACKETDATAWORDS-1];
02742 error |= (val!=oldval);
02743
02744
02745 if (unlikely(error))
02746 {
02747 printk("ERROR: val != oldval: %u != %u at pixcnt = %d\n",
02748 val,oldval,pixcnt);
02749 pixcnt = -pixcnt;
02750 }
02751
02752 *new_count = newcnt;
02753 return pixcnt;
02754 }
02755
02756 int decompress_reconstruct(SciDataPacket_t *scipack, int ctx, Image_t **image)
02757 {
02758 int cnt, new_cnt;
02759 unsigned int N, R, K, SAT;
02760 int errcode;
02761 Decompress_Stat_t *stat;
02762 Image_t *im;
02763
02764 if (!table_initialized)
02765 decompress_inittables();
02766
02767 im = Context[ctx]->image;
02768 stat = &(im->stat);
02769
02770
02771 if (im->firstpacket.cropid == -1)
02772 {
02773 if ((errcode = decompress_context_initimage(ctx, scipack)))
02774 return errcode;
02775 }
02776
02777
02778
02779
02780
02781
02782 N = scipack->compid >> 3;
02783 R = scipack->bitselectid;
02784 K = scipack->compid & 0x7;
02785 SAT = 8;
02786
02787
02788
02789
02790
02791 if ( scipack->offset != stat->numpix )
02792 {
02793 if (scipack->offset > stat->totalpix)
02794 {
02795 printkerr("Warning: Offset count (%d) is larger than " \
02796 "the total number of pixels (%d) for image in context %d " \
02797 "with FSN=%lu, FID=%lu. Discarding image!\n",
02798 scipack->offset,stat->totalpix,ctx,ID2FSN(stat->ID),
02799 ID2FID(stat->ID));
02800 errcode = ERROR_BADOFFSET;
02801 goto failpartial;
02802 }
02803 else
02804 {
02805 if ( scipack->offset < stat->numpix )
02806 {
02807
02808
02809
02810 stat->backup_occured = 1;
02811 }
02812 else if ( scipack->offset > stat->numpix )
02813 {
02814
02815
02816
02817 stat->skip_occured = 1;
02818 }
02819 }
02820 }
02821
02822
02823 if (scipack->compid == 0 || (N==16&&R==0&&K==0)) {
02824 int npix,i;
02825 npix = stat->totalpix - scipack->offset;
02826 if (npix > PACKETDATAWORDS)
02827 npix = PACKETDATAWORDS;
02828 for (i=npix; i<PACKETDATAWORDS; ++i)
02829 if (scipack->data[i] != 0) {
02830 errcode = ERROR_RAW_MODE_TRAILING_GARBAGE;
02831 goto failpartial;
02832 }
02833 memcpy(&Context[ctx]->pixelbuf[scipack->offset], scipack->data, 2*npix);
02834 stat->numpix += npix;
02835 if (stat->numpix > stat->totalpix) {
02836 errcode = ERROR_TOOMANYPIXELS;
02837 goto failpartial;
02838 }
02839 ++(stat->npackets);
02840 return SUCCESS;
02841 }
02842
02843
02844 cnt = decompress_packet(N, K, SAT, &Context[ctx]->pixelbuf[scipack->offset],
02845 &new_cnt, scipack->data);
02846 ++(stat->npackets);
02847
02848 if (cnt < 0)
02849 {
02850 errcode = ERROR_CORRUPTDATA;
02851 goto failpartial;
02852 }
02853 else if ( cnt!=new_cnt && (new_cnt>0))
02854 {
02855 errcode = ERROR_PARTIALOVERWRITE;
02856 goto failpartial;
02857 }
02858 else if (stat->numpix+new_cnt > stat->totalpix)
02859 {
02860
02861
02862 errcode = ERROR_TOOMANYPIXELS;
02863 goto failpartial;
02864 }
02865 else
02866 stat->numpix += new_cnt;
02867
02868
02869 return SUCCESS;
02870
02871 failpartial:
02872
02873
02874
02875
02876
02877 *image = decompress_prepare_image(ctx);
02878 return errcode;
02879 }
02880
02881 int check_completeness(Image_t **image)
02882 {
02883 int status;
02884 unsigned int ctx;
02885 Image_t *im;
02886 Decompress_Stat_t *stat;
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896 *image = NULL;
02897 status = SUCCESS;
02898
02899
02900
02901 for (ctx=0; ctx<numcontexts; ctx++)
02902 {
02903 im = Context[ctx]->image;
02904 stat = &im->stat;
02905
02906
02907
02908
02909 if (im->firstpacket.cropid != -1 && im->keywords != NULL &&
02910 Context[ctx]->pixelbuf[stat->totalpix-1] != 0xffff)
02911 {
02912
02913
02914
02915 *image = decompress_prepare_image(ctx);
02916 status = SUCCESS_IMAGECOMPLETE;
02917 }
02918 }
02919 return status;
02920 }
02921
02922 int decompress_next_vcdu(unsigned short vcdu[PACKETWORDS],
02923 Image_t **image, CCSDS_Packet_t **hk_packets)
02924 {
02925 int i, FSN, FID;
02926 int ctx;
02927 int status = ERROR_NODATA;
02928 unsigned char *p1,*p2;
02929 static unsigned short buffer[PACKETWORDS];
02930 SciDataPacket_t scipack;
02931 unsigned short *w, *hkstart;
02932 IM_PDU_Packet_t im_pdu;
02933 CCSDS_Packet_t ccsds, *p, *p_hk;
02934 HK_Keyword_t *kw, *kw2;
02935
02936
02937
02938
02939
02940
02941
02942 #if __BYTE_ORDER == __LITTLE_ENDIAN
02943 p1 = (unsigned char *)vcdu;
02944 p2 = (unsigned char *)buffer;
02945 for (i=0; i<PACKETWORDS; i++)
02946 {
02947 *(p2+1) = *p1;
02948 *p2 = *(p1+1);
02949 p1 += 2;
02950 p2 += 2;
02951 }
02952 #else
02953 memcpy(buffer, vcdu, PACKETBYTES);
02954 #endif
02955
02956
02957 w = decode_im_pdu(buffer, &im_pdu);
02958
02959
02960 *hk_packets = p_hk = NULL;
02961 *image = NULL;
02962 do
02963 {
02964
02965 hkstart = vcdu + (w-buffer);
02966 w = decode_ccsds(w, &ccsds);
02967
02968
02969 switch(ccsds.apid)
02970 {
02971 case 0:
02972
02973 break;
02974
02975 case APID_HMI_SCIENCE_1:
02976 case APID_HMI_SCIENCE_2:
02977 isHMI = 1;
02978 case APID_AIA_SCIENCE_1:
02979 case APID_AIA_SCIENCE_2:
02980
02981 decode_scidata(w, &scipack);
02982
02983
02984
02985
02986
02987 FSN = UNPACK_FSN(&scipack);
02988 FID = UNPACK_FID(&scipack);
02989
02990 ctx = decompress_findcontext(FSN, FID);
02991 if (ctx>=numcontexts)
02992 {
02993
02994 if ((ctx = decompress_new_context(FSN, FID)) == -1)
02995 return ERROR_CTXOVERFLOW;
02996 }
02997 if ((status = decompress_reconstruct(&scipack, ctx, image)) < 0)
02998 return status;
02999 break;
03000
03001 case APID_HMI_TIME_1:
03002 case APID_HMI_TIME_2:
03003 case APID_AIA_TIME_1:
03004 case APID_AIA_TIME_2:
03005 case 460:
03006
03007 status = SUCCESS;
03008 break;
03009
03010 case 417:
03011 case 407:
03012 case 517:
03013 case 507:
03014
03015
03016
03017 for (i=11; i<888; ++i) {
03018 if (buffer[i] != 0xc0b+(i-11)) {
03019 printk("DC/HRI test pattern error at IM_PDU ID %d Counter %lu\n",
03020 im_pdu.im_pdu_id, im_pdu.im_pdu_count);
03021 break;
03022 }
03023 }
03024 status = SUCCESS_HK;
03025 break;
03026
03027 case APID_HMI_IMSTAT_1:
03028 case APID_HMI_IMSTAT_2:
03029
03030 status = decode_hk_keywords(hkstart, ccsds.apid, &ccsds.keywords);
03031 if (status==SUCCESS)
03032 {
03033
03034 FSN = -1;
03035 FID = -1;
03036 kw = ccsds.keywords;
03037
03038
03039
03040 while(kw)
03041 {
03042 if (!strncasecmp("SEQ_FILTERGRAM_ID", kw->name + 4,
03043 strlen("SEQ_FILTERGRAM_ID")))
03044 FID = kw->raw_value;
03045 if (!strncasecmp("SEQ_FILTERGRAM_SN", kw->name + 4,
03046 strlen("SEQ_FILTERGRAM_SN")))
03047 FSN = kw->raw_value;
03048 kw = kw->next;
03049 }
03050
03051 if (FSN == -1)
03052 return ERROR_MISSING_FSN;
03053 if ( FID == -1)
03054 return ERROR_MISSING_FID;
03055
03056
03057 ctx = decompress_findcontext(FSN,FID);
03058 if (ctx>=numcontexts)
03059 {
03060
03061 if ((ctx = decompress_new_context(FSN,FID)) == -1)
03062 return ERROR_CTXOVERFLOW;
03063 }
03064
03065
03066 Context[ctx]->image->keywords = copy_hk_keywords(ccsds.keywords);
03067
03068
03069 p = malloc(sizeof(CCSDS_Packet_t));
03070 assert(p);
03071 memcpy(p, &ccsds, sizeof(CCSDS_Packet_t));
03072
03073 if (*hk_packets == NULL)
03074 *hk_packets = p_hk = p;
03075 else
03076 {
03077 p_hk->next = p;
03078 p_hk = p_hk->next;
03079 }
03080 p_hk->next = NULL;
03081 status = SUCCESS_HK;
03082 goto DONE_WITH_THIS_VCDU;
03083 }
03084
03085
03086 break;
03087
03088 case APID_AIA_IMSTAT_1:
03089 case APID_AIA_IMSTAT_2:
03090
03091 status = decode_hk_keywords(hkstart, ccsds.apid, &ccsds.keywords);
03092 if (status==SUCCESS)
03093 {
03094
03095 FSN = -1;
03096 FID = -1;
03097 kw = ccsds.keywords;
03098
03099 while(kw)
03100 {
03101 if (!strncasecmp("SEQ_HEADER", kw->name + 4,
03102 strlen("SEQ_HEADER")))
03103 FSN = kw->raw_value;
03104 kw = kw->next;
03105 }
03106
03107 if (FSN == -1)
03108 return ERROR_MISSING_FSN;
03109
03110
03111 ctx = decompress_findcontext(FSN,FID);
03112 if (ctx>=numcontexts)
03113 {
03114
03115 if ((ctx = decompress_new_context(FSN,FID)) == -1)
03116 return ERROR_CTXOVERFLOW;
03117 }
03118
03119
03120 Context[ctx]->image->keywords = copy_hk_keywords(ccsds.keywords);
03121
03122
03123 p = malloc(sizeof(CCSDS_Packet_t));
03124 assert(p);
03125 memcpy(p, &ccsds, sizeof(CCSDS_Packet_t));
03126
03127 if (*hk_packets == NULL)
03128 *hk_packets = p_hk = p;
03129 else
03130 {
03131 p_hk->next = p;
03132 p_hk = p_hk->next;
03133 }
03134 p_hk->next = NULL;
03135 status = SUCCESS_HK;
03136 goto DONE_WITH_THIS_VCDU;
03137 }
03138
03139
03140 break;
03141 default:
03142
03143 status = decode_hk_keywords(hkstart, ccsds.apid, &(ccsds.keywords));
03144 if (status == SUCCESS)
03145 {
03146
03147 p = malloc(sizeof(CCSDS_Packet_t));
03148 assert(p);
03149 memcpy(p, &ccsds, sizeof(CCSDS_Packet_t));
03150
03151 if (*hk_packets == NULL)
03152 *hk_packets = p_hk = p;
03153 else
03154 {
03155 p_hk->next = p;
03156 p_hk = p_hk->next;
03157 }
03158 p_hk->next = NULL;
03159 status = SUCCESS_HK;
03160 }
03161 break;
03162 }
03163 w += ccsds.length/2;
03164 } while ( ccsds.apid>0 && (int)(w-buffer) < PACKETWORDS);
03165
03166 DONE_WITH_THIS_VCDU:
03167
03168
03169
03170 if (status >= 0)
03171 if (SUCCESS_IMAGECOMPLETE == check_completeness(image))
03172 return SUCCESS_IMAGECOMPLETE;
03173
03174 return status;
03175 }
03176
03177
03178
03179 #ifdef KMAX
03180 #undef KMAX
03181 #endif
03182
03183 #define KMAX 13 // max number of unencoded low-order bits
03184 #define KBITS 4 // number of bits required to represent K
03185
03186 #define CHECK_OVERRUN \
03187 if (c > out+bufsz) { free(d); return RICE_ENCODE_OVERRUN; }
03188
03189 #define FLUSH \
03190 *c++=buf>>24; *c++=buf>>16; *c++=buf>>8; *c++=buf; buf = 0; CHECK_OVERRUN
03191
03192 #define PUT_N_BITS(n, val) \
03193 if (bits2go > n) { \
03194 bits2go -= n; \
03195 buf += val << bits2go; \
03196 } else if (bits2go == n) { \
03197 buf += val; \
03198 FLUSH \
03199 bits2go = 32; \
03200 } else { \
03201 buf += val >> (n - bits2go); \
03202 FLUSH \
03203 bits2go = 32 - (n - bits2go); \
03204 buf = val << bits2go; \
03205 }
03206
03207 #define PUT_FS(n) \
03208 if (bits2go > n+1) { \
03209 bits2go -= n+1; \
03210 buf += 1 << bits2go; \
03211 } else if (bits2go == n+1) { \
03212 ++buf; \
03213 FLUSH \
03214 bits2go = 32; \
03215 } else { \
03216 FLUSH \
03217 bits2go += 32 - (n+1); \
03218 while (bits2go < 0) { \
03219 c += 4; \
03220 bits2go += 32; \
03221 } \
03222 buf = 1 << bits2go; \
03223 }
03224
03225 int rice_encode2(
03226 const short *in,
03227 int nin,
03228 unsigned char *out,
03229 int bufsz,
03230 int blksz)
03231 {
03232 unsigned short *d;
03233 unsigned char *c;
03234 unsigned buf = 0;
03235 unsigned val;
03236 int bits2go = 32;
03237 int k;
03238 int i, j;
03239 short curr, last, delta;
03240 unsigned short top, bottom, kmask, tmp;
03241 double pixsum;
03242
03243 d = (unsigned short *) malloc(blksz * sizeof(unsigned short));
03244 if (!d) return RICE_ENCODE_OUT_OF_MEMORY;
03245
03246 memset(out, 0, bufsz);
03247
03248
03249 last = in[0];
03250 val = last;
03251 out[0] = val >> 8;
03252 out[1] = val;
03253
03254 c = out + 2;
03255
03256
03257 for (i = 0; i < nin; i += blksz) {
03258 pixsum = 0.0;
03259 if (nin - i < blksz) blksz = nin - i;
03260 for (j = 0; j < blksz; ++j) {
03261 curr = in[i+j];
03262 if (last == curr) {
03263 d[j] = 0;
03264 continue;
03265 }
03266 delta = curr - last;
03267 last = curr;
03268 d[j] = (delta < 0) ? ~(delta << 1) : (delta << 1);
03269 pixsum += d[j];
03270 }
03271
03272
03273 if (pixsum == 0.0) {
03274 if (bits2go > KBITS)
03275 bits2go -= KBITS;
03276 else {
03277 FLUSH
03278 bits2go += 32 - KBITS;
03279 }
03280 continue;
03281 }
03282
03283
03284 tmp = .5*pixsum/blksz;
03285 for (k=0; tmp; ++k) tmp >>= 1;
03286
03287
03288 if (k == 0) {
03289 val = 1;
03290 PUT_N_BITS(KBITS, val)
03291 for (j = 0; j < blksz; ++j) {
03292 val = d[j];
03293 PUT_FS(val)
03294 }
03295
03296 } else if (k <= KMAX) {
03297 val = k+1;
03298 PUT_N_BITS(KBITS, val)
03299 kmask = (1u<<k) - 1u;
03300 for (j = 0; j < blksz; ++j) {
03301 val = d[j];
03302 top = val >> k;
03303 bottom = val & kmask;
03304 PUT_FS(top)
03305 PUT_N_BITS(k, bottom)
03306 }
03307
03308 } else {
03309 val = KMAX+2;
03310 PUT_N_BITS(KBITS, val)
03311 for (j = 0; j < blksz; ++j) {
03312 val = d[j];
03313 PUT_N_BITS(16, val);
03314 }
03315 }
03316 }
03317
03318 free(d);
03319
03320
03321 i = 4 - bits2go/8;
03322 if (i-- > 0) *c++ = buf >> 24;
03323 if (i-- > 0) *c++ = buf >> 16;
03324 if (i-- > 0) *c++ = buf >> 8;
03325 if (i-- > 0) *c++ = buf;
03326
03327 return (c-out <= bufsz) ? c-out : RICE_ENCODE_OVERRUN;
03328 }
03329
03330 #ifdef KMAX
03331 #undef KMAX
03332 #endif