Skip to main content

Crate x360_w_raw_gadget

Crate x360_w_raw_gadget 

Source
Expand description

§x360-w-raw-gadget

Emulates an Xbox 360 wireless receiver (up to 4 controllers) on Linux via the raw-gadget kernel interface.

The crate is split into two layers:

  • Portable core — pure Rust, no kernel dependency, fully unit-testable on any Linux machine without USB hardware.
  • Hardware transport (transport_hw, Linux only) — drives the actual /dev/raw-gadget device on a USB OTG capable board (e.g. Raspberry Pi Zero 2W).

A C-callable shared library (capi, Linux only) is also built (libx360_w_raw_gadget.so) for use from Python/ctypes or any other language with a C FFI.

§Quick start — Rust

use x360_w_raw_gadget::{Button, ConfigDescriptorSet, InputState, WirelessReceiver};
use x360_w_raw_gadget::RawGadgetTransport;

let config = ConfigDescriptorSet::new(1)?;
let transport = RawGadgetTransport::new(&config, "3f980000.usb", "3f980000.usb")?;
let mut receiver = WirelessReceiver::new(config, Box::new(transport));

let state = InputState::default()
    .with_button(Button::A, true)
    .with_left_stick(-16000, 8000)
    .with_left_trigger(128);

receiver.slot_mut(0).unwrap().set_state(state);
receiver.send_input(0)?;

if let Some(r) = receiver.poll_rumble(0)? {
    println!("rumble left={} right={}", r.left_motor, r.right_motor);
}
if let Some(l) = receiver.poll_led(0)? {
    println!("led {:?}", l.animation);
}

§Testing without hardware

The core is fully testable using MockTransport:

use x360_w_raw_gadget::{
    Button, ConfigDescriptorSet, InputState, WirelessReceiver,
    session::MockTransport,
    protocol::{OutputReport, RumbleReport},
};

let config = ConfigDescriptorSet::new(1).unwrap();
let mut transport = MockTransport::new();
transport.queue_output(0, OutputReport::Rumble(RumbleReport { left_motor: 128, right_motor: 64 }));

let mut receiver = WirelessReceiver::new(config, Box::new(transport));
receiver.slot_mut(0).unwrap().set_state(
    InputState::default().with_button(Button::A, true)
);
receiver.send_input(0).unwrap();

let rumble = receiver.poll_rumble(0).unwrap();
assert!(rumble.is_some());

§Modules

Re-exports§

pub use controller::Button;
pub use controller::ControllerSlot;
pub use controller::InputState;
pub use descriptors::ConfigDescriptorSet;
pub use descriptors::DescriptorError;
pub use descriptors::ReceiverIdentity;
pub use descriptors::StringDescriptorMap;
pub use protocol::InputReport;
pub use protocol::LedAnimation;
pub use protocol::LedReport;
pub use protocol::OutputReport;
pub use protocol::RumbleReport;
pub use session::Transport;
pub use session::WirelessReceiver;
pub use transport_hw::RawGadgetTransport;
pub use udc::detect_udc;

Modules§

capi
C-callable FFI surface for use from Python, C, or any language with a C FFI.
controller
Per-controller input state.
descriptors
USB device identity and configuration descriptors.
ffi
Raw Rust bindings to the Linux raw-gadget kernel interface.
protocol
USB HID packet types for the Xbox 360 wireless receiver protocol.
session
Orchestration layer: WirelessReceiver, the Transport trait, and MockTransport.
transport_hw
Hardware Transport implementation using raw-gadget ioctls.
udc

Macros§

dbg_log
Internal logging macro: prints only when DEBUG is set.

Statics§

DEBUG
Global debug flag. When true, the hardware transport prints verbose logs to stderr. Set via set_debug, the --debug CLI flag, or the X360_DEBUG environment variable.

Functions§

set_debug
Enable or disable verbose debug logging to stderr.