From 46e7ed92c4e8d239f054a45ecd5c33e689a27a2b Mon Sep 17 00:00:00 2001
From: TimEverett <tim.everett3@gmail.com>
Date: Tue, 31 Jul 2018 12:11:30 -0600
Subject: [PATCH] - Add support for ComNav binary format - Add support for
 rover base position in rinex header (for fixed sol)

---
 app/convbin/bcc/_convbin.cbproj        |    9 +
 app/convbin/gcc/makefile               |    5 +-
 app/convbin/msc/msc.vcproj             |  269 ------
 app/convbin/msc/msc.vcxproj            |    1 +
 app/rtkconv/rtkconv.cbproj             |    9 +
 app/rtknavi/rtknavi.cbproj             |    9 +
 app/rtknavi_mkl/rtknavi_mkl.cbproj     |    9 +
 app/rtknavi_win64/rtknavi_win64.cbproj |   21 +
 app/rtkplot/plotinfo.cpp               |    1 +
 app/rtkplot/rtkplot.cbproj             |   27 +-
 app/rtkplot/rtkplot.cpp                |   56 +-
 app/rtkrcv/gcc/makefile                |    5 +-
 app/rtkrcv/gcc/rtkrcv.conf             |   37 +-
 app/srctblbrows/srctblbrows.cbproj     |    9 +
 app/str2str/gcc/makefile               |    5 +-
 app/strsvr/strsvr.cbproj               |    9 +
 src/convrnx.c                          |   16 +-
 src/postpos.c                          |    4 +
 src/rcv/comnav.c                       | 1144 ++++++++++++++++++++++++
 src/rcv/novatel.c                      |  322 +------
 src/rcvraw.c                           |    4 +-
 src/rinex.c                            |    4 +-
 src/rtkcmn.c                           |    4 +-
 src/rtklib.h                           |    6 +-
 src/sbas.c                             |    6 -
 src/src.pro                            |    1 +
 26 files changed, 1313 insertions(+), 679 deletions(-)
 delete mode 100644 app/convbin/msc/msc.vcproj
 create mode 100644 src/rcv/comnav.c

diff --git a/app/convbin/bcc/_convbin.cbproj b/app/convbin/bcc/_convbin.cbproj
index 94dc037..488eedd 100644
--- a/app/convbin/bcc/_convbin.cbproj
+++ b/app/convbin/bcc/_convbin.cbproj
@@ -211,6 +211,9 @@
         <CppCompile Include="..\..\..\src\rcv\tersus.c">
             <BuildOrder>28</BuildOrder>
         </CppCompile>
+        <CppCompile Include="..\..\..\src\rcv\comnav.c">
+            <BuildOrder>29</BuildOrder>
+        </CppCompile>
         <CppCompile Include="..\..\..\src\rcv\ublox.c">
             <BuildOrder>7</BuildOrder>
             <BuildOrder>12</BuildOrder>
@@ -528,6 +531,12 @@
                         <Overwrite>true</Overwrite>
                     </Platform>
                 </DeployFile>
+                <DeployFile LocalName="..\..\..\src\rcv\comnav.c" Configuration="Release" Class="ProjectFile">
+                    <Platform Name="Win32">
+                        <RemoteDir>.\</RemoteDir>
+                        <Overwrite>true</Overwrite>
+                    </Platform>
+                </DeployFile>
                 <DeployFile Condition="'$(DynamicRTL)'=='true' And '$(Multithreaded)'!='true'" LocalName="$(BDS)\bin\cc32250.dll" Class="DependencyModule">
                     <Platform Name="Win32">
                         <Overwrite>true</Overwrite>
diff --git a/app/convbin/gcc/makefile b/app/convbin/gcc/makefile
index e44dec3..9cbb435 100644
--- a/app/convbin/gcc/makefile
+++ b/app/convbin/gcc/makefile
@@ -22,7 +22,7 @@ all  : convbin
 
 convbin    : convbin.o rtkcmn.o rinex.o sbas.o preceph.o rcvraw.o convrnx.o
 convbin    : rtcm.o rtcm2.o rtcm3.o rtcm3e.o pntpos.o ephemeris.o ionex.o
-convbin    : novatel.o swiftnav.o tersus.o ublox.o crescent.o skytraq.o gw10.o javad.o nvs.o
+convbin    : novatel.o swiftnav.o tersus.o comnav.o ublox.o crescent.o skytraq.o gw10.o javad.o nvs.o
 convbin    : binex.o rt17.o qzslex.o septentrio.o cmr.o
 
 convbin.o  : ../convbin.c
@@ -81,6 +81,8 @@ cmr.o      : $(SRC)/rcv/cmr.c
 	$(CC) -c $(CFLAGS) $(SRC)/rcv/cmr.c
 tersus.o   : $(SRC)/rcv/tersus.c
 	$(CC) -c $(CFLAGS) $(SRC)/rcv/tersus.c
+comnav.o   : $(SRC)/rcv/comnav.c
+	$(CC) -c $(CFLAGS) $(SRC)/rcv/comnav.c
 
 convbin.o  : $(SRC)/rtklib.h
 rtkcmn.o   : $(SRC)/rtklib.h
@@ -110,6 +112,7 @@ qzslex.o   : $(SRC)/rtklib.h
 septentrio.o: $(SRC)/rtklib.h
 cmr.o      : $(SRC)/rtklib.h
 tersus.o   : $(SRC)/rtklib.h
+comnav.o   : $(SRC)/rtklib.h
 
 DATDIR = ../../../test/data/rcvraw
 
diff --git a/app/convbin/msc/msc.vcproj b/app/convbin/msc/msc.vcproj
deleted file mode 100644
index 926cfab..0000000
--- a/app/convbin/msc/msc.vcproj
+++ /dev/null
@@ -1,269 +0,0 @@
-<?xml version="1.0" encoding="shift_jis"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="9.00"
-	Name="msc"
-	ProjectGUID="{A9A9B274-2448-4FA0-AC05-857D411DCA48}"
-	RootNamespace="msc"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="131072"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
-			IntermediateDirectory="$(ConfigurationName)"
-			ConfigurationType="1"
-			CharacterSet="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories="C:\rtklib_2.1\src"
-				PreprocessorDefinitions="WIN32;_CRT_SECURE_NO_DEPRECATE;ENAGLO;ENAQZS;ENAGAL;NFREQ=3"
-				MinimalRebuild="true"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="3"
-				UsePrecompiledHeader="0"
-				WarningLevel="3"
-				DebugInformationFormat="4"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="winmm.lib"
-				OutputFile="$(OutDir)\convbin.exe"
-				LinkIncremental="2"
-				GenerateDebugInformation="true"
-				SubSystem="1"
-				RandomizedBaseAddress="1"
-				DataExecutionPrevention="0"
-				TargetMachine="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
-			IntermediateDirectory="$(ConfigurationName)"
-			ConfigurationType="1"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\src"
-				PreprocessorDefinitions="WIN32;_CRT_SECURE_NO_DEPRECATE;ENAGLO;ENAQZS;ENAGAL;NFREQ=3"
-				RuntimeLibrary="2"
-				UsePrecompiledHeader="0"
-				WarningLevel="3"
-				DebugInformationFormat="3"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="winmm.lib"
-				OutputFile="$(OutDir)\convbin.exe"
-				LinkIncremental="1"
-				AdditionalLibraryDirectories=""
-				GenerateDebugInformation="true"
-				SubSystem="1"
-				OptimizeReferences="2"
-				EnableCOMDATFolding="2"
-				RandomizedBaseAddress="1"
-				DataExecutionPrevention="0"
-				TargetMachine="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="ソース ファイル"
-			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
-			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
-			>
-			<File
-				RelativePath="..\convbin.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\src\convrnx.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\src\rcv\crescent.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\src\rcv\gw10.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\src\rcv\javad.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\src\rcv\novatel.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\src\rcv\nvs.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\src\preceph.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\src\rcvraw.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\src\rinex.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\src\rtcm.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\src\rtcm2.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\src\rtcm3.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\src\rtkcmn.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\src\sbas.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\src\rcv\skytraq.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\src\rcv\ss2.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\src\rcv\ublox.c"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="ヘッダー ファイル"
-			Filter="h;hpp;hxx;hm;inl;inc;xsd"
-			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
-			>
-		</Filter>
-		<Filter
-			Name="リソース ファイル"
-			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
-			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
-			>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/app/convbin/msc/msc.vcxproj b/app/convbin/msc/msc.vcxproj
index 75ab36d..ca690dd 100644
--- a/app/convbin/msc/msc.vcxproj
+++ b/app/convbin/msc/msc.vcxproj
@@ -109,6 +109,7 @@
     <ClCompile Include="..\..\..\src\rcv\septentrio.c" />
     <ClCompile Include="..\..\..\src\rcv\swiftnav.c" />
     <ClCompile Include="..\..\..\src\rcv\tersus.c" />
+    <ClCompile Include="..\..\..\src\rcv\comnav.c" />
     <ClCompile Include="..\..\..\src\rtcm3e.c" />
     <ClCompile Include="..\convbin.c" />
     <ClCompile Include="..\..\..\src\convrnx.c" />
diff --git a/app/rtkconv/rtkconv.cbproj b/app/rtkconv/rtkconv.cbproj
index dbedb6d..9fba7f6 100644
--- a/app/rtkconv/rtkconv.cbproj
+++ b/app/rtkconv/rtkconv.cbproj
@@ -250,6 +250,9 @@
         <CppCompile Include="..\..\src\rcv\cmr.c">
             <BuildOrder>38</BuildOrder>
         </CppCompile>
+        <CppCompile Include="..\..\src\rcv\comnav.c">
+            <BuildOrder>40</BuildOrder>
+        </CppCompile>
         <CppCompile Include="..\..\src\rcv\crescent.c">
             <BuildOrder>20</BuildOrder>
             <BuildOrder>10</BuildOrder>
@@ -488,6 +491,12 @@
                         <Overwrite>true</Overwrite>
                     </Platform>
                 </DeployFile>
+                <DeployFile LocalName="..\..\src\rcv\comnav.c" Configuration="Debug" Class="ProjectFile">
+                    <Platform Name="Win32">
+                        <RemoteDir>.\</RemoteDir>
+                        <Overwrite>true</Overwrite>
+                    </Platform>
+                </DeployFile>
                 <DeployFile LocalName="..\..\src\rcv\skytraq.c" Configuration="Debug" Class="ProjectFile">
                     <Platform Name="Win32">
                         <RemoteDir>.\</RemoteDir>
diff --git a/app/rtknavi/rtknavi.cbproj b/app/rtknavi/rtknavi.cbproj
index 457e9d4..c4c7b3f 100644
--- a/app/rtknavi/rtknavi.cbproj
+++ b/app/rtknavi/rtknavi.cbproj
@@ -308,6 +308,9 @@
         <CppCompile Include="..\..\src\rcv\cmr.c">
             <BuildOrder>61</BuildOrder>
         </CppCompile>
+        <CppCompile Include="..\..\src\rcv\comnav.c">
+            <BuildOrder>62</BuildOrder>
+        </CppCompile>
         <CppCompile Include="..\..\src\rcv\crescent.c">
             <BuildOrder>49</BuildOrder>
         </CppCompile>
@@ -713,6 +716,12 @@
                         <Overwrite>true</Overwrite>
                     </Platform>
                 </DeployFile>
+                <DeployFile LocalName="..\..\src\rcv\comnav.c" Configuration="Release" Class="ProjectFile">
+                    <Platform Name="Win32">
+                        <RemoteDir>.\</RemoteDir>
+                        <Overwrite>true</Overwrite>
+                    </Platform>
+                </DeployFile>
                 <DeployFile LocalName="..\..\src\rcvraw.c" Configuration="Release" Class="ProjectFile">
                     <Platform Name="Win32">
                         <RemoteDir>.\</RemoteDir>
diff --git a/app/rtknavi_mkl/rtknavi_mkl.cbproj b/app/rtknavi_mkl/rtknavi_mkl.cbproj
index 5c2bf27..1edaf5c 100644
--- a/app/rtknavi_mkl/rtknavi_mkl.cbproj
+++ b/app/rtknavi_mkl/rtknavi_mkl.cbproj
@@ -352,6 +352,9 @@
             <BuildOrder>56</BuildOrder>
         </CppCompile>
         <CppCompile Include="..\..\src\rcv\cmr.c">
+            <BuildOrder>61</BuildOrder>
+        </CppCompile>
+        <CppCompile Include="..\..\src\rcv\comnav.c">
             <BuildOrder>62</BuildOrder>
         </CppCompile>
         <CppCompile Include="..\..\src\rcv\crescent.c">
@@ -768,6 +771,12 @@
                         <Overwrite>true</Overwrite>
                     </Platform>
                 </DeployFile>
+                <DeployFile LocalName="..\..\src\rcv\comnav.c" Configuration="Release" Class="ProjectFile">
+                    <Platform Name="Win32">
+                        <RemoteDir>.\</RemoteDir>
+                        <Overwrite>true</Overwrite>
+                    </Platform>
+                </DeployFile>
                 <DeployFile LocalName="..\..\src\rcvraw.c" Configuration="Release" Class="ProjectFile">
                     <Platform Name="Win32">
                         <RemoteDir>.\</RemoteDir>
diff --git a/app/rtknavi_win64/rtknavi_win64.cbproj b/app/rtknavi_win64/rtknavi_win64.cbproj
index 2a178aa..c68e1e9 100644
--- a/app/rtknavi_win64/rtknavi_win64.cbproj
+++ b/app/rtknavi_win64/rtknavi_win64.cbproj
@@ -357,6 +357,9 @@
             <BuildOrder>56</BuildOrder>
         </CppCompile>
         <CppCompile Include="..\..\src\rcv\cmr.c">
+            <BuildOrder>61</BuildOrder>
+        </CppCompile>
+        <CppCompile Include="..\..\src\rcv\comnav.c">
             <BuildOrder>62</BuildOrder>
         </CppCompile>
         <CppCompile Include="..\..\src\rcv\crescent.c">
@@ -637,6 +640,18 @@
                         <Overwrite>true</Overwrite>
                     </Platform>
                 </DeployFile>
+                <DeployFile LocalName="..\..\src\rcv\tersus.c" Configuration="Release" Class="ProjectFile">
+                    <Platform Name="Win64">
+                        <RemoteDir>.\</RemoteDir>
+                        <Overwrite>true</Overwrite>
+                    </Platform>
+                </DeployFile>
+                <DeployFile LocalName="..\..\src\rcv\comnav.c" Configuration="Release" Class="ProjectFile">
+                    <Platform Name="Win64">
+                        <RemoteDir>.\</RemoteDir>
+                        <Overwrite>true</Overwrite>
+                    </Platform>
+                </DeployFile>
                 <DeployFile Condition="'$(UsingDelphiRTL)'=='true'" LocalName="$(BDS)\bin\borlndmm.dll" Class="DependencyModule">
                     <Platform Name="Win32">
                         <Overwrite>true</Overwrite>
@@ -742,6 +757,12 @@
                         <Overwrite>true</Overwrite>
                     </Platform>
                 </DeployFile>
