size_t convert_gcs(int igcfile_version, FILE *Ausgabedatei, const uint8_t *const bin_puffer, size_t length, bool oo_fillin) { const uint8_t *const end = bin_puffer + length; IGCHEADER igcheader; C_RECORD task; struct { // All value directly from fix, before conversion char time[10]; char valid; long lat; long lon; } igcfix; int l = 0; int ende; // relative time from the beginning of the logging long time_relative = 0; long temptime; long decl_time; tm firsttime; memset(&firsttime, 0, sizeof(firsttime)); tm realtime; uint8_t Haupttyp; uint8_t Untertyp; const uint8_t *p; const uint8_t *p2; long pl; char PILOT[40]; int tzh, tzm; // word keysn; // binary data format version int bfv = 0; long delta_lat, delta_lon; // Timezone in minutes from FDT field int tzn = 4000; // Ini value for determination, whether the field existed float ftz = 0; // Flag, whether ftz is received from a valid position int tzset = 0; // long ggtz = timezone; if (igcfile_version == 0) igcfile_version = actual_conv_version; igcfix.lat = 0; igcfix.lon = 0; //igcfile_version = 0; igcheader.redirect(Ausgabedatei); //task.init(); decl_time = -1; ende = 0; p = bin_puffer; do { if (p >= end) return 0; Haupttyp = p[0] & rectyp_msk; switch (Haupttyp) { case rectyp_tnd: if (p + 8 > end) return 0; // calculates backwards the time of the first fix time_relative += p[1]; temptime = 65536L * p[2] + 256L * p[3] + p[4]; firsttime.tm_sec = temptime % 3600; firsttime.tm_hour = temptime / 3600; firsttime.tm_min = 0; firsttime.tm_mday = 10 * (p[7] >> 4) + (p[7] & 0x0f); firsttime.tm_mon = 10 * (p[6] >> 4) + (p[6] & 0x0f) - 1; firsttime.tm_year = 10 * (p[5] >> 4) + (p[5] & 0x0f); // Y2K-patch if (igcfile_version >= 424) if (firsttime.tm_year < 80) firsttime.tm_year += 100; firsttime.tm_isdst = -1; firsttime.tm_sec -= time_relative % 3600; firsttime.tm_hour -= time_relative / 3600; //xxxtime mktime(&firsttime); l = 8; break; /* case rectyp_pos : time_relative += p[2]; l = pos_ds_size[bfv][0]; break; case rectyp_poc : if(p[2] & 0x80) { // Endebedingung ende = 1; l = 0; break; } time_relative += p[2]; l = pos_ds_size[bfv][1]; break; */ case rectyp_pos: case rectyp_poc: if (p + 2 >= end) return 0; if (p[2] & 0x80) { // Endebedingung ende = 1; l = 0; break; } if (p + 8 > end) return 0; time_relative += p[2]; igcfix.valid = ((p[0] & 0x10) >> 4) ? 'A' : 'V'; if (Haupttyp == rectyp_pos) { l = pos_ds_size[bfv][0]; igcfix.lon = ((unsigned long)p[6]) << 16 | ((unsigned long)p[7]) << 8 | p[8]; if (p[9] & 0x80) igcfix.lon = -igcfix.lon; } else { l = pos_ds_size[bfv][1]; delta_lon = (((unsigned long)p[3] & 0x78) << 5) | p[5]; if (p[6] & 0x80) delta_lon = -delta_lon; igcfix.lon += delta_lon; } // ftz mit Längengrad füllen // der erste gültige ist der letzte, // der in ftz gespeichert wird if (!tzset) { ftz = float(igcfix.lon); if (igcfix.valid == 'A') tzset = 1; } break; case rectyp_sep: time_relative = 0; bfv = p[0] & ~rectyp_msk; if (bfv > max_bfv) { // unsupported binary file version return 0; } l = 1; break; case 0xC0: l = 1; // Füllzeichen break; case rectyp_end: /* sp = (p - bin_puffer) + 1 */ l = 41; ende = 1; break; case rectyp_vrb: case rectyp_vrt: if (p + 2 >= end) return 0; l = p[1]; switch (Haupttyp) { case rectyp_vrb: p2 = p + 2; break; case rectyp_vrt: time_relative += p[2]; p2 = p + 3; break; default: p2 = p; break; } if (p2 >= end) return 0; Untertyp = (p2[0]); switch (Untertyp) { case FLDNTP: if (p2 + 1 >= end) return 0; task.NTP = p2[1]; decl_time = time_relative; break; case FLDTID: if (p2 + 2 >= end) return 0; task.TID = 256 * p2[1] + p2[2]; if (igcfile_version >= 422) decl_time = time_relative; break; case FLDFDT: if (p2 + 1 + sizeof(task.FDT) > end) return 0; //_fmemcpy(&task.FDT,&p2[1],sizeof task.FDT); memcpy(&task.FDT, &p2[1], sizeof task.FDT); break; case FLDTZN: // Reading timezone offset if (p2 + 1 >= end) return 0; if (p2[1] < 128) tzn = 15 * p2[1]; else tzn = 15 * (p2[1] - 256); break; case FLDTKF: if (p2 + 1 + 12 > end) return 0; task.TKF.packed2unpacked(&p2[1]); break; case FLDSTA: if (p2 + 1 + 12 > end) return 0; task.STA.packed2unpacked(&p2[1]); break; case FLDFIN: if (p2 + 1 + 12 > end) return 0; task.FIN.packed2unpacked(&p2[1]); break; case FLDLDG: if (p2 + 1 + 12 > end) return 0; task.LDG.packed2unpacked(&p2[1]); break; case FLDTP1: if (p2 + 1 + 12 > end) return 0; task.TP[0].packed2unpacked(&p2[1]); break; case FLDTP2: if (p2 + 1 + 12 > end) return 0; task.TP[1].packed2unpacked(&p2[1]); break; case FLDTP3: if (p2 + 1 + 12 > end) return 0; task.TP[2].packed2unpacked(&p2[1]); break; case FLDTP4: task.TP[3].packed2unpacked(&p2[1]); break; case FLDTP5: if (p2 + 1 + 12 > end) return 0; task.TP[4].packed2unpacked(&p2[1]); break; case FLDTP6: if (p2 + 1 + 12 > end) return 0; task.TP[5].packed2unpacked(&p2[1]); break; case FLDTP7: if (p2 + 1 + 12 > end) return 0; task.TP[6].packed2unpacked(&p2[1]); break; case FLDTP8: if (p2 + 1 + 12 > end) return 0; task.TP[7].packed2unpacked(&p2[1]); break; case FLDTP9: if (p2 + 1 + 12 > end) return 0; task.TP[8].packed2unpacked(&p2[1]); break; case FLDTP10: if (p2 + 1 + 12 > end) return 0; task.TP[9].packed2unpacked(&p2[1]); break; case FLDTP11: if (p2 + 1 + 12 > end) return 0; task.TP[10].packed2unpacked(&p2[1]); break; case FLDTP12: if (p2 + 1 + 12 > end) return 0; task.TP[11].packed2unpacked(&p2[1]); break; case FLDPLT1: // Reading pilotname case FLDPLT2: // Reading pilotname case FLDPLT3: // Reading pilotname case FLDPLT4: // Reading pilotname if (p2 + 1 + sizeof(PILOT) > end) return 0; // _fmemcpy(igcheader.PLT, &p2[1], (sizeof igcheader.PLT)); // igcheader.PLT[(sizeof igcheader.PLT)-1] = 0; //_fmemcpy(PILOT, &p2[1], (sizeof PILOT)); memcpy(PILOT, &p2[1], (sizeof PILOT)); PILOT[(sizeof PILOT) - 1] = 0; strcat(igcheader.PLT, PILOT); if (igcfile_version < 413) strcat(igcheader.PLT, " "); break; case FLDGTY: // Reading plane type if (p2 + 1 + sizeof(igcheader.GTY) > end) return 0; //_fmemcpy(igcheader.GTY, &p2[1], (sizeof igcheader.GTY)); memcpy(igcheader.GTY, &p2[1], (sizeof igcheader.GTY)); igcheader.GTY[(sizeof igcheader.GTY) - 1] = 0; break; case FLDGID: // Reading plane reg if (p2 + 1 + sizeof(igcheader.GID) > end) return 0; //_fmemcpy(igcheader.GID, &p2[1], (sizeof igcheader.GID)); memcpy(igcheader.GID, &p2[1], (sizeof igcheader.GID)); igcheader.GID[(sizeof igcheader.GID) - 1] = 0; break; case FLDCCL: // Reading plane class if (p2 + 1 + sizeof(igcheader.CCL) > end) return 0; //_fmemcpy(igcheader.CCL, &p2[1], (sizeof igcheader.CCL)); memcpy(igcheader.CCL, &p2[1], (sizeof igcheader.CCL)); igcheader.CCL[(sizeof igcheader.CCL) - 1] = 0; break; case FLDCID: // Reading plane competition sign if (p2 + 1 + sizeof(igcheader.CID) > end) return 0; //_fmemcpy(igcheader.CID, &p2[1], (sizeof igcheader.CID)); memcpy(igcheader.CID, &p2[1], (sizeof igcheader.CID)); igcheader.CID[(sizeof igcheader.CID) - 1] = 0; break; case FLDHDR: // Reading serial number and other stuff // Public-Key erst mal löschen // 19.10.99 weggemacht, weil schon in main vorhanden //dsa_y_b[0] = 2; dsa_y_b[1] = 0; //memset(&dsa_y_b[2],0,(sizeof dsa_y_b)-2); if (p2 + 7 >= end) return 0; // sonstiges einlesen wordtoserno(igcheader.A, 256 * p2[1] + p2[2]); sprintf(igcheader.DTM, "%03u", p2[3]); sprintf(igcheader.RHW, "%0X.%0X", p2[4] >> 4, (p2[4] & 0xf)); sprintf(igcheader.RFW, "%0X.%0X", p2[5] >> 4, (p2[5] & 0xf)); sprintf(igcheader.FXA, "%03u", p2[7]); // neuer obligatorischer H-Record if (igcfile_version >= 421) sprintf(igcheader.FTY, "GARRECHT INGENIEURGESELLSCHAFT,VOLKSLOGGER 1.0"); break; } ; break; default: ende = 1; break; } p += l; } while (!ende); pl = p - bin_puffer; // Timezone/Hours = floor(LON + 7.5°) / 15° of the first fix ftz = ftz + 450000L; ftz = ftz / 900000L; task.zz_min = int(60 * floor(ftz)); // printf("theoretische Zeitzone = UTC %-d min\n",task.zz_min); // getch(); // for new files if ((igcfile_version >= 420) && (igcfile_version < 422)) // if TZN field does not exist if (tzn == 4000) // emulate it with the calculated tzn = task.zz_min; // for all files // show TZN, if set if (tzn != 4000) { tzh = abs(tzn) / 60; tzm = abs(tzn) % 60; sprintf(igcheader.TZN, "UTC%c%02d:%02d", (tzn < 0 ? '-' : '+'), tzh, tzm); } strftime(igcheader.DTE,sizeof(igcheader.DTE),"%d%m%y",&firsttime); igcheader.output(igcfile_version, oo_fillin); if (igcfile_version >= 414 || (task.STA.koord.lat != 0) || (task.STA.koord.lon != 0)) { if (decl_time >= 0) { task.hasdeclaration = 1; memcpy(&task.TDECL, &firsttime, sizeof task.TDECL); task.TDECL.tm_sec += decl_time % 3600; task.TDECL.tm_hour += decl_time / 3600; task.TDECL.tm_isdst = -1; mktime(&task.TDECL); task.print(igcfile_version, Ausgabedatei); } } igcfix.lat = 0; igcfix.lon = 0; realtime = firsttime; ende = 0; p = bin_puffer; do { Haupttyp = p[0] & rectyp_msk; switch (Haupttyp) { case rectyp_sep: l = 1; if (bfv > max_bfv) { ende = 1; l = 0; break; } break; case 0xC0: l = 1; break; case rectyp_pos: case rectyp_poc: { if (p[2] & 0x80) { // Endebedingung ende = 1; l = 0; break; } time_relative += p[2]; realtime.tm_sec += p[2]; realtime.tm_isdst = -1; mktime(&realtime); igcfix.valid = ((p[0] & 0x10) >> 4) ? 'A' : 'V'; const unsigned press = unsigned(p[0] & 0x0f) << 8 | p[1]; unsigned gpalt, fxa, enl; if (Haupttyp == rectyp_pos) { l = pos_ds_size[bfv][0]; igcfix.lat = ((unsigned long)p[3] & 0x7f) << 16 | ((unsigned long)p[4]) << 8 | p[5]; if (p[3] & 0x80) igcfix.lat = -igcfix.lat; igcfix.lon = ((unsigned long)p[6]) << 16 | ((unsigned long)p[7]) << 8 | p[8]; if (p[9] & 0x80) igcfix.lon = -igcfix.lon; gpalt = unsigned(p[9] & 0x70) << 4 | p[10]; fxa = hdop2fxa(p[9] & 0x0f); enl = 4 * p[11]; } else { l = pos_ds_size[bfv][1]; delta_lat = (((unsigned long)p[3] & 0x07) << 8) | p[4]; if (p[3] & 0x80) delta_lat = -delta_lat; delta_lon = (((unsigned long)p[3] & 0x78) << 5) | p[5]; if (p[6] & 0x80) delta_lon = -delta_lon; igcfix.lat += delta_lat; igcfix.lon += delta_lon; gpalt = unsigned(p[6] & 0x70) << 4 | p[7]; fxa = hdop2fxa(p[6] & 0x0f); enl = 4 * p[8]; } const unsigned latdeg = labs(igcfix.lat) / 60000; const unsigned latmin = labs(igcfix.lat) % 60000; const unsigned londeg = labs(igcfix.lon) / 60000; const unsigned lonmin = labs(igcfix.lon) % 60000; long gps_alt = 10L * gpalt - 1000L; if (igcfile_version >= 423) enl = enlflt(enl); enl = enllim(enl); // Bei allen neuen Dateien auf Wunsch von IAN // aber dank neuer Regeln ab // Konverter Nr. 4.20 nicht mehr !! if ((igcfile_version >= 413) && (igcfile_version < 420)) if (igcfix.valid == 'V') gps_alt = 0; const long pressure_alt = pressure2altitude(press); strftime(igcfix.time,sizeof(igcfix.time),"%H%M%S",&realtime); fprintf(Ausgabedatei, "B%6s%02u%05u%c%03u%05u%c%c%05ld%05ld%03u", igcfix.time, latdeg, latmin, igcfix.lat < 0 ? 'S' : 'N', londeg, lonmin, igcfix.lon < 0 ? 'W' : 'E', igcfix.valid, pressure_alt, gps_alt, fxa); // activate on ENL in I record if ((igcfile_version >= 413) && (igcfile_version < 416)) fprintf(Ausgabedatei, "999"); // have to be active, if sensor exists if (strcmp(igcheader.RHW, "3.3") >= 0) fprintf(Ausgabedatei, "%03u", enl); fprintf(Ausgabedatei, "\n"); } break; case rectyp_vrb: case rectyp_vrt: l = p[1]; switch (Haupttyp) { case rectyp_vrb: p2 = p + 2; break; case rectyp_vrt: realtime.tm_sec += p[2]; realtime.tm_isdst = -1; mktime(&realtime); p2 = p + 3; break; default: p2 = p; break; } Untertyp = (p2[0]); switch (Untertyp) { case FLDEPEV: strftime(igcfix.time,sizeof(igcfix.time),"%H%M%S",&realtime); fprintf(Ausgabedatei, "E%6sPEVEVENTBUTTON PRESSED\n", igcfix.time); break; case FLDETKF: strftime(igcfix.time,sizeof(igcfix.time),"%H%M%S",&realtime); fprintf(Ausgabedatei, "LGCSTKF%6sTAKEOFF DETECTED\n", igcfix.time); break; } ; break; case rectyp_tnd: realtime.tm_sec += p[1]; realtime.tm_isdst = -1; mktime(&realtime); l = 8; break; default: ende = 1; l = 0; break; } p += l; } while (!ende); return pl; }
long convert_gcs(int igcfile_version, FILE *Ausgabedatei, lpb bin_puffer, int oo_fillin, word *serno, long *sp) { IGCHEADER igcheader; C_RECORD task; struct { // Alle Werte direkt aus Fix, vor Umwandlung char time[10]; char valid; long lat; word latdeg; word latmin; long lon; word londeg; word lonmin; word press; word gpalt; long pressure_alt; long gps_alt; word fxa; word hdop; word enl; } igcfix; int l = 0; int ende; long time_relative = 0; // relative Zeit vom Aufzeichnungsbeginn an long temptime; long decl_time; tm firsttime; tm realtime; byte Haupttyp; byte Untertyp; lpb p; lpb p2; long pl; char PILOT[40]; int tzh,tzm; // word keysn; int bfv = 0; // Binärdatenformat-Version long delta_lat,delta_lon; // Zeitzone in Minuten aus Feld FDT int tzn = 4000; // Ini-Wert zur Erkennung, ob es das Feld gab // aus Position berechnete Zeitzone float ftz = 0; // Flag, ob ftz aus gültiger Position stammt int tzset = 0; // Initialize firsttime structure to fix compiler warning firsttime.tm_sec = 0; firsttime.tm_hour = 0; firsttime.tm_min = 0; firsttime.tm_mday = 0; firsttime.tm_mon = 0; firsttime.tm_year = 0; firsttime.tm_yday = 0; firsttime.tm_wday = 0; // long ggtz = timezone; if (igcfile_version == 0) igcfile_version = actual_conv_version; igcfix.lat = 0; igcfix.lon = 0; //igcfile_version = 0; igcheader.redirect(Ausgabedatei); //task.init(); decl_time = -1; ende = 0; p = bin_puffer; do { Haupttyp = p[0] & rectyp_msk; switch (Haupttyp) { case rectyp_tnd : // errechnet rückwärts die Zeit des 1. Fixes time_relative += p[1]; temptime = 65536L * p[2] + 256L * p[3] + p[4]; firsttime.tm_sec = temptime % 3600; firsttime.tm_hour = temptime / 3600; firsttime.tm_min = 0; firsttime.tm_mday = 10*(p[7] >> 4) + (p[7] & 0x0f); firsttime.tm_mon = 10*(p[6] >> 4) + (p[6] & 0x0f) - 1; firsttime.tm_year = 10*(p[5] >> 4) + (p[5] & 0x0f); // Y2K-patch if(igcfile_version >= 424) if(firsttime.tm_year < 80) firsttime.tm_year += 100; firsttime.tm_isdst = -1; firsttime.tm_sec -= time_relative % 3600; firsttime.tm_hour -= time_relative / 3600; //xxxtime //JMW TODO mktime(&firsttime); l = 8; break; /* case rectyp_pos : time_relative += p[2]; l = pos_ds_size[bfv][0]; break; case rectyp_poc : if(p[2] & 0x80) { // Endebedingung ende = 1; l = 0; break; } time_relative += p[2]; l = pos_ds_size[bfv][1]; break; */ case rectyp_pos : case rectyp_poc : if (p[2] & 0x80) { // Endebedingung ende = 1; l = 0; break; } time_relative += p[2]; igcfix.valid = ((p[0] & 0x10) >> 4) ? 'A' : 'V'; if (Haupttyp == rectyp_pos) { l = pos_ds_size[bfv][0]; igcfix.lon = ((unsigned long)p[6] ) << 16 | ((unsigned long)p[7] ) << 8 | p[8]; if (p[9] & 0x80) igcfix.lon = -igcfix.lon; } else { l = pos_ds_size[bfv][1]; delta_lon = (((unsigned long)p[3] & 0x78) << 5) | p[5]; if (p[6] & 0x80) delta_lon = -delta_lon; igcfix.lon += delta_lon; } // ftz mit Längengrad füllen // der erste gültige ist der letzte, // der in ftz gespeichert wird if (!tzset) { ftz = float(igcfix.lon); if (igcfix.valid=='A') tzset=1; } break; case rectyp_sep : time_relative = 0; bfv = p[0] & ~rectyp_msk; if (bfv > max_bfv) { // unsupported binary file version return 0; } l = 1; break; case 0xC0 : l = 1; // Füllzeichen break; case rectyp_end : *sp = (p-bin_puffer) + 1; l = 41; ende = 1; break; case rectyp_vrb : case rectyp_vrt : l = p[1]; switch(Haupttyp) { case rectyp_vrb : p2 = p+2; break; case rectyp_vrt : time_relative += p[2]; p2 = p+3; break; default : p2 = p; break; } Untertyp = (p2[0]); switch (Untertyp) { case FLDNTP : task.NTP = p2[1]; decl_time = time_relative; break; case FLDTID : task.TID = 256*p2[1] + p2[2]; if (igcfile_version >= 422) decl_time = time_relative; break; case FLDFDT : //_fmemcpy(&task.FDT,&p2[1],sizeof task.FDT); memcpy(&task.FDT,&p2[1],sizeof task.FDT); break; case FLDTZN : // Zeitzonenoffset einlesen if (p2[1] < 128) tzn = 15 * p2[1]; else tzn = 15 * (p2[1] - 256); break; case FLDTKF : task.TKF.packed2unpacked(&p2[1]); break; case FLDSTA : task.STA.packed2unpacked(&p2[1]); break; case FLDFIN : task.FIN.packed2unpacked(&p2[1]); break; case FLDLDG : task.LDG.packed2unpacked(&p2[1]); break; case FLDTP1 : task.TP[0].packed2unpacked(&p2[1]); break; case FLDTP2 : task.TP[1].packed2unpacked(&p2[1]); break; case FLDTP3 : task.TP[2].packed2unpacked(&p2[1]); break; case FLDTP4 : task.TP[3].packed2unpacked(&p2[1]); break; case FLDTP5 : task.TP[4].packed2unpacked(&p2[1]); break; case FLDTP6 : task.TP[5].packed2unpacked(&p2[1]); break; case FLDTP7 : task.TP[6].packed2unpacked(&p2[1]); break; case FLDTP8 : task.TP[7].packed2unpacked(&p2[1]); break; case FLDTP9 : task.TP[8].packed2unpacked(&p2[1]); break; case FLDTP10 : task.TP[9].packed2unpacked(&p2[1]); break; case FLDTP11 : task.TP[10].packed2unpacked(&p2[1]); break; case FLDTP12 : task.TP[11].packed2unpacked(&p2[1]); break; case FLDPLT1 : // Pilotenname einlesen case FLDPLT2 : // Pilotenname einlesen case FLDPLT3 : // Pilotenname einlesen case FLDPLT4 : // Pilotenname einlesen // _fmemcpy(igcheader.PLT, &p2[1], (sizeof igcheader.PLT)); // igcheader.PLT[(sizeof igcheader.PLT)-1] = 0; //_fmemcpy(PILOT, &p2[1], (sizeof PILOT)); memcpy(PILOT, &p2[1], (sizeof PILOT)); PILOT[(sizeof PILOT)-1] = 0; strcat(igcheader.PLT,PILOT); if (igcfile_version < 413) // war in alten Dateien so ! strcat(igcheader.PLT," "); break; case FLDGTY : // Flugzeugtyp einlesen //_fmemcpy(igcheader.GTY, &p2[1], (sizeof igcheader.GTY)); memcpy(igcheader.GTY, &p2[1], (sizeof igcheader.GTY)); igcheader.GTY[(sizeof igcheader.GTY)-1] = 0; break; case FLDGID : // Flugzeugkennzeichen einlesen //_fmemcpy(igcheader.GID, &p2[1], (sizeof igcheader.GID)); memcpy(igcheader.GID, &p2[1], (sizeof igcheader.GID)); igcheader.GID[(sizeof igcheader.GID)-1] = 0; break; case FLDCCL : // Wettbewerbsklasse einlesen //_fmemcpy(igcheader.CCL, &p2[1], (sizeof igcheader.CCL)); memcpy(igcheader.CCL, &p2[1], (sizeof igcheader.CCL)); igcheader.CCL[(sizeof igcheader.CCL)-1] = 0; break; case FLDCID : // Wettbewerbskennzeichen einlesen //_fmemcpy(igcheader.CID, &p2[1], (sizeof igcheader.CID)); memcpy(igcheader.CID, &p2[1], (sizeof igcheader.CID)); igcheader.CID[(sizeof igcheader.CID)-1] = 0; break; case FLDHDR : // Seriennummer und anderes einlesen // Public-Key erst mal löschen // 19.10.99 weggemacht, weil schon in main vorhanden //dsa_y_b[0] = 2; dsa_y_b[1] = 0; //memset(&dsa_y_b[2],0,(sizeof dsa_y_b)-2); *serno = (256L*p2[1]+p2[2]); // sonstiges einlesen strcpy(igcheader.A,wordtoserno(*serno)); sprintf(igcheader.DTM,"%03u",p2[3]); sprintf(igcheader.RHW,"%0X.%0X",p2[4]>>4,(p2[4]&0xf)); sprintf(igcheader.RFW,"%0X.%0X",p2[5]>>4,(p2[5]&0xf)); sprintf(igcheader.FXA,"%03u",p2[7]); // neuer obligatorischer H-Record if (igcfile_version >= 421) sprintf(igcheader.FTY,"GARRECHT INGENIEURGESELLSCHAFT,VOLKSLOGGER 1.0"); break; }; break; default : ende = 1; break; } p += l; } while (!ende); pl = p - bin_puffer; // Zeitzone/Stunden = floor (LON+7.5°) / 15° des 1. gültigen Fixes ftz = ftz + 450000L; ftz = ftz / 900000L; task.zz_min = int(60 * floor(ftz)); // printf("theoretische Zeitzone = UTC %-d min\n",task.zz_min); // getch(); // bei neuen Dateien if ( (igcfile_version >= 420) && (igcfile_version<422) ) // falls kein TZN-Feld existierte if (tzn == 4000) // dieses durch das errechnete emulieren tzn = task.zz_min; // bei allen Dateien // TZN anzeigen, wenn (auf welche Weise auch immer) gesetzt if (tzn != 4000) { tzh = abs(tzn) / 60; tzm = abs(tzn) % 60; sprintf(igcheader.TZN,"UTC%c%02d:%02d",(tzn<0 ? '-':'+'),tzh,tzm); } //JMWTODO strftime(igcheader.DTE,sizeof(igcheader.DTE),"%d%m%y",&firsttime); igcheader.output(igcfile_version,oo_fillin); if ( igcfile_version >= 414 || (task.STA.koord.lat != 0) || (task.STA.koord.lon != 0) ) { if (decl_time >= 0) { task.hasdeclaration = 1; memcpy(&task.TDECL, &firsttime, sizeof task.TDECL); task.TDECL.tm_sec += decl_time %3600; task.TDECL.tm_hour += decl_time /3600; task.TDECL.tm_isdst = -1; ////JMW TODO mktime(&task.TDECL); task.print(igcfile_version,Ausgabedatei); } } igcfix.lat = 0; igcfix.lon = 0; realtime = firsttime; ende = 0; p = bin_puffer; do { Haupttyp = p[0] & rectyp_msk; switch(Haupttyp) { case rectyp_sep : l = 1; if (bfv > max_bfv) { ende = 1; l = 0; break; } break; case 0xC0 : l = 1; break; case rectyp_pos : case rectyp_poc : if (p[2] & 0x80) { // Endebedingung ende = 1; l = 0; break; } time_relative += p[2]; realtime.tm_sec += p[2]; realtime.tm_isdst = -1; ////JMW TODO mktime(&realtime); igcfix.valid = ((p[0] & 0x10) >> 4) ? 'A' : 'V'; igcfix.press = ((word)p[0] & 0x0f) << 8 | p[1]; if (Haupttyp == rectyp_pos) { l = pos_ds_size[bfv][0]; igcfix.lat = ((unsigned long)p[3] & 0x7f) << 16 | ((unsigned long)p[4] ) << 8 | p[5]; if (p[3] & 0x80) igcfix.lat = -igcfix.lat; igcfix.lon = ((unsigned long)p[6] ) << 16 | ((unsigned long)p[7] ) << 8 | p[8]; if (p[9] & 0x80) igcfix.lon = -igcfix.lon; igcfix.gpalt = ((word)p[9] & 0x70) << 4 | p[10]; igcfix.fxa = hdop2fxa(p[9] & 0x0f); igcfix.enl = 4*p[11]; } else { l = pos_ds_size[bfv][1]; delta_lat = (((unsigned long)p[3] & 0x07) << 8) | p[4]; if (p[3] & 0x80) delta_lat = -delta_lat; delta_lon = (((unsigned long)p[3] & 0x78) << 5) | p[5]; if (p[6] & 0x80) delta_lon = -delta_lon; igcfix.lat += delta_lat; igcfix.lon += delta_lon; igcfix.gpalt = ((word)p[6] & 0x70) << 4 | p[7]; igcfix.fxa = hdop2fxa(p[6] & 0x0f); igcfix.enl = 4*p[8]; } igcfix.latdeg = labs(igcfix.lat) / 60000; igcfix.latmin = labs(igcfix.lat) % 60000; igcfix.londeg = labs(igcfix.lon) / 60000; igcfix.lonmin = labs(igcfix.lon) % 60000; igcfix.gps_alt = 10L * igcfix.gpalt - 1000L; if (igcfile_version >= 423) igcfix.enl = enlflt(igcfix.enl); igcfix.enl = enllim(igcfix.enl); // Bei allen neuen Dateien auf Wunsch von IAN // aber dank neuer Regeln ab // Konverter Nr. 4.20 nicht mehr !! if ( (igcfile_version >= 413) && (igcfile_version < 420) ) if (igcfix.valid == 'V') igcfix.gps_alt = 0; igcfix.pressure_alt = pressure2altitude(igcfix.press); //JMWTODO strftime(igcfix.time,sizeof(igcfix.time),"%H%M%S",&realtime); fprintf(Ausgabedatei,"B%6s%02u%05u%c%03u%05u%c%c%05ld%05ld%03u", igcfix.time, igcfix.latdeg, igcfix.latmin, ((igcfix.lat<0) ? 'S':'N'), igcfix.londeg, igcfix.lonmin, ((igcfix.lon<0) ? 'W':'E'), igcfix.valid, igcfix.pressure_alt, igcfix.gps_alt, igcfix.fxa ); if ( // erst bei ENL im I-Record aktivieren // waren irrtümlich schon mal aktiv (igcfile_version >= 413) && (igcfile_version <416)) fprintf(Ausgabedatei,"999"); // müssen auf jeden Fall aktiv sein, wenn Sensor da if (strcmp(igcheader.RHW,"3.3")>=0) fprintf(Ausgabedatei,"%03u",igcfix.enl); fprintf(Ausgabedatei,"\n"); break; case rectyp_vrb : case rectyp_vrt : l = p[1]; switch(Haupttyp) { case rectyp_vrb : p2 = p+2; break; case rectyp_vrt : realtime.tm_sec += p[2]; realtime.tm_isdst = -1; ////JMW TODO mktime(&realtime); p2 = p+3; break; default : p2 = p; break; } Untertyp = (p2[0]); switch (Untertyp) { case FLDEPEV : //JMWTODO strftime(igcfix.time,sizeof(igcfix.time),"%H%M%S",&realtime); fprintf(Ausgabedatei,"E%6sPEVEVENTBUTTON PRESSED\n",igcfix.time); break; case FLDETKF : //JMWTODO strftime(igcfix.time,sizeof(igcfix.time),"%H%M%S",&realtime); fprintf(Ausgabedatei,"LGCSTKF%6sTAKEOFF DETECTED\n",igcfix.time); break; }; break; case rectyp_tnd : realtime.tm_sec += p[1]; realtime.tm_isdst = -1; //JMW//JMW TODO mktime(&realtime); l = 8; break; default : ende = 1; l = 0; break; } p += l; } while (!ende); return pl; }