Skip to content

Commit

Permalink
Add Filter and Expert to Find Hardware API
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesMc86 committed Apr 1, 2022
1 parent 0819f1b commit ddecd3d
Show file tree
Hide file tree
Showing 5 changed files with 289 additions and 11 deletions.
197 changes: 197 additions & 0 deletions ni-syscfg/src/experts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
/// Contains the code to handle various functions around the "experts" in the system configuraton API.
///
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum ExpertType {
CanOpen,
CRio,
CRioWithDaqmx,
NetworkDiscovery,
FlexRIOModularIO,
FlexRIOIntegratedIO,
Ni488_2,
Ni568x,
Ni845x,
NiController,
NiDaqmx,
NiDCPower,
NiDCPower416x,
NiDMM,
NiDMM408x,
NiFGen,
NimmWave,
NiOSI,
NiPTP,
NiPXImc,
NiRio,
RTSI,
NiScope,
NiScope5170,
NiScope5164,
NiScope5110,
Serial,
SLSC,
STS,
NiSync,
NiVISA,
NiVNA,
NiVST,
NiWSN,
NiXNET,
PXIPlatformServices,
Softmotion,

Unknown(String),
}

impl From<&str> for ExpertType {
fn from(text: &str) -> Self {
match text {
"ni-canopen" => Self::CanOpen,
"crio" => Self::CRio,
"crioparent" => ExpertType::CRioWithDaqmx,
"network" => ExpertType::NetworkDiscovery,
"niflexrio" => ExpertType::FlexRIOModularIO,
"niflexrio2" => ExpertType::FlexRIOIntegratedIO,
"ni-488.2" => ExpertType::Ni488_2,
"ni-rfpowermeter" => ExpertType::Ni568x,
"845x" => ExpertType::Ni845x,
"ni-controller" => ExpertType::NiController,
"daqmx" => ExpertType::NiDaqmx,
"dcpowerscx" => ExpertType::NiDCPower,
"nidcpower416x" => ExpertType::NiDCPower416x,
"nidmmscx" => ExpertType::NiDMM,
"nidmm408x" => ExpertType::NiDMM408x,
"nifgen5433" => ExpertType::NiFGen,
"ni-mmwave" => ExpertType::NimmWave,
"ni-osi" => ExpertType::NiOSI,
"ni-1588" => ExpertType::NiPTP,
"ni-pximc" => ExpertType::NiPXImc,
"ni-rio" => ExpertType::NiRio,
"rtsi" => ExpertType::RTSI,
"niscopescx" => ExpertType::NiScope,
"niscope5170" => ExpertType::NiScope5170,
"niscope5164" => ExpertType::NiScope5164,
"niscope5110" => ExpertType::NiScope5110,
"serial" => ExpertType::Serial,
"slsc" => ExpertType::SLSC,
"nistsrcbps" => ExpertType::STS,
"ni-sync" => ExpertType::NiSync,
"ni-visa" => ExpertType::NiVISA,
"nivna" => ExpertType::NiVNA,
"ni-vst" => ExpertType::NiVST,
"ni-wsn" => ExpertType::NiWSN,
"xnet" => ExpertType::NiXNET,
"ni-pxi" => ExpertType::PXIPlatformServices,
"mcSysApi" => ExpertType::Softmotion,
_ => ExpertType::Unknown(text.to_string()),
}
}
}

impl ExpertType {
pub fn to_programmatic_string(&self) -> String {
match self {
ExpertType::Unknown(name) => name.clone(),
ExpertType::CanOpen => "ni-canopen".to_string(),
ExpertType::CRio => "crio".to_string(),
ExpertType::CRioWithDaqmx => "crioparent".to_string(),
ExpertType::NetworkDiscovery => "network".to_string(),
ExpertType::FlexRIOModularIO => "niflexrio".to_string(),
ExpertType::FlexRIOIntegratedIO => "niflexrio2".to_string(),
ExpertType::Ni488_2 => "ni-488.2".to_string(),
ExpertType::Ni568x => "ni-rfpowermeter".to_string(),
ExpertType::Ni845x => "845x".to_string(),
ExpertType::NiController => "ni-controller".to_string(),
ExpertType::NiDaqmx => "daqmx".to_string(),
ExpertType::NiDCPower => "dcpowerscx".to_string(),
ExpertType::NiDCPower416x => "nidcpower416x".to_string(),
ExpertType::NiDMM => "nidmmscx".to_string(),
ExpertType::NiDMM408x => "nidmm408x".to_string(),
ExpertType::NiFGen => "nifgen5433".to_string(),
ExpertType::NimmWave => "ni-mmwave".to_string(),
ExpertType::NiOSI => "ni-osi".to_string(),
ExpertType::NiPTP => "ni-1588".to_string(),
ExpertType::NiPXImc => "ni-pximc".to_string(),
ExpertType::NiRio => "ni-rio".to_string(),
ExpertType::RTSI => "rtsi".to_string(),
ExpertType::NiScope => "niscopescx".to_string(),
ExpertType::NiScope5170 => "niscope5170".to_string(),
ExpertType::NiScope5164 => "niscope5164".to_string(),
ExpertType::NiScope5110 => "niscope5110".to_string(),
ExpertType::Serial => "serial".to_string(),
ExpertType::SLSC => "slsc".to_string(),
ExpertType::STS => "nistsrcbps".to_string(),
ExpertType::NiSync => "ni-sync".to_string(),
ExpertType::NiVISA => "ni-visa".to_string(),
ExpertType::NiVNA => "nivna".to_string(),
ExpertType::NiVST => "ni-vst".to_string(),
ExpertType::NiWSN => "ni-wsn".to_string(),
ExpertType::NiXNET => "xnet".to_string(),
ExpertType::PXIPlatformServices => "ni-pxi".to_string(),
ExpertType::Softmotion => "mcSysApi".to_string(),
}
}
}

