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