Skip to main content

openipc_web/
lib.rs

1//! WebAssembly bindings for the OpenIPC receiver pipeline and WebUSB driver.
2//!
3//! The Rust types in this crate wrap `openipc-core` and `openipc-rtl88xx` for
4//! browser and Tauri-webview frontends. JavaScript receives typed video frames,
5//! raw route payloads, diagnostics, and WebUSB helpers through wasm-bindgen.
6
7mod adaptive;
8mod js;
9mod mock;
10mod receiver;
11#[cfg(target_arch = "wasm32")]
12mod session;
13mod video;
14mod webusb;
15
16pub use adaptive::OpenIpcAdaptiveLink;
17pub use mock::{OpenIpcMockPayloadRuntime, OpenIpcMockRtpPipeline};
18pub use receiver::OpenIpcReceiver;
19#[cfg(target_arch = "wasm32")]
20pub use session::WebUsbReceiverSession;
21pub use webusb::supported_usb_filters;
22#[cfg(target_arch = "wasm32")]
23pub use webusb::{
24    list_authorized_usb_devices, WebBbDbgportRead, WebFalseAlarmCounters, WebInitReport,
25    WebIqkReport, WebJaguar3PowerTrackingReport, WebPhydmWatchdogReport, WebPowerTrackingReport,
26    WebQueueDepth8814, WebThermalStatus, WebUsbJaguar3PowerTracking, WebUsbPhydmWatchdog,
27    WebUsbPowerTracking8812, WebUsbPowerTracking8822c, WebUsbRealtekDevice,
28};
29
30use wasm_bindgen::prelude::*;
31
32#[wasm_bindgen(typescript_custom_section)]
33const OPENIPC_VIDEO_FRAME_TYPES: &'static str = r#"
34export type OpenIpcVideoFrame = {
35    data: Uint8Array;
36    codec: "h264" | "h265";
37    codecString: string;
38    isKeyFrame: boolean;
39    timestamp: number;
40    payloadType: number;
41    sequenceNumber: number;
42    nalType: number;
43    decoderConfigComplete: boolean;
44    codecConfig: OpenIpcCodecConfigState;
45};
46
47export type OpenIpcCodecConfigState = {
48    h264Sps: boolean;
49    h264Pps: boolean;
50    h265Vps: boolean;
51    h265Sps: boolean;
52    h265Pps: boolean;
53};
54
55export type OpenIpcRtpStatus = {
56    packets: number;
57    framesEmitted: number;
58    configWaitDrops: number;
59    keyframesWithPrependedConfig: number;
60    parameterSetsPrepended: number;
61    fragmentSequenceGaps: number;
62    fragmentOverflows: number;
63    unsupportedPayloads: number;
64    malformedPackets: number;
65    lastPayloadType: number | null;
66    lastSequenceNumber: number | null;
67    lastTimestamp: number | null;
68    lastCodec: "h264" | "h265" | null;
69    lastNalType: number | null;
70    codecConfig: OpenIpcCodecConfigState;
71    h264ConfigComplete: boolean;
72    h265ConfigComplete: boolean;
73    reorderBufferedPackets: number;
74    reorderedPackets: number;
75    latePackets: number;
76    forcedFlushes: number;
77};
78
79export type OpenIpcMockFrame = {
80    width: number;
81    height: number;
82    frameIndex: string;
83    timestamp: number;
84    rtpPackets: number;
85    rtpBytes: number;
86    rgba: Uint8Array;
87};
88
89export type OpenIpcRawPayload = {
90    data: Uint8Array;
91    packetSeq: string;
92    routeId: number;
93    channelId: number;
94};
95
96export type OpenIpcRxTransferProfile = {
97    frames: OpenIpcVideoFrame[];
98    rawPayloads: OpenIpcRawPayload[];
99    mavlinkPayloads: OpenIpcRawPayload[];
100    rawPayloadCount: number;
101    rawPayloadBytes: number;
102    transferBytes: number;
103    packets: number;
104    acceptedPackets: number;
105    droppedPackets: number;
106    crcDropped: number;
107    icvDropped: number;
108    reportDropped: number;
109    ignoredFrames: number;
110    sessions: number;
111    wfbPayloads: number;
112    rtpPackets: number;
113    videoFrames: number;
114    mavlinkPayloadCount: number;
115    mavlinkBytes: number;
116    parseMs: number;
117    pipelineMs: number;
118    totalMs: number;
119    usbReadMs: number;
120    pendingUsbTransfers: number;
121    rtpStatus: OpenIpcRtpStatus;
122    fecCounters: OpenIpcFecCounters;
123};
124
125export type OpenIpcFecCounters = {
126    totalPackets: number;
127    recoveredPackets: number;
128    lostPackets: number;
129    badPackets: number;
130};
131"#;