# NDI CAPI Sample Readme

This document includes important information before using this software.

## Table of Contents

About the sample

Using the sample

Connecting via DTLS

Building the sample

AR Demo

OpenSSL

List of changes

## About the sample

The Combined API (CAPI) sample application demonstrates how to use the Combined API for Polaris and Aurora systems in a C++ application to communicate with an NDI measurement system. The source code is intended as a reference to help developers become familiar with NDI's API.

Please see license.txt and the copyright notices in source files for the terms associated with the provision of this sample code.

## Using CAPIsample

The usage of the CAPIsample console application is:

1. Connect an NDI measurement system to the host machine and ensure the device is visible on the OS.
   1. For serial devices, ensure the USB drivers are installed and the operating system recognizes the serial port.
      On Windows this will be a COM port listed in the device manager.
      On Linux this will be a /dev/tty* device (usually /dev/ttyUSBx where x is a number).
      On macOS this will be /dev/cu.usbserial-xxxxx and /dev/tty.usbserial-xxxxx. Use the /dev/cu.usbserial-xxxxx port as it is the variant that supports blocked reads and writes.
   2. For ethernet devices, ensure the host machine can ping the hostname or IP address of the NDI device.
2. Compile and link CAPIsample following the instructions below. The build process will produce a shared library and a sample program that uses the library. Pre-compiled binaries are also supplied in ./bin
3. From a terminal window run the program as follows:
   1. To run pre-compiled binaries

   On Linux:

   - `./bin/linux/capisample <hostname> --tools=[file1.rom],[file2.rom] [args]`

   On Windows 64-bit:

   - `bin\win64\sample.exe <hostname> --tools=[file1.rom],[file2.rom] [args]`

   On Mac:

   - `./bin/macosx/CAPIsample <hostname> --tools=[file1.rom],[file2.rom] [args]`
   2. To run custom compiled binaries

   On Linux:

   - `./build/linux/capisample <hostname> --tools=[file1.rom],[file2.rom] [args]`

   On Windows 64-bit:

   - Default: `x64\Release\sample.exe <hostname> --tools=[file1.rom],[file2.rom] [args]`
   - With OpenSSL: `x64\Release_TLS\sample.exe <hostname> --tools=[file1.rom],[file2.rom] [args]`

   On Mac:

   - `./build/macosx/capisample <hostname> --tools=[file1.rom],[file2.rom] [args]`

   where

   - `<hostname>` (required) The measurement device's hostname, IP address, or serial port.
   - `--tools=[file1.rom],[file2.rom]...` (required) A comma delimited list of tools to load.
   - `[args]` (optional) Any other arguments such as tools to load, or SCU to connect to.

   Examples of connection specification:

   - Connecting to device by IP address: 169.254.8.50
   - Connecting to device by hostname: P9-B0103.local
   - Connecting to serial port varies by OS:
     COM10 (Win), /dev/ttyUSB0 (Linux), /dev/cu.usbserial-001014FA (Mac)

   For more information and a list of optional arguments, run the sample with no arguments:

   On Linux:

   - `./bin/linux/capisample`

   On Windows 64-bit:

   - `bin\win64\sample.exe`

   On Mac:

   - `./bin/macosx/CAPIsample`

By default, CAPIsample will connect to a device, initialize it and issue a series of tracking API commands that illustrate the basic principles of communicating with the measurement system. The application does not issue every possible API command, but focuses on the most common and basic tasks including:

- Connecting to an ethernet or serial port device (via serial-to-USB converter)
- Initializing the system
- Loading and initializing passive, active-wireless, and active tools (if an SCU is connected)
- Getting/setting user parameters stored in the device firmware
- Sending BX or BX2 to retrieve tracking data and printing it to the terminal in .csv format
- Printing a small amount of tracking data to a .csv file called "example.csv"

The source code for CAPIsample is provided so it can be analyzed and modified as desired. Developers may want to:

- Explore simulating alerts and how the alert data is transmitted to the application
- Investigate using dummy tools to return 3D data
- Refer to the API guide for their system to add commands that CAPIsample didn't implement
- Completely gut and rewrite CAPIsample as a starting point for their project

### Connecting via DTLS

If you use the `--encrypted` and `--udp` sample arguments together, for systems that support DTLS streaming, the sample will attempt to establish first a TLS connection (for control API calls), then a DTLS connection for sending the STREAM command to stream tracking information from the system. Because of how the DTLS protocol works, it is not made aware when the connection is closed from the camera's perspective. This means that if you run the sample twice in a row, the subsequent DTLS connection attempt will fail if it is within the idle connection timeout (set in the system by the `Param.Connect.Idle Timeout` parameter).

To handle this, there are a few options:

1. Send RESET 1 to the system to end all open connections, and wait for the system to come back up.
2. Shorten the Idle Timeout (default is 300 seconds) so that you can re-establish connections sooner.
3. Wait the full timeout before attempting the new connection or running the sample again.

## Building the sample

CAPIsample can be compiled on Windows using Visual Studio and on Linux and macOS using make. A Visual Studio 2017 .sln and Eclipse project files are provided for convenience.

### Required Tools

The following tools are required to build the sample:

Target OS | Tools Windows | Microsoft Visual Studio 2017 or later
Linux | Native development tool chain including g++ and make
macOS | XCode or Gnu development tool chain including g++ and make

Optional for automatic document generation - Doxygen

### Build the CAPI sample binaries

