1
2
3
4
5
6
7
8
9
10
11
12
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use bytes::Buf;
use log::info;
use std::io::Read;
use crate::{AdsError, AdsErrorCode, Client, Result, AdsCommand, DeviceStateInfo, misc::HandleData};
impl Client {
fn post_read_device_info(rd_dinfo_response : HandleData) -> Result<DeviceStateInfo> {
let payload = rd_dinfo_response.payload
.ok_or_else(|| AdsError{n_error : AdsErrorCode::ADSERR_DEVICE_INVALIDDATA.into(), s_msg : String::from("Invalid data values.")})?;
Client::eval_ams_error(rd_dinfo_response.ams_err)?;
if payload.len() != 24 {
return Err(AdsError{n_error : 0xE, s_msg : String::from("Invalid AMS length") });
} else {
Client::eval_return_code(&payload.slice(0..4))?;
let mut s_device_name = String::new();
payload.slice(8..24)[..].reader().read_to_string(&mut s_device_name)?;
Ok(DeviceStateInfo{
major : u8::from_ne_bytes(payload.slice(4..5)[..].try_into().unwrap_or_default()),
minor : u8::from_ne_bytes(payload.slice(5..6)[..].try_into().unwrap_or_default()),
build : u16::from_ne_bytes(payload.slice(6..8)[..].try_into().unwrap_or_default()),
device_name : s_device_name
})
}
}
/// Submit an asynchronous [ADS Read Device Info](https://infosys.beckhoff.com/content/1031/tc3_ads_intro/115875851.html?id=308075010936482438) request.
///
///
/// # Example
///
/// ```rust
///use ads_client::{ClientBuilder, Result};
///
///#[tokio::main]
///async fn main() -> Result<()> {
///
/// let ads_client = ClientBuilder::new("5.80.201.232.1.1", 10000).build().await?;
///
/// match ads_client.read_device_info().await {
/// Ok(device_info) => {
/// println!("DeviceInfo: TwinCAT {}.{}.{} , Device Name: {}",
/// device_info.major,
/// device_info.minor,
/// device_info.build,
/// device_info.device_name)
/// }
/// Err(err) => println!("Error: {}", err.to_string())
/// }
/// Ok(())
///}
/// ```
/// Checkout the examples [read_device_info](https://github.com/hANSIc99/ads_client/blob/main/examples/read_device_info.rs)
/// and [read_device_info_async](https://github.com/hANSIc99/ads_client/blob/main/examples/read_device_info_async.rs).
pub async fn read_device_info(&self) -> Result<DeviceStateInfo> {
// Prepare read device info request
let invoke_id = self.create_invoke_id();
let ams_header = self.c_init_ams_header(invoke_id, None, AdsCommand::ReadDeviceInfo);
info!("Submit Read Device Info: Invoke ID: {}", invoke_id);
// Create handle
self.register_command_handle(invoke_id, AdsCommand::ReadDeviceInfo);
// Launch the CommandManager future
let cmd_man_future = self.create_cmd_man_future(invoke_id);
// Launch socket future
let socket_future = self.socket_write(&ams_header);
tokio::try_join!(cmd_man_future, socket_future).and_then( | (rs_response, _) | Client::post_read_device_info(rs_response))
}
}