ULS-DeCoNet Protocol Interface Control Document

Electrical, mechanical and communication interfaces of ULS-DeCoNet — the ULS Devices Connection Network protocol for UART and CAN.

ULSDC-PBICD011125 · version 1.0.5 · issued November 13, 2025
The numbered PDF is the controlled copy: download it from the portal.

Introduction

Purpose

The ULS-DeCoNet (ULS Devices Connection Network) protocol is a comprehensive communication protocol designed for Ultra-precise Location Systems (ULS). It provides a robust, hierarchical network architecture for connecting ULS devices across multiple transport mediums including UART and CAN bus.

Scope

This protocol defines:

  • Device discovery and network management
  • Object-oriented data exchange
  • System control and configuration
  • Firmware update mechanisms
  • Multi-hop routing capabilities
  • Blitz sensor data transmission

Key Features

  • Multi-transport Support: UART (with various framing modes) and CAN bus
  • Automatic Device Discovery: Dynamic network topology with automatic ID allocation
  • Hierarchical Addressing: Support for up to 63 local devices per interface
  • Multi-hop Routing: Packet forwarding through intermediate nodes
  • Object-based Data Model: Structured access to device parameters and data
  • Permission System: Read/write/protected access control for objects
  • Firmware Update: Secure bootloader mode with signature verification
  • Low Overhead: Optimized for embedded systems with limited resources

Terminology

TermDescription
DIDDevice ID - Logical identifier for devices on a network segment (0-63)
LIDLocal ID - Synonym for DID
CIDConnection ID - Identifies which connection interface (0-3)
HBHeartbeat - Periodic keep-alive message
NMNetwork Management - Protocol layer for device discovery
CNConnection - Higher-level protocol for data exchange
BlitzFast sensor data messaging subsystem
MRXMulti-Receiver eXtension - Secondary receiver support
GIMUGround IMU - Inertial Measurement Unit on transmitter
TXCTransmitter Control - Ground unit control interface

Protocol Architecture

Protocol Stack

block-beta
  columns 1
  A["Application Layer\n(Device Objects, Blitz Messages, Config)"]
  B["Connection Layer (CN)\n(Object Access, System Commands, Routing)"]
  C["Interface Layer (IF)\n(Network Management, Device Discovery)"]
  D["Framing Layer\n(UART: ESC/COBS, CAN: Multi-frame)"]
  E["Physical Layer\n(UART, CAN/FDCAN)"]

Design Principles

  1. Layered Architecture: Clear separation of concerns between protocol layers
  2. Transport Agnostic: Core protocol independent of physical medium
  3. Efficient Framing: Multiple framing modes optimized for different scenarios
  4. Scalable Addressing: Support for hierarchical and flat addressing schemes
  5. Robust Error Handling: CRC protection and timeout-based error recovery
  6. Plug-and-Play: Automatic device discovery and ID allocation

OSI Layer Model Mapping

The ULS-DeCoNet protocol maps to the OSI reference model as follows:

OSI LayerULS-DeCoNet ComponentResponsibility
7. ApplicationULSObject, ULSDBase, Blitz MessagesDevice-specific data, sensor measurements, configuration
6. PresentationData Structures (packed structs)Data formatting, byte ordering (little-endian)
5. SessionULSBusConnectionConnection establishment, session management
4. TransportCN Protocol LayerReliable message delivery, routing, flow control
3. NetworkIF Protocol LayerAddressing, device discovery, network management
2. Data LinkFraming (ESC/COBS/CAN)Frame delimiting, error detection (CRC)
1. PhysicalUART/CAN HardwarePhysical signaling, bit transmission

Layer Interactions

Application Data (Objects/Blitz)
        ↓
    [CN Layer]
    - Add routing information
    - Add command type
        ↓
    [IF Layer]
    - Add source LID
    - Add command flags
    - Network management
        ↓
    [Framing Layer]
    - Add frame delimiters
    - Add CRC
    - Escape special characters (UART)
    - Multi-frame splitting (CAN)
        ↓
    [Physical Layer]
    - Transmit bytes/frames

Physical Layer

UART Physical Layer

Specifications:

  • Data Format: 8-N-1 (8 data bits, no parity, 1 stop bit)
  • Baud Rates: Configurable (typically 115200, 230400, 460800, 921600 bps)
  • Voltage Levels: Device-dependent (typically 3.3V or 5V TTL/RS232)
  • Flow Control: Optional hardware (RTS/CTS) or software (XON/XOFF)

Advantages:

  • Simple two-wire interface
  • Widely supported
  • Point-to-point or multi-drop with appropriate hardware

Limitations:

  • Distance limitations without level shifters
  • No built-in arbitration for multi-device scenarios

CAN Physical Layer

Specifications:

  • CAN Version: Classical CAN and CAN-FD (FDCAN) supported
  • Bit Rates:
    • Classical CAN: Up to 1 Mbps
    • CAN-FD: Up to 5 Mbps (data phase)
  • Bus Topology: Multi-drop differential bus
  • Termination: 120Ω termination resistors required at both ends
  • Max Devices: Theoretically unlimited (practical limit ~32-64)
  • Max Distance: Up to 40m @ 1Mbps, longer at lower speeds