Open a terminal window and change the current directory to the directory where the capisample package is installed. The following terminal commands can be used to compile CAPIsample and its Doxygen documentation.

Windows:

There are two options:

- Open the solution file with Visual Studio and build the solution from with Visual Studio, or
- Open developer console window from the start menu (search for "dev"). Go to the CAPIsample directory and type
  `> msbuild /p:Configuration=Release CAPIsample.sln`

Mac and Linux:
To build the library, the sample executable, as well as the GStreamer-based ARDemo (see below), open a terminal window in the CAPIsample directory and type:
`$ make`

To build the library and the sample without the GStreamer-based ARDemo (see below), specify the following target instead:
`$ make sample`

Documentation:
Doxygen documentation can be built if Doxygen is installed by using the command line and typing
`$ doxygen doxygen.conf`

## ARDemo

A video camera unit is an option for the Polaris Vega. This presents opportunities for combining the tracking and video data streams for augmented reality scenarios.

For customers that have this option, an example of using CAPISample along with the GStreamer framework is provided. The ARDemo sample files can be found in the capisample\ndigst directory.

Please see capisample\ndigst\doc\GStreamerNotes.docx for more information.

Pre built binaries for windows can be found here: capisample\ndigst\bin

The executable ardemo.exe can be run with the appropriate parameters, for example:
`> ardemo 169.254.176.61 c:/capisample/sroms/ 8700339.rom 554`
Change the IP address of the PSU, directory path of rom files, rom file, and video port as needed.

Note that to run this executable, the GStreamer framework needs to be installed and the path environment variable set accordingly. (See capisample\ndigst\doc\GStreamerNotes.docx for more information).

### To build this ARDemo sample:

Windows:

There are two options:

- Open the capisample\ndigst\ndigst.sln solution file with Visual Studio and build the solution from with Visual Studio (one of the x64 configurations), or
- Open developer console window from the start menu (search for "dev"). Go to the capisample\ndigst directory and type
  `> msbuild /p:Configuration=Release ndigst.sln`

## OpenSSL

Transport Layer Security (TLS) encrypts TCP streams. Datagram TLS (DTLS) encrypts UDP streams. OpenSSL is an open source library that can be integrated into existing applications to provide secure communication. It consists of two shared libraries: libssl (TLS/DTLS abstractions) and libcrypto (cryptography functions)

More details

Download binaries

### Build instructions

Windows:

1. Install openssl via one of the binary distributions from the link above. Eg. C:\Program Files\OpenSSL-Win64
2. `msbuild /p:Configuration=Release_TLS CAPIsample.sln`

Mac:

1. Install openssl via homebrew. Eg: `brew install openssl`
2. `make clean sample_tls`

Linux:

1. Install openssl via the package manager. Eg. Ubuntu 20.04: `apt install openssl libssl-dev`
2. `make clean sample_tls`

Note that the "`make clean`" is necessary because make will not detect changes in preprocessor options alone. If the sample is built without OpenSSL first, make will believe there is nothing to do, ignoring the fact that the sample_tls target adds preprocessor flags and linker options that require recompiling and relinking.

## List of Changes

The changes between versions of the sample are listed below:

Version | Changes
1.9.7 | STREAM command response ("OKAY") was being erased and interpreted as an error.
1.9.6 | Fixed issue introduced in 1.8.0 that made it impossible to run the sample executable with a serially connected device. Bug fix: ToolData.h's `SystemStatus` values were defined incorrectly as enumerated rather than bit flags. Added the "Hardware Configuration Changed" status to the `SystemStatus` values.
1.9.5 | Improved error handling for connecting via DTLS in the library and in the sample executable. Improved error handling for streaming via TCP/TLS/UDP/DTLS. Added a `RESET 0` command after initial connection in the sample executable to improve repeatability.
1.9.4 | Fixed a bug in the `stopStreaming` method that closed a connection before parsing the reply to `USTREAM`.
1.9.3 | Reverted changes to UDP to support Vega/Lyra CFR 10 implementation
1.9.2 | Added support for Version 2 of the GBF recording files, which may contain tagged key-value pairs in the header.
1.9.1 | Added ability to parse the Marker 3D Error GBF component (`0x9`) and the Line Separations GBF component (`0xB`), introduced to the BX2 command in API version G.003.007.
1.9.0 | Added the --cipher=[ciphersuite] option to allow TLS/DTLS ciphersuite to be specified
1.8.2 | Improved parsing of GBF recording files by monitoring the number of samples expected in the file. Added parsing of NDI-internal components in a separate library with MSVS solution file.
1.8.1 | Method for parsing GBF recording files had an issue where the file reader was reading two extra bytes into the buffer every time a GBF container was read, resulting in quitting early from the method in cases with long files.
1.8.0 | Added method to CAPI to print a GBF recording file to a text file
1.7.1 | GBF Button component processing was made more robust
1.7.0 | Added DTLS (encrypted UDP) support
1.6.0 | Added the --encrypted option to demonstrate using Vega's new TLS encryption included in CFR008. Replaced tabs with spaces. Added streaming support (TCP and UDP)
1.4.1 | Uses ioctl() to set baud rate for MacOS 11 Big Sur PVWR command uses int string instead of hex string CAPI connect() returns an error code for failed serial port connections
1.4.0 | AR Demo builds on Linux and Mac
1.3.0 | Added the AR Demo (Windows)
1.2.0 | Improved readme and doxygen generation
1.1.0 | Replaced CMake build with make and visual studio builds