rseip (eip-rs) - EtherNet/IP in pure Rust

Overview

rseip

rseip (eip-rs) - EtherNet/IP in pure Rust

Features

  • Pure Rust Library
  • Asynchronous
  • Extensible
  • Explicit Messaging (Connected / Unconnected)
  • Open Source

How to use

Add rseip to your cargo project's dependencies

rseip={git="https://github.com/Joylei/eip-rs.git"}

Example

Read tag from Allen-bradley CompactLogIx device

rseip::Result<()> { dst.put_u16_le(self.0); Ok(()) } fn bytes_count(&self) -> usize { 2 } } ">
use anyhow::Result;
use byteorder::{ByteOrder, LittleEndian};
use bytes::{BufMut, BytesMut};
use rseip::{client::Client, codec::Encodable, frame::cip::*};

#[tokio::main]
pub async fn main() -> Result<()> {
    let connection_path = EPath::from(vec![Segment::Port(PortSegment::default())]);
    let mut client = Client::connect("192.168.0.83").await?;
    let mr_request = MessageRouterRequest::new(
        0x4c,
        EPath::from(vec![Segment::Symbol("test_car1_x".to_owned())]),
        ElementCount(1),
    );
    let resp = client.send(mr_request, connection_path).await?;
    assert_eq!(resp.reply_service, 0xCC); // read tag service reply
    assert_eq!(LittleEndian::read_u16(&resp.data[0..2]), 0xC4); // DINT
    client.close().await?;
    Ok(())
}

struct ElementCount(u16);

impl Encodable for ElementCount {
    fn encode(self, dst: &mut BytesMut) -> rseip::Result<()> {
        dst.put_u16_le(self.0);
        Ok(())
    }
    fn bytes_count(&self) -> usize {
        2
    }
}

Please find more examples within examples.

License

MIT

Related Projects

  • EIPScanner

    Free implementation of EtherNet/IP in C++

  • EEIP.NET

    Ethernet/IP compatible library for .NET implementations

  • digitalpetri/ethernet-ip

    Asynchronous, non-blocking, EtherNet/IP client implementation for Java

  • node-ethernet-ip

    A Lightweight Ethernet/IP API written to interface with Rockwell ControlLogix/CompactLogix Controllers.

  • OpENer

    OpENer is an EtherNet/IP stack for I/O adapter devices. It supports multiple I/O and explicit connections and includes objects and services for making EtherNet/IP-compliant products as defined in the ODVA specification.

  • cpppo

    Communications Protocol Python Parser and Originator -- EtherNet/IP CIP

