Struct hidapi::HidApi

source ·
pub struct HidApi { /* private fields */ }
Expand description

Object for handling hidapi context and implementing RAII for it. Only one instance can exist at a time.

Implementations§

source§

impl HidApi

source

pub fn new() -> HidResult<Self>

Initializes the hidapi.

Will also initialize the currently available device list.

Examples found in repository?
examples/logitech_gprox.rs (line 19)
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
fn main() -> Result<(), Box<dyn Error>> {
    let vol = std::env::args()
        .nth(1)
        .map(|arg| arg.parse::<u8>())
        .ok_or("missing sidechannel volume arg")??
        .min(100);

    let api = HidApi::new()?;
    let dev = api.open(0x046d, 0x0aaa)?;

    println!("Setting sidechannel volume to {}", vol);

    dev.write(&[0x11, 0xff, 0x05, 0x1c, vol])?;

    Ok(())
}
More examples
Hide additional examples
examples/readhid.rs (line 16)
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
fn main() {
    let api = HidApi::new().expect("Failed to create API instance");

    let joystick = api.open(1103, 45320).expect("Failed to open device");

    loop {
        let mut buf = [0u8; 256];
        let res = joystick.read(&mut buf[..]).unwrap();

        let mut data_string = String::new();

        for u in &buf[..res] {
            data_string.push_str(&(u.to_string() + "\t"));
        }

        println!("{}", data_string);
    }
}
examples/static_lifetime_bound.rs (line 24)
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
fn test_lt() -> Rc<HidDevice> {
    let api = HidApi::new().expect("Hidapi init failed");

    let mut devices = api.device_list();

    let dev_info = devices
        .next()
        .expect("There is not a single hid device available");

    let dev = Rc::new(
        api.open(dev_info.vendor_id(), dev_info.product_id())
            .expect("Can not open device"),
    );

    let dev_1 = dev.clone();
    requires_static_lt_bound(move || {
        println!("{}", dev_1.check_error().unwrap()); //<! Can be captured by closure with static lt
    });

    dev //<! Can be returned from a function, which exceeds the lifetime of the API context
}
examples/open_first_device.rs (line 16)
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    fn run() -> Result<(), HidError> {
        let hidapi = HidApi::new()?;

        let device_info = hidapi
            .device_list()
            .next()
            .expect("No devices are available!")
            .clone();

        println!(
            "Opening device:\n VID: {:04x}, PID: {:04x}\n",
            device_info.vendor_id(),
            device_info.product_id()
        );

        let device = device_info.open_device(&hidapi)?;

        let mut buf = vec![0; 64];

        println!("Reading data from device ...\n");

        loop {
            let len = device.read(&mut buf)?;
            println!("{:?}", &buf[..len]);
        }
    }
examples/lshid.rs (line 16)
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
fn main() {
    println!("Printing all available hid devices:");

    match HidApi::new() {
        Ok(api) => {
            for device in api.device_list() {
                println!(
                    "VID: {:04x}, PID: {:04x}, Serial: {}, Product name: {}",
                    device.vendor_id(),
                    device.product_id(),
                    match device.serial_number() {
                        Some(s) => s,
                        _ => "<COULD NOT FETCH>",
                    },
                    match device.product_string() {
                        Some(s) => s,
                        _ => "<COULD NOT FETCH>",
                    }
                );
            }
        }
        Err(e) => {
            eprintln!("Error: {}", e);
        }
    }
}
examples/co2mon.rs (line 89)
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
fn main() {
    let api = HidApi::new().expect("HID API object creation failed");

    let dev = open_device(&api);

    dev.send_feature_report(&[0; PACKET_SIZE])
        .expect("Feature report failed");

    println!(
        "Manufacurer:\t{:?}",
        dev.get_manufacturer_string()
            .expect("Failed to read manufacurer string")
    );
    println!(
        "Product:\t{:?}",
        dev.get_product_string()
            .expect("Failed to read product string")
    );
    println!(
        "Serial number:\t{:?}",
        dev.get_serial_number_string()
            .expect("Failed to read serial number")
    );

    loop {
        let mut buf = [0; PACKET_SIZE];
        match dev.read_timeout(&mut buf[..], HID_TIMEOUT) {
            Ok(PACKET_SIZE) => (),
            Ok(res) => {
                println!("Error: unexpected length of data: {}/{}", res, PACKET_SIZE);
                continue;
            }
            Err(err) => {
                println!("Error: {:}", err);
                sleep(Duration::from_secs(RETRY_SEC));
                continue;
            }
        }
        match decode_buf(buf) {
            CO2Result::Temperature(val) => println!("Temp:\t{:?}", val),
            CO2Result::Concentration(val) => println!("Conc:\t{:?}", val),
            CO2Result::Unknown(..) => (),
            CO2Result::Error(val) => {
                println!("Error:\t{}", val);
                sleep(Duration::from_secs(RETRY_SEC));
            }
        }
    }
}
source

pub fn new_without_enumerate() -> HidResult<Self>

Initializes the hidapi. it skips device scanning.

source

pub fn refresh_devices(&mut self) -> HidResult<()>

Refresh devices list and information about them (to access them use device_list() method)

source

pub fn device_list(&self) -> impl Iterator<Item = &DeviceInfo>

Returns iterator containing information about attached HID devices.

