///|
/// F1 lockwire live-capability completion surface.
///
/// Enumerates the six native capabilities that previously blocked the
/// PROFINET/EtherCAT rawnet → lockwire session bindings: local_mac discovery,
/// last_rx receive timestamp, non-blocking wrapper, monotonic_millis,
/// sleep_until_micros, and Windows realtime thread affinity. Each capability
/// ships a native C ABI (Windows/Linux platform-gated) and a wasm-gc fallback
/// that returns not-implemented, so `moon test` on wasm-gc proves the catalog
/// and policy shape while real live I/O stays gated by Blocked hardware tasks.
///|
pub(all) struct NativeLiveCapability {
id : String
capability_family : String
native_symbol : String
fallback_returns_not_implemented : Bool
implemented_probe_symbol : String
platform_scope : String
unblocks_binding : String
} derive(Eq, Debug)
///|
pub(all) struct NativeLiveCapabilityReport {
capability_count : Int
clock_capability_count : Int
rt_affinity_capability_count : Int
npcap_live_ext_capability_count : Int
raw_socket_live_ext_capability_count : Int
local_mac_capability_count : Int
last_capture_capability_count : Int
nonblock_capability_count : Int
all_fallbacks_return_not_implemented : Bool
all_implemented_probes_present : Bool
live_evidence_present : Bool
evidence_label : String
} derive(Eq, Debug)
///|
pub fn native_live_capability_catalog() -> Array[NativeLiveCapability] {
[
{
id: "native.live-capability.monotonic-millis",
capability_family: "clock-millis",
native_symbol: "lockwire_native_monotonic_millis",
fallback_returns_not_implemented: true,
implemented_probe_symbol: "ffi_monotonic_millis",
platform_scope: "windows+linux+unsupported-fallback",
unblocks_binding: "profinet.rawnet.clock.to_lockwire_highres_clock",
},
{
id: "native.live-capability.sleep-until-micros",
capability_family: "clock-sleep",
native_symbol: "lockwire_native_sleep_until_micros",
fallback_returns_not_implemented: true,
implemented_probe_symbol: "ffi_sleep_until_micros",
platform_scope: "windows+linux+unsupported-fallback",
unblocks_binding: "profinet.rawnet.clock.to_lockwire_highres_clock",
},
{
id: "native.live-capability.win-rt-affinity",
capability_family: "rt-affinity",
native_symbol: "lockwire_native_win_rt_set_affinity",
fallback_returns_not_implemented: true,
implemented_probe_symbol: "ffi_win_rt_supported",
platform_scope: "windows+unsupported-fallback",
unblocks_binding: "profinet.rawnet.clock.to_lockwire_highres_clock",
},
{
id: "native.live-capability.npcap-local-mac",
capability_family: "npcap-local-mac",
native_symbol: "lockwire_native_npcap_local_mac",
fallback_returns_not_implemented: true,
implemented_probe_symbol: "ffi_npcap_local_mac",
platform_scope: "windows+unsupported-fallback",
unblocks_binding: "profinet.rawnet.windows_npcap.to_lockwire_session",
},
{
id: "native.live-capability.npcap-last-capture-micros",
capability_family: "npcap-last-capture",
native_symbol: "lockwire_native_npcap_last_capture_micros",
fallback_returns_not_implemented: true,
implemented_probe_symbol: "ffi_npcap_last_capture_micros",
platform_scope: "windows+unsupported-fallback",
unblocks_binding: "profinet.rawnet.windows_npcap.to_lockwire_session",
},
{
id: "native.live-capability.npcap-set-nonblock",
capability_family: "npcap-nonblock",
native_symbol: "lockwire_native_npcap_set_nonblock",
fallback_returns_not_implemented: true,
implemented_probe_symbol: "ffi_npcap_set_nonblock",
platform_scope: "windows+unsupported-fallback",
unblocks_binding: "profinet.rawnet.windows_npcap.to_lockwire_session",
},
{
id: "native.live-capability.raw-socket-local-mac",
capability_family: "raw-socket-local-mac",
native_symbol: "lockwire_native_raw_socket_local_mac",
fallback_returns_not_implemented: true,
implemented_probe_symbol: "ffi_raw_socket_local_mac",
platform_scope: "linux+unsupported-fallback",
unblocks_binding: "profinet.rawnet.linux_af_packet.to_lockwire_session",
},
{
id: "native.live-capability.raw-socket-last-capture-micros",
capability_family: "raw-socket-last-capture",
native_symbol: "lockwire_native_raw_socket_last_capture_micros",
fallback_returns_not_implemented: true,
implemented_probe_symbol: "ffi_raw_socket_last_capture_micros",
platform_scope: "linux+unsupported-fallback",
unblocks_binding: "profinet.rawnet.linux_af_packet.to_lockwire_session",
},
{
id: "native.live-capability.raw-socket-set-nonblock",
capability_family: "raw-socket-nonblock",
native_symbol: "lockwire_native_raw_socket_set_nonblock",
fallback_returns_not_implemented: true,
implemented_probe_symbol: "ffi_raw_socket_set_nonblock",
platform_scope: "linux+unsupported-fallback",
unblocks_binding: "profinet.rawnet.linux_af_packet.to_lockwire_session",
},
]
}
///|
pub fn NativeLiveCapabilityReport::passes(
self : NativeLiveCapabilityReport,
) -> Bool {
self.capability_count == 9 &&
self.clock_capability_count == 2 &&
self.rt_affinity_capability_count == 1 &&
self.npcap_live_ext_capability_count == 3 &&
self.raw_socket_live_ext_capability_count == 3 &&
self.local_mac_capability_count == 2 &&
self.last_capture_capability_count == 2 &&
self.nonblock_capability_count == 2 &&
self.all_fallbacks_return_not_implemented &&
self.all_implemented_probes_present &&
!self.live_evidence_present &&
self.evidence_label == "native.live-capability.report"
}
///|
pub fn native_live_capability_report() -> NativeLiveCapabilityReport {
let catalog = native_live_capability_catalog()
let count = fn(fam : String) {
let mut n = 0
for entry in catalog {
if entry.capability_family == fam {
n += 1
}
}
n
}
let contains_family = fn(fam : String) -> Bool {
for entry in catalog {
if entry.capability_family == fam {
return true
}
}
false
}
{
capability_count: catalog.length(),
clock_capability_count: count("clock-millis") + count("clock-sleep"),
rt_affinity_capability_count: count("rt-affinity"),
npcap_live_ext_capability_count: count("npcap-local-mac") +
count("npcap-last-capture") +
count("npcap-nonblock"),
raw_socket_live_ext_capability_count: count("raw-socket-local-mac") +
count("raw-socket-last-capture") +
count("raw-socket-nonblock"),
local_mac_capability_count: count("npcap-local-mac") +
count("raw-socket-local-mac"),
last_capture_capability_count: count("npcap-last-capture") +
count("raw-socket-last-capture"),
nonblock_capability_count: count("npcap-nonblock") +
count("raw-socket-nonblock"),
all_fallbacks_return_not_implemented: catalog.all(fn(entry) {
entry.fallback_returns_not_implemented
}),
all_implemented_probes_present: contains_family("clock-millis") &&
contains_family("clock-sleep") &&
contains_family("rt-affinity") &&
contains_family("npcap-local-mac") &&
contains_family("npcap-last-capture") &&
contains_family("npcap-nonblock") &&
contains_family("raw-socket-local-mac") &&
contains_family("raw-socket-last-capture") &&
contains_family("raw-socket-nonblock"),
live_evidence_present: false,
evidence_label: "native.live-capability.report",
}
}
///|
pub fn monotonic_millis() -> Int64 {
ffi_monotonic_millis()
}
///|
pub fn sleep_until_micros(deadline_micros : Int64) -> Int {
ffi_sleep_until_micros(deadline_micros)
}
///|
pub fn win_rt_set_affinity(mask : UInt, priority : Int) -> Int {
ffi_win_rt_set_affinity(mask, priority)
}
///|
pub fn win_rt_supported() -> Int {
ffi_win_rt_supported()
}
///|
pub fn native_npcap_local_mac(interface_name : String) -> Bytes {
ffi_npcap_local_mac(@utf8.encode(interface_name))
}
///|
pub fn native_npcap_last_capture_micros() -> Int64 {
ffi_npcap_last_capture_micros()
}
///|
pub fn NativeNpcapLiveAdapter::local_mac(
self : NativeNpcapLiveAdapter,
) -> Bytes {
ffi_npcap_local_mac(@utf8.encode(self.interface_name))
}
///|
pub fn NativeNpcapLiveAdapter::last_capture_micros(
self : NativeNpcapLiveAdapter,
) -> Int64 {
ignore(self)
ffi_npcap_last_capture_micros()
}
///|
pub fn NativeNpcapLiveAdapter::set_nonblock(
self : NativeNpcapLiveAdapter,
enable : Bool,
) -> Int {
ffi_npcap_set_nonblock(self.fd, if enable { 1 } else { 0 })
}
///|
pub fn NativeNpcapLiveAdapter::try_capture(
self : NativeNpcapLiveAdapter,
) -> Bytes raise NativeLinkError {
let frame = ffi_npcap_capture_one(self.fd, 0)
if frame.is_empty() && native_last_error_code() < 0 {
raise native_link_error("npcap_try_capture")
}
frame
}
///|
pub fn native_raw_socket_local_mac(interface_name : String) -> Bytes {
ffi_raw_socket_local_mac(@utf8.encode(interface_name))
}
///|
pub fn native_raw_socket_last_capture_micros() -> Int64 {
ffi_raw_socket_last_capture_micros()
}
///|
pub fn NativeRawSocketAdapter::local_mac(
self : NativeRawSocketAdapter,
) -> Bytes {
ffi_raw_socket_local_mac(@utf8.encode(self.interface_name))
}
///|
pub fn NativeRawSocketAdapter::last_capture_micros(
self : NativeRawSocketAdapter,
) -> Int64 {
ignore(self)
ffi_raw_socket_last_capture_micros()
}
///|
pub fn NativeRawSocketAdapter::set_nonblock(
self : NativeRawSocketAdapter,
enable : Bool,
) -> Int {
ffi_raw_socket_set_nonblock(self.fd, if enable { 1 } else { 0 })
}
///|
pub fn NativeRawSocketAdapter::try_capture(
self : NativeRawSocketAdapter,
) -> Bytes raise NativeLinkError {
let frame = ffi_raw_socket_capture_one(self.fd, 0)
if frame.is_empty() && native_last_error_code() < 0 {
raise native_link_error("raw_socket_try_capture")
}
frame
}