Comments
  • Backtrace

    Backtrace

    template instance: Template { instance_id: 1575, handle: 13998, member_count: 233, object_size: 1411, struct_size: 1868 } thread 'main' panicked at 'assertion failed: self.remaining() >= dst.len()', ../.cargo/registry/src/github.com-1ecc6299db9ec823/bytes-1.1.0/src/buf/buf_impl.rs:253:9 stack backtrace: 0: rust_begin_unwind at /rustc/6a705566166debf5eff88c57140df607fa409aaa/library/std/src/panicking.rs:584:5 1: core::panicking::panic_fmt at /rustc/6a705566166debf5eff88c57140df607fa409aaa/library/core/src/panicking.rs:143:14 2: core::panicking::panic at /rustc/6a705566166debf5eff88c57140df607fa409aaa/library/core/src/panicking.rs:48:5 3: bytes::buf::buf_impl::Buf::copy_to_slice at ../.cargo/registry/src/github.com-1ecc6299db9ec823/bytes-1.1.0/src/buf/buf_impl.rs:253:9 4: bytes::buf::buf_impl::Buf::get_u16_le at ../.cargo/registry/src/github.com-1ecc6299db9ec823/bytes-1.1.0/src/buf/buf_impl.rs:354:9 5: <rseip::client::ab_eip::template::decoder::DefaultDefinitionDecoder as rseip::client::ab_eip::template::decoder::DefinitionDecoder>::partial_decode at ./src/client/ab_eip/template/decoder.rs:60:39 6: rseip::client::ab_eip::template::TemplateRead<T,D>::call::{{closure}} at ./src/client/ab_eip/template.rs:197:13 7: <core::future::from_generator::GenFuture as core::future::future::Future>::poll at /rustc/6a705566166debf5eff88c57140df607fa409aaa/library/core/src/future/mod.rs:91:19 8: rseip::main::{{closure}} at ./src/main.rs:30:54 9: <core::future::from_generator::GenFuture as core::future::future::Future>::poll at /rustc/6a705566166debf5eff88c57140df607fa409aaa/library/core/src/future/mod.rs:91:19 10: tokio::park::thread::CachedParkThread::block_on::{{closure}} at ../.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/park/thread.rs:263:54 11: tokio::coop::with_budget::{{closure}} at ../.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/coop.rs:102:9 12: std::thread::local::LocalKey::try_with at /rustc/6a705566166debf5eff88c57140df607fa409aaa/library/std/src/thread/local.rs:413:16 13: std::thread::local::LocalKey::with at /rustc/6a705566166debf5eff88c57140df607fa409aaa/library/std/src/thread/local.rs:389:9 14: tokio::coop::with_budget at ../.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/coop.rs:95:5 15: tokio::coop::budget at ../.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/coop.rs:72:5 16: tokio::park::thread::CachedParkThread::block_on at ../.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/park/thread.rs:263:31 17: tokio::runtime::enter::Enter::block_on at ../.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/runtime/enter.rs:151:13 18: tokio::runtime::thread_pool::ThreadPool::block_on at ../.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/runtime/thread_pool/mod.rs:73:9 19: tokio::runtime::Runtime::block_on at ../.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/runtime/mod.rs:477:43 20: rseip::main at ./src/main.rs:33:5 21: core::ops::function::FnOnce::call_once at /rustc/6a705566166debf5eff88c57140df607fa409aaa/library/core/src/ops/function.rs:227:5 note: Some details are omitted, run with RUST_BACKTRACE=full for a verbose backtrace.

    opened by GeneL 6
  • Future cannot be sent between threads safely

    Future cannot be sent between threads safely

    I have worked through the example you provided in the ReadMe, and it works great! I can read/write tags without a hitch.

    The issue arises when I attempt to create a background task to handle the reading/writing of tags. Rust Analyzer gives me the following error:

    future cannot be sent between threads safely
    the trait `std::marker::Send` is not implemented for `dyn std::future::Future<Output = Result<rseip::client::ab_eip::TagValue<i32>, ClientError>>`rustc
    [main.rs(18, 32): ]()future is not `Send` as it awaits another future which is not `Send`
    [spawn.rs(127, 21): ]()required by a bound in `tokio::spawn` 
    

    However, in the docs, it specifically says that ClientError is Send and TagValue is Send so long as T is also Send. This might just be my inexperience with tokio, but I am wondering if you could shed some light on how to do this properly.

    Here is my sample code:

    use rseip::client::ab_eip::*;
    use rseip::precludes::*;
    
    #[tokio::main]
    async fn main(){
        tokio::spawn(async move {
            background().await;
        });
    }
    
    async fn background() -> Result<()> {
        let mut client = AbEipClient::new_host_lookup("192.168.0.83")
            .await?
            .with_connection_path(PortSegment::default());
        let tag = EPath::parse_tag("test_car1_x")?;
        println!("read tag...");
        let value: TagValue<i32> = client.read_tag(tag.clone()).await?;
        println!("tag value: {:?}", value);
        client.write_tag(tag, value).await?;
        println!("write tag - done");
        client.close().await?;
        Ok(())
    }
    

    Thank you in advance!

    bug 
    opened by aruddy-slb 3
  • Can not read a large template

    Can not read a large template

    let template = client.find_template(tag_info.1).await?; println!("template instance:\n{:?}", template);

    These statements work for a small (<500 bytes) templates, but do not work for a large (>500 bytes) templates:

    let info = client.read_template(&template).call().await?;
    println!("template definition:\n{:?}", info);
    
    bug 
    opened by GeneL 3
  • Future goals

    Future goals

    I happened across this lib just about the time you made your first commit. I am impressed by the rapid development.

    I am wonder what your future plans/goals are for this lib.

    I actually started writing some code to use your early work to read the template / structure data out of the processor. I then took another look at the repository, and BAM......already there!!!!! Impressive!!!!

    opened by klmurphy72 1
  • Float values

    Float values

    Hi,

    I really appreciate this crate. Thank you for putting it together.

    I am new to Ethernet/IP and I have a question.

    When trying to read float type tags, I get a compiler error saying that Encode Decode are not implemented for f32. What's the best way to read and write f32 values for REAL type tags on AB PLCs?

    Thanks

    opened by crimsondamask 0
  • I was not able to read a tag value in a controller..

    I was not able to read a tag value in a controller..

    I was not able to read a tag in a controller with this command:

    let mut client = AbEipConnection::new_host_lookup("xx.xx.xx.xx", OpenOptions::default()).await?; println!("read tag...{:?}", client); let tag1 = EPath::from_symbol("Cfg_LoSeverity"); println!("read tag...{:?}", tag1); let value: TagValue = client.read_tag(tag1.clone()).await?; println!("read tag...{:?}", value); client.close().await?;

    This is the output: read tag...Connection { addr: xx.xx.xx.xx:44818, origin_options: OpenOptions { o_t_connection_id: 0, t_o_connection_id: 0, priority_tick_time: 3, timeout_ticks: 250, connection_serial_number: 6332, vendor_id: 255, originator_serial_number: 4294967295, o_t_rpi: 16960, t_o_rpi: 16960, timeout_multiplier: 3, connection_path: EPath([Port(PortSegment { port: 1, link: b"\0" }), Class(2), Instance(1)]), o_t_params: ConnectionParameters { redundant_owner: false, connection_type: P2P, variable_length: Fixed, priority: High, connection_size: 504 }, t_o_params: ConnectionParameters { redundant_owner: false, connection_type: P2P, variable_length: Fixed, priority: High, connection_size: 504 }, transport_direction: Server, transport_class: Class3, transport_trigger: Application, large_open: false }, connected_options: None, service: None, seq_id: 0 }

    read tag...EPath([Symbol("Cfg_LoSeverity")])

    Error: Custom { kind: "custom", msg: "forward open failed" }


    opened by GeneL 1
Releases(v0.3.0)
Owner
joylei
Rust, C#, Python
joylei
Backroll is a pure Rust implementation of GGPO rollback networking library.

backroll-rs Backroll is a pure Rust implementation of GGPO rollback networking library. Development Status This is still in an untested alpha stage. A

Hourai Teahouse 273 Dec 28, 2022
Pure rust mqtt cilent

NOTE: Archived. No further development under this repo. Follow progress of a different implementation here Pure rust MQTT client which strives to be s

Ather Energy Pvt Ltd 201 Dec 2, 2022
Grow Rust is a Growtopia Private Server made in Rust

Grow Rust is a Growtopia Private Server made in Rust

null 14 Dec 7, 2022
Multiplex server for rust-analyzer, allows multiple LSP clients (editor windows) to share a single rust-analyzer instance per cargo workspace

ra-multiplex   Multiplex server for rust-analyzer, allows multiple LSP clients (editor windows) to share a single rust-analyzer instance per cargo wor

max 95 Dec 29, 2022
Rust crate for configurable parallel web crawling, designed to crawl for content

url-crawler A configurable parallel web crawler, designed to crawl a website for content. Changelog Docs.rs Example extern crate url_crawler; use std:

Pop!_OS 56 Aug 22, 2021
Rust crate for scraping URLs from HTML pages

url-scraper Rust crate for scraping URLs from HTML pages. Example extern crate url_scraper; use url_scraper::UrlScraper; fn main() { let director

Pop!_OS 35 Aug 18, 2022
FTP client for Rust

rust-ftp FTP client for Rust Documentation rust-ftp Installation Usage License Contribution Development environment Installation FTPS support is achie

Matt McCoy 155 Nov 12, 2022
The gRPC library for Rust built on C Core library and futures

gRPC-rs gRPC-rs is a Rust wrapper of gRPC Core. gRPC is a high performance, open source universal RPC framework that puts mobile and HTTP/2 first. Sta

TiKV Project 1.6k Jan 7, 2023
A library to work with CIDRs in rust

ipnetwork This is a library to work with IPv4 and IPv6 CIDRs in Rust Run Clippy by doing rustup component add clippy cargo clippy Installation This c

Abhishek Chanda 98 Dec 12, 2022
Network simulation in Rust

netsim - A Rust library for network simulation and testing (currently linux-only). netsim is a crate for simulating networks for the sake of testing n

Andrew Cann 115 Dec 15, 2022
Cross-platform, low level networking using the Rust programming language.

libpnet Linux ∪ OS X Build Status: Windows Build Status: Discussion and support: #libpnet on freenode / #rust-networking on irc.mozilla.org / #rust on

null 1.8k Jan 6, 2023
A runtime for writing reliable asynchronous applications with Rust. Provides I/O, networking, scheduling, timers, ...

Tokio A runtime for writing reliable, asynchronous, and slim applications with the Rust programming language. It is: Fast: Tokio's zero-cost abstracti

Tokio 18.7k Dec 30, 2022
Easy protocol definitions in Rust

protocol Documentation Easy protocol definitions in Rust. This crate adds a custom derive that can be added to types, allowing structured data to be s

Dylan McKay 157 Dec 30, 2022
Actor framework for Rust.

Actix Actor framework for Rust Documentation User Guide API Documentation API Documentation (master branch) Features Async and sync actors Actor commu

Actix 7.6k Jan 7, 2023
Nanomsg library for Rust

Nanomsg Documentation Nanomsg is a modern messaging library that is the successor to ZeroMQ, written in C by Martin Sustrik and colleagues. The nanoms

Daniel Fagnan 371 Nov 18, 2022
NNTP client for Rust

rust-nntp NNTP Client for Rust Usage extern crate nntp; use nntp::{Article, NNTPStream}; fn main() { let mut nntp_stream = match NNTPStream::connec

Matt McCoy 13 Jan 22, 2022
POP3 client for Rust

rust-pop3 POP3 Client for Rust This client has SSL support. SSL is configured using an SSLContext that is passed into the connect method of a POP3Stre

Matt McCoy 26 Dec 19, 2022
Rust bindings for libssh2

ssh2-rs Documentation Rust bindings to libssh2, an ssh client library. Usage # Cargo.toml [dependencies] ssh2 = "0.9" Building on OSX 10.10+ This libr

Alex Crichton 366 Dec 30, 2022
A STOMP client in Rust. Compatible with RabbitMQ, ActiveMQ.

stomp-rs stomp-rs provides a full STOMP 1.2 client implementation for the Rust programming language. This allows programs written in Rust to interact

Zack Slayton 84 Dec 4, 2022