Examples found in repository?
examples/static_lifetime_bound.rs (line 26)
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
fn test_lt() -> Rc<HidDevice> {
    let api = HidApi::new().expect("Hidapi init failed");

    let mut devices = api.device_list();

    let dev_info = devices
        .next()
        .expect("There is not a single hid device available");

    let dev = Rc::new(
        api.open(dev_info.vendor_id(), dev_info.product_id())
            .expect("Can not open device"),
    );

    let dev_1 = dev.clone();
    requires_static_lt_bound(move || {
        println!("{}", dev_1.check_error().unwrap()); //<! Can be captured by closure with static lt
    });

    dev //<! Can be returned from a function, which exceeds the lifetime of the API context
}
More examples
Hide additional examples
examples/open_first_device.rs (line 19)
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    fn run() -> Result<(), HidError> {
        let hidapi = HidApi::new()?;

        let device_info = hidapi
            .device_list()
            .next()
            .expect("No devices are available!")
            .clone();

        println!(
            "Opening device:\n VID: {:04x}, PID: {:04x}\n",
            device_info.vendor_id(),
            device_info.product_id()
        );

        let device = device_info.open_device(&hidapi)?;

        let mut buf = vec![0; 64];

        println!("Reading data from device ...\n");

        loop {
            let len = device.read(&mut buf)?;
            println!("{:?}", &buf[..len]);
        }
    }
examples/lshid.rs (line 18)
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
fn main() {
    println!("Printing all available hid devices:");

    match HidApi::new() {
        Ok(api) => {
            for device in api.device_list() {
                println!(
                    "VID: {:04x}, PID: {:04x}, Serial: {}, Product name: {}",
                    device.vendor_id(),
                    device.product_id(),
                    match device.serial_number() {
                        Some(s) => s,
                        _ => "<COULD NOT FETCH>",
                    },
                    match device.product_string() {
                        Some(s) => s,
                        _ => "<COULD NOT FETCH>",
                    }
                );
            }
        }
        Err(e) => {
            eprintln!("Error: {}", e);
        }
    }
}
source

pub fn open(&self, vid: u16, pid: u16) -> HidResult<HidDevice>

Open a HID device using a Vendor ID (VID) and Product ID (PID).

When multiple devices with the same vid and pid are available, then the first one found in the internal device list will be used. There are however no guarantees, which device this will be.

Examples found in repository?
examples/co2mon.rs (line 78)
76
77
78
79
80
81
82
83
84
85
86
fn open_device(api: &HidApi) -> HidDevice {
    loop {
        match api.open(DEV_VID, DEV_PID) {
            Ok(dev) => return dev,
            Err(err) => {
                println!("{}", err);
                sleep(Duration::from_secs(RETRY_SEC));
            }
        }
    }
}
More examples
Hide additional examples
examples/logitech_gprox.rs (line 20)
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
fn main() -> Result<(), Box<dyn Error>> {
    let vol = std::env::args()
        .nth(1)
        .map(|arg| arg.parse::<u8>())
        .ok_or("missing sidechannel volume arg")??
        .min(100);

    let api = HidApi::new()?;
    let dev = api.open(0x046d, 0x0aaa)?;

    println!("Setting sidechannel volume to {}", vol);

    dev.write(&[0x11, 0xff, 0x05, 0x1c, vol])?;

    Ok(())
}
examples/readhid.rs (line 18)
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
fn main() {
    let api = HidApi::new().expect("Failed to create API instance");

    let joystick = api.open(1103, 45320).expect("Failed to open device");

    loop {
        let mut buf = [0u8; 256];
        let res = joystick.read(&mut buf[..]).unwrap();

        let mut data_string = String::new();

        for u in &buf[..res] {
            data_string.push_str(&(u.to_string() + "\t"));
        }

        println!("{}", data_string);
    }
}
examples/static_lifetime_bound.rs (line 33)
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
fn test_lt() -> Rc<HidDevice> {
    let api = HidApi::new().expect("Hidapi init failed");

    let mut devices = api.device_list();

    let dev_info = devices
        .next()
        .expect("There is not a single hid device available");

    let dev = Rc::new(
        api.open(dev_info.vendor_id(), dev_info.product_id())
            .expect("Can not open device"),
    );

    let dev_1 = dev.clone();
    requires_static_lt_bound(move || {
        println!("{}", dev_1.check_error().unwrap()); //<! Can be captured by closure with static lt
    });

    dev //<! Can be returned from a function, which exceeds the lifetime of the API context
}
source

pub fn open_serial(&self, vid: u16, pid: u16, sn: &str) -> HidResult<HidDevice>

Open a HID device using a Vendor ID (VID), Product ID (PID) and a serial number.

source

pub fn open_path(&self, device_path: &CStr) -> HidResult<HidDevice>

The path name be determined by inspecting the device list available with HidApi::devices()

Alternatively a platform-specific path name can be used (eg: /dev/hidraw0 on Linux).

source

pub fn check_error(&self) -> HidResult<HidError>

Get the last non-device specific error, which happened in the underlying hidapi C library. To get the last device specific error, use HidDevice::check_error.

The Ok() variant of the result will contain a HidError::HidApiError.

When Err() is returned, then acquiring the error string from the hidapi C library failed. The contained HidError is the cause, why no error could be fetched.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

const: unstable · source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

const: unstable · source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
const: unstable · source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
const: unstable · source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.