1 pub use std::ptr; 2 3 macro_rules! merge { 4 ($default:expr => $($field:ident : $value:expr),*) => { 5 { 6 let mut x = $default; 7 $( x.$field = $value; )* 8 9 x 10 } 11 } 12 } 13 14 #[macro_export] 15 macro_rules! endpoint_descriptor { 16 ($($key:ident : $value:expr),*) => { 17 merge!( 18 libusb1_sys::libusb_endpoint_descriptor { 19 bLength: 7, 20 bDescriptorType: 0x05, 21 bEndpointAddress: 0x00, 22 bmAttributes: 0x00, 23 wMaxPacketSize: 16, 24 bInterval: 1, 25 bRefresh: 1, 26 bSynchAddress: 0, 27 extra: $crate::test_helpers::ptr::null(), 28 extra_length: 0 29 } => $($key: $value),* 30 ) 31 } 32 } 33 34 #[macro_export] 35 macro_rules! interface_descriptor { 36 ($($key:ident : $value:expr),*) => { 37 merge!( 38 libusb1_sys::libusb_interface_descriptor { 39 bLength: 9, 40 bDescriptorType: 0x04, 41 bInterfaceNumber: 0, 42 bAlternateSetting: 0, 43 bNumEndpoints: 0, 44 bInterfaceClass: 0, 45 bInterfaceSubClass: 0, 46 bInterfaceProtocol: 0, 47 iInterface: 0, 48 endpoint: $crate::test_helpers::ptr::null(), 49 extra: $crate::test_helpers::ptr::null(), 50 extra_length: 0 51 } => $($key: $value),* 52 ) 53 }; 54 ($($endpoint:expr),+) => { 55 { 56 let endpoints = vec![$($endpoint),+]; 57 58 let r = libusb1_sys::libusb_interface_descriptor { 59 bLength: 9, 60 bDescriptorType: 0x04, 61 bInterfaceNumber: 0, 62 bAlternateSetting: 0, 63 bNumEndpoints: endpoints.len() as u8, 64 bInterfaceClass: 0, 65 bInterfaceSubClass: 0, 66 bInterfaceProtocol: 0, 67 iInterface: 0, 68 endpoint: (&endpoints[..]).as_ptr(), 69 extra: $crate::test_helpers::ptr::null(), 70 extra_length: 0 71 }; 72 73 // leak the Vec so the returned pointer remains valid 74 ::std::mem::forget(endpoints); 75 r 76 } 77 } 78 } 79 80 #[macro_export] 81 macro_rules! interface { 82 ($($descriptor:expr),*) => { 83 { 84 let descriptors = vec![$($descriptor),*]; 85 86 let r = libusb1_sys::libusb_interface { 87 altsetting: descriptors.as_ptr(), 88 num_altsetting: descriptors.len() as ::libc::c_int 89 }; 90 91 // leak the Vec so the returned pointer remains valid 92 ::std::mem::forget(descriptors); 93 r 94 } 95 } 96 } 97 98 #[macro_export] 99 macro_rules! config_descriptor { 100 ($($key:ident : $value:expr),*) => { 101 merge!( 102 libusb1_sys::libusb_config_descriptor { 103 bLength: 9, 104 bDescriptorType: 0x02, 105 wTotalLength: 9, 106 bNumInterfaces: 0, 107 bConfigurationValue: 0, 108 iConfiguration: 0, 109 bmAttributes: 0x00, 110 bMaxPower: 10, 111 interface: $crate::test_helpers::ptr::null(), 112 extra: $crate::test_helpers::ptr::null(), 113 extra_length: 0 114 } => $($key: $value),* 115 ) 116 }; 117 ($($interface:expr),+) => { 118 { 119 let interfaces = vec![$($interface),+]; 120 121 let r = libusb1_sys::libusb_config_descriptor { 122 bLength: 9, 123 bDescriptorType: 0x02, 124 wTotalLength: 9, 125 bNumInterfaces: interfaces.len() as u8, 126 bConfigurationValue: 0, 127 iConfiguration: 0, 128 bmAttributes: 0x00, 129 bMaxPower: 10, 130 interface: (&interfaces[..]).as_ptr(), 131 extra: $crate::test_helpers::ptr::null(), 132 extra_length: 0 133 }; 134 135 // leak the Vec so the returned pointer remains valid 136 ::std::mem::forget(interfaces); 137 r 138 } 139 } 140 } 141 142 #[macro_export] 143 macro_rules! device_descriptor { 144 ($($key:ident : $value:expr),*) => { 145 merge!( 146 libusb1_sys::libusb_device_descriptor { 147 bLength: 18, 148 bDescriptorType: 0x01, 149 bcdUSB: 0x0110, 150 bDeviceClass: 0, 151 bDeviceSubClass: 0, 152 bDeviceProtocol: 0, 153 bMaxPacketSize0: 16, 154 idVendor: 0x1234, 155 idProduct: 0x5678, 156 bcdDevice: 0x0123, 157 iManufacturer: 0, 158 iProduct: 0, 159 iSerialNumber: 0, 160 bNumConfigurations: 1 161 } => $($key: $value),* 162 ) 163 } 164 } 165