Advantages:

  • Multi-master capability with arbitration
  • Built-in error detection and signaling
  • Robust in electrically noisy environments
  • Supports broadcast and multicast

CAN Identifiers:

  • Standard 11-bit identifiers used
  • Identifier structure defined by implementation

The Data Link Layer provides reliable frame transmission with error detection. Different framing modes are supported for UART, while CAN has its own native framing.

UART Framing Modes

The protocol supports four UART framing modes:

RAW Mode (SERIAL_MODE_RAW)

Description: No framing - direct byte transmission

Use Case: Binary data transfer when frame boundaries are managed at higher layers

Structure:

[DATA BYTES...]

Characteristics:

  • No overhead
  • No frame delimiting
  • No error detection at this layer
  • Highest throughput
  • Requires higher layer to manage message boundaries

ESC Mode (SERIAL_MODE_ESC)

Description: Frame delimiting with byte stuffing and CRC-16

Frame Structure:

packet-beta
title "ESC Mode Frame Structure"
0-7: "SOF 0x55 (1 byte)"
8-15: "START_TYPE 0x01 (1 byte)"
16-23: "PAYLOAD (variable, ~1 byte)"
24-31: "CRC_LOW (1 byte)"
32-39: "CRC_HIGH (1 byte)"
40-47: "EOF 0x55 (1 byte)"
48-55: "END_TYPE 0x03 (1 byte)"

Byte Stuffing:

  • If data byte == 0x55, insert 0x02 after it
  • Delimiter 0x55 is escaped when it appears in payload or CRC

CRC Calculation:

  • Algorithm: CRC-16 (polynomial 0x8005, init 0xFFFF)
  • Applied to payload only
  • 2 bytes transmitted (low byte, high byte)

Example:

Original payload: [0x12, 0x55, 0x34]
CRC: 0xABCD

Transmitted frame:
0x55 0x01 0x12 0x55 0x02 0x34 0xCD 0xAB 0x55 0x03

Characteristics:

  • Frame boundaries clearly defined
  • Error detection with CRC-16
  • Variable overhead (depends on data content)
  • Average overhead: ~15-25%

ESC Simple CRC Mode (SERIAL_MODE_ESC_SIMPLE_CRC)

Description: Similar to ESC mode but with simpler 8-bit checksum

Frame Structure:

packet-beta
title "ESC Simple Mode Frame Structure (8-bit Checksum)"
0-7: "SOF 0x55 (1 byte)"
8-15: "START_TYPE 0x01 (1 byte)"
16-23: "PAYLOAD (variable, ~1 byte)"
24-31: "CHECKSUM (1 byte)"
32-39: "EOF 0x55 (1 byte)"
40-47: "END_TYPE 0x03 (1 byte)"

Checksum:

  • Simple byte summation: checksum = Σ(data_bytes) & 0xFF
  • 1 byte transmitted

Characteristics:

  • Faster than CRC-16
  • Lower error detection capability
  • Less overhead than full ESC mode
  • Suitable for low-error-rate environments

COBS Mode (SERIAL_MODE_COBS)

Description: Consistent Overhead Byte Stuffing with CRC-16

Advantages:

  • Predictable framing overhead
  • Zero byte (0x00) used as frame delimiter
  • No data expansion for most byte values
  • Very efficient for binary data

Frame Structure:

packet-beta
title "COBS Mode Frame Structure"
0-7: "SOF 0x00 (1 byte)"
8-15: "COBS CODE (1 byte)"
16-79: "ENCODED DATA (variable, ~8 bytes)"
80-87: "CRC_LOW (1 byte)"
88-95: "CRC_HIGH (1 byte)"
96-103: "EOF 0x00 (1 byte)"

COBS Encoding Algorithm:

  1. Packet is divided into blocks separated by zero bytes
  2. Each block is preceded by a code byte:
    • Code byte = number of non-zero bytes following + 1
    • Maximum block size = 254 bytes
    • Code byte 0xFF means 254 non-zero bytes follow

Example:

Original data: [0x45, 0x00, 0x00, 0x2C, 0x4C]

COBS encoded: [0x02, 0x45, 0x01, 0x03, 0x2C, 0x4C]
              ^^^^^ ^^^^  ^^^^  ^^^^^ ^^^^^^^^^^
              code  data  code  code  data data

With frame delimiters:
0x00 0x02 0x45 0x01 0x03 0x2C 0x4C [CRC_L] [CRC_H] 0x00

COBS Characteristics:

  • Overhead: +1 byte per 254 bytes + frame delimiters
  • Maximum overhead: ~0.4% + fixed overhead
  • Excellent for binary protocols
  • No byte escaping needed
  • Efficient zero-crossing detection

CRC Calculation in COBS:

  • CRC-16 calculated on original unencoded data
  • CRC bytes are COBS encoded with the data

CAN Framing

CAN bus has built-in framing at the hardware level, but ULS-DeCoNet adds an additional application-level framing layer for large messages.

