Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

zigmeshcore

zigmeshcore is a Zig implementation of the core MeshCore packet protocol. It provides packet encoding and decoding, cryptographic primitives, identity and group messaging, packet scheduling, radio integration, and a high-level mesh node API.

The library is designed for embedded and native applications. Protocol data uses fixed-capacity storage, and platform-specific behavior is supplied through small type-erased interfaces.

Current version: 0.1.0

Requirements

  • Zig 0.16.0 or newer
  • A radio implementation when using the dispatcher or high-level mesh API

The package has no external Zig dependencies.

Add the dependency

Add zigmeshcore to your project's build.zig.zon. For a local checkout:

.dependencies = .{
    .zigmeshcore = .{
        .path = "../zigmeshcore",
    },
},

Then import the module in build.zig:

const zigmeshcore = b.dependency("zigmeshcore", .{
    .target = target,
    .optimize = optimize,
});

exe.root_module.addImport("zigmeshcore", zigmeshcore.module("zigmeshcore"));

In application code:

const mesh = @import("zigmeshcore");

Packet example

The Packet type stores decoded packet fields and serializes them into the MeshCore wire format.

const std = @import("std");
const mesh = @import("zigmeshcore");

pub fn main() !void {
    var packet: mesh.Packet = .init();
    packet.header =
        (mesh.constants.PAYLOAD_TYPE_ACK << mesh.constants.PH_TYPE_SHIFT) |
        mesh.constants.ROUTE_TYPE_DIRECT;
    packet.payload[0..4].* = .{ 1, 2, 3, 4 };
    packet.payload_len = 4;

    var encoded: [mesh.constants.MAX_TRANS_UNIT]u8 = undefined;
    const encoded_len = packet.writeTo(&encoded) orelse
        return error.InvalidPacket;

    var decoded: mesh.Packet = .init();
    if (!decoded.readFrom(encoded[0..encoded_len]))
        return error.InvalidPacket;

    std.debug.assert(
        decoded.getPayloadType() == mesh.constants.PAYLOAD_TYPE_ACK,
    );
}

Packet.writeTo returns null if the packet is invalid or the destination is too small. Packet.readFrom returns false for malformed or unsupported input.

High-level mesh API

Mesh connects the protocol implementation to application-owned platform services:

  • Radio handles raw frame transmission and reception.
  • PacketManager owns packets and the inbound and outbound queues.
  • Clock provides monotonic time.
  • RealtimeClock provides Unix time for advertisements.
  • RNG supplies random bytes.
  • Tables tracks packets used for duplicate detection.
  • Handler receives mesh events and supplies peer and channel lookups.
  • LocalIdentity supplies Ed25519 signing and X25519 agreement operations.

Create concrete implementations, wrap them with each interface's init function, and pass the resulting interfaces to Mesh.init. Call begin once, then call loop regularly from the application's event loop.

var node: mesh.Mesh = .init(
    mesh.Radio.init(&radio_impl),
    packet_pool.interface(),
    mesh.Clock.init(&clock_impl),
    rng_impl.rng(),
    mesh.RealtimeClock.init(&realtime_impl),
    mesh.Tables.init(&tables_impl),
    local_identity,
    mesh.Handler.init(&handler_impl),
);

try node.begin();

while (true) {
    try node.loop();
}

The exact method requirements for each platform interface are documented in the generated API reference and enforced at compile time.

Main features

  • MeshCore packet parsing, validation, hashing, and serialization
  • Flood, transport flood, direct, and zero-hop routing
  • Advertisements, peer datagrams, anonymous datagrams, and group datagrams
  • Acknowledgements, path returns, trace packets, and custom data packets
  • Fixed-capacity packet pools and scheduled inbound and outbound queues
  • Type-erased radio, clock, entropy, RNG, handler, and storage interfaces
  • SHA-256, SHA-512, HMAC, AES-128, X25519, and Ed25519 support
  • Software crypto implementations with replaceable backends
  • Dispatcher statistics, fault tracking, airtime budgeting, and radio recovery

Public modules

The package exports commonly used types and functions at its root. It also exposes focused modules for lower-level access:

  • packet, path, and constants
  • mesh, dispatcher, radio, and packet_manager
  • identity, group_channel, mesh_handler, and mesh_tables
  • hash, cipher, ecdh, and signature
  • rng, entropy, clock, instant, and hex

See src/root.zig for the complete public surface.

Build and test

Run all library and downstream import tests:

zig build test

Generate the API documentation:

zig build docs

The generated documentation is written to zig-out/docs/index.html.

Packet ownership

Packets obtained from a Mesh or PacketManager belong to the caller until they are queued or released. A successful send operation transfers the packet to the outbound queue. If packet creation or sending fails, release any packet still owned by the caller. Do not free or reuse a queued packet.

For simple fixed-capacity storage, use StaticPoolPacketManager(N) or FixedPacketManager(pool_size, outbound_size, inbound_size).

License

zigmeshcore is available under the MIT License. See LICENSE.

About

Zig implementation of the MeshCore packet protocol.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages