General Considerations
The software available through links on this page is taken from the
BINEX section of the teqc source code,
with little or minimal modification. The teqc source code is written
so that it can be compiled either with a Kernighan/Ritchie C compiler (compile
with "-DKR_C" option), or with an ANSI C/C++ compiler by default. In general,
the teqc code has been compiled on almost 20 different compiler/OS
combinations, with both little-endian and big-endian processors. The code
available here is the first teqc code that is being made publically
available, in order to help jump start BINEX usage.

There are some general considerations. First, you must make sure of the
sizes of the following standard C/C++ data types for your particular
compiler and platform:

Non-standard C/C++ data types (long long, long double, and so on) are not
used directly.

Currently, none of the supplied code can be compiled as is into a
standalone executable. Instead, the supplied C functions are meant
as a template (not in the C++ sense!) for your own development effort.
You are free to make use of the supplied software as you see fit.
But like software from the Free Software Foundation, Inc.:

This software is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Errors or significant code enhancements should be submitted to the
UNAVCO BINEX contact. Please make
sure that any submitted code changes are consistent with both Kernighan/Ritchie C
and ANSI C/C++ styles.

Now, go for it!

Forward BINEX Record Parsing Function:
In binex.c, prototyped in
binex.h,
is the function next_BINEX_record(), which will parse a BINEX stream
pointed to by file->fp, reading it in the forward direction only.
It is designed to work with reading files and stdin, depending of the
value of file->fp.
Before this function is called the first time, it is assumed that the
user has determined the endian-ness
of the processor being used, and has set teq.tr.little_endian
to the appropriate value. At the end of the function, a
switch is used to call the correct interpretation function depending
on the record ID of the BINEX record.

Basically, this function is an implimentation of the
forward record parsing algorithm.
The function is designed to be called repeatedly until the end-of-file marker
is encountered, and NORMAL_BINEX_EOF is returned. The only BINEX-related
functions that are called are:

sufficient for creating or verifying the checksum/CRC of any
BINEX record of less than 2^20 = 1048576 bytes (which will probably
be all BINEX records for the foreseeable future).
Yet to be finalized is md5(), for record lengths of 2^20 or greater bytes.

The CRCs (cyclic redundancy checks) are computed using static lookup tables,
to minimize computation time. Each function accepts one or two pointers
to unsigned char, buff and mess,
which point to the bytes for which the checksum or CRC is to be computed.
The unsigned long values buff_length and mess_length indicate
the number of bytes to sum at each pointer, respectively.
If both pointers are not NULL, buff must occur first, immediately
followed by mess. The reason for this two-part pointer method is
the construction of any BINEX record: The initial
record ID bytes are
followed by the record length bytes,
but the record length is usually not known until the entire
record message has been
constructed. It is useful, therefore, when creating a BINEX record,
to store the record ID and record length bytes in buff, and create
the record message in mess.

Interpretation of Record ID 0x01 = 1:
Though not complete (since they access other teqc-specific functions), the following
C/C++ functions and prototyping are provided in
binex.c and
binex.h
as help in learning how to interpret (decompose) BINEX
record ID 0x01:

decompose_binex_01():
for record 0x01, determines the subrecord value (currently only subrecord 0x01 is valid),
and calls binex_extract_SV_id(), binary_NAV(), and
binary_ephemeris(), the latter two of which are teqc functions: binary_NAV()
sets initial RINEX NAV file header information, binary_ephemeris() essentially
just calls binex_01_01_ephemeris() if subrecord 0x01 and does other teqc specific tasks

binex_01_01_ephemeris():
decomposition of BINEX record 0x01-01
for GPS satellites (GLONASS will be another case statement defined later); if teq.edit.opt_X & BINEX_OUT
is non-zero, BINEX values will be generated and if zero, RINEX values will be generated
(only relevant for the SV health and SV fit interval components of the GPS navigation message)

decompose_binex_7f():
for record 0x7f, determines the subrecord value (currently only subrecord 0x00 is valid),
and calls teqc functions which establish the observation epoch time based on
the GPS week and seconds into the week, and for subrecord 0x00 then establishes the current observable part of
the constellation (indirectly calls binex_7f_00_constellation()) and
obtains the observables (indirectly call binex_7f_00_obs()).

binex_7f_00_constellation(): determines the observable part of the constellation
(SVs being tracked) in current 0x7f-00

binex_7f_00_obs(): decomposition of the observables:

C1 = C/A pseudorange; nearest 0.001 meter

P1 = P1 pseudorange; nearest 0.001 meter

P2 = P2 pseudorange; nearest 0.001 meter

S1 = raw SNR value for L1 (one byte is currently assumed)

S2 = raw SNR value for L2 (one byte is currently assumed)

L1 = L1(P1) phase; nearest 0.0001 L1-cycle

LA = L1(CA) phase; nearest 0.0001 L1-cycle

L2 = L2(P2) phase; nearest 0.0001 L2-cycle

Also, extraction of the "possible error" byte for C1, P1, P2, LA, L1, L2;
receiver channel number; A/S status; and loss-of-lock for L1 and L2.
(Full-wavelength tracking of LA, L1, and L2 is assumed. index == 0xff
is a teqc-ism that means that that specific observable was not requested.)