Single-Frame CAN Messages

Structure:

packet-beta
title "Single-Frame CAN Message (8-byte data field)"
0-7: "CMD (1 byte)"
8-15: "SRC (1 byte)"
16-23: "(varies) (1 byte)"
24-87: "PAYLOAD (variable, ~8 bytes)"

Field Description:

  • Byte 0 (CMD): Command type (IF layer command)
  • Byte 1 (SRC): Source device ID (bits 0-5), connection ID (bits 6-7)
  • Bytes 2+: Command-specific payload

Used for:

  • Network management messages (HB, REQUEST_ID, SET_ID)
  • Blitz messages (up to 10 bytes payload)
  • Short system commands

Multi-Frame CAN Messages

For messages larger than can fit in a single CAN frame, multi-frame protocol is used.

Frame Structure:

packet-beta
title "Multi-Frame CAN Message"
0-7: "CMD (1 byte)"
8-15: "DID (1 byte)"
16-23: "FRMCTL (1 byte)"
24-95: "PAYLOAD (variable, ~9 bytes)"

FRMCTL byte: Bit 7 = End-of-message flag (1 = last frame); Bits 6-0 = Frame sequence number (0–127)

Multi-Frame Protocol:

  1. Frame Sequence: Frames numbered 0, 1, 2, … N
  2. Last Frame Marker: Frame N has bit 7 set (value = N | 0x80)
  3. Payload per Frame: 9 bytes (DLC = 11, minus 3 header bytes)
  4. Frame Pool: Receiver maintains a pool of 256 frame buffers
  5. Timeout: Device timeout of 128 frames worth of time

Transmission Algorithm:

total_frames = ceil(message_len / 9)
for frame_num in 0..total_frames-1:
    can_frame.data[0] = CMD
    can_frame.data[1] = SRC_DID
    can_frame.data[2] = frame_num
    if frame_num == total_frames-1:
        can_frame.data[2] |= 0x80  // Mark last frame
    copy up to 9 bytes to can_frame.data[3..11]
    send_can_frame()

Reception Algorithm:

On receiving CAN frame:
    1. Store frame in pool indexed by (DID, frame_num)
    2. Set device timeout
    3. If last_frame_flag:
        a. Verify all frames 0..N received
        b. Reconstruct message from frames
        c. If complete: process message
        d. If incomplete: log missing frames, discard
        e. Free pool entries for this DID

Frame Pool Management:

  • Pool Size: 256 frame slots
  • Device Table: 64 device entries with timeouts
  • Timeout Value: CN_CAN_DEV_TIMEOUT = 128 frames
  • Cleanup: On timeout, all frames from device are freed

Example Multi-Frame Message:

Message length: 25 bytes
Frames needed: 3 (9+9+7)

Frame 0: [CMD][DID][0x00][data 0-8]
Frame 1: [CMD][DID][0x01][data 9-17]
Frame 2: [CMD][DID][0x82][data 18-24][pad]
                    ^^^^
                    0x80 | 0x02 = last frame, number 2

Error Handling:

  • Missing frame detection by sequence number gaps
  • Device timeout triggers cleanup
  • Duplicate frames overwrite previous (allows retransmission)
  • Pool full triggers emergency cleanup of timed-out devices

CRC-16 Algorithm

Polynomial: 0x8005 (CRC-16-IBM/ANSI)
Initial Value: 0xFFFF
Table-based implementation for efficiency

uint16_t crc = 0xFFFF;
for each byte in data:
    crc = (crc >> 8) ^ crc16_table[(crc ^ byte) & 0xFF]

Validation:

  • Receiver calculates CRC over received data
  • Valid frame: calculated CRC == 0x0000 (after including received CRC bytes)

Network Layer

The Network Layer (IF Layer) manages device addressing, discovery, and basic packet routing.

Addressing Scheme

Device ID (DID/LID)

Range: 0-63 (6 bits)

ID RangeUsage
0Master device (network controller)
1-62Regular network nodes
63Broadcast address / Uninitialized device

Special IDs:

  • ID 0: Reserved for the master device (typically the main controller or coordinator)
  • ID 63: Used by devices before ID assignment and for broadcast messages

Connection ID (CID)

Range: 0-3 (2 bits)

Identifies which physical connection a device uses when a node has multiple network interfaces.

Combined Routing ID (CNRID):

CNRID = (CID << 6) | DID
       = [CID(2)][DID(6)]

Bits: 7 6 5 4 3 2 1 0
      └─┘ └─────────┘
      CID     DID

Network Management (NM) Protocol

The NM protocol handles device discovery and ID allocation.

Device States

stateDiagram-v2
  [*] --> UNINITIALIZED: Power On (DID=63)
  UNINITIALIZED --> WaitingSetID: Send REQUEST_ID
  WaitingSetID --> OK: Receive SET_ID (DID assigned)
  OK --> OK: Send HB / Timeout

NM Messages

IF_CMD_NM_HB (0x01) - Heartbeat

Purpose: Keep-alive message to announce presence

Structure:

packet-beta
title "IF_CMD_NM_HB (0x01) Heartbeat"
0-7: "CMD 0x01 (1 byte)"
8-15: "SRC (DID) (1 byte)"
16-47: "UID0 (4 bytes)"

Fields:

  • CMD: 0x01
  • SRC: Source device ID
  • UID0: Device unique ID (first 32 bits)

Timing:

  • Send Interval: Every 1000ms (IF_NM_PING_HB_TIMEOUT)
  • Receive Timeout: 3000ms (IF_NM_DVICE_HB_TIMEOUT)
  • Device considered disconnected if no HB received within timeout

Behavior:

  • All devices with assigned ID send periodic HB
  • Master and slaves both participate
  • Timeout detection triggers disconnection callback
IF_CMD_NM_REQUEST_ID (0x03) - Request ID Allocation

Purpose: Device requests ID assignment from master

Structure:

packet-beta
title "IF_CMD_NM_REQUEST_ID (0x03)"
0-7: "CMD 0x03 (1 byte)"
8-15: "SRC 63 (1 byte)"
16-47: "KEY (4 bytes)"

Fields:

  • CMD: 0x03
  • SRC: 63 (uninitialized)
  • KEY: Random 32-bit key derived from device UID

Key Generation:

key = DEVICE_KEY ^ key_counter
where DEVICE_KEY = UID0 ^ UID1 ^ UID2 ^ UID3

Timing:

  • Sent every 100ms + random offset
  • Up to 5 attempts
  • If no master responds, device self-assigns random free ID
IF_CMD_NM_SET_ID (0x04) - ID Assignment

Purpose: Master assigns ID to requesting device

Structure:

packet-beta
title "IF_CMD_NM_SET_ID (0x04)"
0-7: "CMD 0x04 (1 byte)"
8-15: "SRC 0 (1 byte)"
16-23: "NEW_ID (1 byte)"
24-55: "KEY (4 bytes)"

Fields:

  • CMD: 0x04
  • SRC: 0 (master device)
  • NEW_ID: Assigned device ID (1-62)
  • KEY: The key from REQUEST_ID message

ID Allocation Algorithm (Master):

1. Maintain table of active devices (timeout-based)
2. On REQUEST_ID received:
   a. Scan table for first free ID (timeout == 0)
   b. Assign that ID
   c. Send SET_ID with matching KEY
   d. Set timeout for new device

Reception (Requesting Device):

1. Receive SET_ID
2. Verify KEY matches own key
3. If match:
   a. Set DID = NEW_ID
   b. Change state to OK
   c. Send immediate HB
4. If no match:
   Ignore (not for us)
IF_CMD_NM_RESET_ID (0x05) - Reset Device ID

Purpose: Force device to return to uninitialized state

Structure:

packet-beta
title "IF_CMD_NM_RESET_ID (0x05)"
0-7: "CMD 0x05 (1 byte)"
8-15: "SRC 0 (1 byte)"
16-23: "DST_DID (1 byte)"

Note: Defined but not fully implemented in current version

Static ID Assignment

Method: ifSetStaticDID(uint8_t static_did)

Devices can be configured with static IDs (1-62) that bypass the dynamic allocation process.

Usage:

  • Configuration storage in device
  • Fixed topology networks
  • Deterministic addressing requirements

Behavior:

  • Device uses static ID immediately
  • Still sends HB for presence indication
  • Bypasses REQUEST_ID mechanism

Network Topology

The IF layer supports various network topologies:

Star Topology

flowchart TB
  Master["Master (ID=0)"] --> N1["Node (1)"]
  Master --> N2["Node (2)"]
  Master --> N3["Node (3)"]

Characteristics:

  • Single master (ID=0)
  • All slaves connect directly to master
  • Master performs ID allocation
  • Common for UART bus configurations

Multi-Master (CAN)

flowchart LR
  N0["(0)"] --- N1["(1)"] --- N2["(2)"] --- N3["(3)"]
  N0 --- N4["(4)"]
  N3 --- N5["(5)"]
  N4~~~N5

CAN BUS (shared medium)

Characteristics:

  • Any device can be master (first ID=0 or all peer)
  • Peer-to-peer communication possible
  • ID allocation can be distributed
  • Typical for CAN bus configurations

Packet Structure (IF Layer)

packet-beta
title "IF Layer Packet Structure"
0-7: "CMD (1 byte)"
8-15: "SRC_LID (1 byte)"
16-79: "PAYLOAD (variable, ~8 bytes)"

CMD Field (1 byte):

  • Bit 4: Frame type flag
    • 0x00-0x0F: Network management / System commands
    • 0x10-0x1F: Higher layer protocols (CN layer)
  • Bits 3-0: Command code

IF Layer Commands:

CodeNameDescription
0x00IF_CMD_SYSSystem command
0x01IF_CMD_NM_HBNetwork heartbeat
0x02IF_CMD_NM_GET_STATUSGet device status
0x03IF_CMD_NM_REQUEST_IDRequest ID allocation
0x04IF_CMD_NM_SET_IDAssign device ID
0x05IF_CMD_NM_RESET_IDReset device ID
0x06IF_CMD_BLITZBlitz sensor data

Transport Layer

The Transport Layer (CN - Connection Layer) provides routing, object access, and system management.

CN Protocol Overview

The Connection layer adds:

  • Multi-hop routing
  • Object-oriented data access
  • System configuration and firmware update
  • Reliable request-response patterns

Routing Mechanism

Route Table

Routes are stored as arrays of routing IDs (CNRID):

Route = [hop0, hop1, hop2, ..., hopN]

Each hop contains:
  - Bits 7-6: CID (Connection ID)
  - Bits 5-0: DID (Device ID)

Route Direction:

  • Forward Route (command): hop0 = source, hopN = destination
  • Reverse Route (response): route is reversed

CN Packet Structure

packet-beta
title "CN Packet Structure"
0-7: "CMD (1 byte)"
8-15: "SRC_DID (1 byte)"
16-23: "HOP (1 byte)"
24-79: "ROUTE (variable, ~8 bytes)"
80-143: "PAYLOAD (variable, ~8 bytes)"

HOP byte: Bits 7-4 = current hop index; Bits 3-0 = route size

Packet Fields:

  • CMD: CN command type
  • SRC_DID: Original source device ID
  • HOP: Hop counter (high nibble) and route size (low nibble)
  • ROUTE: Array of CNRID values defining path
  • PAYLOAD: Command-specific data

Routing Example

Scenario: Device A (DID=1, CID=0) sends message to Device C (DID=3, CID=2) through Device B (DID=2, CID=1)

Forward Packet (A→B→C):

At A:
  CMD = CN_CMD_GETOBJ
  SRC_DID = 1
  HOP = 0x03 (hop=0, route_size=3)
  ROUTE = [0x01, 0x42, 0x83]
          ^^^^  ^^^^  ^^^^
          A     B     C
          CID=0 CID=1 CID=2
          DID=1 DID=2 DID=3

At B (forwarding):
  - Increment hop: HOP = 0x13 (hop=1, route_size=3)
  - Next destination = ROUTE[1] = 0x42 (DID=2)
  - Forward to CID=1

At C (final destination):
  - hop == route_size-1, packet is for us
  - Process CN_CMD_GETOBJ

Response Packet (C→B→A):

At C:
  CMD = CN_ACK_GETOBJ
  SRC_DID = 3
  HOP = 0x03 (hop=0, route_size=3)
  ROUTE = [0x83, 0x42, 0x01]  // Reversed!
          ^^^^  ^^^^  ^^^^
          C     B     A

Routing process same as forward

Route Discovery

Routes are built dynamically through Explorer messages:

  1. Master sends CN_CMD_EXPLORER with empty route
  2. Each device:
    • Adds its CNRID to route
    • Forwards to all connections
    • Responds with CN_ACK_EXPLORER containing reverse route
  3. Master builds topology map from responses

CN Commands

Command Types

CodeNameDescription
0x10CN_CMD_EXPLORERNetwork exploration
0x11CN_ACK_EXPLORERExplorer response with status
0x12CN_CMD_SYSSystem command
0x13CN_ACK_SYSSystem command acknowledgment
0x14CN_CMD_GETOBJGet object data
0x15CN_ACK_GETOBJObject data response
0x16CN_CMD_SETOBJSet object data
0x17CN_ACK_SETOBJSet object acknowledgment

Explorer Protocol

CN_CMD_EXPLORER (0x10)

Purpose: Discover network topology

Structure:

packet-beta
title "CN_CMD_EXPLORER (0x10)"
0-7: "0x10 (1 byte)"
8-15: "SRC_DID (1 byte)"
16-23: "HOP (1 byte)"
24-87: "ROUTE (variable, ~8 bytes)"

Transmission:

1. Master sends with HOP=0x00, empty route
2. Each device receives:
   a. Append own CNRID to route
   b. If HOP < 15:
      - Increment HOP
      - Forward to all other connections
   c. Send CN_ACK_EXPLORER with reverse route

CN_ACK_EXPLORER (0x11)

Purpose: Respond to explorer with device info

Structure:

packet-beta
title "CN_ACK_EXPLORER (0x11)"
0-7: "0x11 (1 byte)"
8-15: "SRC_DID (1 byte)"
16-23: "HOP (1 byte)"
24-79: "ROUTE (variable, ~8 bytes)"
80-111: "TYPE (4 bytes)"
112-239: "NAME (16 bytes)"

Fields:

  • TYPE: Device type code (uint32_t)
  • NAME: Device name (null-terminated string, max 16 chars)

Object Access

CN_CMD_GETOBJ (0x14) - Read Object

Purpose: Read data from device object

Request Structure:

packet-beta
title "CN_CMD_GETOBJ (0x14) Request"
0-7: "0x14 (1 byte)"
8-15: "SRC_DID (1 byte)"
16-23: "HOP (1 byte)"
24-79: "ROUTE (variable, ~8 bytes)"
80-95: "OBJ_ADDR (2 bytes)"

Fields:

  • OBJ_ADDR: Object address/ID (uint16_t)

