SightLine Applications Command, Control, and Script API  v3.3
SightLine Applications Command, Control, and Script API

Introduction

This document describes two distinct but related methods for controlling SightLine Applications video stabilization and tracking systems:

The packet-based messaging protocol outlined in this document is valid for this release and any prior release. Changes between revisions are noted throughout the document. Lua script support is new in the 2.23 release.

Both methods of control utilize similar data formats and concept of operations. The remainder of this document describes details specific to the two control methods (see Command and Control Protocol and Script API). For detailed descriptions of messages and functions, see Common Features of Protocol and API.

Common Features of Protocol and API

See Message Identifiers section for a list of data structures in this API, or see the corresponding list of Lua Script Functions.

Protocol messages and API data structures have a 1-to-1 relationship. For example, the message defined by SLASetStabilizationParameters_t defines a corresponding data structure that may be used by the API function SLASetStabilizationParameters in a Lua script. Except where specified, the terms "messages" and "data structures" are used interchangeably in the remainder of this document.

Bit and Byte Order

Messages are defined as a list of parameters. The basic data types and sizes used for each parameter are:

Type Length in bytes Description
u8 1 Unsigned 8-bit integer
s8 1 Signed two's-complement 8-bit integer
u16 2 Unsigned 16 bit integer
s16 2 Signed two's-complement short
u24 3 Unsigned 24-bit integer
u32 4 Unsigned 32-bit integer
s32 4 Signed two's-complement 32-bit integer
u64 8 Unsigned 64-bit integer
s64 8 Signed two's-complement 64-bit integer
u16be 2 Unsigned 16-bit integer (in MSB-LSB order)
u32be 4 Unsigned 32-bit integer (in MSB-LSB order)

All multi-byte fields are encoded with the Least Significant Byte (LSB) first, followed by MSB.

Some parameters are defined as bit values within a larger basic type. In these cases, all bits are right aligned. For example, a parameter of type u8 with value 0xC9 (hexadecimal notation) has an upper nibble with value 'C' and a lower nibble with value '9'. The upper nibble, 'C', has the binary representation '1100' and the lower nibble '9' is '1001' in binary. Thus a parameter of type u8 with value 0xC9 has the following bit pattern:

7 6 5 4 3 2 1 0
1 1 0 0 1 0 0 1

Variable Naming Convension

Strings and Arrays

The variable length types SVPEndString_t and SVPLenString_t are two different ways that names and other text strings are represented. For protocol messages, the length of SVPEndString_t is determined by the length of the packet (with the string length filling in 0 to 255 bytes needed to bring the packet length to the value specified in the message header). For API data structures, an array of 255 bytes is used to store a null-terminated string – some of the 255 bytes may be unused depending on the actual length of the string. SVPLenString_t uses a u8, SVPLenString_t::len, followed immediately by a text string. For protocol messages, only the number of bytes specified by SVPLenString_t::len are part of the message. For API data structures, space is reserved for the maximum length string, but only the appropriate number of bytes is utilized.

Two kinds of arrays are also referenced in the data structure documentation. Fixed-length arrays of a sub-struct, currently used only for SLASetUserPalette_t and SLACurrentUserPalette_t, indicates a repetition of the struct. For example, SLASetUserPalette_t::palette contains 256 y-u-v triplets. Variable length arrays similarly indicate a repetition of the struct. However, the actual number of repetitions is controlled by the u8 immediately preceding the array. See, for example, SLATrackingBoxPixelStats_t::stat which contains up to 255 sets of statistics elements with the actual number present represented by the preceding value SLATrackingBoxPixelStats_t::numTracks.

Time Codes

Throughout the document certain packets may refer to time codes. Each time code shall be a 64-bit unsigned integer representing the micro-second time at which this frame was captured. The time code is based on the internal high resolution clock. This clock is initialized to 1970-01-01 00:00:00.0 on start-up. The clock can be synchronize with a Universal Time Code via SLASetMetadataValues_t::utcTime.

The UTC time is not preserved during a power cycle to the SightLine hardware.

Coordinate Systems

Image coordinates are referenced as row and column coordinates, with the origin in the upper left corner of the frame. Increasing column values are to the right, and increasing row values are downward in the frame. Unless otherwise identified, a video frame is 640 pixels wide and 480 pixels high.

Application Bits

System features are controlled through application bits (AppBits) in a license file unique to each hardware platform. See SLAVersionNumber_t.

Command and Control Protocol

Individual getter commands have been replaced with a single generic getter command of SLAGetParameters_t. This command takes the corresponding setter command's message ID as an input. For example, SLAVersionNumber_t can be returned by using either SLAGetVersionNumber_t or the new way using SLAGetParameters_t with SLAGetParameters_t::id set to 0x00. The complete message would look like: 0x51, 0xAC, 0x03, 0x28, 0x00, 0x73.

