Repository navigation
Encapsulate libudpard in a jarnax::cyphal::Interface implementation #61
Copy link
Copy link
Open
Description
Activity
Progress update —
CyphalUDPInterfacecore encapsulation (commit de96db7 ondevelop):Done
O1HeapPoolmoved fromnucleo-cyphalintojarnax-cyphal-udp, implementscore::AllocatorwithUdpardMemoryResource/UdpardRxMemoryResourcesfactories (64 KiB arena).- Socket abstraction
modules/jarnax/source/include/jarnax/services/CyphalUDPSocket.hpp—udp::Endpoint,DatagramHandler,Socket(Join/Leave/Send) plusMicrosecondClockso the generic module stays cortex-free and host-testable. CyphalUDPInterfacein the newCyphalUDPInterface.*ppfiles — implements all 6Interfacevirtuals +Loopable::Execute(TX drain) +DatagramHandler::OnDatagramReceived(RX dispatch). Pooled subscriptions (8), RPC ports (8), per-port TID counters (16), remembered request TIDs (8), fixed Nominal priority,udpardGatherscratch,TransportStatistics.nucleo-cyphalnow depends onjarnax-cyphal-udp;CyphalAppusesjarnax::cyphal::O1HeapPool.- GoogleTest suite:
gtest-cyphal-o1heappool+gtest-cyphal-udpinterface(12 tests) withMockUDPSocket(gmock). RX datagrams are produced by a localUdpardTxinstance — no hand-built wire formats. Covers lifecycle, Join-once service group, publish/request/respond, TX-error stats, subject and RPC round-trips, unknown/bad datagram handling. Also fixed stale over-alignment expectation.
Verification
on-host-native-llvm21/21,on-host-native-clang21/21,on-target-cortex-m4-gcc-arm-none-eabiandon-target-cortex-m7-gcc-arm-none-eabiall pass (62/62injarnax-cyphalalone). Cross builds clean.PLAN.mdupdated (steps 4,5,7 marked complete);GOTCHAS.mdappended with 6 new gotchas (empty-transferudpardGather,PortIdnon-assignable, client-group response routing, o1heap alignment, etc.).
Remaining per #61
- Hypha adapter implementing
Socket - Refactor
CyphalAppontoCyphalUDPInterface(remove inline udpard plumbing) - Hardware verification via
pylink-square-mcp/RTT +yactui(heartbeat, GetInfo server/client) - Final
./scripts/build-all-presets.shand PR todevelop
Commit:
de96db7— pushed todevelop(branchdevelopahead ofmacmini/developby 3). Noudpard.htypes leak into app headers yet (full removal on app refactor).- added a commit that references this issue
on Aug 23, 2026 Progress update — socket abstraction replaced with a
udp::Dispatcher(commit8982428on branchissue-61):Done since last update
- Replaced the
udp::Socketabstraction withudp::Dispatcher(Join/Leave/Send);CyphalUDPInterfacenow takes aDispatcherand incoming datagrams are pushed in by the dispatcher implementation (libhypha on target). - Added application-owned
nucleo::cyphal::HyphaUdpDispatcher, which adapts libhypha's UDP callback and multicast TX/RX preparation toudp::Dispatcher.Leave()stops local dispatching because libhypha has no unprepare API. - GoogleTest suite migrated to
MockUDPDispatcher(gmock); still 62/62 injarnax-cyphalalone.
Verification
- Branch
issue-61created offdevelop(currently31b1f9f) with the single commit8982428. on-host-native-llvm21/21,on-host-native-clang21/21,on-target-cortex-m4-gcc-arm-none-eabiandon-target-cortex-m7-gcc-arm-none-eabiall pass/build clean.
Remaining per #61
- Refactor
CyphalAppontoCyphalUDPInterface(remove inline udpard plumbing) - Hardware verification via
pylink-square-mcp/RTT +yactui(heartbeat, GetInfo server/client) - Final
./scripts/build-all-presets.shand PR todevelop
- Replaced the
Merged via PR #66 (
e0a8eafondevelop) — theudp::Dispatcherrefactor is in. Branchissue-61deleted.Remaining per #61:
- Refactor
CyphalAppontoCyphalUDPInterface(remove inline udpard plumbing) - Hardware verification via
pylink-square-mcp/RTT +yactui(heartbeat, GetInfo server/client) - Final
./scripts/build-all-presets.shpass before closing
- Refactor
Metadata
Metadata
Assignees
Labels
No labels
Plan: Encapsulate libudpard in a
cyphal::InterfaceimplementationSummary
Extract the libudpard plumbing currently inlined in
applications/nucleo-cyphal/source/CyphalApp.cpp(~400 of 795 lines) into a reusablejarnax::cyphal::Interfaceimplementation (UdpInterface), so any application can use Cyphal/UDP without touching udpard directly. This is mostly an extraction/refactor, not greenfield work.Current state
jarnax::cyphal::Interface(modules/jarnax/include/jarnax/cyphal/Interface.hpp:80) is defined with a GoogleMock (MockInterface.hpp), andNode/Serviceare already tested against the mock — but no concrete implementation exists.third-party/libudpard(plain C99, compiles on host).CyphalApp.cppalready does all the udpard work inline:UdpardMemoryResourcebridge (UdpardAlloc/UdpardFree)ProcessTransmitQueue)Work breakdown
PortId↔ udpard ports, negated error codes →core::Status, timestamps)UdpInterfaceimplementationListen/Remove, dispatcher wiring, per-port transfer-ID counters, fragment gathering viaudpardGather, statistics forGetStatisticsCyphalApponto itTotal estimate: 4–7 days.
Impedance mismatches (design decisions)
Send(Metadata&, SerializedMessage)carries no priority or transfer-ID — udpard requires both. Plan: default priority = Nominal and keep internal per-port tid counters inside the implementation (avoids breakingMetadata,Node,Service, and their tests). ExtendingMetadatacan come later if needed.Listener::OnReceivetakescore::Span; udpard deliversUdpardFragmentlists → one copy bounded by extent, plus a defined buffer ownership policy.Listen()must join the subject's multicast group in hypha (and add the MAC filter);Remove()must leave it. The socket abstraction owns this.UdpardMemoryResourceinstead of reaching forO1HeapPool::Instance().TransportStatisticsalready has the array shape for more later.Steps
issue-<N>trackingdevelopmodules/jarnaxjarnax::cyphal::udp::UdpInterface(implements all 6 virtuals +jarnax::Loopablefor TX drain / RX dispatch)CyphalAppto useUdpInterface; verify on hardware via pylink/RTTcmake --workflow --preset on-host-native-llvm,on-host-native-clang, and both cross presets; then./scripts/build-all-presets.shAcceptance criteria
CyphalAppincludes noudpard.h)