Response (CN_ACK_GETOBJ):

packet-beta
title "CN_ACK_GETOBJ (0x15) Response"
0-7: "0x15 (1 byte)"
8-15: "SRC_DID (1 byte)"
16-23: "HOP (1 byte)"
24-79: "ROUTE (variable, ~8 bytes)"
80-95: "OBJ_ADDR (2 bytes)"
96-159: "OBJ_DATA (variable, ~8 bytes)"

Process:

  1. Request routed to target device
  2. Device looks up object by OBJ_ADDR
  3. Check read permission
  4. If OK: respond with object data
  5. If error: no response or error code
CN_CMD_SETOBJ (0x16) - Write Object

Purpose: Write data to device object

Request Structure:

packet-beta
title "CN_CMD_SETOBJ (0x16) Request"
0-7: "0x16 (1 byte)"
8-15: "SRC_DID (1 byte)"
16-23: "HOP (1 byte)"
24-79: "ROUTE (variable, ~8 bytes)"
80-95: "OBJ_ADDR (2 bytes)"
96-159: "OBJ_DATA (variable, ~8 bytes)"

Response (CN_ACK_SETOBJ):

packet-beta
title "CN_ACK_SETOBJ (0x17) Response"
0-7: "0x17 (1 byte)"
8-15: "SRC_DID (1 byte)"
16-23: "HOP (1 byte)"
24-79: "ROUTE (variable, ~8 bytes)"
80-95: "OBJ_ADDR (2 bytes)"

Process:

  1. Request routed to target device
  2. Device looks up object by OBJ_ADDR
  3. Check write permission
  4. If OK: write data, respond with ACK
  5. If error: no response or error code

System Commands

CN_CMD_SYS (0x12) - System Operations

Purpose: Device configuration and firmware update

Structure:

packet-beta
title "CN_CMD_SYS (0x12)"
0-7: "0x12 (1 byte)"
8-15: "SRC_DID (1 byte)"
16-23: "HOP (1 byte)"
24-79: "ROUTE (variable, ~8 bytes)"
80-87: "SYSCMD (1 byte)"
88-151: "SYS_PAYLOAD (variable, ~8 bytes)"

System Sub-Commands:

CodeNameDescription
0CN_SYS_CMD_PINGPing device
1CN_SYS_CMD_SETMODESet operational mode
2CN_SYS_CMD_ERASEErase flash memory
3CN_SYS_CMD_WRITEWrite flash memory
4CN_SYS_CMD_SETSIGNATURESet firmware signature
5CN_SYS_CMD_SAVECFGSave configuration
PING (0x00)

Request:

packet-beta
title "SYS PING (0x00) Request"
0-7: "SYSCMD 0x00 (1 byte)"
8-23: "DEVTYPE (2 bytes)"

Response: Operation result (CN_ACK_SYS)

SETMODE (0x01)

Purpose: Switch between application and bootloader mode

Request:

┌─────────┬──────┐
│ SYSCMD  │ MODE │
│  0x01   │(1 b) │
└─────────┴──────┘

MODE values:
  0 = CN_SYS_MODE_APP (application)
  1 = CN_SYS_MODE_LOADER (bootloader)

Usage:

  • Switch to loader mode for firmware update
  • Requires device reset after mode change
ERASE (0x02)

Purpose: Erase flash memory region

Request:

packet-beta
title "SYS ERASE (0x02)"
0-7: "SYSCMD 0x02 (1 byte)"
8-39: "KEY (4 bytes)"
40-71: "START (4 bytes)"
72-103: "LEN (4 bytes)"

Fields:

  • KEY: Operation authorization key
  • START: Start address in flash
  • LEN: Length to erase (bytes)

Response: Operation result with status code

WRITE (0x03)

Purpose: Write data to flash memory

Request:

packet-beta
title "SYS WRITE (0x03)"
0-7: "SYSCMD 0x03 (1 byte)"
8-39: "KEY (4 bytes)"
40-71: "START (4 bytes)"
72-103: "LEN (4 bytes)"
104-135: "DATA (up to 512 bytes)"

Fields:

  • KEY: Operation authorization key
  • START: Start address in flash
  • LEN: Length to write (bytes)
  • DATA: Data to write

Response: Operation result with status code

SETSIGNATURE (0x04)

Purpose: Set firmware signature information

Request:

packet-beta
title "SYS SETSIGNATURE (0x04)"
0-7: "SYSCMD 0x04 (1 byte)"
8-39: "KEY (4 bytes)"
40-295: "FW version (32 bytes)"
296-551: "LDR version (32 bytes)"
552-583: "FWTIME (4 bytes)"
584-615: "PROGSIZE (4 bytes)"
616-647: "PROGCRC (4 bytes)"

Fields:

  • KEY: Operation authorization key
  • FW: Firmware version string (32 chars)
  • LDR: Loader version string (32 chars)
  • FWTIME: Firmware flashing timestamp
  • PROGSIZE: Program size in bytes
  • PROGCRC: Program CRC32 checksum

Purpose: Store metadata after firmware update completion