+                <DeployFile LocalName="..\..\src\rcv\comnav.c" Configuration="Release" Class="ProjectFile">
+                    <Platform Name="Win32">
+                        <RemoteDir>.\</RemoteDir>
+                        <Overwrite>true</Overwrite>
+                    </Platform>
+                </DeployFile>
                 <DeployFile LocalName="..\..\src\rcv\crescent.c" Configuration="Release" Class="ProjectFile">
                     <Platform Name="Win32">
                         <RemoteDir>.\</RemoteDir>
diff --git a/app/rtkplot/plotinfo.cpp b/app/rtkplot/plotinfo.cpp
index 2b0e67e..0a8a307 100644
--- a/app/rtkplot/plotinfo.cpp
+++ b/app/rtkplot/plotinfo.cpp
@@ -408,3 +408,4 @@ void __fastcall TPlot::UpdatePoint(int x, int y)
     Message2->Caption=A2U(msg);
 }
 //---------------------------------------------------------------------------
+
diff --git a/app/rtkplot/rtkplot.cbproj b/app/rtkplot/rtkplot.cbproj
index 5138d6c..2704f63 100644
--- a/app/rtkplot/rtkplot.cbproj
+++ b/app/rtkplot/rtkplot.cbproj
@@ -4,7 +4,7 @@
         <ProjectType>CppVCLApplication</ProjectType>
         <MainSource>rtkplot.cpp</MainSource>
         <Base>True</Base>
-        <Config Condition="'$(Config)'==''">Release</Config>
+        <Config Condition="'$(Config)'==''">Debug</Config>
         <FrameworkType>VCL</FrameworkType>
         <ProjectVersion>18.2</ProjectVersion>
         <Platform Condition="'$(Platform)'==''">Win32</Platform>
@@ -19,11 +19,6 @@
         <CfgParent>Base</CfgParent>
         <Base>true</Base>
     </PropertyGroup>
-    <PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
-        <Base_Win64>true</Base_Win64>
-        <CfgParent>Base</CfgParent>
-        <Base>true</Base>
-    </PropertyGroup>
     <PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
         <Cfg_1>true</Cfg_1>
         <CfgParent>Base</CfgParent>
@@ -35,12 +30,6 @@
         <Cfg_1>true</Cfg_1>
         <Base>true</Base>
     </PropertyGroup>
-    <PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win64)'!=''">
-        <Cfg_1_Win64>true</Cfg_1_Win64>
-        <CfgParent>Cfg_1</CfgParent>
-        <Cfg_1>true</Cfg_1>
-        <Base>true</Base>
-    </PropertyGroup>
     <PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
         <Cfg_2>true</Cfg_2>
         <CfgParent>Base</CfgParent>
@@ -105,13 +94,6 @@
         <UWP_CppLogo44>$(BDS)\bin\Artwork\Windows\UWP\cppreg_UwpDefault_44.png</UWP_CppLogo44>
         <UWP_CppLogo150>$(BDS)\bin\Artwork\Windows\UWP\cppreg_UwpDefault_150.png</UWP_CppLogo150>
     </PropertyGroup>
-    <PropertyGroup Condition="'$(Base_Win64)'!=''">
-        <BCC_Defines>_RTLDLL;WIN32;TRACE;ENAGLO;ENAGAL;ENAQZS;ENACMP;NEXOBS=3;NFREQ=3;$(BCC_Defines)</BCC_Defines>
-        <TASM_Defines>_RTLDLL;WIN32;TRACE;ENAGLO;ENAGAL;ENAQZS;NFREQ=3;$(TASM_Defines)</TASM_Defines>
-        <BRCC_Defines>_RTLDLL;WIN32;TRACE;ENAGLO;ENAGAL;ENAQZS;NFREQ=3;$(BRCC_Defines)</BRCC_Defines>
-        <UWP_CppLogo44>$(BDS)\bin\Artwork\Windows\UWP\cppreg_UwpDefault_44.png</UWP_CppLogo44>
-        <UWP_CppLogo150>$(BDS)\bin\Artwork\Windows\UWP\cppreg_UwpDefault_150.png</UWP_CppLogo150>
-    </PropertyGroup>
     <PropertyGroup Condition="'$(Cfg_1)'!=''">
         <DCC_AdditionalSwitches> -V</DCC_AdditionalSwitches>
         <DCC_Define>DEBUG;$(DCC_Define);$(DCC_Define)</DCC_Define>
@@ -139,9 +121,6 @@
         <VerInfo_Locale>1033</VerInfo_Locale>
         <BCC_wpar>false</BCC_wpar>
     </PropertyGroup>
-    <PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
-        <BCC_Defines>_DEBUG;$(BCC_Defines);$(BCC_Defines)</BCC_Defines>
-    </PropertyGroup>
     <PropertyGroup Condition="'$(Cfg_2)'!=''">
         <DCC_AdditionalSwitches> -$O+</DCC_AdditionalSwitches>
         <IntermediateOutputDir>Release_Build</IntermediateOutputDir>
@@ -366,6 +345,9 @@
         <CppCompile Include="..\..\src\rcv\cmr.c">
             <BuildOrder>61</BuildOrder>
         </CppCompile>
+        <CppCompile Include="..\..\src\rcv\comnav.c">
+            <BuildOrder>62</BuildOrder>
+        </CppCompile>
         <CppCompile Include="..\..\src\rcv\crescent.c">
             <BuildOrder>37</BuildOrder>
             <BuildOrder>20</BuildOrder>
@@ -546,7 +528,6 @@
             </CPlusPlusBuilder.Personality>
             <Platforms>
                 <Platform value="Win32">True</Platform>
-                <Platform value="Win64">False</Platform>
             </Platforms>
             <Deployment Version="3">
                 <DeployFile LocalName="..\..\src\rcv\binex.c" Configuration="Release" Class="ProjectFile">
diff --git a/app/rtkplot/rtkplot.cpp b/app/rtkplot/rtkplot.cpp
index 269a284..fd3f4f9 100644
--- a/app/rtkplot/rtkplot.cpp
+++ b/app/rtkplot/rtkplot.cpp
@@ -42,7 +42,6 @@
 
 
 
-USEFORM("vmapdlg.cpp", VecMapDialog);
 USEFORM("..\appcmn\tcpoptdlg.cpp", TcpOptDialog);
 USEFORM("..\appcmn\serioptdlg.cpp", SerialOptDialog);
 USEFORM("..\appcmn\refdlg.cpp", RefDialog);
@@ -57,15 +56,16 @@ USEFORM("..\appcmn\aboutdlg.cpp", AboutDialog);
 USEFORM("..\appcmn\console.cpp", Console);
 USEFORM("..\appcmn\ftpoptdlg.cpp", FtpOptDialog);
 USEFORM("..\appcmn\fileoptdlg.cpp", FileOptDialog);
+USEFORM("conndlg.cpp", ConnectDialog);
 USEFORM("pntdlg.cpp", PntDialog);
 USEFORM("plotopt.cpp", PlotOptDialog);
-USEFORM("plotmain.cpp", Plot);
+USEFORM("vmapdlg.cpp", VecMapDialog);
 USEFORM("skydlg.cpp", SkyImgDialog);
 USEFORM("satdlg.cpp", SatDialog);
+USEFORM("plotmain.cpp", Plot);
+USEFORM("mapdlg.cpp", MapAreaDialog);
 USEFORM("gmview.cpp", GoogleMapView);
 USEFORM("geview.cpp", GoogleEarthView);