pub struct SystemExpert {
expert_type: ExpertType,
display_name: String,
version: String,
}

#[cfg(test)]
mod test {

use super::*;

fn test_string_conversion(expert_type: ExpertType, programmatic_name: &str) {
assert_eq!(
expert_type.to_programmatic_string(),
programmatic_name.to_string()
);
assert_eq!(expert_type, programmatic_name.into());
}

#[test]
fn type_to_string() {
test_string_conversion(ExpertType::Unknown("unknown".to_string()), "unknown");
test_string_conversion(ExpertType::CanOpen, "ni-canopen");
test_string_conversion(ExpertType::CRio, "crio");
test_string_conversion(ExpertType::CRioWithDaqmx, "crioparent");
test_string_conversion(ExpertType::NetworkDiscovery, "network");
test_string_conversion(ExpertType::FlexRIOModularIO, "niflexrio");
test_string_conversion(ExpertType::FlexRIOIntegratedIO, "niflexrio2");
test_string_conversion(ExpertType::Ni488_2, "ni-488.2");
test_string_conversion(ExpertType::Ni568x, "ni-rfpowermeter");
test_string_conversion(ExpertType::Ni845x, "845x");
test_string_conversion(ExpertType::NiController, "ni-controller");
test_string_conversion(ExpertType::NiDaqmx, "daqmx");
test_string_conversion(ExpertType::NiDCPower, "dcpowerscx");
test_string_conversion(ExpertType::NiDCPower416x, "nidcpower416x");
test_string_conversion(ExpertType::NiDMM, "nidmmscx");
test_string_conversion(ExpertType::NiDMM408x, "nidmm408x");
test_string_conversion(ExpertType::NiFGen, "nifgen5433");
test_string_conversion(ExpertType::NimmWave, "ni-mmwave");
test_string_conversion(ExpertType::NiOSI, "ni-osi");
test_string_conversion(ExpertType::NiPTP, "ni-1588");
test_string_conversion(ExpertType::NiPXImc, "ni-pximc");
test_string_conversion(ExpertType::NiRio, "ni-rio");
test_string_conversion(ExpertType::RTSI, "rtsi");
test_string_conversion(ExpertType::NiScope, "niscopescx");
test_string_conversion(ExpertType::NiScope5170, "niscope5170");
test_string_conversion(ExpertType::NiScope5164, "niscope5164");
test_string_conversion(ExpertType::NiScope5110, "niscope5110");
test_string_conversion(ExpertType::Serial, "serial");
test_string_conversion(ExpertType::SLSC, "slsc");
test_string_conversion(ExpertType::STS, "nistsrcbps");
test_string_conversion(ExpertType::NiSync, "ni-sync");
test_string_conversion(ExpertType::NiVISA, "ni-visa");
test_string_conversion(ExpertType::NiVNA, "nivna");
test_string_conversion(ExpertType::NiVST, "ni-vst");
test_string_conversion(ExpertType::NiWSN, "ni-wsn");
test_string_conversion(ExpertType::NiXNET, "xnet");
test_string_conversion(ExpertType::PXIPlatformServices, "ni-pxi");
test_string_conversion(ExpertType::Softmotion, "mcSysApi");
}
}
3 changes: 2 additions & 1 deletion ni-syscfg/src/hardware_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl HardwareFilter {
}

