Skip to content

Commit 09fa6db

Browse files
committed
rework autorouting
1 parent 6cf65ae commit 09fa6db

File tree

1 file changed

+42
-35
lines changed

1 file changed

+42
-35
lines changed

examples/adstool.rs

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
//! Reproduces the functionality of "adstool" from the Beckhoff ADS C++ library.
22
33
use std::convert::TryInto;
4-
use std::io::{self, stdin, stdout, Read, Write};
4+
use std::io::{stdin, stdout, Read, Write};
5+
use std::net::{IpAddr, Ipv4Addr, TcpStream};
56
use std::str::FromStr;
67
use std::time::Duration;
78

@@ -61,8 +62,8 @@ impl Cli {
6162
(username, password)
6263
}
6364

64-
pub fn timeout(&self) -> ads::Timeouts {
65-
ads::Timeouts { connect: Some(Duration::from_secs(self.timeout)), ..Default::default() }
65+
pub const fn timeout(&self) -> ads::Timeouts {
66+
ads::Timeouts { connect: Some(Duration::from_secs(self.timeout)), ..ads::Timeouts::none() }
6667
}
6768
}
6869

@@ -103,7 +104,7 @@ struct CredentialArgs {
103104

104105
/// password for logging into the system (defaults to `1`)
105106
#[clap(long)]
106-
password: Option<String>
107+
password: Option<String>,
107108
}
108109

109110
#[derive(Parser, Debug)]
@@ -376,6 +377,40 @@ fn connect(port: ads::AmsPort, args: &Cli) -> ads::Result<(ads::Client, ads::Ams
376377
let amsaddr = ads::AmsAddr::new(target_netid, amsport);
377378
let source = if matches!(target.host.as_str(), "127.0.0.1" | "localhost") {
378379
ads::Source::Request
380+
} else if args.autoroute {
381+
// temp. connection to remote to get the corrent IP addr of the interface in use
382+
let sock = TcpStream::connect(tcp_addr)
383+
.map_err(|e| ads::Error::Io("attempting to resolve local IP address", e))?;
384+
385+
let local_ip = sock.local_addr()
386+
.map(|addr| addr.ip())
387+
.map_err(|e| ads::Error::Io("attempting to resolve local IP address", e))?;
388+
389+
// if not using IPv4 address or IPv6 address with IPv4 mapping,
390+
// create an arbitrary AMS NetID
391+
let local_net_id = {
392+
let [a, b, c, d] = match local_ip {
393+
IpAddr::V4(ip) => ip.octets(),
394+
IpAddr::V6(ip) => ip.to_ipv4().unwrap_or(Ipv4Addr::new(1, 2, 3, 4)).octets()
395+
};
396+
397+
ads::AmsNetId::new(a, b, c, d, 1, 1)
398+
};
399+
400+
let (username, password) = args.credentials();
401+
402+
// add the route using the collected IP information and derived AMS NetID
403+
ads::udp::add_route(
404+
(target.host.as_str(), ads::UDP_PORT),
405+
local_net_id,
406+
&local_ip.to_string(),
407+
None,
408+
username,
409+
password,
410+
true,
411+
)?;
412+
413+
ads::Source::Addr(ads::AmsAddr::new(local_net_id, 58913))
379414
} else {
380415
ads::Source::Any
381416
};
@@ -384,34 +419,6 @@ fn connect(port: ads::AmsPort, args: &Cli) -> ads::Result<(ads::Client, ads::Ams
384419
// (probably because of a bad route)
385420
let client = ads::Client::new(tcp_addr, args.timeout(), source)?;
386421

387-
if args.autoroute {
388-
let (username, password) = args.credentials();
389-
390-
match client.device(amsaddr).get_info() {
391-
Err(e) => {
392-
println!("Error connecting to client: (error: '{e}')");
393-
println!("Attempting to autoroute");
394-
395-
let [a, b, c, d, ..] = client.source().netid().0;
396-
let ip = format!("{a}.{b}.{c}.{d}");
397-
398-
ads::udp::add_route(
399-
(target.host.as_str(), ads::UDP_PORT),
400-
client.source().netid(),
401-
&ip,
402-
None,
403-
username,
404-
password,
405-
true,
406-
)?;
407-
408-
return connect(port, args);
409-
}
410-
411-
_ => ()
412-
}
413-
}
414-
415422
Ok((client, amsaddr))
416423
}
417424

@@ -539,8 +546,7 @@ fn main_inner(args: Cli) -> Result<(), Error> {
539546
}
540547

541548
FileAction::Read { path } => {
542-
let mut file =
543-
file::File::open(dev, path, file::READ | file::BINARY | file::ENSURE_DIR)?;
549+
let mut file = file::File::open(dev, path, file::READ | file::BINARY | file::ENSURE_DIR)?;
544550
std::io::copy(&mut file, &mut stdout())?;
545551
}
546552

@@ -657,7 +663,8 @@ fn main_inner(args: Cli) -> Result<(), Error> {
657663

658664
if let Some(length) = length {
659665
let mut read_data = vec![0; *length];
660-
let nread = dev.write_read(*index_group, *index_offset, &write_data, &mut read_data)?;
666+
let nread =
667+
dev.write_read(*index_group, *index_offset, &write_data, &mut read_data)?;
661668
if *hex {
662669
hexdump(&read_data[..nread]);
663670
} else {

0 commit comments

Comments
 (0)