-USEFORM("conndlg.cpp", ConnectDialog);
-USEFORM("mapdlg.cpp", MapAreaDialog);
 //---------------------------------------------------------------------------
 WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
 {
@@ -74,30 +74,30 @@ WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
 		Application->Initialize();
 		Application->Title = "RTKPLOT";
 		Application->CreateForm(__classid(TPlot), &Plot);
-		Application->CreateForm(__classid(TPlotOptDialog), &PlotOptDialog);
-		Application->CreateForm(__classid(TSatDialog), &SatDialog);
-		Application->CreateForm(__classid(TRefDialog), &RefDialog);
-		Application->CreateForm(__classid(TAboutDialog), &AboutDialog);
-		Application->CreateForm(__classid(TSpanDialog), &SpanDialog);
-		Application->CreateForm(__classid(TTimeDialog), &TimeDialog);
-		Application->CreateForm(__classid(TConnectDialog), &ConnectDialog);
-		Application->CreateForm(__classid(TSerialOptDialog), &SerialOptDialog);
-		Application->CreateForm(__classid(TTcpOptDialog), &TcpOptDialog);
-		Application->CreateForm(__classid(TCmdOptDialog), &CmdOptDialog);
-		Application->CreateForm(__classid(TFileOptDialog), &FileOptDialog);
-		Application->CreateForm(__classid(TKeyDialog), &KeyDialog);
-		Application->CreateForm(__classid(TTextViewer), &TextViewer);
-		Application->CreateForm(__classid(TViewerOptDialog), &ViewerOptDialog);
-		Application->CreateForm(__classid(TPntDialog), &PntDialog);
-		Application->CreateForm(__classid(TConfDialog), &ConfDialog);
-		Application->CreateForm(__classid(TGoogleEarthView), &GoogleEarthView);
-		Application->CreateForm(__classid(TFtpOptDialog), &FtpOptDialog);
-		Application->CreateForm(__classid(TConsole), &Console);
-		Application->CreateForm(__classid(TGoogleMapView), &GoogleMapView);
-		Application->CreateForm(__classid(TMapAreaDialog), &MapAreaDialog);
-		Application->CreateForm(__classid(TSkyImgDialog), &SkyImgDialog);
-		Application->CreateForm(__classid(TVecMapDialog), &VecMapDialog);
-		Application->Run();
+         Application->CreateForm(__classid(TPlotOptDialog), &PlotOptDialog);
+         Application->CreateForm(__classid(TSatDialog), &SatDialog);
+         Application->CreateForm(__classid(TRefDialog), &RefDialog);
+         Application->CreateForm(__classid(TAboutDialog), &AboutDialog);
+         Application->CreateForm(__classid(TSpanDialog), &SpanDialog);
+         Application->CreateForm(__classid(TTimeDialog), &TimeDialog);
+         Application->CreateForm(__classid(TConnectDialog), &ConnectDialog);
+         Application->CreateForm(__classid(TSerialOptDialog), &SerialOptDialog);
+         Application->CreateForm(__classid(TTcpOptDialog), &TcpOptDialog);
+         Application->CreateForm(__classid(TCmdOptDialog), &CmdOptDialog);
+         Application->CreateForm(__classid(TFileOptDialog), &FileOptDialog);
+         Application->CreateForm(__classid(TKeyDialog), &KeyDialog);
+         Application->CreateForm(__classid(TTextViewer), &TextViewer);
+         Application->CreateForm(__classid(TViewerOptDialog), &ViewerOptDialog);
+         Application->CreateForm(__classid(TPntDialog), &PntDialog);
+         Application->CreateForm(__classid(TConfDialog), &ConfDialog);
+         Application->CreateForm(__classid(TGoogleEarthView), &GoogleEarthView);
+         Application->CreateForm(__classid(TFtpOptDialog), &FtpOptDialog);
+         Application->CreateForm(__classid(TConsole), &Console);
+         Application->CreateForm(__classid(TGoogleMapView), &GoogleMapView);
+         Application->CreateForm(__classid(TMapAreaDialog), &MapAreaDialog);
+         Application->CreateForm(__classid(TSkyImgDialog), &SkyImgDialog);
+         Application->CreateForm(__classid(TVecMapDialog), &VecMapDialog);
+         Application->Run();
 	}
 	catch (Exception &exception)
 	{
diff --git a/app/rtkrcv/gcc/makefile b/app/rtkrcv/gcc/makefile
index a95bd4d..6776c7d 100644
--- a/app/rtkrcv/gcc/makefile
+++ b/app/rtkrcv/gcc/makefile
@@ -21,7 +21,7 @@ rtkrcv     : rtkrcv.o vt.o rtkcmn.o rtksvr.o rtkpos.o geoid.o solution.o lambda.
 rtkrcv     : sbas.o stream.o rcvraw.o rtcm.o preceph.o options.o pntpos.o ppp.o ppp_ar.o
 rtkrcv     : novatel.o ublox.o swiftnav.o crescent.o skytraq.o gw10.o javad.o nvs.o binex.o
 rtkrcv     : rt17.o ephemeris.o rinex.o ionex.o rtcm2.o rtcm3.o rtcm3e.o qzslex.o
-rtkrcv     : ppp_corr.o tides.o septentrio.o cmr.o tersus.o
+rtkrcv     : ppp_corr.o tides.o septentrio.o cmr.o tersus.o comnav.o
 
 rtkrcv.o   : ../rtkrcv.c
 	$(CC) -c $(CFLAGS) ../rtkrcv.c
@@ -101,6 +101,8 @@ cmr.o      : $(SRC)/rcv/cmr.c
 	$(CC) -c $(CFLAGS) $(SRC)/rcv/cmr.c
 tersus.o   : $(SRC)/rcv/tersus.c
 	$(CC) -c $(CFLAGS) $(SRC)/rcv/tersus.c
+comnav.o   : $(SRC)/rcv/comnav.c
+	$(CC) -c $(CFLAGS) $(SRC)/rcv/comnav.c
 
 rtkrcv.o   : $(SRC)/rtklib.h ../vt.h
 rtkcmn.o   : $(SRC)/rtklib.h
@@ -132,6 +134,7 @@ rt17.o     : $(SRC)/rtklib.h
 septentrio.o: $(SRC)/rtklib.h
 cmr.o      : $(SRC)/rtklib.h
 tersus.o   : $(SRC)/rtklib.h
+comnav.o   : $(SRC)/rtklib.h
 ephemeris.o: $(SRC)/rtklib.h
 rinex.o    : $(SRC)/rtklib.h
 ionex.o    : $(SRC)/rtklib.h
diff --git a/app/rtkrcv/gcc/rtkrcv.conf b/app/rtkrcv/gcc/rtkrcv.conf
index cabe22f..77f59dd 100644
--- a/app/rtkrcv/gcc/rtkrcv.conf
+++ b/app/rtkrcv/gcc/rtkrcv.conf
@@ -5,24 +5,24 @@ console-timetype   =gpst       # (0:gpst,1:utc,2:jst,3:tow)
 console-soltype    =dms        # (0:dms,1:deg,2:xyz,3:enu,4:pyl)
 console-solflag    =1          # (0:off,1:std+2:age/ratio/ns)
 inpstr1-type       =serial     # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,7:ntripcli,8:ftp,9:http)
-inpstr2-type       =serial     # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,7:ntripcli,8:ftp,9:http)
-inpstr3-type       =ftp        # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,7:ntripcli,8:ftp,9:http)
-inpstr1-path       =ttyS0:115200:8:n:1:off
+inpstr2-type       =off     # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,7:ntripcli,8:ftp,9:http)
+inpstr3-type       =off        # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,7:ntripcli,8:ftp,9:http)
+inpstr1-path       =ttyS4:115200:8:n:1:off
 inpstr2-path       =ttyS1:115200:8:n:1:off
 inpstr3-path       =anonymous:passwd@cddis.gsfc.nasa.gov/gps/products/%W/igu%W%D_%hb.sp3.Z::T=-14400,21600,7200,600
-inpstr1-format     =oem4       # (0:rtcm2,1:rtcm3,2:oem4,3:oem3,4:ubx,5:ss2,6:hemis,7:skytraq,14:sp3)
+inpstr1-format     =ubx       # (0:rtcm2,1:rtcm3,2:oem4,3:oem3,4:ubx,5:ss2,6:hemis,7:skytraq,14:sp3)
 inpstr2-format     =oem4       # (0:rtcm2,1:rtcm3,2:oem4,3:oem3,4:ubx,5:ss2,6:hemis,7:skytraq,14:sp3)
 inpstr3-format     =sp3        # (0:rtcm2,1:rtcm3,2:oem4,3:oem3,4:ubx,5:ss2,6:hemis,7:skytraq,14:sp3)
 inpstr2-nmeareq    =off        # (0:off,1:latlon,2:single)
 inpstr2-nmealat    =0          # (deg)
 inpstr2-nmealon    =0          # (deg)
-outstr1-type       =off        # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripsvr)
+outstr1-type       =file        # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripsvr)
 outstr2-type       =off        # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripsvr)
 outstr1-path       =sol1_%Y%m%d%h%M.pos
 outstr2-path       =sol2_%Y%m%d%h%M.pos
 outstr1-format     =llh        # (0:llh,1:xyz,2:enu,3:nmea)
 outstr2-format     =nmea       # (0:llh,1:xyz,2:enu,3:nmea)
-logstr1-type       =off        # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripsvr)
+logstr1-type       =file       # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripsvr)
 logstr2-type       =off        # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripsvr)
 logstr3-type       =off        # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripsvr)
 logstr1-path       =rov_%Y%m%d%h%M.log
@@ -34,23 +34,23 @@ misc-reconnect     =30000      # (ms)
 misc-nmeacycle     =5000       # (ms)
 misc-buffsize      =32768      # (bytes)
 misc-navmsgsel     =rover      # (0:all,1:rover,1:base,2:corr)
-misc-startcmd      =./rtkstart.sh
-misc-stopcmd       =./rtkshut.sh
-file-cmdfile1      =../../../data/oem4_raw_1hz.cmd
+misc-startcmd      =
+misc-stopcmd       =
+file-cmdfile1      =../../../../bins/demo5_b29c/m8t_5hz_usb.cmd
 file-cmdfile2      =../../../data/oem4_raw_1hz.cmd
 file-cmdfile3      =
 pos1-posmode       =single     # (0:single,1:dgps,2:kinematic,3:static,4:movingbase,5:fixed,6:ppp-kine,7:ppp-static)
 pos1-frequency     =l1         # (1:l1,2:l1+l2,3:l1+l2+l5)
 pos1-soltype       =forward    # (0:forward,1:backward,2:combined)
 pos1-elmask        =15         # (deg)
-pos1-snrmask       =0          # (dBHz)
+pos1-snrmask       =off          # (dBHz)
 pos1-dynamics      =off        # (0:off,1:on)
 pos1-tidecorr      =off        # (0:off,1:on)
 pos1-ionoopt       =brdc       # (0:off,1:brdc,2:sbas,3:dual-freq,4:est-stec)
 pos1-tropopt       =saas       # (0:off,1:saas,2:sbas,3:est-ztd,4:est-ztdgrad)
-pos1-sateph        =precise    # (0:brdc,1:precise,2:brdc+sbas,3:brdc+ssrapc,4:brdc+ssrcom)
+pos1-sateph        =brdc    # (0:brdc,1:precise,2:brdc+sbas,3:brdc+ssrapc,4:brdc+ssrcom)
 pos1-exclsats      =           # (prn ...)
-pos1-navsys        =1          # (1:gps+2:sbas+4:glo+8:gal+16:qzs+32:comp)
+pos1-navsys        =15          # (1:gps+2:sbas+4:glo+8:gal+16:qzs+32:comp)
 pos2-armode        =off        # (0:off,1:continuous,2:instantaneous,3:fix-and-hold)
 pos2-gloarmode     =off        # (0:off,1:on,2:autocal)
 pos2-arthres       =5
@@ -78,7 +78,8 @@ out-solstatic      =all        # (0:all,1:single)
 out-nmeaintv1      =0          # (s)
 out-nmeaintv2      =0          # (s)
 out-outstat        =off        # (0:off,1:state,2:residual)
-stats-errratio     =100
+out-outvel         =on
+stats-errratio     =300
 stats-errphase     =0.003      # (m)
 stats-errphaseel   =0.003      # (m)
 stats-errphasebl   =0          # (m/10km)
@@ -110,12 +111,12 @@ ant2-antdeln       =0          # (m)
 ant2-antdelu       =0          # (m)
 misc-timeinterp    =off        # (0:off,1:on)
 misc-sbasatsel     =0          # (0:all)
-file-satantfile    =../../../data/igs05.atx
-file-rcvantfile    =../../../data/igs05.atx
-file-staposfile    =../../../data/station.pos
+file-satantfile    =#../../../data/igs05.atx
+file-rcvantfile    =#../../../data/igs05.atx
+file-staposfile    =#../../../data/station.pos
 file-geoidfile     =
-file-dcbfile       =../../../data/P1C1_ALL.DCB
-file-tempdir       =temp
+file-dcbfile       =#../../../data/P1C1_ALL.DCB
+file-tempdir       =#temp
 file-geexefile     =
 file-solstatfile   =
 file-tracefile     =
diff --git a/app/srctblbrows/srctblbrows.cbproj b/app/srctblbrows/srctblbrows.cbproj
index 05727ea..2366d8c 100644
--- a/app/srctblbrows/srctblbrows.cbproj
+++ b/app/srctblbrows/srctblbrows.cbproj
@@ -249,6 +249,9 @@
         <CppCompile Include="..\..\src\rcv\tersus.c">
             <BuildOrder>25</BuildOrder>
         </CppCompile>
+        <CppCompile Include="..\..\src\rcv\comnav.c">
+            <BuildOrder>26</BuildOrder>
+        </CppCompile>
         <CppCompile Include="..\..\src\rcv\ublox.c">
             <BuildOrder>3</BuildOrder>
             <BuildOrder>10</BuildOrder>
@@ -398,6 +401,12 @@
                         <Overwrite>true</Overwrite>
                     </Platform>
                 </DeployFile>
+                <DeployFile LocalName="..\..\src\rcv\comnav.c" Configuration="Release" Class="ProjectFile">
+                    <Platform Name="Win32">
+                        <RemoteDir>.\</RemoteDir>
+                        <Overwrite>true</Overwrite>
+                    </Platform>
+                </DeployFile>
                 <DeployFile LocalName="..\..\src\rcvraw.c" Configuration="Release" Class="ProjectFile">
                     <Platform Name="Win32">
                         <RemoteDir>.\</RemoteDir>
diff --git a/app/str2str/gcc/makefile b/app/str2str/gcc/makefile
index 6b1c0e0..62308ad 100644
--- a/app/str2str/gcc/makefile
+++ b/app/str2str/gcc/makefile
@@ -22,7 +22,7 @@ all        : str2str
 str2str    : str2str.o stream.o rtkcmn.o solution.o sbas.o geoid.o
 str2str    : rcvraw.o novatel.o ublox.o swiftnav.o crescent.o skytraq.o gw10.o javad.o
 str2str    : nvs.o binex.o rt17.o rtcm.o rtcm2.o rtcm3.o rtcm3e.o preceph.o streamsvr.o
-str2str    : septentrio.o cmr.o tersus.o
+str2str    : septentrio.o cmr.o tersus.o comnav.o
 
 str2str.o  : ../str2str.c
 	$(CC) -c $(CFLAGS) ../str2str.c
@@ -76,6 +76,8 @@ cmr.o      : $(SRC)/rcv/cmr.c
 	$(CC) -c $(CFLAGS) $(SRC)/rcv/cmr.c
 tersus.o   : $(SRC)/rcv/tersus.c
 	$(CC) -c $(CFLAGS) $(SRC)/rcv/tersus.c
+comnav.o   : $(SRC)/rcv/tersus.c
+	$(CC) -c $(CFLAGS) $(SRC)/rcv/comnav.c
 
 str2str.o  : $(SRC)/rtklib.h
 stream.o   : $(SRC)/rtklib.h
@@ -103,6 +105,7 @@ preceph.o  : $(SRC)/rtklib.h
 septentrio.o: $(SRC)/rtklib.h
 cmr.o      : $(SRC)/rtklib.h
 tersus.o   : $(SRC)/rtklib.h
+comnav.o   : $(SRC)/rtklib.h
 
 install:
 	cp str2str $(BINDIR)
diff --git a/app/strsvr/strsvr.cbproj b/app/strsvr/strsvr.cbproj
index 523e3a5..7635596 100644
--- a/app/strsvr/strsvr.cbproj
+++ b/app/strsvr/strsvr.cbproj
@@ -307,6 +307,9 @@
         <CppCompile Include="..\..\src\rcv\tersus.c">
             <BuildOrder>41</BuildOrder>
         </CppCompile>
+        <CppCompile Include="..\..\src\rcv\comnav.c">
+            <BuildOrder>42</BuildOrder>
+        </CppCompile>
         <CppCompile Include="..\..\src\rcv\ublox.c">
             <BuildOrder>35</BuildOrder>
         </CppCompile>
@@ -567,6 +570,12 @@
                         <Overwrite>true</Overwrite>
                     </Platform>
                 </DeployFile>
+              <DeployFile LocalName="..\..\src\rcv\comnav.c" Configuration="Release" Class="ProjectFile">
+                    <Platform Name="Win32">
+                        <RemoteDir>.\</RemoteDir>
+                        <Overwrite>true</Overwrite>
+                    </Platform>
+                </DeployFile>
                 <DeployFile LocalName="..\..\src\rcv\skytraq.c" Configuration="Release" Class="ProjectFile">
                     <Platform Name="Win32">
                         <RemoteDir>.\</RemoteDir>
diff --git a/src/convrnx.c b/src/convrnx.c
index ba0f762..41144f6 100644
--- a/src/convrnx.c
+++ b/src/convrnx.c
@@ -696,13 +696,13 @@ static void set_obstype(int format, rnxopt_t *opt)
         {CODE_L1I,CODE_L7I},
         {0}
     };