SAVECFG (0x05)

Purpose: Save current configuration to non-volatile memory

Request:

packet-beta
title "SYS SAVECFG (0x05)"
0-7: "SYSCMD 0x05 (1 byte)"
8-39: "KEY (4 bytes)"
CN_ACK_SYS (0x13) - System Command Response

Structure:

packet-beta
title "CN_ACK_SYS (0x13)"
0-7: "0x13 (1 byte)"
8-15: "SRC_DID (1 byte)"
16-23: "HOP (1 byte)"
24-79: "ROUTE (variable, ~8 bytes)"
80-87: "RESULT (1 byte)"

Result Codes:

CodeNameDescription
0CN_SYS_OPERATION_UNDEFINEDOperation not defined
1CN_SYS_OPERATION_OKOperation successful
2CN_SYS_OPERATION_ERROROperation failed
3CN_SYS_OPERATION_WRONGKEYInvalid authorization key

Operation Keys

Purpose: Prevent unauthorized firmware modifications

Key Generation:

#define _ULS_OPERATION_KEY 0x24041982

#define DEVICE_KEY (UID0 ^ UID1 ^ UID2 ^ UID3)

uint32_t operation_key = _ULS_OPERATION_KEY;
// Or device-specific key for some operations

Usage:

  • ERASE, WRITE, SETSIGNATURE, SAVECFG require valid key
  • Key validation prevents accidental or malicious operations
  • Each device can have unique key derived from UID

Application Layer

The Application Layer defines device-specific data structures and high-level protocols.

Object Model

Object Architecture

Objects provide structured access to device parameters, configuration, and data.

Object Base Class:

class ULSObjectBase {
    uint16_t id;                      // Object address
    uint16_t size;                    // Size of single element
    uint16_t len;                     // Array length (1 for scalar)
    uint8_t *data;                    // Pointer to data
    const char *name;                 // Object name
    const char *description;          // Object description
    _ulsbus_obj_permissions permission; // Access permission
}

Object Permissions

PermissionValueReadWriteDescription
READONLY0✓✗Read-only data
WRITEONLY1✗✓Write-only (e.g., commands)
READWRITE2✓✓Full access
PROTECTED3✓✓*Requires authorization
CONFIG4✓✓*Configuration parameters
SYSCONFIG5✓✓*System configuration
ADMIN6✓✓*Administrator only

*Note: Protected/Config/Admin levels require additional authorization mechanisms (implementation-specific)

Standard Objects

System Signature Object (0x0001)

Purpose: Device identification and firmware information

Structure:

struct ULSObjectSignature {
    char fw[32];                  // Firmware version
    char ldr[32];                 // Loader/bootloader version
    uint32_t serial[4];           // Device serial number (UID)
    uint32_t progflashingtime;    // Firmware flash timestamp
    uint32_t progsize;            // Program size
    uint32_t progcrc;             // Program CRC32
    uint32_t type;                // Device type code
}; // Total: 128 bytes

Permission: READONLY

Usage:

  • Device identification
  • Firmware version tracking
  • Update verification

Device Base Class

class ULSDBase {
    const char *devname;          // Device name
    const char *typeName;         // Type name string
    uint16_t typeCode;            // Numeric type code
    ULSList<ULSObjectBase> objects; // List of objects
    
    ULSObjectBase* getObject(uint16_t obj_id);
    void setData(uint16_t obj_id, uint8_t *buf);
};

Purpose: Base class for all ULS devices providing:

  • Object management
  • Device identification
  • Configuration storage

Blitz Protocol

The Blitz protocol provides high-frequency sensor data transmission with minimal overhead.

Blitz Packet Structure (IF Layer)

packet-beta
title "Blitz Packet (IF Layer)"
0-7: "CMD 0x06 (1 byte)"
8-15: "SRC_LID (1 byte)"
16-31: "MSG_ID (2 bytes)"
32-95: "DATA (8 bytes)"

Fields:

  • CMD: 0x06 (IF_CMD_BLITZ)
  • SRC_LID: Source device ID
  • MSG_ID: Blitz message type identifier
  • DATA: Message-specific payload (max 8 bytes)

Blitz Message Types

See separate document: ULS-DeCoNet_Blitz_Messages.md for complete message definitions.

Summary of Message Types:

Message IDNameDescription
0x0010XCG1_RX_RAW_MEASURMENTLegacy raw measurement (limited angular range)
0x0011RX_RAW_MEASURMENTRaw measurement with full angular range
0x0012RX_POS_IN_TX_FRAME3D position in transmitter frame
0x0013RX_MRXMulti-receiver information (yaw, distance)
0x0014RX_DACSDACS information with continuous yaw
0x0020GIMU_MEASUREMENTGround IMU measurement (roll, pitch, yaw)
0x0030XX_TXC_IMU_OVERRIDEIMU override for ground unit
0x0031XX_TXC_MAG_OVERRIDEMagnetometer override for ground unit

Blitz Data Flow

Sensor → Measurement → Blitz Packet → IF Layer → Framing → Physical Layer
  ↓