The objective in making this change is to reduce the number of new message IDs required in the future. Currently, when a new feature is implemented, the following new commands are implemented: a setter, getter, and a result reply. With 2.17 and future releases, only a new setter and result reply will be needed. Most of the getter functions do not require any additional parameters. A single generic getter has been implemented, which uses the setter command ID as its parameter.

Sample Code

For development of C/C++ command and control applications, SightLine provides sample code for writing applications that implement our protocol. This is primarily available in slfip.h and slfip.cpp and can be downloaded as part of the Example Code sample. This code can be used as a starting point for writing your own application and is also useful for conforming to any changes to the protocol that may take place over time. SightLine Command and Control Example Code and Resources can be downloaded at https://sightlineapplications.com/command-control/.

Command Packets

Command Packet Header

Every command packet sent over a serial or Ethernet connection begins with a pair of signature header bytes (0x51, 0xAC) and a length field. The value specified in the length field is the number of bytes that follow with the packet up to and including the checksum. The length field can be 1 byte or 2 bytes long depending on the length of the command packet. If the command packet length is greater than 127 bytes, then the length field occupies 2 bytes.
The following tables specify how the length field is encoded:

Normal packets (Length<128 bytes):

Header1 Header2 Length Message ID Message-dependent Checksum
0x51 0xAC len id data_bytes... cs

Extended length packets (Length>=128 bytes):

Header1 Header2 Length Low Length High Message ID Message-dependent Checksum
0x51 0xAC xx yy id data_bytes... cs

xx: Lower 7 bits of the length. Bit 7 must be set to 1.
yy: Upper bits of the length.

To obtain the length from xx and yy, here is a code snippet in C language:

Length = (yy << 7) | (xx & ~0x80);

For example, 128 bytes is encoded as xx: 0x80, yy: 0x01.

NOTE: two byte length field could be used for packets whose length is less than 128.
Checksum is calculated for the data highlighted in bold above (Message ID + Message-dependent data bytes).

Example of packet with length = 3

Header1 Header2 Length Message ID Mode Checksum
0x51 0xAC 0x03 0x01 0x020xBC

NOTE: Command Packets are not the same as UDP packets. A UDP packet sent to the Ethernet command port can contain one or more Command Packets.

Message ID

Every command packet has a Message ID (previously known as the Type or Type ID). This is a 1 byte field. The message ID can also be used to query for state using SLAGetParameters_t.

Message-dependent Data

Each packet may have 0 or more bytes of payload data. This data is defined for each message.

Checksum Calculation

Checksums are calculated over the bytes following the length field, up to but not including the checksum field. To ensure proper packet framing, if the checksum fails, the bytes following the faulty signature header (0x51, 0xAC) are be scanned for the signature header bytes again.

NOTE: The checksum is also necessary when communicating over Ethernet with SightLine hardware.

The checksum can be calculated using the following table and pseudo code:

const int8 crc8_Table[ ] =
{
0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,
17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53
};
crc = 0x01;
for ( each byte_Value between length and checksum fields)
{
crc = crc8_Table[ crc ^ byte_Value ] ;
}

Checksum Calculation Example

Data Description Action CRC
0x51 Header 1 Ignored 0x01
0xAC Header 2 Ignored 0x01
0x02 Length Ignored 0x01
0x07 Message ID Used 0x01 ^ 0x07 = 0x06
Look up result - - Table[6] = 221 (0xDD)

CRC should equal 221.

Communication

Serial Ports

Command and Control is available on most serial ports. Serial port parameters are configured to 57600 Baud, 8 data bits, 1 stop bit, no parity, and no handshake by default. See SLASetPortConfiguration_t for information on additional modes supported. Refer to the specific hardware ICD to determine if serial port is 3.3V TTL or RS-232C level signals.

Ethernet

Command and control is also available over Ethernet. All commands can be sent as a UDP packet (containing one or more command packets) to the IP address of the system on port 14001. All replies will be sent to the IP address of the sender on port 14002. These ports can be changed using SLASetNetworkParameters_t.

User Program Communication

Command and control is also available for internal ARM programs, which needs to communicate to VideoTrack (e.g. an RTSP Server). One or more commands can be sent as a UDP packets to VideoTrack on port 14003. All replies are sent by VideoTrack on the same socket that it received the command packet from the client.

Multiple clients can communicate with VideoTrack simultaneously on port 14003. It is important to remember that responses will be sent to the last program that communicated with VideoTrack. This can have implications for ARM applications that receive commands from SLACommandPassThrough (0x3D) while using RTSP Video Output.

IP Address Assignment

The static IP address of the SightLine hardware can be set using SLASetNetworkParameters_t. If a static IP address has not been set, the SightLine hardware will attempt to obtain an IP address using DHCP. If DHCP fails, the system will use a specific link local (RFC 3927) type address 169.254.1.180.

Summary Table

If Static... Else try DHCP... If DHCP Fails try...
IP Address User Defined DHCP Defined 169.254.1.180 or 169.254.1.181
Subnet Mask User Defined DHCP Defined 255.255.0.0
Gateway User Defined DHCP Defined NOT DEFINED

NOTE: Use this table as guidance for setting the IP address of your PC so that it is on the same subnet as the SightLine hardware.

Network Port Numbers

The range of valid port numbers is 1 through 65536. 0 is reserved and is either invalid or indicates no change, depending on the specific message. Before assigning a number, make sure the port is not already in use. Multiple sockets using the same port can result in errors.

Network Ports commonly used by SightLine

Port Description
14001 Inbound commands on SightLine HARDWARE
14002 Input reply port on PC
51000 SLDISCOVER Listen Port
5004 Default port for RTP-MJPEG
15004 Default port for MPEG2-TS H.264
21 FTP port
23 SSH port
52000 Watchdog timer port for diagnostics information
14003 Inbound commands on SightLine HARDWARE from internal ARM programs
14004 RTSP to VideoTrack command port
45001 TCP port number for upgrade.
65100 Acquarius protocol
554 RTSP listen port
8008 RTSP to VideoTrack UDP video (Net0)
8010 RTSP to VideoTrack UDP video (Net1)

SightLine Hardware Types

See also SLAVersionNumber_t.

Hardware Type Description ID
2000 2000-OEM 0
1500 1500-OEM 7
Upgrade Upgrade Server 10
3000 3000-OEM Revision B 12
3000C 3000-OEM Revision C 14
4000 4000-OEM 18

Host Name

The default system host name takes the form SLA<Hardware Type>_<MAC>, where MAC is last 3 octets of the MAC address. Example: SLA1500_fe01cd

Start Up Behavior

On start up, the SightLine hardware will send the SLAVersionNumber_t packet after the 3rd frame is acquired. At this point the system is ready to receive commands.

Network Display ID

Throughtout the API, many commands and replies use dispID. This refers to a Network Display ID more commonly called Net0 and Net1. Video may be sent to one or both locations. see SLASetEthernetDisplayParameters_t.

1500-OEM - This field is ignored or can be set to 0x0000.

3000-OEM & 4000-OEM - Configured for dual channel using Application Bits. If not present, then command may apply to both Network Displays. Some exceptions apply (e.g. SLASetSDRecordingParameters_t)

dispID Network Display ID
0x0002 Net0
0x0080 Net1
0x0082 Net0 & Net1

Script API

Each data structure named SLA<name>_t has a corresponding Lua script function named SLA<name> that takes the following parameters:

  1. void *context – System supplied script handle
  2. SLA<name>_t *v – Input structure reference
  3. SVPOut_t *out – Output structure reference
  4. u16 nElements – Number of elements in input structure

In the example below, the function that performs a system reset is SLAResetAllParameters, which references SLAResetAllParameters_t as the second parameter. SVPOut_t provides a convenient mechanism to access the return value of the function.

NOTE: nElements should be an unchanging value for any software release, but may change if additional elements are added to messages in future releases.

typedef struct {
union {
SLAGetVersionNumber_t GetVersionNumber;
SLAResetAllParameters_t ResetAllParameters;
SLASetStabilizationParameters_t SetStabilizationParameters;
SLAGetStabilizationParameters_t GetStabilizationParameters;
SLAResetStabilizationParameters_t ResetStabilizationParameters;
//
// all other data structure types included here
//
SLAStreamingControl_t StreamingControl;
};
} SLAUnion;
typedef struct SVPOut_t {
s32 type;
u32 outLen;
SLAUnion *out;
bool isFipEx;
} SVPOut_t;

The example below illustrates how to call a function and correctly pass context, out, and nElements. Since functions may return unexpected types, verify out.type before accessing out.out.

-- Global frame count, incremented in SLPostAnalyze
local ffi = require("ffi")
local framecount = 0
function SLPostAnalyze( _vtstate, cameraIndex )
framecount = framecount + 1
if framecount == 2 then
local gv = ffi.new("SLAGetVersionNumber_t")
local out = ffi.new("SVPOut_t")
local rv = ffi.new("SLAUnion");
out.out = rv;
ffi.C.SLAGetVersionNumber(_vtstate, gv, out, ffi.sizeof(gv))
if out.type == ffi.C.VersionNumber then
print("Version is ", rv.VersionNumber.swMajor, ".", rv.VersionNumber.swMinor, ".", rv.VersionNumber.swRelease)
end
end
end

For a complete list of functions in the API, see Lua Script Functions.

NOTE: Append ULL to 64 bit integer values. Eg. setTime.utcTime = 0x54deab2bd7500ULL

See EAN-SLA-Script-Development.pdf for instructions on how to configure, setup, and use Lua scripts on SightLine Applications systems.