#pragma once // ============================================================================== // C ABI bridge between the C++ protocol stack and the Swift app layer // ============================================================================== // This header is imported into Swift via -import-objc-header, so it must stay // pure C (no C++ types). The C++ modules implement these entry points. // ============================================================================== #include #include #ifdef __cplusplus extern "C" { #endif // Human-readable version string of the protocol stack. char const *xone_version(void); // TRUE if an Xbox Wireless Dongle is connected, FALSE otherwise. bool xone_dongle_present(void); // Opaque handle to an open dongle session. Create with xone_open(); only one // session may be open at a time. The getters are safe to call from any thread. typedef struct xone_dongle xone_dongle; // Session states reported by xone_state(). enum { XONE_STATE_IDLE = 0, // Probed; no firmware loaded yet XONE_STATE_STARTING, // Firmware load + radio init in progress XONE_STATE_READY, // Radio initialized XONE_STATE_ERROR // Last operation failed (see xone_error) }; // Open a dongle session: probe and USB reset. Fast; returns NULL if no dongle // is present or opening fails. The EFUSE getters (xone_pid/xone_chip_id/ // xone_mac_address) are valid immediately after this. xone_dongle *xone_open(void); // Kick off firmware load + radio init on a background thread. Non-blocking: // returns 0 once started, -1 if the session is busy or already ready. If // firmware_path is NULL, the common upstream image // (firmware/xow_dongle.bin) is used. int xone_start(xone_dongle *d, char const *firmware_path); // Close the session and release the dongle. Waits for any in-progress start. void xone_close(xone_dongle *d); // Current session state (XONE_STATE_*). int xone_state(xone_dongle const *d); // Human-readable error from the last failed operation. Empty string if none. char const *xone_error(xone_dongle const *d); // Product ID of the connected dongle (e.g. 0x02E6). uint16_t xone_pid(xone_dongle const *d); // Chip ID from EFUSE (e.g. 0x7612 for MT7612). 0 if unknown. uint16_t xone_chip_id(xone_dongle const *d); // MAC address from EFUSE as "xx:xx:xx:xx:xx:xx". Valid until xone_close(). char const *xone_mac_address(xone_dongle const *d); // Build string of the loaded firmware image (e.g. "201703281033____"). // Empty string if the firmware was not loaded. Valid until xone_close(). char const *xone_firmware_build(xone_dongle const *d); // Number of connected controllers. int xone_controller_count(xone_dongle const *d); // Copy the controller at index into buf as "xx:xx:xx:xx:xx:xx". Returns 0 on // success, -1 if index is out of range. int xone_controller_mac(xone_dongle const *d, int index, char *buf, int len); // Snapshot of the latest standard Xbox controller input report. Stick values // are signed 16-bit values; trigger values are unsigned 10-bit values. The // buttons field uses the standard GIP gamepad bit assignments. Battery fields // come from periodic GIP status packets (battery_type is 0 when unknown). struct xone_controller_state { uint16_t buttons; bool guide_down; bool gip_ready; bool input_active; uint16_t trigger_left; uint16_t trigger_right; int16_t stick_left_x; int16_t stick_left_y; int16_t stick_right_x; int16_t stick_right_y; uint32_t sequence; uint8_t battery_type; uint8_t battery_level; }; // Copy the latest input state for the controller at index. Returns 0 on // success, -1 if index is out of range or state is NULL. int xone_controller_get_state(xone_dongle const *d, int index, struct xone_controller_state *state); // Enter or leave pairing mode (beacon pairing flag + LED blink). void xone_set_pairing(xone_dongle *d, bool enable); // Send a rumble packet to the controller at index (host to controller TX // over the GIP data path). Intensities use a 0..255 scale; passing zero for // both stops the motors. Returns 0 on success, -1 for an invalid session or // index, or if the client is not ready. int xone_controller_rumble(xone_dongle *d, int index, uint8_t left, uint8_t right); #ifdef __cplusplus } #endif