[Status Bits]
[Counter]
[Sensor Data]

Status Bits (common to most Blitz messages):

BitFlagDescription
0CARRIER_OKIR signal detected
1SQ_OKSignal quality OK
2POS_OKPosition estimated
3VEL_OKVelocity estimated
4GU_IMU_OKGround Unit IMU OK
5MRX_OKMRX message received
6MRXDATA_OKMRX calculations OK

Blitz Usage Pattern

Transmitter:

// Construct Blitz message
__uls_blitz_msg_rx_raw_measurmet msg;
msg.status = calculate_status();
msg.counter = counter++;
msg.aX = angle_x_scaled;
msg.aY = angle_y_scaled;
msg.distance = distance_cm;

// Send via IF layer
interface->ifSendBLITZ(
    ULS_BLITZ_MSG_ID_RX_RAW_MEASURMENT,
    (uint8_t*)&msg,
    sizeof(msg)
);

Receiver:

// Set callback
interface->ifclbkBlitzReceived = &onBlitzReceived;

void onBlitzReceived(ULSBusInterface *iface) {
    uint16_t msg_id = iface->ifRxPacket->blitz.msg_id;
    uint8_t *data = iface->ifRxPacket->blitz.data;
    
    switch(msg_id) {
        case ULS_BLITZ_MSG_ID_RX_RAW_MEASURMENT:
            process_raw_measurement(data);
            break;
        // ... handle other message types
    }
}

Application Examples

Read Configuration Object

Scenario: Read object 0x0100 from device at DID=5

// Prepare route (direct connection)
uint8_t route[] = {0x05}; // DID=5, CID=0

// Send GET request
connection->cnSendGetObject(
    route,              // Route array
    1,                  // Route size (hops)
    0x0100             // Object address
);

// Response handled in callback
connection->cnclbkObjReceived = &onObjectReceived;

void onObjectReceived(ULSBusConnection *cn) {
    uint16_t obj_addr = *((uint16_t*)&cn->cnRxPacket->pld[cn->cnRxPacket->hop & 0xF]);
    uint8_t *obj_data = &cn->cnRxPacket->pld[(cn->cnRxPacket->hop & 0xF) + 2];
    
    // Process object data
    process_config(obj_addr, obj_data);
}

Firmware Update Procedure

1. Switch to Loader Mode:
   cnSendSysSetMode(route, hops, CN_SYS_MODE_LOADER)
   → Device resets into bootloader

2. Erase Flash:
   cnSendSysErase(route, hops, key, start_addr, length)
   → Wait for CN_ACK_SYS with OK result

3. Write Firmware (in blocks):
   for each 512-byte block:
       cnSendSysWrite(route, hops, key, addr, 512, data)
       → Wait for CN_ACK_SYS with OK result
       addr += 512

4. Set Signature:
   cnSendSysSetSignature(route, hops, key, fw_ver, ldr_ver, 
                         timestamp, size, crc)
   → Device validates and stores metadata

5. Save Configuration:
   cnSendSysSaveConfig(route, hops, key)
   → Device commits changes

6. Switch to Application Mode:
   cnSendSysSetMode(route, hops, CN_SYS_MODE_APP)
   → Device resets into new firmware

Security Considerations

Authentication

Operation Keys:

  • System operations require 32-bit keys
  • Key validation prevents unauthorized firmware modification
  • Keys can be device-specific (derived from UID)

Recommendations:

  • Change default _ULS_OPERATION_KEY for production
  • Implement challenge-response for critical operations
  • Consider encryption for sensitive data

Access Control

Object Permissions:

  • Enforce read/write restrictions
  • Protected objects require authorization
  • Validate permissions before object access

Firmware Integrity

CRC Validation:

  • Firmware CRC32 stored in signature
  • Bootloader verifies before execution
  • Prevents corrupted firmware execution

Signature Verification:

  • Firmware version and timestamp tracking
  • Size validation
  • Metadata consistency checks

Network Security

ID Allocation:

  • Master controls ID assignment
  • Duplicate ID detection
  • Timeout-based cleanup

Routing:

  • Route validation
  • Hop count limits prevent loops
  • Source verification

Best Practices

  1. Use static IDs for critical devices
  2. Implement authentication for system commands
  3. Validate all inputs at object level
  4. Use CRC checking on all transports
  5. Implement timeouts for all operations
  6. Log security events for audit trails
  7. Encrypt sensitive data if required by application
  8. Protect operation keys in device storage


References

  • ULS-DeCoNet Source Code: ULSOpenLib/
  • ULSDC-PBDS021125 - ULS-DeCoNet CAN Transport Specification
  • ULSDC-PBDS031125 - ULS-DeCoNet UART Transport Specification
  • ULSDC-PBDS041125 - ULS-DeCoNet Quick Reference Guide
  • ULSDC-PBDS051125 - ULS-DeCoNet Blitz Messages Specification

Copyright © 2020-2026 UAVLAS <www.uavlas.com>
License: GNU Lesser General Public License v3.0+
Project: ULS Devices Connection Network (ULS-DeCoNet)