-    static const unsigned char codes_oem3[NSATSYS][8]={ /* novatel oem3 */
-        {CODE_L1C,CODE_L2P},
-        {0},
-        {0},
-        {0},
-        {CODE_L1C},
-        {0},
+    static const unsigned char codes_cnav[NSATSYS][8]={ /* comnav */
+        {CODE_L1C,CODE_L1P,CODE_L2D,CODE_L2X,CODE_L5I},
+        {CODE_L1C,CODE_L2C},
+        {CODE_L1B,CODE_L1X,CODE_L5X,CODE_L7X,CODE_L8X},
+        {CODE_L1C,CODE_L2X,CODE_L5Q},
+        {CODE_L1C,CODE_L5I},
+        {CODE_L1I,CODE_L7I},
         {0}
     };
     static const unsigned char codes_oem4[NSATSYS][8]={ /* novatel oem6 */
@@ -802,7 +802,7 @@ static void set_obstype(int format, rnxopt_t *opt)
             case STRFMT_RTCM2: codes=codes_rtcm2[i]; break;
             case STRFMT_RTCM3: codes=codes_rtcm3[i]; break;
             case STRFMT_OEM4 : codes=codes_oem4 [i]; break;
-            case STRFMT_OEM3 : codes=codes_oem3 [i]; break;
+            case STRFMT_CNAV : codes=codes_cnav [i]; break;
             case STRFMT_CRES : codes=codes_cres [i]; break;
             case STRFMT_SBP  : codes=codes_sbp  [i]; break;
             case STRFMT_JAVAD: codes=codes_javad[i]; break;
diff --git a/src/postpos.c b/src/postpos.c
index 75e883b..3b29d1f 100644
--- a/src/postpos.c
+++ b/src/postpos.c
@@ -1038,6 +1038,10 @@ static int execses(gtime_t ts, gtime_t te, double ti, const prcopt_t *popt,
             freeobsnav(&obss,&navs);
             return 0;
         }
+        if (!antpos(&popt_,2,&obss,&navs,stas,fopt->stapos)) {
+            freeobsnav(&obss,&navs);
+            return 0;
+        }
     }
     else if (PMODE_DGPS<=popt_.mode&&popt_.mode<=PMODE_STATIC_START) {
         if (!antpos(&popt_,2,&obss,&navs,stas,fopt->stapos)) {
diff --git a/src/rcv/comnav.c b/src/rcv/comnav.c
new file mode 100644
index 0000000..6e344a7
--- /dev/null
+++ b/src/rcv/comnav.c
@@ -0,0 +1,1144 @@
+/*------------------------------------------------------------------------------
+* comnav.c : ComNav receiver functions
+*
+*          Copyright (C) 2007-2017 by T.TAKASU, All rights reserved.
+*
+* reference :
+*     [1] ComNav, CNT-OEM-RM001, Rev 1.5 COMNAV OEM BOARD REFERENCE MANUAL, 2018
+
+*
+* history : 2007/10/08 1.0 new
+
+*-----------------------------------------------------------------------------*/
+#include "rtklib.h"
+
+#define CNAVSYNC1   0xAA        /* cnav message start sync code 1 */
+#define CNAVSYNC2   0x44        /* cnav message start sync code 2 */
+#define CNAVSYNC3   0x12        /* cnav message start sync code 3 */
+
+#define CNAVHLEN    28          /* cnav message header length (bytes) */
+
+#define ID_ALMANAC  73          /* message id: cnav decoded almanac */
+#define ID_GLOALMANAC 718       /* message id: cnav glonass decoded almanac */
+#define ID_GLOEPHEMERIS 723     /* message id: cnav glonass ephemeris */
+#define ID_IONUTC   8           /* message id: cnav iono and utc data */
+#define ID_RANGE    43          /* message id: cnav range measurement */
+#define ID_RANGECMP 140         /* message id: cnav range compressed */
+#define ID_RAWALM   74          /* message id: cnav raw almanac */
+#define ID_RAWEPHEM 41          /* message id: cnav raw ephemeris */
+#define ID_RAWWAASFRAME 287     /* message id: cnav raw waas frame */
+
+#define ID_QZSSIONUTC 1347      /* message id: oem6 qzss ion/utc parameters */
+#define ID_QZSSRAWEPHEM 1330    /* message id: oem6 qzss raw ephemeris */
+#define ID_QZSSRAWSUBFRAME 1331 /* message id: oem6 qzss raw subframe */
+#define ID_RAWSBASFRAME 973     /* message id: oem6 raw sbas frame */
+#define ID_GALEPHEMERIS 1122    /* message id: oem6 decoded galileo ephemeris */
+#define ID_GALALMANAC 1120      /* message id: oem6 decoded galileo almanac */
+#define ID_GALCLOCK 1121        /* message id: oem6 galileo clockinformation */
+#define ID_GALIONO  1127        /* message id: oem6 decoded galileo iono corrections */
+#define ID_GALFNAVRAWPAGE 1413  /* message id: oem6 raw galileo f/nav paga data */
+#define ID_GALINAVRAWWORD 1414  /* message id: oem6 raw galileo i/nav word data */
+#define ID_RAWCNAVFRAME 1066    /* message id: oem6 raw cnav frame data */
+#define ID_BDSEPHEMERIS 1696    /* message id: oem6 decoded bds ephemeris */
+
+#define WL1         0.1902936727984
+#define WL2         0.2442102134246
+#define MAXVAL      8388608.0
+
+#define OFF_FRQNO   -7          /* F/W ver.3.620 */
+
+/* get fields (little-endian) ------------------------------------------------*/
+#define U1(p) (*((unsigned char *)(p)))
+#define I1(p) (*((signed char *)(p)))
+static unsigned short U2(unsigned char *p) {unsigned short u; memcpy(&u,p,2); return u;}
+static unsigned int   U4(unsigned char *p) {unsigned int   u; memcpy(&u,p,4); return u;}
+static int            I4(unsigned char *p) {int            i; memcpy(&i,p,4); return i;}
+static float          R4(unsigned char *p) {float          r; memcpy(&r,p,4); return r;}
+static double         R8(unsigned char *p) {double         r; memcpy(&r,p,8); return r;}
+
+/* extend sign ---------------------------------------------------------------*/
+static int exsign(unsigned int v, int bits)
+{
+    return (int)(v&(1<<(bits-1))?v|(~0u<<bits):v);
+}
+/* checksum ------------------------------------------------------------------*/
+static unsigned char chksum(const unsigned char *buff, int len)
+{
+    unsigned char sum=0;
+    int i;
+    for (i=0;i<len;i++) sum^=buff[i];
+    return sum;
+}
+/* adjust weekly rollover of gps time ----------------------------------------*/
+static gtime_t adjweek(gtime_t time, double tow)
+{
+    double tow_p;
+    int week;
+    tow_p=time2gpst(time,&week);
+    if      (tow<tow_p-302400.0) tow+=604800.0;
+    else if (tow>tow_p+302400.0) tow-=604800.0;
+    return gpst2time(week,tow);
+}
+/* get observation data index ------------------------------------------------*/
+static int obsindex(obs_t *obs, gtime_t time, int sat)
+{
+    int i,j;
+    
+    if (obs->n>=MAXOBS) return -1;
+    for (i=0;i<obs->n;i++) {
+        if (obs->data[i].sat==sat) return i;
+    }
+    obs->data[i].time=time;
+    obs->data[i].sat=sat;
+    for (j=0;j<NFREQ+NEXOBS;j++) {
+        obs->data[i].L[j]=obs->data[i].P[j]=0.0;
+        obs->data[i].D[j]=0.0;
+        obs->data[i].SNR[j]=obs->data[i].LLI[j]=0;
+        obs->data[i].code[j]=CODE_NONE;
+    }
+    obs->n++;
+    return i;
+}
+/* decode cnav tracking status -------------------------------------------------
+* deocode cnav tracking status
+* args   : unsigned int stat I  tracking status field
+*          int    *sys   O      system (SYS_???)
+*          int    *code  O      signal code (CODE_L??)
+*          int    *track O      tracking state
+*                         (cnav/5)
+*                         0=L1 idle                   8=L2 idle
+*                         1=L1 sky search             9=L2 p-code align
+*                         2=L1 wide freq pull-in     10=L2 search
+*                         3=L1 narrow freq pull-in   11=L2 pll
+*                         4=L1 pll                   12=L2 steering
+*                         5=L1 reacq
+*                         6=L1 steering
+*                         7=L1 fll
+*                         (oem6)
+*                         0=idle                      7=freq-lock loop
+*                         2=wide freq band pull-in    9=channel alignment
+*                         3=narrow freq band pull-in 10=code search
+*                         4=phase lock loop          11=aided phase lock loop
+*          int    *plock O      phase-lock flag   (0=not locked, 1=locked)
+*          int    *clock O      code-lock flag    (0=not locked, 1=locked)
+*          int    *parity O     parity known flag (0=not known,  1=known)
+*          int    *halfc O      phase measurement (0=half-cycle not added,
+*                                                  1=added)
+* return : signal frequency (0:L1,1:L2,2:L5,3:L6,4:L7,5:L8,-1:error)
+* notes  : refer [1][3]
+*-----------------------------------------------------------------------------*/
+static int decode_trackstat(unsigned int stat, int *sys, int *code, int *track,
+                            int *plock, int *clock, int *parity, int *halfc)
+{
+    int satsys,sigtype,freq=0;
+    
+    *track =stat&0x1F;
+    *plock =(stat>>10)&1;
+    *parity=(stat>>11)&1;
+    *clock =(stat>>12)&1;
+    satsys =(stat>>16)&7;
+    *halfc =(stat>>28)&1;
+    sigtype=(stat>>21)&0x1F;
+    
+    switch (satsys) {
+        case 0: *sys=SYS_GPS; break;
+        case 1: *sys=SYS_GLO; break;
+        case 2: *sys=SYS_SBS; break;
+        case 3: *sys=SYS_GAL; break; /* OEM6 */
+        case 4: *sys=SYS_CMP; break; /* OEM6 F/W 6.400 */
+        case 5: *sys=SYS_QZS; break; /* OEM6 */
+        default:
+            trace(2,"cnav unknown system: sys=%d\n",satsys);
+            return -1;
+    }
+    if (*sys==SYS_GPS||*sys==SYS_QZS) {
+        switch (sigtype) {
+            case  0: freq=0; *code=CODE_L1C; break; /* L1C/A */
+            case  2: freq=2; *code=CODE_L5I; break; /* L5 */
+            case  5: freq=0; *code=CODE_L1P; break; /* L1P */
+            case  9: freq=1; *code=CODE_L2D; break; /* L2P codeless */
+            case 14: freq=2; *code=CODE_L5I; break; /* L5I */
+            case 17: freq=1; *code=CODE_L2X; break; /* L2C(M+L) */
+            default: freq=-1; break;
+        }
+    }
+    else if (*sys==SYS_GLO) {
+        switch (sigtype) {
+            case  0: freq=0; *code=CODE_L1C; break; /* L1C/A */
+            case  1: freq=1; *code=CODE_L2C; break; /* L2C/A (OEM6) */
+            case  5: freq=1; *code=CODE_L2C; break; /* L2C */
+            default: freq=-1; break;
+        }
+    }
+    else if (*sys==SYS_GAL) {
+        switch (sigtype) {
+            case  1: freq=0; *code=CODE_L1B; break; /* E1B  (OEM6) */
+            case  2: freq=0; *code=CODE_L1X; break; /* E1C  (OEM6) */
+            case 12: freq=2; *code=CODE_L5X; break; /* E5aQ (OEM6) */
+            case 17: freq=4; *code=CODE_L7X; break; /* E5bQ (OEM6) */
+            case 20: freq=5; *code=CODE_L8X; break; /* AltBOCQ (OEM6) */
+            default: freq=-1; break;
+        }
+    }
+    else if (*sys==SYS_CMP) {
+        switch (sigtype) {
+            case  0: freq=0; *code=CODE_L1I; break; /* B1 with D1 (OEM6) */
+            case  1: freq=1; *code=CODE_L7I; break; /* B2 with D1 (OEM6) */
+            case  4: freq=0; *code=CODE_L1I; break; /* B1 with D2 (OEM6) */
+            case  5: freq=1; *code=CODE_L7I; break; /* B2 with D2 (OEM6) */
+            default: freq=-1; break;
+        }
+    }
+    else if (*sys==SYS_SBS) {
+        switch (sigtype) {
+            case  0: freq=0; *code=CODE_L1C; break; /* L1C/A */
+            case  6: freq=2; *code=CODE_L5I; break; /* L5I (OEM6) */
+            default: freq=-1; break;
+        }
+    }
+    if (freq<0) {
+        trace(2,"cnav signal type error: sys=%d sigtype=%d\n",*sys,sigtype);
+        return -1;
+    }
+    return freq;
+}
+/* check code priority and return obs position -------------------------------*/
+static int checkpri(const char *opt, int sys, int code, int freq)
+{
+    int nex=NEXOBS; /* number of extended obs data */
+    
+    if (sys==SYS_GPS) {
+        if (strstr(opt,"-GL1P")&&freq==0) return code==CODE_L1P?0:-1;
+        if (strstr(opt,"-GL2X")&&freq==1) return code==CODE_L2X?1:-1;
+        if (code==CODE_L1P) return nex<1?-1:NFREQ;
+        if (code==CODE_L2X) return nex<2?-1:NFREQ+1;
+    }
+    else if (sys==SYS_GLO) {
+        if (strstr(opt,"-RL2C")&&freq==1) return code==CODE_L2C?1:-1;
+        if (code==CODE_L2C) return nex<1?-1:NFREQ;
+    }
+    else if (sys==SYS_GAL) {
+        if (strstr(opt,"-EL1B")&&freq==0) return code==CODE_L1B?0:-1;
+        if (code==CODE_L1B) return nex<1?-1:NFREQ;
+        if (code==CODE_L7Q) return nex<2?-1:NFREQ+1;
+        if (code==CODE_L8Q) return nex<3?-1:NFREQ+2;
+    }
+    return freq<NFREQ?freq:-1;
+}
+/* decode rangecmpb ----------------------------------------------------------*/
+static int decode_rangecmpb(raw_t *raw)
+{
+    double psr,adr,adr_rolls,lockt,tt,dop,snr,wavelen;
+    int i,index,nobs,prn,sat,sys,code,freq,pos;
+    int track,plock,clock,parity,halfc,lli;
+    char *msg;
+    unsigned char *p=raw->buff+CNAVHLEN;
+    
+    trace(3,"decode_rangecmpb: len=%d\n",raw->len);
+    
+    nobs=U4(p);
+    
+    if (raw->outtype) {
+        msg=raw->msgtype+strlen(raw->msgtype);
+        sprintf(msg," nobs=%2d",nobs);
+    }
+    if (raw->len<CNAVHLEN+4+nobs*24) {
+        trace(2,"cnav rangecmpb length error: len=%d nobs=%d\n",raw->len,nobs);
+        return -1;
+    }
+    for (i=0,p+=4;i<nobs;i++,p+=24) {
+        
+        /* decode tracking status */
+        if ((freq=decode_trackstat(U4(p),&sys,&code,&track,&plock,&clock,
+                                   &parity,&halfc))<0) continue;
+        
+        /* obs position */
+        if ((pos=checkpri(raw->opt,sys,code,freq))<0) continue;
+        
+        prn=U1(p+17);
+        if (sys==SYS_GLO) prn-=37;
+        
+        if (!(sat=satno(sys,prn))) {
+            trace(3,"cnav rangecmpb satellite number error: sys=%d,prn=%d\n",sys,prn);
+            continue;
+        }
+        if (sys==SYS_GLO&&!parity) continue; /* invalid if GLO parity unknown */
+        
+        dop=exsign(U4(p+4)&0xFFFFFFF,28)/256.0;
+        psr=(U4(p+7)>>4)/128.0+U1(p+11)*2097152.0;
+        
+        if ((wavelen=satwavelen(sat,freq,&raw->nav))<=0.0) {
+            if (sys==SYS_GLO) wavelen=CLIGHT/(freq==0?FREQ1_GLO:FREQ2_GLO);
+            else wavelen=lam_carr[freq];
+        }
+        adr=I4(p+12)/256.0;
+        adr_rolls=(psr/wavelen+adr)/MAXVAL;
+        adr=-adr+MAXVAL*floor(adr_rolls+(adr_rolls<=0?-0.5:0.5));
+        
+        lockt=(U4(p+18)&0x1FFFFF)/32.0; /* lock time */
+        if (lockt<2) parity=0; /* pseudo-parity */
+        
+        if (raw->tobs[sat-1][pos].time!=0) {
+            tt=timediff(raw->time,raw->tobs[sat-1][pos]);
+            lli=(lockt<65535.968&&lockt-raw->lockt[sat-1][pos]+0.05<=tt)?LLI_SLIP:0;
+        }
+        else {
+            lli=0;
+        }
+
+        if (!parity) lli|=LLI_HALFC;
+        if (halfc  ) lli|=LLI_HALFA;
+        raw->tobs [sat-1][pos]=raw->time;
+        raw->lockt[sat-1][pos]=lockt;
+        raw->halfc[sat-1][pos]=halfc;
+        
+        snr=((U2(p+20)&0x3FF)>>5)+20.0;
+        if ((sys!=SYS_GAL&&!clock)||(sys==SYS_GAL&&!plock)) psr=0.0;     /* code unlock */
+        if (!plock) adr=dop=0.0; /* phase unlock */
+        
+        if (fabs(timediff(raw->obs.data[0].time,raw->time))>1E-9) {
+            raw->obs.n=0;
+        }
+        if ((index=obsindex(&raw->obs,raw->time,sat))>=0) {
+            raw->obs.data[index].L  [pos]=adr;
+            raw->obs.data[index].P  [pos]=psr;
+            raw->obs.data[index].D  [pos]=(float)dop;
+            raw->obs.data[index].SNR[pos]=
+                0.0<=snr&&snr<255.0?(unsigned char)(snr*4.0+0.5):0;
+            raw->obs.data[index].LLI[pos]=(unsigned char)lli;
+            raw->obs.data[index].code[pos]=code;
+#if 0
+            /* L2C phase shift correction (L2C->L2P) */
+            if (code==CODE_L2X) {
+                raw->obs.data[index].L[pos]+=0.25;
+                trace(3,"cnav L2C phase shift corrected: prn=%2d\n",prn);
+            }
+#endif
+        }
+    }
+    return 1;
+}
+/* decode rangeb -------------------------------------------------------------*/
+static int decode_rangeb(raw_t *raw)
+{
+    double psr,adr,dop,snr,lockt,tt;
+    char *msg;
+    int i,index,nobs,prn,sat,sys,code,freq,pos;
+    int track,plock,clock,parity,halfc,lli,gfrq;
+    unsigned char *p=raw->buff+CNAVHLEN;
+    
+    trace(3,"decode_rangeb: len=%d\n",raw->len);
+    
+    nobs=U4(p);
+    
+    if (raw->outtype) {
+        msg=raw->msgtype+strlen(raw->msgtype);
+        sprintf(msg," nobs=%2d",nobs);
+    }
+    if (raw->len<CNAVHLEN+4+nobs*44) {
+        trace(2,"cnav rangeb length error: len=%d nobs=%d\n",raw->len,nobs);
+        return -1;
+    }
+    for (i=0,p+=4;i<nobs;i++,p+=44) {
+        
+        /* decode tracking status */
+        if ((freq=decode_trackstat(U4(p+40),&sys,&code,&track,&plock,&clock,
+                                   &parity,&halfc))<0) continue;
+        
+        /* obs position */
+        if ((pos=checkpri(raw->opt,sys,code,freq))<0) continue;
+        
+        prn=U2(p);
+        if (sys==SYS_GLO) prn-=37;
+        
+        if (!(sat=satno(sys,prn))) {
+            trace(3,"cnav rangeb satellite number error: sys=%d,prn=%d\n",sys,prn);
+            continue;
+        }
+        if (sys==SYS_GLO&&!parity) continue; /* invalid if GLO parity unknown */
+        
+        gfrq =U2(p+ 2);
+        psr  =R8(p+ 4);
+        adr  =R8(p+16);
+        dop  =R4(p+28);
+        snr  =R4(p+32);
+        lockt=R4(p+36);
+        if (lockt<2) parity=0; /* pseudo-parity */
+        
+        /* set glonass frequency channel number */
+        if (sys==SYS_GLO&&raw->nav.geph[prn-1].sat!=sat) {
+            raw->nav.geph[prn-1].frq=gfrq-7;
+        }
+        if (raw->tobs[sat-1][pos].time!=0) {
+            tt=timediff(raw->time,raw->tobs[sat-1][pos]);
+            lli=lockt-raw->lockt[sat-1][pos]+0.05<=tt?LLI_SLIP:0;
+        }
+        else {
+            lli=0;
+        }
+        if (!parity) lli|=LLI_HALFC;
+        if (halfc  ) lli|=LLI_HALFA;
+        raw->tobs [sat-1][pos]=raw->time;
+        raw->lockt[sat-1][pos]=lockt;
+        raw->halfc[sat-1][pos]=halfc;
+        
+        if (!clock) psr=0.0;     /* code unlock */
+        if (!plock) adr=dop=0.0; /* phase unlock */
+        
+        if (fabs(timediff(raw->obs.data[0].time,raw->time))>1E-9) {
+            raw->obs.n=0;
+        }
+        if ((index=obsindex(&raw->obs,raw->time,sat))>=0) {
+            raw->obs.data[index].L  [pos]=-adr;
+            raw->obs.data[index].P  [pos]=psr;
+            raw->obs.data[index].D  [pos]=(float)dop;
+            raw->obs.data[index].SNR[pos]=
+                0.0<=snr&&snr<255.0?(unsigned char)(snr*4.0+0.5):0;
+            raw->obs.data[index].LLI[pos]=(unsigned char)lli;
+            raw->obs.data[index].code[pos]=code;
+#if 0
+            /* L2C phase shift correction */
+            if (code==CODE_L2X) {
+                raw->obs.data[index].L[pos]+=0.25;
+                trace(3,"cnav L2C phase shift corrected: prn=%2d\n",prn);
+            }
+#endif
+        }
+    }
+    return 1;
+}
+/* decode rawephemb ----------------------------------------------------------*/
+static int decode_rawephemb(raw_t *raw)
+{
+    unsigned char *p=raw->buff+CNAVHLEN;
+    eph_t eph={0};
+    int prn,sat;
+    
+    trace(3,"decode_rawephemb: len=%d\n",raw->len);
+    
+    if (raw->len<CNAVHLEN+102) {
+        trace(2,"cnav rawephemb length error: len=%d\n",raw->len);
+        return -1;
+    }
+    prn=U4(p);
+    if (!(sat=satno(SYS_GPS,prn))) {
+        trace(2,"cnav rawephemb satellite number error: prn=%d\n",prn);
+        return -1;
+    }
+    if (decode_frame(p+ 12,&eph,NULL,NULL,NULL,NULL)!=1||
+        decode_frame(p+ 42,&eph,NULL,NULL,NULL,NULL)!=2||
+        decode_frame(p+ 72,&eph,NULL,NULL,NULL,NULL)!=3) {
+        trace(2,"cnav rawephemb subframe error: prn=%d\n",prn);
+        return -1;
+    }
+    if (!strstr(raw->opt,"-EPHALL")) {
+        if (eph.iode==raw->nav.eph[sat-1].iode) return 0; /* unchanged */
+    }
+    eph.sat=sat;
+    raw->nav.eph[sat-1]=eph;
+    raw->ephsat=sat;
+    trace(4,"decode_rawephemb: sat=%2d\n",sat);
+    return 2;
+}
+/* decode ionutcb ------------------------------------------------------------*/
+static int decode_ionutcb(raw_t *raw)
+{
+    unsigned char *p=raw->buff+CNAVHLEN;
+    int i;
+    
+    trace(3,"decode_ionutcb: len=%d\n",raw->len);
+    
+    if (raw->len<CNAVHLEN+108) {
+        trace(2,"cnav ionutcb length error: len=%d\n",raw->len);
+        return -1;
+    }
+    for (i=0;i<8;i++) raw->nav.ion_gps[i]=R8(p+i*8);
+    raw->nav.utc_gps[0]=R8(p+72);
+    raw->nav.utc_gps[1]=R8(p+80);
+    raw->nav.utc_gps[2]=U4(p+68);
+    raw->nav.utc_gps[3]=U4(p+64);
+    raw->nav.leaps =I4(p+96);
+    return 9;
+}
+/* decode rawwaasframeb ------------------------------------------------------*/
+static int decode_rawwaasframeb(raw_t *raw)
+{
+    unsigned char *p=raw->buff+CNAVHLEN;
+    int i,prn;
+    
+    trace(3,"decode_rawwaasframeb: len=%d\n",raw->len);
+    
+    if (raw->len<CNAVHLEN+48) {
+        trace(2,"cnav rawwaasframeb length error: len=%d\n",raw->len);
+        return -1;
+    }
+    prn=U4(p+4);
+    
+    if (MINPRNQZS_S<=prn&&prn<=MAXPRNQZS_S) {
+        prn+=10; /* QZSS SAIF PRN -> QZSS PRN */
+    }
+    else if (prn<MINPRNSBS||MAXPRNSBS<prn) return 0;
+    
+    raw->sbsmsg.tow=(int)time2gpst(raw->time,&raw->sbsmsg.week);
+    raw->sbsmsg.prn=prn;
+    for (i=0,p+=12;i<29;i++,p++) raw->sbsmsg.msg[i]=*p;
+    return 3;
+}
+/* decode rawsbasframeb ------------------------------------------------------*/
+static int decode_rawsbasframeb(raw_t *raw)
+{
+    trace(3,"decode_rawsbasframeb: len=%d\n",raw->len);
+    
+    /* format same as rawwaasframeb */
+    return decode_rawwaasframeb(raw);
+}
+/* decode gloephemerisb ------------------------------------------------------*/
+static int decode_gloephemerisb(raw_t *raw)
+{
+    unsigned char *p=raw->buff+CNAVHLEN;
+    geph_t geph={0};
+    char *msg;
+    double tow,tof,toff;
+    int prn,sat,week;
+    
+    trace(3,"decode_gloephemerisb: len=%d\n",raw->len);
+    
+    if (raw->len<CNAVHLEN+144) {
+        trace(2,"cnav gloephemerisb length error: len=%d\n",raw->len);
+        return -1;
+    }
+    prn        =U2(p)-37;
+    
+    if (raw->outtype) {
+        msg=raw->msgtype+strlen(raw->msgtype);
+        sprintf(msg," prn=%3d",prn);
+    }
+    if (!(sat=satno(SYS_GLO,prn))) {
+        trace(2,"cnav gloephemerisb prn error: prn=%d\n",prn);
+        return -1;
+    }
+    geph.frq   =U2(p+  2)+OFF_FRQNO;
+    week       =U2(p+  6);
+    tow        =floor(U4(p+8)/1000.0+0.5); /* rounded to integer sec */
+    toff       =U4(p+ 12);
+    geph.iode  =U4(p+ 20)&0x7F;
+    geph.svh   =U4(p+ 24);
+    geph.pos[0]=R8(p+ 28);
+    geph.pos[1]=R8(p+ 36);
+    geph.pos[2]=R8(p+ 44);
+    geph.vel[0]=R8(p+ 52);
+    geph.vel[1]=R8(p+ 60);
+    geph.vel[2]=R8(p+ 68);
+    geph.acc[0]=R8(p+ 76);
+    geph.acc[1]=R8(p+ 84);
+    geph.acc[2]=R8(p+ 92);
+    geph.taun  =R8(p+100);
+    geph.gamn  =R8(p+116);
+    tof        =U4(p+124)-toff; /* glonasst->gpst */
+    geph.age   =U4(p+136);
+    geph.toe=gpst2time(week,tow);
+    tof+=floor(tow/86400.0)*86400;
+    if      (tof<tow-43200.0) tof+=86400.0;
+    else if (tof>tow+43200.0) tof-=86400.0;
+    geph.tof=gpst2time(week,tof);
+    
+    if (!strstr(raw->opt,"-EPHALL")) {
+        if (fabs(timediff(geph.toe,raw->nav.geph[prn-1].toe))<1.0&&
+            geph.svh==raw->nav.geph[prn-1].svh) return 0; /* unchanged */
+    }
+    geph.sat=sat;
+    raw->nav.geph[prn-1]=geph;
+    raw->ephsat=sat;
+    return 2;
+}
+/* decode qzss rawephemb -----------------------------------------------------*/
+static int decode_qzssrawephemb(raw_t *raw)
+{
+    unsigned char *p=raw->buff+CNAVHLEN,*q;
+    eph_t eph={0};
+    char *msg;
+    int i,prn,id,sat;
+    
+    trace(3,"decode_qzssrawephemb: len=%d\n",raw->len);
+    
+    if (raw->len<CNAVHLEN+44) {
+        trace(2,"cnav qzssrawephemb length error: len=%d\n",raw->len);
+        return -1;
+    }
+    prn=U4(p);
+    id =U4(p+4);
+    
+    if (raw->outtype) {
+        msg=raw->msgtype+strlen(raw->msgtype);
+        sprintf(msg," prn=%3d id=%d",prn,id);
+    }
+    if (!(sat=satno(SYS_QZS,prn))) {
+        trace(2,"cnav qzssrawephemb satellite number error: prn=%d\n",prn);
+        return -1;
+    }
+    if (id<1||3<id) return 0;
+    
+    q=raw->subfrm[sat-1]+(id-1)*30;
+    for (i=0;i<30;i++) *q++=p[8+i];
+    
+    if (id<3) return 0;
+    if (decode_frame(raw->subfrm[sat-1]   ,&eph,NULL,NULL,NULL,NULL)!=1||
+        decode_frame(raw->subfrm[sat-1]+30,&eph,NULL,NULL,NULL,NULL)!=2||
+        decode_frame(raw->subfrm[sat-1]+60,&eph,NULL,NULL,NULL,NULL)!=3) {
+        return 0;
+    }
+    if (!strstr(raw->opt,"-EPHALL")) {
+        if (eph.iodc==raw->nav.eph[sat-1].iodc&&
+            eph.iode==raw->nav.eph[sat-1].iode) return 0; /* unchanged */
+    }
+    eph.sat=sat;
+    raw->nav.eph[sat-1]=eph;
+    raw->ephsat=sat;
+    trace(4,"decode_qzssrawephemb: sat=%2d\n",sat);
+    return 2;
+}
+/* decode qzss rawsubframeb --------------------------------------------------*/
+static int decode_qzssrawsubframeb(raw_t *raw)
+{
+    unsigned char *p=raw->buff+CNAVHLEN;
+    eph_t eph={0};
+    char *msg;
+    int prn,sat;
+    
+    trace(3,"decode_qzssrawsubframeb: len=%d\n",raw->len);
+    
+    if (raw->len<CNAVHLEN+44) {
+        trace(2,"cnav qzssrawsubframeb length error: len=%d\n",raw->len);
+        return -1;
+    }
+    prn=U4(p);
+    
+    if (raw->outtype) {
+        msg=raw->msgtype+strlen(raw->msgtype);
+        sprintf(msg," prn=%3d",prn);
+    }
+    if (!(sat=satno(SYS_QZS,prn))) {
+        trace(2,"cnav qzssrawephemb satellite number error: prn=%d\n",prn);
+        return -1;
+    }
+    if (decode_frame(p+12,&eph,NULL,NULL,NULL,NULL)!=1||
+        decode_frame(p+42,&eph,NULL,NULL,NULL,NULL)!=2||
+        decode_frame(p+72,&eph,NULL,NULL,NULL,NULL)!=3) {
+        return 0;
+    }
+    if (!strstr(raw->opt,"-EPHALL")) {
+        if (eph.iodc==raw->nav.eph[sat-1].iodc&&
+            eph.iode==raw->nav.eph[sat-1].iode) return 0; /* unchanged */
+    }
+    eph.sat=sat;
+    raw->nav.eph[sat-1]=eph;
+    raw->ephsat=sat;
+    trace(4,"decode_qzssrawsubframeb: sat=%2d\n",sat);
+    return 2;
+}
+/* decode qzssionutcb --------------------------------------------------------*/
+static int decode_qzssionutcb(raw_t *raw)
+{
+    unsigned char *p=raw->buff+CNAVHLEN;
+    int i;
+    
+    trace(3,"decode_qzssionutcb: len=%d\n",raw->len);
+    
+    if (raw->len<CNAVHLEN+108) {
+        trace(2,"cnav qzssionutcb length error: len=%d\n",raw->len);
+        return -1;
+    }
+    for (i=0;i<8;i++) raw->nav.ion_qzs[i]=R8(p+i*8);
+    raw->nav.utc_qzs[0]=R8(p+72);
+    raw->nav.utc_qzs[1]=R8(p+80);
+    raw->nav.utc_qzs[2]=U4(p+68);
+    raw->nav.utc_qzs[3]=U4(p+64);
+    raw->nav.leaps =I4(p+96);
+    return 9;
+}
+/* decode galephemerisb ------------------------------------------------------*/
+static int decode_galephemerisb(raw_t *raw)
+{
+    eph_t eph={0};
+    unsigned char *p=raw->buff+CNAVHLEN;
+    double tow,sqrtA,af0_fnav,af1_fnav,af2_fnav,af0_inav,af1_inav,af2_inav,tt;
+    char *msg;
+    int prn,rcv_fnav,rcv_inav,svh_e1b,svh_e5a,svh_e5b,dvs_e1b,dvs_e5a,dvs_e5b;
+    int toc_fnav,toc_inav,week,sel_nav=0;
+    
+    trace(3,"decode_galephemerisb: len=%d\n",raw->len);
+    
+    if (raw->len<CNAVHLEN+220) {
+        trace(2,"cnav galephemrisb length error: len=%d\n",raw->len);
+        return -1;
+    }
+    prn       =U4(p);   p+=4;
+    rcv_fnav  =U4(p)&1; p+=4;
+    rcv_inav  =U4(p)&1; p+=4;
+    svh_e1b   =U1(p)&3; p+=1;
+    svh_e5a   =U1(p)&3; p+=1;
+    svh_e5b   =U1(p)&3; p+=1;
+    dvs_e1b   =U1(p)&1; p+=1;
+    dvs_e5a   =U1(p)&1; p+=1;
+    dvs_e5b   =U1(p)&1; p+=1;
+    eph.sva   =U1(p);   p+=1+1; /* SISA */
+    eph.iode  =U4(p);   p+=4;   /* IODNav */
+    eph.toes  =U4(p);   p+=4;
+    sqrtA     =R8(p);   p+=8;
+    eph.deln  =R8(p);   p+=8;
+    eph.M0    =R8(p);   p+=8;
+    eph.e     =R8(p);   p+=8;
+    eph.omg   =R8(p);   p+=8;
+    eph.cuc   =R8(p);   p+=8;
+    eph.cus   =R8(p);   p+=8;
+    eph.crc   =R8(p);   p+=8;
+    eph.crs   =R8(p);   p+=8;
+    eph.cic   =R8(p);   p+=8;
+    eph.cis   =R8(p);   p+=8;
+    eph.i0    =R8(p);   p+=8;
+    eph.idot  =R8(p);   p+=8;
+    eph.OMG0  =R8(p);   p+=8;
+    eph.OMGd  =R8(p);   p+=8;
+    toc_fnav  =U4(p);   p+=4;
+    af0_fnav  =R8(p);   p+=8;
+    af1_fnav  =R8(p);   p+=8;
+    af2_fnav  =R8(p);   p+=8;
+    toc_inav  =U4(p);   p+=4;
+    af0_inav  =R8(p);   p+=8;
+    af1_inav  =R8(p);   p+=8;
+    af2_inav  =R8(p);   p+=8;
+    eph.tgd[0]=R8(p);   p+=8; /* BGD: E5A-E1 (s) */
+    eph.tgd[1]=R8(p);         /* BGD: E5B-E1 (s) */
+    eph.iodc  =eph.iode;
+    eph.svh   =(svh_e5b<<7)|(dvs_e5b<<6)|(svh_e5a<<4)|(dvs_e5a<<3)|
+               (svh_e1b<<1)|dvs_e1b;
+    
+    /* ephemeris selection (0:INAV,1:FNAV) */
+    if      (strstr(raw->opt,"-GALINAV")) sel_nav=0;
+    else if (strstr(raw->opt,"-GALFNAV")) sel_nav=1;
+    else if (!rcv_inav&&rcv_fnav) sel_nav=1;
+    
+    eph.A     =sqrtA*sqrtA;
+    eph.f0    =sel_nav?af0_fnav:af0_inav;
+    eph.f1    =sel_nav?af1_fnav:af1_inav;
+    eph.f2    =sel_nav?af2_fnav:af2_inav;
+    eph.code  =sel_nav?2:1; /* data source 1:I/NAV E1B,2:F/NAV E5a-I */
+    
+    if (raw->outtype) {
+        msg=raw->msgtype+strlen(raw->msgtype);
+        sprintf(msg," prn=%3d iod=%3d toes=%6.0f",prn,eph.iode,eph.toes);
+    }
+    if (!(eph.sat=satno(SYS_GAL,prn))) {
+        trace(2,"oemv galephemeris satellite error: prn=%d\n",prn);
+        return -1;
+    }
+    tow=time2gpst(raw->time,&week);
+    eph.week=week; /* gps-week = gal-week */
+    eph.toe=gpst2time(eph.week,eph.toes);
+    
+    /* for week-handover problem */
+    tt=timediff(eph.toe,raw->time);
+    if      (tt<-302400.0) eph.week++;
+    else if (tt> 302400.0) eph.week--;
+    eph.toe=gpst2time(eph.week,eph.toes);
+    eph.toc=adjweek(eph.toe,sel_nav?toc_fnav:toc_inav);
+    eph.ttr=adjweek(eph.toe,tow);
+    
+    if (!strstr(raw->opt,"-EPHALL")) {
+        if (raw->nav.eph[eph.sat-1].iode==eph.iode&&
+            raw->nav.eph[eph.sat-1].code==eph.code) return 0; /* unchanged */
+    }
+    raw->nav.eph[eph.sat-1]=eph;
+    raw->ephsat=eph.sat;
+    return 2;
+}
+/* decode galalmanacb --------------------------------------------------------*/
+static int decode_galalmanacb(raw_t *raw)
+{
+    alm_t alm={0};
+    unsigned char *p=raw->buff+CNAVHLEN;
+    double dsqrtA,sqrtA=sqrt(29601297.0);
+    int prn,rcv_fnav,rcv_inav,svh_e1b,svh_e5a,svh_e5b,ioda;
+    
+    trace(3,"decode_galalmanacb: len=%d\n",raw->len);
+    
+    if (raw->len<CNAVHLEN+100) {
+        trace(2,"cnav galephemrisb length error: len=%d\n",raw->len);
+        return -1;
+    }
+    prn     =U4(p);   p+=4;
+    rcv_fnav=U4(p)&1; p+=4;
+    rcv_inav=U4(p)&1; p+=4;
+    svh_e1b =U1(p)&3; p+=1;
+    svh_e5a =U1(p)&3; p+=1;
+    svh_e5b =U1(p)&3; p+=1+1;
+    ioda    =U4(p);   p+=4;
+    alm.week=U4(p);   p+=4; /* gst week */
+    alm.toas=U4(p);   p+=4;
+    alm.e   =R8(p);   p+=8;
+    alm.OMGd=R8(p);   p+=8;
+    alm.OMG0=R8(p);   p+=8;
+    alm.omg =R8(p);   p+=8;
+    alm.M0  =R8(p);   p+=8;
+    alm.f0  =R8(p);   p+=8;
+    alm.f1  =R8(p);   p+=8;
+    dsqrtA  =R8(p);   p+=8;
+    alm.i0  =(R8(p)+56.0)*D2R;
+    alm.svh =(svh_e5b<<7)|(svh_e5a<<4)|(svh_e1b<<1);
+    alm.A   =(sqrtA+dsqrtA)*(sqrtA+dsqrtA);
+    
+    if (!(alm.sat=satno(SYS_GAL,prn))) {
+        trace(2,"oemv galalmanac satellite error: prn=%d\n",prn);
+        return -1;
+    }
+    alm.toa=gst2time(alm.week,alm.toas);
+    raw->nav.alm[alm.sat-1]=alm;
+    return 0;
+}
+/* decode galclockb ----------------------------------------------------------*/
+static int decode_galclockb(raw_t *raw)
+{
+    unsigned char *p=raw->buff+CNAVHLEN;
+    double a0,a1,a0g,a1g;
+    int leaps,tot,wnt,wnlsf,dn,dtlsf,t0g,wn0g;
+    
+    trace(3,"decode_galclockb: len=%d\n",raw->len);
+    
+    if (raw->len<CNAVHLEN+64) {
+        trace(2,"cnav galclockb length error: len=%d\n",raw->len);
+        return -1;
+    }
+    a0   =R8(p); p+=8;
+    a1   =R8(p); p+=8;
+    leaps=I4(p); p+=4;
+    tot  =U4(p); p+=4;
+    wnt  =U4(p); p+=4;
+    wnlsf=U4(p); p+=4;
+    dn   =U4(p); p+=4;
+    dtlsf=U4(p); p+=4;
+    a0g  =R8(p); p+=8;
+    a1g  =R8(p); p+=8;
+    t0g  =U4(p); p+=4;
+    wn0g =U4(p);
+    
+    raw->nav.utc_gal[0]=a0;
+    raw->nav.utc_gal[1]=a1;
+    raw->nav.utc_gal[2]=tot; /* utc reference tow (s) */
+    raw->nav.utc_gal[3]=wnt; /* utc reference week */
+    return 9;
+}
+/* decode galionob -----------------------------------------------------------*/
+static int decode_galionob(raw_t *raw)
+{
+    unsigned char *p=raw->buff+CNAVHLEN;
+    double ai[3];
+    int i,sf[5];
+    
+    trace(3,"decode_galionob: len=%d\n",raw->len);
+    
+    if (raw->len<CNAVHLEN+29) {
+        trace(2,"cnav galionob length error: len=%d\n",raw->len);
+        return -1;
+    }
+    ai[0]=R8(p); p+=8;
+    ai[1]=R8(p); p+=8;
+    ai[2]=R8(p); p+=8;
+    sf[0]=U1(p); p+=1;
+    sf[1]=U1(p); p+=1;
+    sf[2]=U1(p); p+=1;
+    sf[3]=U1(p); p+=1;
+    sf[4]=U1(p);
+    
+    for (i=0;i<3;i++) raw->nav.ion_gal[i]=ai[i];
+    return 9;
+}
+/* decode galfnavrawpageb ----------------------------------------------------*/
+static int decode_galfnavrawpageb(raw_t *raw)
+{
+    unsigned char *p=raw->buff+CNAVHLEN;
+    unsigned char buff[27];
+    int i,sigch,satid,page;
+    
+    trace(3,"decode_galfnavrawpageb: len=%d\n",raw->len);
+    
+    if (raw->len<CNAVHLEN+35) {
+        trace(2,"cnav galfnavrawpageb length error: len=%d\n",raw->len);
+        return -1;
+    }
+    sigch=U4(p); p+=4;
+    satid=U4(p); p+=4;
+    for (i=0;i<27;i++) {
+        buff[i]=U1(p); p+=1;
+    }
+    page=getbitu(buff,0,6);
+    
+    trace(3,"%s E%2d FNAV     (%2d) ",time_str(raw->time,0),satid,page);
+    traceb(3,buff,27);
+    
+    return 0;
+}
+/* decode galinavrawwordb ----------------------------------------------------*/
+static int decode_galinavrawwordb(raw_t *raw)
+{
+    unsigned char *p=raw->buff+CNAVHLEN;
+    unsigned char buff[16];
+    gtime_t time=raw->time;
+    char *sig;
+    int i,sigch,satid,sigtype,type,week=0,tow=0;
+    
+    trace(3,"decode_galinavrawwordb: len=%d\n",raw->len);
+    
+    if (raw->len<CNAVHLEN+28) {
+        trace(2,"cnav galinavrawwordb length error: len=%d\n",raw->len);
+        return -1;
+    }
+    sigch  =U4(p); p+=4;
+    satid  =U4(p); p+=4;
+    sigtype=U4(p); p+=4;
+    
+    switch (sigtype) {
+        case 10433: sig="E1 "; break;
+        case 10466: sig="E5A"; break;
+        case 10499: sig="E5B"; break;
+        default: sig="???"   ; break;
+    }
+    for (i=0;i<16;i++) {
+        buff[i]=U1(p); p+=1;
+    }
+    type=getbitu(buff,0,6);
+    if (type==0&&getbitu(buff,6,2)==2) {
+        week=getbitu(buff, 96,12); /* gst week */
+        tow =getbitu(buff,108,20);
+        time=gst2time(week,tow);
+    }
+    trace(3,"%s E%2d INAV-%s (%2d) ",time_str(time,0),satid,sig,type);
+    traceb(3,buff,16);
+    
+    return 0;
+}
+/* decode rawcnavframeb ------------------------------------------------------*/
+static int decode_rawcnavframeb(raw_t *raw)
+{
+    unsigned char *p=raw->buff+CNAVHLEN;
+    unsigned char buff[38];
+    int i,sigch,prn,frmid;
+    
+    trace(3,"decode_rawcnavframeb: len=%d\n",raw->len);
+    
+    if (raw->len<CNAVHLEN+50) {
+        trace(2,"cnav rawcnavframeb length error: len=%d\n",raw->len);
+        return -1;
+    }
+    sigch=U4(p); p+=4;
+    prn  =U4(p); p+=4;
+    frmid=U4(p); p+=4;
+    
+    for (i=0;i<38;i++) {
+        buff[i]=U1(p); p+=1;
+    }
+    trace(3,"%s PRN=%3d FRMID=%2d ",time_str(raw->time,0),prn,frmid);
+    traceb(3,buff,38);
+    
+    return 0;
+}
+/* decode bdsephemerisb ------------------------------------------------------*/
+static int decode_bdsephemerisb(raw_t *raw)
+{
+    eph_t eph={0};
+    unsigned char *p=raw->buff+CNAVHLEN;
+    double ura,sqrtA;
+    char *msg;
+    int prn,toc;
+    
+    trace(3,"decode_bdsephemerisb: len=%d\n",raw->len);
+    
+    if (raw->len<CNAVHLEN+196) {
+        trace(2,"cnav bdsephemrisb length error: len=%d\n",raw->len);
+        return -1;
+    }
+    prn       =U4(p);   p+=4;
+    eph.week  =U4(p);   p+=4;
+    ura       =R8(p);   p+=8;
+    eph.svh   =U4(p)&1; p+=4;
+    eph.tgd[0]=R8(p);   p+=8; /* TGD1 for B1 (s) */
+    eph.tgd[1]=R8(p);   p+=8; /* TGD2 for B2 (s) */
+    eph.iodc  =U4(p);   p+=4; /* AODC */
+    toc       =U4(p);   p+=4;
+    eph.f0    =R8(p);   p+=8;
+    eph.f1    =R8(p);   p+=8;
+    eph.f2    =R8(p);   p+=8;
+    eph.iode  =U4(p);   p+=4; /* AODE */
+    eph.toes  =U4(p);   p+=4;
+    sqrtA     =R8(p);   p+=8;
+    eph.e     =R8(p);   p+=8;
+    eph.omg   =R8(p);   p+=8;
+    eph.deln  =R8(p);   p+=8;
+    eph.M0    =R8(p);   p+=8;
+    eph.OMG0  =R8(p);   p+=8;
+    eph.OMGd  =R8(p);   p+=8;
+    eph.i0    =R8(p);   p+=8;
+    eph.idot  =R8(p);   p+=8;
+    eph.cuc   =R8(p);   p+=8;
+    eph.cus   =R8(p);   p+=8;
+    eph.crc   =R8(p);   p+=8;
+    eph.crs   =R8(p);   p+=8;
+    eph.cic   =R8(p);   p+=8;
+    eph.cis   =R8(p);
+    eph.A     =sqrtA*sqrtA;
+    eph.sva   =uraindex(ura,SYS_CMP);
+    
+    if (raw->outtype) {
+        msg=raw->msgtype+strlen(raw->msgtype);
+        sprintf(msg," prn=%3d iod=%3d toes=%6.0f",prn,eph.iode,eph.toes);
+    }
+    if (!(eph.sat=satno(SYS_CMP,prn))) {
+        trace(2,"oemv bdsephemeris satellite error: prn=%d\n",prn);
+        return -1;
+    }
+    eph.toe=bdt2gpst(bdt2time(eph.week,eph.toes)); /* bdt -> gpst */
+    eph.toc=bdt2gpst(bdt2time(eph.week,toc));      /* bdt -> gpst */
+    eph.ttr=raw->time;
+    
+    if (!strstr(raw->opt,"-EPHALL")) {
+        if (timediff(raw->nav.eph[eph.sat-1].toe,eph.toe)==0.0&&
+            raw->nav.eph[eph.sat-1].iode==eph.iode&&
+            raw->nav.eph[eph.sat-1].iodc==eph.iodc) return 0; /* unchanged */
+    }
+    raw->nav.eph[eph.sat-1]=eph;
+    raw->ephsat=eph.sat;
+    return 2;
+}
+        
+/* decode cnav message -------------------------------------------------------*/
+static int decode_cnav(raw_t *raw)
+{
+    double tow;
+    int msg,week,type=U2(raw->buff+4);
+    
+    trace(3,"decode_cnav: type=%3d len=%d\n",type,raw->len);
+    
+    /* check crc32 */
+    if (rtk_crc32(raw->buff,raw->len)!=U4(raw->buff+raw->len)) {
+        trace(2,"cnav crc error: type=%3d len=%d\n",type,raw->len);
+        return -1;
+    }
+    msg =(U1(raw->buff+6)>>4)&0x3;
+    if (!(week=U2(raw->buff+14))) {
+        return -1;
+    }
+    week=adjgpsweek(week);
+    tow =U4(raw->buff+16)*0.001;
+    raw->time=gpst2time(week,tow);
+    
+    if (raw->outtype) {
+        sprintf(raw->msgtype,"CNAV %4d (%4d): msg=%d %s",type,raw->len,msg,
+                time_str(gpst2time(week,tow),2));
+    }
+    if (msg!=0) return 0; /* message type: 0=binary,1=ascii */
+    
+    switch (type) {
+        case ID_RANGECMP      : return decode_rangecmpb      (raw);
+        case ID_RANGE         : return decode_rangeb         (raw);
+        case ID_RAWEPHEM      : return decode_rawephemb      (raw);
+        case ID_RAWWAASFRAME  : return decode_rawwaasframeb  (raw);
+        case ID_RAWSBASFRAME  : return decode_rawsbasframeb  (raw);
+        case ID_IONUTC        : return decode_ionutcb        (raw);
+        case ID_GLOEPHEMERIS  : return decode_gloephemerisb  (raw);
+        case ID_QZSSRAWEPHEM  : return decode_qzssrawephemb  (raw);
+        case ID_QZSSRAWSUBFRAME: return decode_qzssrawsubframeb(raw);
+        case ID_QZSSIONUTC    : return decode_qzssionutcb    (raw);
+        case ID_GALEPHEMERIS  : return decode_galephemerisb  (raw);
+        case ID_GALALMANAC    : return decode_galalmanacb    (raw);
+        case ID_GALCLOCK      : return decode_galclockb      (raw);
+        case ID_GALIONO       : return decode_galionob       (raw);
+        case ID_GALFNAVRAWPAGE: return decode_galfnavrawpageb(raw);
+        case ID_GALINAVRAWWORD: return decode_galinavrawwordb(raw);
+        case ID_RAWCNAVFRAME  : return decode_rawcnavframeb  (raw);
+        case ID_BDSEPHEMERIS  : return decode_bdsephemerisb  (raw);
+    }
+    return 0;
+}
+/* sync header ---------------------------------------------------------------*/
+static int sync_cnav(unsigned char *buff, unsigned char data)
+{
+    buff[0]=buff[1]; buff[1]=buff[2]; buff[2]=data;
+    return buff[0]==CNAVSYNC1&&buff[1]==CNAVSYNC2&&buff[2]==CNAVSYNC3;
+}
+/* input comnav raw data from stream ----------------------------------------
+* fetch next comnav raw data and input a mesasge from stream
+* args   : raw_t *raw   IO     receiver raw data control struct
+*          unsigned char data I stream data (1 byte)
+* return : status (-1: error message, 0: no message, 1: input observation data,
+*                  2: input ephemeris, 3: input sbas message,
+*                  9: input ion/utc parameter)
+*
+* notes  : to specify input options for cnav, set raw->opt to the following
+*          option strings separated by spaces.
+*
+*          -EPHALL : input all ephemerides
+*          -GL1P   : select 1P for GPS L1 (default 1C)
+*          -GL2X   : select 2X for GPS L2 (default 2W)
+*          -RL2C   : select 2C for GLO L2 (default 2P)
+*          -EL2C   : select 2C for GAL L2 (default 2C)
+*          -GALINAV: use I/NAV for GAL ephemeris
+*          -GALFNAV: use F/NAV for GAL ephemeris
+*
+*-----------------------------------------------------------------------------*/
+extern int input_cnav(raw_t *raw, unsigned char data)
+{
+    trace(5,"input_cnav: data=%02x\n",data);
+    
+    /* synchronize frame */
+    if (raw->nbyte==0) {
+        if (sync_cnav(raw->buff,data)) raw->nbyte=3;
+        return 0;
+    }
+    raw->buff[raw->nbyte++]=data;
+    
+    if (raw->nbyte==10&&(raw->len=U2(raw->buff+8)+CNAVHLEN)>MAXRAWLEN-4) {
+        trace(2,"cnav length error: len=%d\n",raw->len);
+        raw->nbyte=0;
+        return -1;
+    }
+    if (raw->nbyte<10||raw->nbyte<raw->len+4) return 0;
+    raw->nbyte=0;
+    
+    /* decode cnav message */
+    return decode_cnav(raw);
+}
+/* input comnav raw data from file ------------------------------------------
+* fetch next comnav raw data and input a message from file
+* args   : raw_t  *raw   IO     receiver raw data control struct
+*          int    format I      receiver raw data format (STRFMT_???)
+*          FILE   *fp    I      file pointer
+* return : status(-2: end of file, -1...9: same as above)
+*-----------------------------------------------------------------------------*/
+extern int input_cnavf(raw_t *raw, FILE *fp)
+{
+    int i,data;
+    
+    trace(4,"input_cnavf:\n");
+    
+    /* synchronize frame */
+    if (raw->nbyte==0) {
+        for (i=0;;i++) {
+            if ((data=fgetc(fp))==EOF) return -2;
+            if (sync_cnav(raw->buff,(unsigned char)data)) break;
+            if (i>=4096) return 0;
+        }
+    }
+    if (fread(raw->buff+3,7,1,fp)<1) return -2;
+    raw->nbyte=10;
+    
+    if ((raw->len=U2(raw->buff+8)+CNAVHLEN)>MAXRAWLEN-4) {
+        trace(2,"cnav length error: len=%d\n",raw->len);
+        raw->nbyte=0;
+        return -1;
+    }
+    if (fread(raw->buff+10,raw->len-6,1,fp)<1) return -2;
+    raw->nbyte=0;
+    
+    /* decode cnav message */
+    return decode_cnav(raw);
+}
+    
diff --git a/src/rcv/novatel.c b/src/rcv/novatel.c
index 482c950..89daff3 100644
--- a/src/rcv/novatel.c
+++ b/src/rcv/novatel.c
@@ -1,5 +1,5 @@
 /*------------------------------------------------------------------------------
-* notvatel.c : NovAtel OEM6/OEM5/OEM4/OEM3 receiver functions
+* notvatel.c : NovAtel OEM6/OEM5/OEM4 receiver functions
 *
 *          Copyright (C) 2007-2017 by T.TAKASU, All rights reserved.
 *
@@ -57,12 +57,8 @@
 #define OEM4SYNC1   0xAA        /* oem4 message start sync code 1 */
 #define OEM4SYNC2   0x44        /* oem4 message start sync code 2 */
 #define OEM4SYNC3   0x12        /* oem4 message start sync code 3 */
-#define OEM3SYNC1   0xAA        /* oem3 message start sync code 1 */
-#define OEM3SYNC2   0x44        /* oem3 message start sync code 2 */
-#define OEM3SYNC3   0x11        /* oem3 message start sync code 3 */
 
 #define OEM4HLEN    28          /* oem4 message header length (bytes) */
-#define OEM3HLEN    12          /* oem3 message header length (bytes) */
 
 #define ID_ALMANAC  73          /* message id: oem4 decoded almanac */
 #define ID_GLOALMANAC 718       /* message id: oem4 glonass decoded almanac */
@@ -87,16 +83,6 @@
 #define ID_RAWCNAVFRAME 1066    /* message id: oem6 raw cnav frame data */
 #define ID_BDSEPHEMERIS 1696    /* message id: oem6 decoded bds ephemeris */
 
-#define ID_ALMB     18          /* message id: oem3 decoded almanac */
-#define ID_IONB     16          /* message id: oem3 iono parameters */
-#define ID_UTCB     17          /* message id: oem3 utc parameters */
-#define ID_FRMB     54          /* message id: oem3 framed raw navigation data */
-#define ID_RALB     15          /* message id: oem3 raw almanac */
-#define ID_RASB     66          /* message id: oem3 raw almanac set */
-#define ID_REPB     14          /* message id: oem3 raw ephemeris */
-#define ID_RGEB     32          /* message id: oem3 range measurement */
-#define ID_RGED     65          /* message id: oem3 range compressed */
-
 #define WL1         0.1902936727984
 #define WL2         0.2442102134246
 #define MAXVAL      8388608.0
@@ -1060,222 +1046,7 @@ static int decode_bdsephemerisb(raw_t *raw)
     raw->ephsat=eph.sat;
     return 2;
 }
-/* decode rgeb ---------------------------------------------------------------*/
-static int decode_rgeb(raw_t *raw)
-{
-    unsigned char *p=raw->buff+OEM3HLEN;
-    double tow,psr,adr,tt,lockt,dop,snr;
-    int i,week,nobs,prn,sat,stat,sys,parity,lli,index,freq;
-    
-    trace(3,"decode_rgeb: len=%d\n",raw->len);
-    
-    week=adjgpsweek(U4(p));
-    tow =R8(p+ 4);
-    nobs=U4(p+12);
-    raw->time=gpst2time(week,tow);
-    
-    if (raw->len!=OEM3HLEN+20+nobs*44) {
-        trace(2,"oem3 regb length error: len=%d nobs=%d\n",raw->len,nobs);
-        return -1;
-    }
-    for (i=0,p+=20;i<nobs;i++,p+=44) {
-        prn   =U4(p   );
-        psr   =R8(p+ 4);
-        adr   =R8(p+16);
-        dop   =R4(p+28);
-        snr   =R4(p+32);
-        lockt =R4(p+36);     /* lock time (s) */
-        stat  =I4(p+40);     /* tracking status */
-        freq  =(stat>>20)&1; /* L1:0,L2:1 */
-        sys   =(stat>>15)&7; /* satellite sys (0:GPS,1:GLONASS,2:WAAS) */
-        parity=(stat>>10)&1; /* parity known */
-        if (!(sat=satno(sys==1?SYS_GLO:(sys==2?SYS_SBS:SYS_GPS),prn))) {
-            trace(2,"oem3 regb satellite number error: sys=%d prn=%d\n",sys,prn);
-            continue;
-        }
-        if (raw->tobs[sat-1][freq].time!=0) {
-            tt=timediff(raw->time,raw->tobs[sat-1][freq]);
-            lli=lockt-raw->lockt[sat-1][freq]+0.05<tt||
-                parity!=raw->halfc[sat-1][freq];
-        }
-        else {
-            lli=0;
-        }
-        if (!parity) lli|=2;
-        raw->tobs [sat-1][freq]=raw->time;
-        raw->lockt[sat-1][freq]=lockt;
-        raw->halfc[sat-1][freq]=parity;
-        
-        if (fabs(timediff(raw->obs.data[0].time,raw->time))>1E-9) {
-            raw->obs.n=0;
-        }        
-        if ((index=obsindex(&raw->obs,raw->time,sat))>=0) {
-            raw->obs.data[index].L  [freq]=-adr; /* flip sign */
-            raw->obs.data[index].P  [freq]=psr;
-            raw->obs.data[index].D  [freq]=(float)dop;
-            raw->obs.data[index].SNR[freq]=
-                0.0<=snr&&snr<255.0?(unsigned char)(snr*4.0+0.5):0;
-            raw->obs.data[index].LLI[freq]=(unsigned char)lli;
-            raw->obs.data[index].code[freq]=freq==0?CODE_L1C:CODE_L2P;
-        }
-    }
-    return 1;
-}
-/* decode rged ---------------------------------------------------------------*/
-static int decode_rged(raw_t *raw)
-{
-    unsigned int word;
-    unsigned char *p=raw->buff+OEM3HLEN;
-    double tow,psrh,psrl,psr,adr,adr_rolls,tt,lockt,dop;
-    int i,week,nobs,prn,sat,stat,sys,parity,lli,index,freq,snr;
-    
-    trace(3,"decode_rged: len=%d\n",raw->len);
-    
-    nobs=U2(p);
-    week=adjgpsweek(U2(p+2));
-    tow =U4(p+4)/100.0;
-    raw->time=gpst2time(week,tow);
-    if (raw->len!=OEM3HLEN+12+nobs*20) {
-        trace(2,"oem3 regd length error: len=%d nobs=%d\n",raw->len,nobs);
-        return -1;
-    }
-    for (i=0,p+=12;i<nobs;i++,p+=20) {
-        word  =U4(p);
-        prn   =word&0x3F;
-        snr   =((word>>6)&0x1F)+20;
-        lockt =(word>>11)/32.0;
-        adr   =-I4(p+4)/256.0;
-        word  =U4(p+8);
-        psrh  =word&0xF;
-        dop   =exsign(word>>4,28)/256.0;
-        psrl  =U4(p+12);
-        stat  =U4(p+16)>>8;
-        freq  =(stat>>20)&1; /* L1:0,L2:1 */
-        sys   =(stat>>15)&7; /* satellite sys (0:GPS,1:GLONASS,2:WAAS) */
-        parity=(stat>>10)&1; /* parity known */
-        if (!(sat=satno(sys==1?SYS_GLO:(sys==2?SYS_SBS:SYS_GPS),prn))) {
-            trace(2,"oem3 regd satellite number error: sys=%d prn=%d\n",sys,prn);
-            continue;
-        }
-        psr=(psrh*4294967296.0+psrl)/128.0;
-        adr_rolls=floor((psr/(freq==0?WL1:WL2)-adr)/MAXVAL+0.5);
-        adr=adr+MAXVAL*adr_rolls;
-        
-        if (raw->tobs[sat-1][freq].time!=0) {
-            tt=timediff(raw->time,raw->tobs[sat-1][freq]);
-            lli=lockt-raw->lockt[sat-1][freq]+0.05<tt||
-                parity!=raw->halfc[sat-1][freq];
-        }
-        else {
-            lli=0;
-        }
-        if (!parity) lli|=2;
-        raw->tobs [sat-1][freq]=raw->time;
-        raw->lockt[sat-1][freq]=lockt;
-        raw->halfc[sat-1][freq]=parity;
-        
-        if (fabs(timediff(raw->obs.data[0].time,raw->time))>1E-9) {
-            raw->obs.n=0;
-        }
-        if ((index=obsindex(&raw->obs,raw->time,sat))>=0) {
-            raw->obs.data[index].L  [freq]=adr;
-            raw->obs.data[index].P  [freq]=psr;
-            raw->obs.data[index].D  [freq]=(float)dop;
-            raw->obs.data[index].SNR[freq]=(unsigned char)(snr*4.0+0.5);
-            raw->obs.data[index].LLI[freq]=(unsigned char)lli;
-            raw->obs.data[index].code[freq]=freq==0?CODE_L1C:CODE_L2P;
-        }
-    }
-    return 1;
-}
-/* decode repb ---------------------------------------------------------------*/
-static int decode_repb(raw_t *raw)
-{
-    unsigned char *p=raw->buff+OEM3HLEN;
-    eph_t eph={0};
-    int prn,sat;
-    
-    trace(3,"decode_repb: len=%d\n",raw->len);
-    
-    if (raw->len!=OEM3HLEN+96) {
-        trace(2,"oem3 repb length error: len=%d\n",raw->len);
-        return -1;
-    }
-    prn=U4(p);
-    if (!(sat=satno(SYS_GPS,prn))) {
-        trace(2,"oem3 repb satellite number error: prn=%d\n",prn);
-        return -1;
-    }
-    if (decode_frame(p+ 4,&eph,NULL,NULL,NULL,NULL)!=1||
-        decode_frame(p+34,&eph,NULL,NULL,NULL,NULL)!=2||
-        decode_frame(p+64,&eph,NULL,NULL,NULL,NULL)!=3) {
-        trace(2,"oem3 repb subframe error: prn=%d\n",prn);
-        return -1;
-    }
-    if (!strstr(raw->opt,"-EPHALL")) {
-        if (eph.iode==raw->nav.eph[sat-1].iode) return 0; /* unchanged */
-    }
-    eph.sat=sat;
-    raw->nav.eph[sat-1]=eph;
-    raw->ephsat=sat;
-    return 2;
-}
-/* decode frmb --------------------------------------------------------------*/
-static int decode_frmb(raw_t *raw)
-{
-    unsigned char *p=raw->buff+OEM3HLEN;
-    double tow;
-    int i,week,prn,nbit;
-    
-    trace(3,"decode_frmb: len=%d\n",raw->len);
-    
-    week=adjgpsweek(U4(p));
-    tow =R8(p+ 4);
-    prn =U4(p+12);
-    nbit=U4(p+20);
-    raw->time=gpst2time(week,tow);
-    if (nbit!=250) return 0;
-    if (prn<MINPRNSBS||MAXPRNSBS<prn) {
-        trace(2,"oem3 frmb satellite number error: prn=%d\n",prn);
-        return -1;
-    }
-    raw->sbsmsg.week=week;
-    raw->sbsmsg.tow=(int)tow;
-    raw->sbsmsg.prn=prn;
-    for (i=0;i<29;i++) raw->sbsmsg.msg[i]=p[24+i];
-    return 3;
-}
-/* decode ionb ---------------------------------------------------------------*/
-static int decode_ionb(raw_t *raw)
-{
-    unsigned char *p=raw->buff+OEM3HLEN;
-    int i;
-    
-    if (raw->len!=64+OEM3HLEN) {
-        trace(2,"oem3 ionb length error: len=%d\n",raw->len);
-        return -1;
-    }
-    for (i=0;i<8;i++) raw->nav.ion_gps[i]=R8(p+i*8);
-    return 9;
-}
-/* decode utcb ---------------------------------------------------------------*/
-static int decode_utcb(raw_t *raw)
-{
-    unsigned char *p=raw->buff+OEM3HLEN;
-    
-    trace(3,"decode_utcb: len=%d\n",raw->len);
-    
-    if (raw->len!=40+OEM3HLEN) {
-        trace(2,"oem3 utcb length error: len=%d\n",raw->len);
-        return -1;
-    }
-    raw->nav.utc_gps[0]=R8(p   );
-    raw->nav.utc_gps[1]=R8(p+ 8);
-    raw->nav.utc_gps[2]=U4(p+16);
-    raw->nav.utc_gps[3]=adjgpsweek(U4(p+20));
-    raw->nav.leaps =I4(p+28);
-    return 9;
-}
+
 /* decode oem4 message -------------------------------------------------------*/
 static int decode_oem4(raw_t *raw)
 {
@@ -1325,44 +1096,14 @@ static int decode_oem4(raw_t *raw)
     }
     return 0;
 }
-/* decode oem3 message -------------------------------------------------------*/
-static int decode_oem3(raw_t *raw)
-{
-    int type=U4(raw->buff+4);
-    
-    trace(3,"decode_oem3: type=%3d len=%d\n",type,raw->len);
-    
-    /* checksum */
-    if (chksum(raw->buff,raw->len)) {
-        trace(2,"oem3 checksum error: type=%3d len=%d\n",type,raw->len);
-        return -1;
-    }
-    if (raw->outtype) {
-        sprintf(raw->msgtype,"OEM3 %4d (%4d):",type,raw->len);
-    }
-    switch (type) {
-        case ID_RGEB: return decode_rgeb(raw);
-        case ID_RGED: return decode_rged(raw);
-        case ID_REPB: return decode_repb(raw);
-        case ID_FRMB: return decode_frmb(raw);
-        case ID_IONB: return decode_ionb(raw);
-        case ID_UTCB: return decode_utcb(raw);
-    }
-    return 0;
-}
 /* sync header ---------------------------------------------------------------*/
 static int sync_oem4(unsigned char *buff, unsigned char data)
 {
     buff[0]=buff[1]; buff[1]=buff[2]; buff[2]=data;
     return buff[0]==OEM4SYNC1&&buff[1]==OEM4SYNC2&&buff[2]==OEM4SYNC3;
 }
-static int sync_oem3(unsigned char *buff, unsigned char data)
-{
-    buff[0]=buff[1]; buff[1]=buff[2]; buff[2]=data;
-    return buff[0]==OEM3SYNC1&&buff[1]==OEM3SYNC2&&buff[2]==OEM3SYNC3;
-}
-/* input oem4/oem3 raw data from stream ----------------------------------------
-* fetch next novatel oem4/oem3 raw data and input a mesasge from stream
+/* input oem4 raw data from stream ----------------------------------------
+* fetch next novatel oem4 raw data and input a mesasge from stream
 * args   : raw_t *raw   IO     receiver raw data control struct
 *          unsigned char data I stream data (1 byte)
 * return : status (-1: error message, 0: no message, 1: input observation data,
@@ -1403,30 +1144,8 @@ extern int input_oem4(raw_t *raw, unsigned char data)
     /* decode oem4 message */
     return decode_oem4(raw);
 }
-extern int input_oem3(raw_t *raw, unsigned char data)
-{
-    trace(5,"input_oem3: data=%02x\n",data);
-    
-    /* synchronize frame */
-    if (raw->nbyte==0) {
-        if (sync_oem3(raw->buff,data)) raw->nbyte=3;
-        return 0;
-    }
-    raw->buff[raw->nbyte++]=data;
-    
-    if (raw->nbyte==12&&(raw->len=U4(raw->buff+8))>MAXRAWLEN) {
-        trace(2,"oem3 length error: len=%d\n",raw->len);
-        raw->nbyte=0;
-        return -1;
-    }
-    if (raw->nbyte<12||raw->nbyte<raw->len) return 0;
-    raw->nbyte=0;
-    
-    /* decode oem3 message */
-    return decode_oem3(raw);
-}
-/* input oem4/oem3 raw data from file ------------------------------------------
-* fetch next novatel oem4/oem3 raw data and input a message from file
+/* input oem4 raw data from file ------------------------------------------
+* fetch next novatel oem4 raw data and input a message from file
 * args   : raw_t  *raw   IO     receiver raw data control struct
 *          int    format I      receiver raw data format (STRFMT_???)
 *          FILE   *fp    I      file pointer
@@ -1460,31 +1179,4 @@ extern int input_oem4f(raw_t *raw, FILE *fp)
     /* decode oem4 message */
     return decode_oem4(raw);
 }
-extern int input_oem3f(raw_t *raw, FILE *fp)
-{
-    int i,data;
-    
-    trace(4,"input_oem3f:\n");
-    
-    /* synchronize frame */
-    if (raw->nbyte==0) {
-        for (i=0;;i++) {
-            if ((data=fgetc(fp))==EOF) return -2;
-            if (sync_oem3(raw->buff,(unsigned char)data)) break;
-            if (i>=4096) return 0;
-        }
-    }
-    if (fread(raw->buff+3,1,9,fp)<9) return -2;
-    raw->nbyte=12;
-    
-    if ((raw->len=U4(raw->buff+8))>MAXRAWLEN) {
-        trace(2,"oem3 length error: len=%d\n",raw->len);
-        raw->nbyte=0;
-        return -1;
-    }
-    if (fread(raw->buff+12,1,raw->len-12,fp)<(size_t)(raw->len-12)) return -2;
-    raw->nbyte=0;
-    
-    /* decode oem3 message */
-    return decode_oem3(raw);
-}
+
diff --git a/src/rcvraw.c b/src/rcvraw.c
index 12ba571..dd9daed 100644
--- a/src/rcvraw.c
+++ b/src/rcvraw.c
@@ -990,7 +990,7 @@ extern int input_raw(raw_t *raw, int format, unsigned char data)
     
     switch (format) {
         case STRFMT_OEM4 : return input_oem4 (raw,data);
-        case STRFMT_OEM3 : return input_oem3 (raw,data);
+        case STRFMT_CNAV : return input_cnav (raw,data);
         case STRFMT_UBX  : return input_ubx  (raw,data);
         case STRFMT_SBP  : return input_sbp  (raw,data);
         case STRFMT_CRES : return input_cres (raw,data);
@@ -1020,7 +1020,7 @@ extern int input_rawf(raw_t *raw, int format, FILE *fp)
     
     switch (format) {
         case STRFMT_OEM4 : return input_oem4f (raw,fp);
-        case STRFMT_OEM3 : return input_oem3f (raw,fp);
+        case STRFMT_CNAV : return input_cnavf (raw,fp);
         case STRFMT_UBX  : return input_ubxf  (raw,fp);
         case STRFMT_SBP  : return input_sbpf  (raw,fp);
         case STRFMT_CRES : return input_cresf (raw,fp);
diff --git a/src/rinex.c b/src/rinex.c
index e926590..e53704a 100644
--- a/src/rinex.c
+++ b/src/rinex.c
@@ -1962,11 +1962,11 @@ extern int outrnxobsh(FILE *fp, const rnxopt_t *opt, const nav_t *nav)
 /* output obs data field -----------------------------------------------------*/
 static void outrnxobsf(FILE *fp, double obs, int lli, int qual)
 {
-    if (obs==0.0||obs<=-1E9||obs>=1E9) {
+    if (obs==0.0) { 
         fprintf(fp,"              ");
     }
     else {
-        fprintf(fp,"%14.3f",obs);
+        fprintf(fp,"%14.3f",fmod(obs,1e9));
     }
     if (lli<0||!(lli&(LLI_SLIP|LLI_HALFC|LLI_BOCTRK))) {
         fprintf(fp," ");
diff --git a/src/rtkcmn.c b/src/rtkcmn.c
index 671c3c6..54f0ca0 100644
--- a/src/rtkcmn.c
+++ b/src/rtkcmn.c
@@ -204,7 +204,7 @@ const prcopt_t prcopt_default={ /* defaults processing options */
     {0},{0},{0},                /* baseline,ru,rb */
     {"",""},                    /* anttype */
     {{0}},{{0}},{0},            /* antdel,pcv,exsats */
-    1                           /* maxaveep */
+    1,1                           /* maxaveep,initrst */
 };
 const solopt_t solopt_default={ /* defaults solution output options */
     SOLF_LLH,TIMES_GPST,1,3,    /* posf,times,timef,timeu */
@@ -217,7 +217,7 @@ const char *formatstrs[32]={    /* stream format strings */
     "RTCM 2",                   /*  0 */
     "RTCM 3",                   /*  1 */
     "NovAtel OEM6",             /*  2 */
-    "NovAtel OEM3",             /*  3 */
+    "ComNav",                   /*  3 */
     "u-blox",                   /*  4 */
     "Swift Navigation SBP",     /*  5 */
     "Hemisphere",               /*  6 */
diff --git a/src/rtklib.h b/src/rtklib.h
index 3f3287a..c479ae7 100644
--- a/src/rtklib.h
+++ b/src/rtklib.h
@@ -436,7 +436,7 @@ extern "C" {
 #define STRFMT_RTCM2 0                  /* stream format: RTCM 2 */
 #define STRFMT_RTCM3 1                  /* stream format: RTCM 3 */
 #define STRFMT_OEM4  2                  /* stream format: NovAtel OEMV/4 */
-#define STRFMT_OEM3  3                  /* stream format: NovAtel OEM3 */
+#define STRFMT_CNAV  3                  /* stream format: ComNav */
 #define STRFMT_UBX   4                  /* stream format: u-blox LEA-*T */
 #define STRFMT_SBP   5                  /* stream format: Swift Navigation SBP */
 #define STRFMT_CRES  6                  /* stream format: Hemisphere */
@@ -1688,7 +1688,7 @@ EXPORT void free_cmr  (raw_t *raw);
 EXPORT int update_cmr (raw_t *raw, rtksvr_t *svr, obs_t *obs);
 
 EXPORT int input_oem4  (raw_t *raw, unsigned char data);
-EXPORT int input_oem3  (raw_t *raw, unsigned char data);
+EXPORT int input_cnav  (raw_t *raw, unsigned char data);
 EXPORT int input_ubx   (raw_t *raw, unsigned char data);
 EXPORT int input_sbp   (raw_t *raw, unsigned char data);
 EXPORT int input_cres  (raw_t *raw, unsigned char data);
@@ -1703,7 +1703,7 @@ EXPORT int input_cmr   (raw_t *raw, unsigned char data);
 EXPORT int input_tersus(raw_t *raw, unsigned char data);
 EXPORT int input_lexr  (raw_t *raw, unsigned char data);
 EXPORT int input_oem4f (raw_t *raw, FILE *fp);
-EXPORT int input_oem3f (raw_t *raw, FILE *fp);
+EXPORT int input_cnavf (raw_t *raw, FILE *fp);
 EXPORT int input_ubxf  (raw_t *raw, FILE *fp);
 EXPORT int input_sbpf  (raw_t *raw, FILE *fp);
 EXPORT int input_cresf (raw_t *raw, FILE *fp);
diff --git a/src/sbas.c b/src/sbas.c
index 09a3ec2..6920ffb 100644
--- a/src/sbas.c
+++ b/src/sbas.c
@@ -484,12 +484,6 @@ static void readmsgs(const char *file, int sel, gtime_t ts, gtime_t te,
             if (sscanf(++p,"%d,%d",&ch,&prn)<2) continue;
             if (!(p=getfield(p,4))) continue;
         }
-        else if (!strncmp(buff,"$FRMA",5)) { /* NovAtel OEM3 */
-            if (!(p=getfield(buff,2))) continue;
-            if (sscanf(p,"%d,%lf,%d",&week,&tow,&prn)<3) continue;
-            if (!(p=getfield(p,6))) continue;
-            if (week<WEEKOFFSET) week+=WEEKOFFSET;
-        }
         else continue;
         
         if (sel!=0&&sel!=prn) continue;
diff --git a/src/src.pro b/src/src.pro
index 20cc422..0f99e4b 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -61,6 +61,7 @@ SOURCES += rtkcmn.c \
     rcv/ss2.c \
     rcv/ublox.c \
     rcv/tersus.c \
+    rcv/comnav.c \
     rcv/swiftnav.c \
     rcv/cmr.c
 
-- 
GitLab