• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use std::ops::Deref;
6 
7 use crate::bindings::{self, libusb_config_descriptor};
8 use crate::interface_descriptor::InterfaceDescriptor;
9 
10 /// ConfigDescriptor wraps libusb_config_descriptor.
11 pub struct ConfigDescriptor {
12     descriptor: *mut libusb_config_descriptor,
13 }
14 
15 impl Drop for ConfigDescriptor {
16     // Free configuration descriptor.
17     // Safe because 'self' is intialized with a valid libusb_config_descriptor from libusb
18     // functions.
drop(&mut self)19     fn drop(&mut self) {
20         unsafe {
21             bindings::libusb_free_config_descriptor(self.descriptor);
22         }
23     }
24 }
25 
26 impl ConfigDescriptor {
27     /// Build ConfigDescriptor. 'descriptor' should be a valid pointer from
28     /// libusb_config_descriptor. This function will panic if it's null.
new(descriptor: *mut libusb_config_descriptor) -> ConfigDescriptor29     pub unsafe fn new(descriptor: *mut libusb_config_descriptor) -> ConfigDescriptor {
30         assert!(!descriptor.is_null());
31         ConfigDescriptor { descriptor }
32     }
33 
34     /// Get interface by number and alt setting.
get_interface_descriptor( &self, interface_num: u8, alt_setting: i32, ) -> Option<InterfaceDescriptor>35     pub fn get_interface_descriptor(
36         &self,
37         interface_num: u8,
38         alt_setting: i32,
39     ) -> Option<InterfaceDescriptor> {
40         let config_descriptor = self.deref();
41         if interface_num >= config_descriptor.bNumInterfaces {
42             return None;
43         }
44         // Safe because interface num is checked.
45         let interface = unsafe { &*(config_descriptor.interface.offset(interface_num as isize)) };
46 
47         if alt_setting >= interface.num_altsetting {
48             return None;
49         }
50         // Safe because setting num is checked.
51         unsafe {
52             Some(InterfaceDescriptor::new(
53                 &*(interface.altsetting.offset(alt_setting as isize)),
54             ))
55         }
56     }
57 }
58 
59 impl Deref for ConfigDescriptor {
60     type Target = libusb_config_descriptor;
61 
deref(&self) -> &libusb_config_descriptor62     fn deref(&self) -> &libusb_config_descriptor {
63         // Safe because 'self.descriptor' is valid.
64         unsafe { &*(self.descriptor) }
65     }
66 }
67