Add verified Joy-Con 2 USB bridge with native mouse support
Implement the standalone USB protocol probe and Bluetooth-backed right Joy-Con bridge with its own persistent virtual pairing identity. Preserve complete ordered native reports, including opaque motion data, and match the console feature set. Relay built-in vibration cues only after genuine source acknowledgement and expose safe BOOTSEL pairing control. Include native capture diagnostics and focused protocol, packet-lifecycle, and cue regressions. Native mouse operation confirmed on Switch with bridge 0.24; private captures and firmware backups remain outside the commit.
This commit is contained in:
parent
485ad39709
commit
3040c9d294
34 changed files with 3777 additions and 15 deletions
68
tools/switch2_usb_probe/protocol.h
Normal file
68
tools/switch2_usb_probe/protocol.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
#pragma once
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define PROBE_COMMAND_MAX_SIZE 263u
|
||||
#define PROBE_REPLY_MAX_SIZE 96u
|
||||
#define PROBE_HOST_MAX_ADDRESSES ((255u - 2u) / 6u)
|
||||
#define PROBE_PAIRING_BLOB_SIZE (6u + 1u + PROBE_HOST_MAX_ADDRESSES * 6u + 16u)
|
||||
#define PROBE_INPUT_SIZE 63u
|
||||
|
||||
typedef struct {
|
||||
bool initialized;
|
||||
uint8_t report_id;
|
||||
bool test_rail_buttons;
|
||||
bool runtime03_0c; // Observed USB toggle; full semantics remain unknown.
|
||||
uint8_t right_stick_center[3];
|
||||
bool controller_active;
|
||||
uint8_t controller_buttons[2]; // Native right Joy-Con button ordering.
|
||||
uint8_t controller_stick[3]; // Raw packed 12-bit axes from the selected donor.
|
||||
uint8_t player_leds; // Virtual four-LED mask, exposed through UART diagnostics.
|
||||
bool player_leds_flashing;
|
||||
// Negotiated virtual features; relative mouse events belong to the USB sender.
|
||||
uint8_t feature_mask;
|
||||
uint8_t enabled_features;
|
||||
bool vibration_parameters_set;
|
||||
uint8_t vibration_parameters[20]; // Captured 0A/08 format; no motor output.
|
||||
uint8_t host_address[6];
|
||||
uint8_t controller_address[6]; // Own virtual identity, wire byte order (LE).
|
||||
const uint8_t* firmware_version; // Twelve captured bytes; caller retains their lifetime.
|
||||
// Every payload-bearing address exchange starts a fresh pending context.
|
||||
uint8_t pending_host_count;
|
||||
uint8_t pending_host_addresses[PROBE_HOST_MAX_ADDRESSES][6];
|
||||
bool pending_key_valid;
|
||||
uint8_t pending_key[16]; // Standard AES byte order, not wire byte order.
|
||||
bool challenge_confirmed;
|
||||
// A zero count means no committed pairing record.
|
||||
uint8_t committed_host_count;
|
||||
uint8_t committed_host_addresses[PROBE_HOST_MAX_ADDRESSES][6];
|
||||
uint8_t committed_key[16]; // Standard AES byte order.
|
||||
// Synchronous durable save; NULL disables successful finalization.
|
||||
bool (*save_pairing)(const uint8_t* blob, size_t length);
|
||||
bool (*read_memory)(uint32_t address, uint8_t* output, size_t length);
|
||||
// Queue a physical sample, returning true only with a nonzero completion token.
|
||||
// Acceptance is not a Bluetooth application ACK.
|
||||
bool (*play_sample)(uint8_t sample_id, uint64_t* token);
|
||||
uint32_t report_counter;
|
||||
} probe_protocol_state;
|
||||
|
||||
void probe_protocol_reset(probe_protocol_state* state);
|
||||
// Blob: own address[6], count[1], zero-padded host addresses[42][6], AES key[16].
|
||||
// Rejects other identities, invalid counts/padding/lengths without mutation.
|
||||
// A successful restore replaces the committed record and clears pending state.
|
||||
bool probe_protocol_restore_pairing(probe_protocol_state* state,
|
||||
const uint8_t* blob, size_t length);
|
||||
// Complete command frames only. Unsupported/malformed commands return zero
|
||||
// and do not mutate state. Pairing finalization requires a successful save.
|
||||
// When non-NULL, deferred_token is cleared before validation. Synchronous replies
|
||||
// leave it zero. Sample 0A/02 requires this output and play_sample; acceptance
|
||||
// prepares an 8-byte reply and returns its nonzero source completion token.
|
||||
// Those bytes MUST NOT be transmitted until that token has a genuine positive
|
||||
// Bluetooth application ACK. Failure, cancellation or expiry must discard them.
|
||||
size_t probe_protocol_command(probe_protocol_state* state, const uint8_t* command,
|
||||
size_t length, uint8_t* reply, size_t capacity,
|
||||
uint64_t* deferred_token);
|
||||
// Button/stick snapshot without relative mouse events; safe for GET_REPORT.
|
||||
size_t probe_protocol_report(const probe_protocol_state* state, uint8_t report_id,
|
||||
uint8_t* output, size_t capacity);
|
||||
Loading…
Add table
Add a link
Reference in a new issue