Skip to content

Feature: DroneCAN DNA (Dynamic Node Allocation) Server #4

@daijoubu

Description

@daijoubu

Summary

Implement a DroneCAN DNA allocation server in INAV to enable plug-and-play support for peripherals that ship configured for dynamic node allocation (node_id=0).

Background

Many DroneCAN peripherals ship with node_id=0, expecting an allocator to assign them an ID at runtime. Currently, users must manually configure each peripheral's node ID. A DNA server in INAV would automatically handle this.

The DroneCAN specification supports two allocator modes:

  • Non-redundant (single) - Simple, suitable for flight controllers
  • Redundant (Raft) - Complex, for multi-allocator fault-tolerant networks

INAV should implement non-redundant mode - the spec explicitly states this is valid.

How DNA Allocation Works

1. Anonymous node (node_id=0) broadcasts Allocation request
   - first_part_of_unique_id = true
   - unique_id contains first 6 bytes of 16-byte UID

2. Server receives request, echoes back unique_id bytes
   - Node sends next chunk (first_part_of_unique_id = false)

3. After all 16 bytes matched, server assigns node_id
   - Look up existing allocation or assign new ID
   - Broadcast Allocation with node_id set
   - Node becomes active

Data Structures

// Allocation table entry
typedef struct {
    uint8_t unique_id[16];      // Node's unique identifier
    uint8_t node_id;            // Assigned node ID (1-125)
    uint8_t flags;              // Valid flag, etc.
} dnaAllocationEntry_t;

// Server state
typedef struct {
    dnaAllocationEntry_t entries[DNA_MAX_NODES];  // Allocation table
    uint8_t pendingUniqueId[16];    // UID being accumulated
    uint8_t pendingOffset;          // Bytes received so far
    uint8_t nextAvailableId;        // Next ID to assign (counts down from 125)
    timeMs_t lastRequestTime;       // For timeout handling
} dnaServer_t;

#define DNA_MAX_NODES 8             // Support up to 8 dynamic peripherals

Storage: 8 entries × 18 bytes = 144 bytes + state ≈ 170 bytes

Settings

- name: dronecan_dna_server
  description: "Enable DNA allocation server for plug-and-play DroneCAN peripherals"
  default_value: OFF
  field: dna_server_enabled
  type: bool

- name: dronecan_dna_max_nodes
  description: "Maximum dynamic node allocations"
  default_value: 8
  min: 1
  max: 16

Implementation Phases

Phase Task Effort
1 Data structures 1 hour
2 Request handler 2-3 hours
3 Integration into dronecan.c 1-2 hours
4 Settings 30 min
5 Persistence (optional) 2 hours
6 Testing 2-3 hours
Total 6-10 hours

Files to Create/Modify

  • New: src/main/drivers/dronecan/dronecan_dna_server.c
  • New: src/main/drivers/dronecan/dronecan_dna_server.h
  • Modify: src/main/drivers/dronecan/dronecan.c - Add handler
  • Modify: src/main/fc/settings.yaml - Add settings

Reference Implementation

ArduPilot: libraries/AP_DroneCAN/AP_DroneCAN_DNA_Server.cpp

  • Stores allocations in flash (1KB area)
  • Supports up to 125 nodes
  • Uses FNV-1a hash for fast UID lookup

Target Version

INAV 10.x (optional feature)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions