# XDecode User Guide

## Foreword
This document is a work-in-progress. The new `xdecode` is still under development,
and features may change with little prior warning. That said, most of what's documented
here is expected to remain stable.

## Overview
`xdecode` is a tool for extracting data from the SBD packets transmitted by MRV floats.

Due to the bandwidth-constrained nature of satellite communications, great care is taken
to transmit as much information as possible in as few bytes as possible. Therefore,
data is transmitted in a tightly-packed encoded binary format called XMessage, originally
developed by SIO.

The purpose of the `xdecode` tool is to serve as a single simple way of extracting all
data from an arbitrary set of XMessage packets (.sbd files).

## Quick Start
Take a quick, human-readable look at data for a dive, assuming the SBD messages for that
dive are in some directory `dive/`:
```
$ xdecode path/to/dive/
```

Decode a set of dives, and write JSON serialized data to a file:
```
$ xdecode -fjson path/to/dive1 path/to/dive2 ... -o out.json
```
or
```
$ xdecode path/to/dives/ -fj > out.json
```

Decode data for a float, spanning dives, in json format:
```
$ xdecode path/to/data -f json
[
  {
    "sn": 9001,
    "model": "Alamo/Alto",
    "dives": [
      {
        "dn": 1,
        ..
      }
      {
        "dn": 2,
        ...
      }
      ...
    ]
  }
]
```

Quickly crack SBD messages to find out which data packets are present for which floats/dives
in a data set:
```
$ xdecode path/to/data --split
```

### Combining `xdecode` with other tools (Linux/MacOS)
Check for errors in a dive:
```
$ xdecode path/to/dive | grep -C2 'error'
```

Check how the `DFT` parameter changes across three dives:
```
$ xdecode path/to/dive1 path/to/dive2 path/to/dive3 | grep 'DFT'
```

Find out which floats/dives a directory has data for
```
$ xdecode path/to/data --split | grep -i 'float'
```

## Usage
Usually, `xdecode` is run on a directory structure holding SBD messages for a dive.
It does not generally make sense to decode a single SBD from a dive in isolation.
It *is* possible, but you may need to supply additional information normally found in some
of the other XMessage packets. See the `--model` and `--version` options, described below.

Most use-cases are covered in the examples above.

General usage, along with all available options and flags, are documented in the `xdecode`
application itself. The help can be displayed by running `xdecode -h` or just `xdecode` with
no input (short help), or `xdecode --help` (long help).

### Flags
#### `-h/--help`
Print help information and exit

#### `-s/--split`
Just crack open the SBD messages to examine which floats/dives and XMessage
packet IDs are present. Do not decode any data.

```
$ xdecode ~/data/9001/200 --split
Float 9001 Dive 200
 01 02 10 20 30 40 50 60 80 98 A8 B8 D0 D1 E7 E8 E9 EA EB F0
```

#### `-c/--continue`
Try to stagger on even if errors occur while decoding. Note that some errors
may affect the integrity of decoded data; if errors or warnings are logged, you should **not**
trust the correctness of the output.
  
Pay attention to warning/error messages, some of them may be resolved by supplying additional
information.

#### `-S/--follow-links`
Follow symbolic links in the input paths.

#### `-u/--ugly`
Do not pretty-print output, if applicable to the output format.

If the output of this invocation of `xdecode` will only be consumed by another program, this can
be useful to reduce file size (e.g. by removing all newlines/whitespace in the JSON format).

```
$ xdecode -ufj ~/db/9001/200
[{"sn":9001,"model":"Alamo/Alto","dives":[{"dn":200,"sw_version":"5.0.a","trajectory":{"gps":[{"kind":"DiveStart","datetime":...
```

#### `-v[vv]`
Control verbosity of logging by number of `v`s (0-3):

  * None: Warnings and errors only. Standard.
  * (`-v`): Informational messages and above. Verbose.
  * (`-vv`): Debug messages and above. Very verbose.
  * (`-vvv`): Program trace/all logs. Very very verbose.

#### `--force`
Force use of user-specifed float model and version. If this flag is given, then both the
`--model` and `--version` options described below *must* be provided.

This may cause additional errors during decoding, and should *only* be specified if you
believe the decoder is deducing an incorrect value for one or both of those options.

### Options
#### `-o/--output <filename>`
If specified, write decoded output to `filename` instead of `stdout`.
```
$ xdecode ~/data/9001/200 -o out/sn9001_dn200.txt
$ ls out/
  sn9001_dn200.txt
```

#### `-f/--format <format>`
Set output format to `format`, which is one of the following (default `text`):

  * `t/text`: Output is human readable with some nicely formatted tables.
  Assumes terminal support for UTF-8 encoded characters.
  * `j/json`: JavaScript Ojbect Notation is a fairly ubiquitous data interchange format that has become
  a sort of de-facto standard. Software libraries exist to parse it in almost every programming language.
  * `y/yaml`: A format that is both human readable and fairly easy for software to parse.
  * `q/quiet/silent`: Normal output is supressed, but data is still fully decoded. Useful to verify data integrity
  (warnings/errors will still be printed).

#### `-t/--model <model>`
Float model hint. Generally only needed if the data cannot be decoded correctly otherwise.
Possible values for `model`:

* `alamo`: MRV Alamo/Alto family.
* `solo`: SIO SoloII or MRV S2A/S2X family.
* `deep`: Deep Solo floats.

Unless the `--force` flag is also specified, this will be ignored if the float model can be uniquely
determined from the input data.

#### `--version <sw_version>`
Float software version hint. Generally only needed if the data cannot be correctly decoded otherwise.

```
$ xdecode ~/db/9002/1 --version 6.1.3
```

Unless the `--force` flag is also specified, this will be ignored if the float model can be uniquely
determined from the input data.


## Output
By default, `xdecode` writes output to `stdout` and logging/warning/error messages to `stderr`.

On *nix/MacOS, output can be redirected as usual to a file or another application using pipes
or fifos.

The `-o`, or `--output` option is available to write output to a file instead. This is the
recommended way to write output to a file on Windows.


## Installation
Archives of precompiled binaries for `xdecode` are available for Linux, MacOS, and Windows.

As with most command-line tools, if you frequently use `xdecode` it is recommended to place it
in your path, so that it can be run in the same manner from any terminal.