/// Set the mode for the filter, determining how the filter match is applied.
pub fn set_mode(mut self, mode: FilterMode) -> Self {
pub fn set_mode(&mut self, mode: FilterMode) -> &mut Self {
self.mode = mode;
self
}
Expand All @@ -42,6 +42,7 @@ impl HardwareFilter {
impl Drop for HardwareFilter {
fn drop(&mut self) {
let _ = close_handle(self.handle);
println!("Drop Filter");
}
}

Expand Down
2 changes: 2 additions & 0 deletions ni-syscfg/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
mod error;
mod experts;
mod handles;
mod hardware_filter;
mod parameters;
mod resources;
mod session;

pub use experts::ExpertType;
pub use hardware_filter::FilterMode;
pub use session::*;
79 changes: 71 additions & 8 deletions ni-syscfg/src/session.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use ni_syscfg_sys::*;
use std::ffi::{c_void, CString};
use std::ffi::CString;
use std::time::Duration;

use crate::error::{api_status, Result};
use crate::experts::ExpertType;
use crate::handles::close_handle;
use crate::hardware_filter::{FilterMode, HardwareFilter};
use crate::parameters::ApiBool;
Expand Down Expand Up @@ -133,7 +134,7 @@ impl Session {
///
/// let session = SessionConfig::new().connect().unwrap();
///
/// for hardware in session.find_hardware(None).unwrap() {
/// for hardware in session.find_hardware(None, None).unwrap() {
/// println!("Found {}", hardware.name().unwrap())
/// }
/// ```
Expand All @@ -144,13 +145,28 @@ impl Session {
///
/// let session = SessionConfig::new().connect().unwrap();
/// let mut filter = session.create_filter().unwrap();
/// filter.mode = FilterMode::MatchValuesAny;
/// filter.set_mode(FilterMode::MatchValuesAny);
///
/// for hardware in session.find_hardware(Some(filter)).unwrap() {
/// for hardware in session.find_hardware(Some(&filter), None).unwrap() {
/// println!("Found {}", hardware.name().unwrap())
/// }
/// ```
pub fn find_hardware(&self, filtering: Option<HardwareFilter>) -> Result<HardwareResourceList> {
///
/// # Example With DAQmx Expert Filter
/// ```
/// use ni_syscfg::{SessionConfig, ExpertType};
///
/// let session = SessionConfig::new().connect().unwrap();
///
/// for hardware in session.find_hardware(None, Some(&[ExpertType::NiDaqmx])).unwrap() {
/// println!("Found {}", hardware.name().unwrap())
/// }
/// ```
pub fn find_hardware(
&self,
filtering: Option<&HardwareFilter>,
experts: Option<&[ExpertType]>,
) -> Result<HardwareResourceList> {
let mut list_handle: NISysCfgEnumResourceHandle = std::ptr::null_mut();

let (filter_mode, filter_handle) = if let Some(filter) = filtering {
Expand All @@ -162,12 +178,18 @@ impl Session {
)
};

let expert_list = if let Some(list) = experts {
expert_list_to_text(list)?
} else {
CString::new("")?
};

unsafe {
api_status(NISysCfgFindHardware(
self.handle,
filter_mode as i32,
filter_handle,
std::ptr::null(),
expert_list.as_ptr(),
&mut list_handle,
))?;
}
Expand All @@ -176,6 +198,16 @@ impl Session {
}
}

/// Convert the expert list to a format expect by the API.
fn expert_list_to_text(list: &[ExpertType]) -> Result<CString> {
let list_string = list
.iter()
.map(|ex| ex.to_programmatic_string())
.collect::<Vec<String>>()
.join(",");
Ok(CString::new(list_string)?)
}

impl Drop for Session {
fn drop(&mut self) {
let _ = close_handle(self.handle);
Expand All @@ -184,8 +216,39 @@ impl Drop for Session {

#[cfg(test)]
mod tests {

use super::*;

#[test]
fn it_works() {
super::SessionConfig::new().connect().unwrap();
fn expert_list_to_string() {
//use a list of unknown so we know what it will produce.
let list = vec![
ExpertType::Unknown("test1".to_string()),
ExpertType::Unknown("test2".to_string()),
];

let result = expert_list_to_text(&list).unwrap();

assert_eq!(result.to_str().unwrap(), "test1,test2");
}

#[test]
fn expert_list_to_string_single() {
//use a list of unknown so we know what it will produce.
let list = vec![ExpertType::Unknown("test1".to_string())];

let result = expert_list_to_text(&list).unwrap();

assert_eq!(result.to_str().unwrap(), "test1");
}

#[test]
fn expert_list_to_string_empty() {
//use a list of unknown so we know what it will produce.
let list = vec![];

let result = expert_list_to_text(&list).unwrap();

assert_eq!(result.to_str().unwrap(), "");
}
}
19 changes: 17 additions & 2 deletions ni-syscfg/tests/list_hardware.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
use ni_syscfg::SessionConfig;
use ni_syscfg::{ExpertType, FilterMode, SessionConfig};

#[test]
fn test_list_hardware() {
let session = SessionConfig::new()
.connect()
.expect("Couldn't Open Session");

for hardware in session.find_hardware(None).expect("Couldn't List Hardware") {
for hardware in session
.find_hardware(None, Some(&[ExpertType::NiDaqmx]))
.expect("Couldn't List Hardware")
{
let name = hardware.name().expect("Couldn't Get hardware Name");
let bus_type = hardware
.connects_to_bus_type()
.expect("Couldnt get bus type");
println!("Hardware found {name} connected to {bus_type:?}");
}
}

#[test]
fn test_list_hardware_with_filter() {
let session = SessionConfig::new().connect().unwrap();
let mut filter = session.create_filter().unwrap();
filter.set_mode(FilterMode::MatchValuesAny);
let hardware_list = session.find_hardware(Some(&filter), None).unwrap();

for hardware in hardware_list {
println!("Found {}", hardware.name().unwrap())
}
}

0 comments on commit ddecd3d

Please sign in to comment.