Index: /trunk/clock_and_orbit/readRTCM3.cpp
===================================================================
--- /trunk/clock_and_orbit/readRTCM3.cpp	(revision 6208)
+++ /trunk/clock_and_orbit/readRTCM3.cpp	(revision 6208)
@@ -0,0 +1,547 @@
+/* Programheader
+ *
+        Name:           readRTCM.cpp
+        Project:        SSR test
+        Version:        $Id$
+        Description:    reads, decodes and writes mixed RTCM SSR data sets
+                        supported messages:
+                        - System:          part of 1013,
+                        - Ephemeris Data:  1019, 1020,
+                        - Orbit and Clock: 1057, 1058, 1061,1063, 1064, 1067
+                        - Code Biases:     1059, 1065,
+                        - Phase Biases:    1265, 1266,
+                        - VTEC:            1264
+*/
+
+extern "C" {
+#include "clock_orbit_rtcm.h"
+#include "rtcm3torinex.h"
+}
+
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <stdlib.h>
+#include <unistd.h>
+#include <vector>
+using namespace std;
+
+typedef enum {
+    GPS, GLO, GAL, QZSS, SBAS, BDS
+} SATSYS;
+int GPSUTCdiff = 16;
+/* prototype, don't use any of this code in a final application */
+void printClock(const char* filename, struct ClockOrbit* clockOrb, SATSYS sys,
+        char satSys, int offsetGnss);
+
+void printOrbit(const char* filename, struct ClockOrbit* clockOrb, SATSYS sys,
+        char satSys, int offsetGnss);
+
+void printUra(const char* filename, struct ClockOrbit* clockOrb, SATSYS sys,
+        char satSys, int offsetGnss);
+
+void printVtec(const char* filename, struct VTEC* vtec);
+
+void printCodeBias(const char* filename, struct CodeBias* codeBias, SATSYS sys,
+        char satSys, int offsetGnss);
+
+void printPhaseBias(const char* filename, struct PhaseBias* phaseBias, SATSYS sys,
+        char satSys, int offsetGnss);
+
+void printSystemParameters(const char* filename,
+        struct RTCM3ParserData* parser);
+
+void printTextMessageType(const char* filename, int messageType);
+
+void printGpsEph(const char* filename, struct gpsephemeris* ephemerisGPS);
+
+void printGlonassEph(const char* filename,
+        struct glonassephemeris* ephemerisGLO);
+
+void decodeFileContent(char* inputFile, char* outputFile);
+
+int main(void) {
+    char inFilename[124]  = "ssr2_svpb_data/svpb224m.rtc";
+    char outFilename[124] = "ssr2_svpb_data/svpb224m_bkg.txt";
+    unlink(outFilename);
+    // Decode and save rtcm & ssr messages
+    decodeFileContent(inFilename, outFilename);
+    return 0;
+}
+
+void decodeFileContent(char* inputFile, char* outputFile) {
+    char obuffer[CLOCKORBIT_BUFFERSIZE];
+    long int offset = 0;
+    FILE * pFile = fopen(inputFile, "rb");
+    if (pFile == NULL) {
+        fputs("File error", stderr);
+        return;
+    }
+    while (1) {
+        RTCM3ParserData rtcm3Out; memset(&rtcm3Out, 0, sizeof(rtcm3Out));
+        ClockOrbit coOut; memset(&coOut, 0, sizeof(coOut));
+        CodeBias cbOut; memset(&cbOut, 0, sizeof(cbOut));
+        PhaseBias pbOut; memset(&pbOut, 0, sizeof(pbOut));
+        VTEC vtecOut; memset(&vtecOut, 0, sizeof(vtecOut));
+        fseek(pFile, offset, SEEK_SET);
+        int l = fread(obuffer, 1, CLOCKORBIT_BUFFERSIZE, pFile);
+        int bytesUsed = 0;
+        GCOB_RETURN nl = GetSSR(&coOut, &cbOut, &vtecOut, &pbOut, obuffer, l, &bytesUsed);
+        offset += bytesUsed;
+        if (nl <= -30) {
+            fprintf(stderr, "Not enough data. Error code: %d .\n", nl);
+            break;
+        } else if (nl < 0) {
+            fprintf(stderr, "GCOB_RETURN %d\nTry now RTCM3TORINEX\n", nl);
+            int z;
+            for (z = 0; z < bytesUsed; ++z) {
+                HandleByte(&rtcm3Out, (unsigned int) obuffer[z]);
+            }
+            fprintf(stderr, "RTCM message type: %d\n",rtcm3Out.blocktype);
+            switch (rtcm3Out.blocktype) {
+                case 1013:
+                    printSystemParameters(outputFile, &rtcm3Out);
+                    break;
+                case 1019:
+                    printGpsEph(outputFile, &rtcm3Out.ephemerisGPS);
+                    break;
+                case 1020:
+                    printGlonassEph(outputFile, &rtcm3Out.ephemerisGLONASS);
+                    break;
+                case 1029:// rtcm3torinex is unable to decode this type of RTCM message
+                	printTextMessageType(outputFile, rtcm3Out.blocktype);
+                    break;
+                case 1230:// rtcm3torinex is unable to decode this type of RTCM message
+                	printTextMessageType(outputFile, rtcm3Out.blocktype);
+            }
+        } else if (nl == GCOBR_OK) {//fprintf(stderr, "GCOBR_OK\n");
+            switch (coOut.messageType) {
+                case 1057:
+                    printOrbit(outputFile, &coOut, GPS, 'G',
+                            CLOCKORBIT_OFFSETGPS);
+                    break;
+                case 1058:
+                    printClock(outputFile, &coOut, GPS, 'G',
+                            CLOCKORBIT_OFFSETGPS);
+                    break;
+                case 1061:
+                    printUra(outputFile, &coOut, GPS, 'G',
+                            CLOCKORBIT_OFFSETGPS);
+                    break;
+                case 1063:
+                    printOrbit(outputFile, &coOut, GLO, 'R',
+                            CLOCKORBIT_OFFSETGLONASS);
+                    break;
+                case 1064:
+                    printClock(outputFile, &coOut, GLO, 'R',
+                            CLOCKORBIT_OFFSETGLONASS);
+                    break;
+                case 1067:
+                    printUra(outputFile, &coOut, GLO, 'R',
+                            CLOCKORBIT_OFFSETGLONASS);
+                    break;
+            }
+            switch (cbOut.messageType) {
+                case 1059:
+                    printCodeBias(outputFile, &cbOut, GPS, 'G',
+                            CLOCKORBIT_OFFSETGPS);
+                    break;
+                case 1065:
+                    printCodeBias(outputFile, &cbOut, GLO, 'R',
+                            CLOCKORBIT_OFFSETGLONASS);
+                    break;
+            }
+            switch (pbOut.messageType) {
+                case 1265:
+                    printPhaseBias(outputFile, &pbOut, GPS, 'G',
+                            CLOCKORBIT_OFFSETGPS);
+                    break;
+                case 1266:
+                    printPhaseBias(outputFile, &pbOut, GLO, 'R',
+                            CLOCKORBIT_OFFSETGLONASS);
+                    break;
+            }
+            if (vtecOut.EpochTime) {
+                printVtec(outputFile, &vtecOut);
+            }
+        } else if (nl == GCOBR_MESSAGEFOLLOWS) {
+            fprintf(stderr, "GCOBR_MESSAGEFOLLOWS\n");
+        }
+    }
+}
+
+void printClock(const char* filename, struct ClockOrbit* clockOrb, SATSYS sys,
+        char satSys, int offsetGnss) {
+    int timeOffset = 0;
+    string datum[2] = { "ITRF", "LOCAL" };
+    FILE *filestream = fopen(filename, "ab+");
+    if (filestream == NULL) {
+        fprintf(stderr, "ERROR: open file %s\n", filename);
+        return;
+    }
+    switch (sys) {
+        case GPS:
+            fprintf(filestream,
+                    "**RTCM 3 - SSR GPS Clock Message <%d>\nSystem:\t\t%10d (GPS)\nTime of week [s]:",
+                    clockOrb->messageType, sys);
+            timeOffset = 0;
+            break;
+        case GLO:
+            fprintf(filestream,
+                    "**RTCM 3 - SSR GLONASS Clock Message <%d>\nSystem:\t\t%10d (GLONASS)\nTime of day [s]:",
+                    clockOrb->messageType, sys);
+            timeOffset = (GPSUTCdiff - 3 * 3600);
+            break;
+    }
+    fprintf(filestream,
+            "\t%10d\nUpdate Interval:\t%10d\nIOD SSR:\t\t%10d\n"
+                    "ProviderId:\t\t%10d\nSolutionId:\t\t%10d\nNumber of Satellites:\t%10d\n"
+                    "PRN     A0[m]     A1[mm/s]  A2[mm/s^2]\n",
+            clockOrb->EpochTime[sys] + timeOffset, clockOrb->UpdateInterval,
+            clockOrb->SSRIOD, clockOrb->SSRProviderID, clockOrb->SSRSolutionID,
+            clockOrb->NumberOfSat[sys]);
+    unsigned int i = 0;
+    for (i = offsetGnss; i < offsetGnss + clockOrb->NumberOfSat[sys]; ++i) {
+        fprintf(filestream, "%c%02d %10.4f%10.3f%10.5f\n", satSys,
+                clockOrb->Sat[i].ID, clockOrb->Sat[i].Clock.DeltaA0,
+                clockOrb->Sat[i].Clock.DeltaA1 * 1.0E3,
+                clockOrb->Sat[i].Clock.DeltaA2 * 1.0E3);
+    }
+    fclose(filestream);
+    return;
+}
+
+void printOrbit(const char* filename, struct ClockOrbit* clockOrb, SATSYS sys,
+        char satSys, int offsetGnss) {
+    int timeOffset = 0;
+    string datum[2] = { "ITRF", "LOCAL" };
+    FILE *filestream = fopen(filename, "ab+");
+    if (filestream == NULL) {
+        fprintf(stderr, "ERROR: open file %s\n", filename);
+        return;
+    }
+    switch (sys) {
+        case GPS:
+            fprintf(filestream,
+                    "**RTCM 3 - SSR GPS Orbit Message <%d>\nSystem:\t\t%10d (GPS)\nTime of week [s]:",
+                    clockOrb->messageType, sys);
+            timeOffset = 0;
+            break;
+        case GLO:
+            fprintf(filestream,
+                    "**RTCM 3 - SSR GLONASS Orbit Message <%d>\nSystem:\t\t%10d (GLONASS)\nTime of day [s]:",
+                    clockOrb->messageType, sys);
+            timeOffset = (GPSUTCdiff - 3 * 3600);
+            break;
+    }
+    fprintf(filestream,
+            "\t%10d\nUpdate Interval:\t%10d\nIOD SSR:\t\t%10d\n"
+                    "ProviderId:\t\t%10d\nSolutionId:\t\t%10d\nReference Datum:\t\t%s\nNumber of Satellites:\t%10d\n"
+                    "PRN   IOD    Radial    AlongTrk  CrossTrk[m]    DotDelta[mm/s]\n",
+            clockOrb->EpochTime[sys] + timeOffset, clockOrb->UpdateInterval,
+            clockOrb->SSRIOD, clockOrb->SSRProviderID, clockOrb->SSRSolutionID,
+            (datum[clockOrb->SatRefDatum]).c_str(), clockOrb->NumberOfSat[sys]);
+    unsigned int i = 0;
+    for (i = offsetGnss; i < offsetGnss + clockOrb->NumberOfSat[sys]; ++i) {
+        fprintf(filestream, "%c%02d %5d %10.4f%10.4f%10.4f%10.3f%10.3f%10.3f\n",
+                satSys, clockOrb->Sat[i].ID, clockOrb->Sat[i].IOD,
+                clockOrb->Sat[i].Orbit.DeltaRadial,
+                clockOrb->Sat[i].Orbit.DeltaAlongTrack,
+                clockOrb->Sat[i].Orbit.DeltaCrossTrack,
+                clockOrb->Sat[i].Orbit.DotDeltaRadial * 1.0E3,
+                clockOrb->Sat[i].Orbit.DotDeltaAlongTrack * 1.0E3,
+                clockOrb->Sat[i].Orbit.DotDeltaAlongTrack * 1.0E3);
+    }
+    fclose(filestream);
+    return;
+}
+
+void printUra(const char* filename, struct ClockOrbit* clockOrb, SATSYS sys,
+        char satSys, int offsetGnss) {
+    int timeOffset = 0;
+    FILE *filestream = fopen(filename, "ab+");
+    if (filestream == NULL) {
+        fprintf(stderr, "ERROR: open file %s\n", filename);
+        return;
+    }
+    switch (sys) {
+        case GPS:
+            fprintf(filestream,
+                    "**RTCM 3 - SSR GPS URA Message <%d>\nSystem:\t\t%10d (GPS)\nTime of week [s]:",
+                    clockOrb->messageType, sys);
+            timeOffset = 0;
+            break;
+        case GLO:
+            fprintf(filestream,
+                    "**RTCM 3 - SSR GLONASS URA Message <%d>\nSystem:\t\t%10d (GLONASS)\nTime of day [s]:",
+                    clockOrb->messageType, sys);
+            timeOffset = (GPSUTCdiff - 3 * 3600);
+            break;
+    }
+    fprintf(filestream,
+            "\t%10d\nUpdate Interval:\t%10d\nIOD SSR:\t\t%10d\n"
+                    "ProviderId:\t\t%10d\nSolutionId:\t\t%10d\nNumber of Satellites:\t%10d\n"
+                    "PRN     URA[m]\n", clockOrb->EpochTime[sys] + timeOffset,
+            clockOrb->UpdateInterval, clockOrb->SSRIOD, clockOrb->SSRProviderID,
+            clockOrb->SSRSolutionID, clockOrb->NumberOfSat[sys]);
+    unsigned int i = 0;
+    for (i = offsetGnss; i < offsetGnss + clockOrb->NumberOfSat[sys]; ++i) {
+        fprintf(filestream, "%c%02d %10.4f\n", satSys, clockOrb->Sat[i].ID,
+                clockOrb->Sat[i].UserRangeAccuracy);
+    }
+    fclose(filestream);
+    return;
+}
+
+void printCodeBias(const char* filename, struct CodeBias* codeBias, SATSYS sys,
+        char satSys, int offsetGnss) {
+    int timeOffset = 0;
+    FILE *filestream = fopen(filename, "ab+");
+    if (filestream == NULL) {
+        fprintf(stderr, "ERROR: open file %s\n", filename);
+        return;
+    }
+    switch (sys) {
+        case GPS:
+            fprintf(filestream,
+                    "**RTCM 3 - SSR GPS Code Bias Message <%d>\nSystem:\t\t%10d (GPS)\nTime of week [s]:",
+                    codeBias->messageType, sys);
+            timeOffset = 0;
+            break;
+        case GLO:
+            fprintf(filestream,
+                    "**RTCM 3 - SSR GLONASS Code Bias Message <%d>\nSystem:\t\t%10d (GLONASS)\nTime of day [s]:",
+                    codeBias->messageType, sys);
+            timeOffset = (GPSUTCdiff - 3 * 3600);
+            break;
+    }
+    fprintf(filestream,
+            "\t%10d\nUpdate Interval:\t%10d\nIOD SSR:\t\t%10d\n"
+                    "ProviderId:\t\t%10d\nSolutionId:\t\t%10d\nNumber of Satellites:\t%10d\n"
+                    "PRN  Number      Type      Bias[m]     Type     Bias[m]\n",
+            codeBias->EpochTime[sys] + timeOffset, codeBias->UpdateInterval,
+            codeBias->SSRIOD, codeBias->SSRProviderID, codeBias->SSRSolutionID,
+            codeBias->NumberOfSat[sys]);
+    unsigned int i = 0;
+    for (i = offsetGnss; i < offsetGnss + codeBias->NumberOfSat[sys]; ++i) {
+        fprintf(filestream, "%c%02d %5d ", satSys, codeBias->Sat[i].ID,
+                codeBias->Sat[i].NumberOfCodeBiases);
+        int j;
+        for (j = 0; j < codeBias->Sat[i].NumberOfCodeBiases; j++) {
+            fprintf(filestream, "%10d %12.2f", codeBias->Sat[i].Biases[j].Type,
+                    codeBias->Sat[i].Biases[j].Bias);
+        }
+        fprintf(filestream, "\n");
+    }
+    fclose(filestream);
+    return;
+}
+
+void printPhaseBias(const char* filename, struct PhaseBias* phaseBias, SATSYS sys,
+        char satSys, int offsetGnss) {
+    int timeOffset = 0;
+    FILE *filestream = fopen(filename, "ab+");
+    if (filestream == NULL) {
+        fprintf(stderr, "ERROR: open file %s\n", filename);
+        return;
+    }
+    switch (sys) {
+        case GPS:
+            fprintf(filestream,
+                    "**RTCM 3 - SSR GPS Phase Bias Message <%d>\nSystem:\t\t%10d (GPS)\nTime of week [s]:",
+                    phaseBias->messageType, sys);
+            timeOffset = 0;
+            break;
+        case GLO:
+            fprintf(filestream,
+                    "**RTCM 3 - SSR GLONASS Phase Bias Message <%d>\nSystem:\t\t%10d (GLONASS)\nTime of day [s]:",
+                    phaseBias->messageType, sys);
+            timeOffset = (GPSUTCdiff - 3 * 3600);
+            break;
+    }
+    fprintf(filestream,
+            "\t%10d\nUpdate Interval:\t\t%10d\nIOD SSR:\t\t\t%10d\n"
+                    "ProviderId:\t\t\t%10d\nSolutionId:\t\t\t%10d\n"
+    		        "DispersiveBiasConsistencyIndicator\t%2d\nMWConsistencyIndicator\t\t%10d\nNumber of Satellites:\t\t%10d\n"
+                    "PRN  Yaw[deg] YawRate[deg/sec] Number Type INT-ind  WL-ind  DISC-count Bias[m] Type INT-ind  WL-ind  DISC-count Bias[m]\n",
+                    phaseBias->EpochTime[sys] + timeOffset,
+                    phaseBias->UpdateInterval,
+                    phaseBias->SSRIOD, phaseBias->SSRProviderID, phaseBias->SSRSolutionID,
+                    phaseBias->DispersiveBiasConsistencyIndicator ,
+                    phaseBias->MWConsistencyIndicator,
+                    phaseBias->NumberOfSat[sys]);
+    unsigned int i = 0;
+    for (i = offsetGnss; i < offsetGnss + phaseBias->NumberOfSat[sys]; ++i) {
+        fprintf(filestream, "%c%02d %8.3f %8.4f %12d",
+        		satSys,phaseBias->Sat[i].ID,
+        		phaseBias->Sat[i].YawAngle,
+        		phaseBias->Sat[i].YawRate,
+                phaseBias->Sat[i].NumberOfPhaseBiases);
+        int j;
+        for (j = 0; j < phaseBias->Sat[i].NumberOfPhaseBiases; j++) {
+            fprintf(filestream, "%6d %6d %6d %10d %10.2f",
+            		phaseBias->Sat[i].Biases[j].Type,
+            		phaseBias->Sat[i].Biases[j].SignalIntegerIndicator,
+            		phaseBias->Sat[i].Biases[j].SignalsWideLaneIntegerIndicator,
+            		phaseBias->Sat[i].Biases[j].SignalDiscontinuityCounter,
+                    phaseBias->Sat[i].Biases[j].Bias);
+        }
+        fprintf(filestream, "\n");
+    }
+    fclose(filestream);
+    return;
+}
+
+void printVtec(const char* filename, struct VTEC* vtec) {
+    FILE *filestream = fopen(filename, "ab+");
+    if (filestream == NULL) {
+        fprintf(stderr, "ERROR: open file %s\n", filename);
+        return;
+    }
+    fprintf(filestream,
+            "**RTCM 3 - SSR VTEC Message <1264>\n"
+                    "Time of week [s]:\t%10d\nUpdate Interval:\t%10d\nIOD SSR:\t\t%10d\n"
+                    "ProviderId:\t\t%10d\nSolutionId:\t\t%10d\nNumber of Layers:\t%10d\n"
+                    "Quality:\t\t%13.3f\n", vtec->EpochTime,
+            vtec->UpdateInterval, vtec->SSRIOD, vtec->SSRProviderID,
+            vtec->SSRSolutionID, vtec->NumLayers, vtec->Quality);
+
+    unsigned int i, j, k;
+    for (i = 0; i < vtec->NumLayers; ++i) {
+        fprintf(filestream,
+                "Layer: %2d Height [m]: %f Degree n:%2d Order m:%2d\n", i,
+                vtec->Layers[i].Height, vtec->Layers[i].Degree,
+                vtec->Layers[i].Order);
+        for (j = 0; j <= vtec->Layers[i].Degree; ++j) {
+            fprintf(filestream, "Cn%d [TECU]: ", j);
+            for (k = 0; k <= vtec->Layers[i].Order; ++k) {
+                fprintf(filestream, " %7.3f", vtec->Layers[i].Cosinus[k][j]);
+            }
+            fprintf(filestream, "\n");
+        }
+        for (j = 1; j <= vtec->Layers[i].Degree; ++j) {
+            fprintf(filestream, "Sn%d [TECU]: ", j);
+            for (k = 0; k <= vtec->Layers[i].Order; ++k) {
+                fprintf(filestream, " %7.3f", vtec->Layers[i].Sinus[k][j]);
+            }
+            fprintf(filestream, "\n");
+        }
+    }
+    fclose(filestream);
+    return;
+}
+
+void printSystemParameters(const char* filename,
+        struct RTCM3ParserData* parser) {
+    FILE *filestream = fopen(filename, "ab+");
+    if (filestream == NULL) {
+        fprintf(stderr, "ERROR: open file %s\n", filename);
+        return;
+    }
+    fprintf(filestream,
+            "**RTCM 3 - System parameters <1013>\n"
+                    "Modified Julian Day:\t %d\nSeconds of Day:\t\t%2d\nLeapSeconds:\t\t%2d\n",
+            parser->modjulday, parser->secofday, parser->leapsec);
+    fclose(filestream);
+    return;
+}
+
+void printTextMessageType(const char* filename, int messageType) {
+    FILE *filestream = fopen(filename, "ab+");
+    if (filestream == NULL) {
+        fprintf(stderr, "ERROR: open file %s\n", filename);
+        return;
+    }
+    fprintf(filestream,
+            "**RTCM 3 - Text Message <%d>\n", messageType);
+    fclose(filestream);
+    return;
+}
+void printGpsEph(const char* filename, struct gpsephemeris* ephemerisGPS) {
+    FILE *filestream = fopen(filename, "ab+");
+    if (filestream == NULL) {
+        fprintf(stderr, "ERROR: open file %s\n", filename);
+        return;
+    }
+    fprintf(filestream, "**RTCM 3 - GPS Ephemeris <1019>\n"
+            "PRN                    %13d\n"
+            "IODE                   %13d\n"
+            "URAindex [1..15]       %13d\n"
+            "SVhealth               %13d\n"
+            "GPSweek                %13d\n"
+            "IODC                   %13d\n"
+            "TOW [s]                %13d\n"
+            "TOC [s]                %13d\n"
+            "TOE [s]                %13d\n"
+            "clock_bias [s]         %13e\n"
+            "clock_drift[s/s]       %13e\n"
+            "clock_driftrate [s/s^2]%13e\n"
+            "Crs [m]                %13e\n"
+            "Delta_n [rad/s]        %13e\n"
+            "M0 [rad]               %13e\n"
+            "Cuc [rad]              %13e\n"
+            "e                      %13e\n"
+            "Cus [rad]              %13e\n"
+            "sqrt_A [m^0.5]         %13e\n"
+            "Cic [rad]              %13e\n"
+            "OMEGA0 [rad]           %13e\n"
+            "Cis [rad]              %13e\n"
+            "i0 [rad]               %13e\n"
+            "Crc [m]                %13e\n"
+            "omega [rad]            %13e\n"
+            "OMEGADOT [rad/s]       %13e\n"
+            "IDOT [rad/s]           %13e\n"
+            "TGD [s]                %13e\n", ephemerisGPS->satellite,
+            ephemerisGPS->IODE, ephemerisGPS->URAindex, ephemerisGPS->SVhealth,
+            ephemerisGPS->GPSweek, ephemerisGPS->IODC, ephemerisGPS->TOW,
+            ephemerisGPS->TOC, ephemerisGPS->TOE, ephemerisGPS->clock_bias,
+            ephemerisGPS->clock_drift, ephemerisGPS->clock_driftrate,
+            ephemerisGPS->Crs, ephemerisGPS->Delta_n, ephemerisGPS->M0,
+            ephemerisGPS->Cuc, ephemerisGPS->e, ephemerisGPS->Cus,
+            ephemerisGPS->sqrt_A, ephemerisGPS->Cic, ephemerisGPS->OMEGA0,
+            ephemerisGPS->Cis, ephemerisGPS->i0, ephemerisGPS->Crc,
+            ephemerisGPS->omega, ephemerisGPS->OMEGADOT, ephemerisGPS->IDOT,
+            ephemerisGPS->TGD);
+    fclose(filestream);
+    return;
+    return;
+}
+
+void printGlonassEph(const char* filename,
+        struct glonassephemeris* ephemerisGLO) {
+    FILE *filestream = fopen(filename, "ab+");
+    if (filestream == NULL) {
+        fprintf(stderr, "ERROR: open file %s\n", filename);
+        return;
+    }
+    fprintf(filestream, "**RTCM 3 - GLONASS Ephemeris <1020>\n"
+            "SV                      %10d\n"
+            "frequency_number        %10d\n"
+            "tb [s]                  %10d\n"
+            "tk [s]                  %10d\n"
+            "E  [days]               %10d\n"
+            "tau [s]                 %13e\n"
+            "gamma                   %13e\n"
+            "x_pos [km]              %13e\n"
+            "x_velocity [km/s]       %13e\n"
+            "x_acceleration [km/s^2] %13e\n"
+            "y_pos [km]              %13e\n"
+            "y_velocity [km/s]       %13e\n"
+            "y_acceleration [km/s^2] %13e\n"
+            "z_pos [km]              %13e\n"
+            "z_velocity [km/s]       %13e\n"
+            "z_acceleration [km/s^2] %13e\n", ephemerisGLO->almanac_number,
+            ephemerisGLO->frequency_number, ephemerisGLO->tb, ephemerisGLO->tk,
+            ephemerisGLO->E, ephemerisGLO->tau, ephemerisGLO->gamma,
+            ephemerisGLO->x_pos, ephemerisGLO->x_velocity,
+            ephemerisGLO->x_acceleration, ephemerisGLO->y_pos,
+            ephemerisGLO->y_velocity, ephemerisGLO->y_acceleration,
+            ephemerisGLO->z_pos, ephemerisGLO->z_velocity,
+            ephemerisGLO->z_acceleration);
+    fclose(filestream);
+    return;
+}
+
