Skip to content

Commit

Permalink
Properly switched to nusb as the usb backend
Browse files Browse the repository at this point in the history
  • Loading branch information
G2-Games committed Mar 21, 2024
1 parent d009cc4 commit 212b8ac
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 59 deletions.
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
[package]
name = "sixaxis_go"
version = "0.1.0"
version = "1.0.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
futures-lite = "2.2.0"
hidapi = "2.4.1"
futures-lite = "2.3.0"
macaddr = "1.0.1"
nusb = "0.1.7"
74 changes: 33 additions & 41 deletions src/hidapi.rs
Original file line number Diff line number Diff line change
@@ -1,72 +1,64 @@
use std::error::Error;

use futures_lite::future::block_on;
use nusb::list_devices;
use nusb::{Device, DeviceInfo, Interface, InterfaceInfo};
use nusb::transfer::{ControlType, ControlIn, Recipient, Control};
use nusb::{Interface, list_devices, transfer::{ControlIn, ControlType, Recipient, ControlOut}};

pub struct HidApi {
pub struct SixaxisApi;

}

pub struct HidDevice {
device: Device,
pub struct SixaxisDevice {
interface: Interface,
}

impl HidApi {
impl SixaxisApi {
pub fn new() -> Self {
Self {}
}

pub fn open(&self, vendor_id: u16, product_id: u16) -> Result<HidDevice, Box<dyn Error>> {
let device;
for dev_info in list_devices()? {
if dev_info.vendor_id() == vendor_id
&& dev_info.product_id() == product_id
{
let temp_dev = dev_info.open()?;
pub fn open(&self, vendor_id: u16, product_id: u16) -> Result<SixaxisDevice, Box<dyn Error>> {
let device = list_devices()
.unwrap()
.find(|dev| dev.vendor_id() == vendor_id && dev.product_id() == product_id)
.expect("Unable to find SixAxis device!")
.open()?;

device = HidDevice::new(temp_dev, dev_info)?;
return Ok(device)
}
}
let interface = device.detach_and_claim_interface(0)?;

Err("Could not find requested device".into())
Ok(SixaxisDevice {
interface,
})
}
}

impl HidDevice {
fn new(device: Device, device_info: DeviceInfo) -> Result<Self, Box<dyn Error>> {
let interface;
for int_info in device_info.interfaces() {
if int_info.class() == 3 { // Ensure it's an HID interface
interface = device.detach_and_claim_interface(0)?;

return Ok(Self {
device,
interface
})
}
}

Err("Could not find valid interface".into())
}

impl SixaxisDevice {
pub fn get_feature_report(&self, report_number: u8) -> Result<Vec<u8>, Box<dyn Error>> {
let result = block_on(self.interface.control_in(
ControlIn {
control_type: ControlType::Class,
recipient: Recipient::Interface,
request: 0x01,
value: (3 << 8) | report_number as u16,
request: 1,
value: 0x300 | report_number as u16,
index: 0,
length: 8
}
)).into_result()?;

dbg!(result.clone());
let result = result[2..].to_vec();

Ok(result)
}

pub fn set_feature_report(&self, report_number: u8, out_buffer: &Vec<u8>) -> Result<(), Box<dyn Error>> {
block_on(self.interface.control_out(
ControlOut {
control_type: ControlType::Class,
recipient: Recipient::Interface,
request: 9,
value: 0x300 | report_number as u16,
index: 0,
data: out_buffer,
}
)).into_result()?;

Ok(())
}
}
25 changes: 10 additions & 15 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use hidapi::{HidApi, HidDevice};
mod hidapi;

use crate::hidapi::{SixaxisApi, SixaxisDevice};
use macaddr::MacAddr6;
use std::str::FromStr;
use std::{env, error::Error, process::exit};
use std::{env, error::Error, process::exit, str::FromStr};

const VENDOR: u16 = 0x054c;
const PRODUCT: u16 = 0x0268;
Expand All @@ -11,10 +12,7 @@ fn main() {
let args: Vec<String> = env::args().collect();

// Get HIDAPI context
let api = match HidApi::new() {
Ok(api) => api,
Err(_) => panic!(),
};
let api = SixaxisApi::new();

// Try to get the first sixaxis controller
let device = match api.open(VENDOR, PRODUCT) {
Expand All @@ -40,29 +38,26 @@ fn main() {
} else if args.len() == 2 {
// If mac address provided, set it
set_pairing(device, args[1].as_str()).unwrap();
println!("New Device: {}", args[1]);
} else {
println!("Usage:\n\n{} [mac]", args[0]);
}
}

/// Get the current pairing of a SixAxis controller
fn pairing(device: HidDevice) -> Result<Box<[u8]>, Box<dyn Error>> {
let mut buffer = [0u8; 8];
buffer[0] = MAC_REPORT_ID;

device.get_feature_report(&mut buffer)?;
let result = &buffer[2..];
fn pairing(device: SixaxisDevice) -> Result<Box<[u8]>, Box<dyn Error>> {
let result = device.get_feature_report(MAC_REPORT_ID)?;

Ok(result.into())
}

/// Set the new pairing of a SixAxis controller
fn set_pairing(device: HidDevice, address: &str) -> Result<(), Box<dyn Error>> {
fn set_pairing(device: SixaxisDevice, address: &str) -> Result<(), Box<dyn Error>> {
let mut buffer = vec![MAC_REPORT_ID, 0x0];
let mut address = MacAddr6::from_str(address)?.as_bytes().to_vec();
buffer.append(&mut address);

device.send_feature_report(&buffer)?;
device.set_feature_report(MAC_REPORT_ID, &buffer)?;

Ok(())
}

0 comments on commit 212b8ac

Please sign in to comment.