Joylei / eip-rs

rseip - EIP&CIP client in pure Rust, for generic CIP and AB PLC
MIT License
49 stars 6 forks source link

Apply connection size restriction #4

Closed Joylei closed 2 years ago

GeneL commented 2 years ago

Hi Joylei, Great library! Could you provide examples to read a LARGE structured tag (>500) and list USER DEFINED structure types including the ones > 500. Thank you in advance, Eugene Liberman.

Joylei commented 2 years ago

@GeneL

The library is able to list UDT for you automatically. You do not need to do additional works. Please check the examples in the repository.

For large structured tag, I think you have 2 options.

const CONNECTION_SIZE:u16=2000;
let opts = OpenOptions::default().connection_size(CONNECTION_SIZE).large_open(true);
let mut client =
    AbEipConnection::new_host_lookup("YOUR_DEVICE_IP", opts).await?;
GeneL commented 2 years ago

Thank you for a quick response! I can read UDT and their components for a small UDT size, but it did not work for me to get components of LARGE UDTs. Can you provide a code example for it?

Also, What is the parameter in “client.read_tag_fragmented(...)” could you provide a working example where I can enter tag name and IP address?


From: joylei @.> Sent: Wednesday, February 23, 2022 2:37 AM To: Joylei/eip-rs @.> Cc: Eugene Liberman @.>; Mention @.> Subject: EXTERNAL: Re: [Joylei/eip-rs] Apply connection size restriction (Issue #4)

[Use caution with links & attachments]

@GeneLhttps://urldefense.com/v3/__https://github.com/GeneL__;!!JhrIYaSK6lFZ!5Jzh9IA58HGQtYmbr9vyOzmu5a8CpDSFhbeuPg90iMPBRJoh_AqkSnbJI7FUeUecN2iN$

The library is able to list UDT for you automatically. You do not need to do additional works. Please check the examples in the repository.

For large structured tag, I think you have 2 options.

const CONNECTION_SIZE:u16=2000; let opts = OpenOptions::default().connection_size(CONNECTION_SIZE).large_open(true); let mut client = AbEipConnection::new_host_lookup("YOUR_DEVICE_IP", opts).await?;

let mut buf = BytesMut::new(); let total:u16 = ...; loop { let (hasmore, value): (,TagValue) = client.read_tag_fragmented(...) .total(total).offset(buf.len()) .call().await; let bytes = value.value; buf.put_slice(&bytes[...]); if !has_more { break; } } // decode your tag data from buf

check source codehttps://urldefense.com/v3/__https://github.com/Joylei/eip-rs/blob/fe066a50b097da8b3682eca4d705bf1f385c6ec0/src/client/ab_eip/value.rs__;!!JhrIYaSK6lFZ!5Jzh9IA58HGQtYmbr9vyOzmu5a8CpDSFhbeuPg90iMPBRJoh_AqkSnbJI7FUeay2izCo$ for how to decode.

— Reply to this email directly, view it on GitHubhttps://urldefense.com/v3/__https://github.com/Joylei/eip-rs/issues/4*issuecomment-1048514044__;Iw!!JhrIYaSK6lFZ!5Jzh9IA58HGQtYmbr9vyOzmu5a8CpDSFhbeuPg90iMPBRJoh_AqkSnbJI7FUeUFmIyst$, or unsubscribehttps://urldefense.com/v3/__https://github.com/notifications/unsubscribe-auth/AAHCUP4MRGJGO5OL32LOYT3U4SFCJANCNFSM5G64VRFA__;!!JhrIYaSK6lFZ!5Jzh9IA58HGQtYmbr9vyOzmu5a8CpDSFhbeuPg90iMPBRJoh_AqkSnbJI7FUeSI5YVKl$. Triage notifications on the go with GitHub Mobile for iOShttps://urldefense.com/v3/__https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675__;!!JhrIYaSK6lFZ!5Jzh9IA58HGQtYmbr9vyOzmu5a8CpDSFhbeuPg90iMPBRJoh_AqkSnbJI7FUeZE2dG3C$ or Androidhttps://urldefense.com/v3/__https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign*3Dnotification-email*26utm_medium*3Demail*26utm_source*3Dgithub__;JSUlJSU!!JhrIYaSK6lFZ!5Jzh9IA58HGQtYmbr9vyOzmu5a8CpDSFhbeuPg90iMPBRJoh_AqkSnbJI7FUeZPMmbg2$. You are receiving this because you were mentioned.Message ID: @.***>

Joylei commented 2 years ago

let me do a little testing

Joylei commented 2 years ago

One possible solution is read your UDT's members separately.

and Let me try read_tag_fragmented.

Joylei commented 2 years ago

list tag and type definition

let's say you list tags

...
Ok(SymbolInstance { id: 0x6d10, name: "test_frag", symbol_type: SymbolType { type: "struct", dims: 0, instance_id: 0xa82 } })
...

the template instance id is 0xa82. Then you read the template for 0xa82:

template instance:
Template { instance_id: 2690, handle: 34287, member_count: 16, object_size: 117, struct_size: 1408 }
template definition:
TemplateDefinition { name: "frag", members: {"long_name_long_2": MemberInfo { name: "long_name_long_2", array_size: 0, type_info: SymbolType { type: "struct", dims: 0, instance_id: 0xfce }, offset: 88 }, "long_name_long_3": MemberInfo { 
name: "long_name_long_3", array_size: 0, type_info: SymbolType { type: "struct", dims: 0, instance_id: 0xfce }, offset: 176 }, "long_name_long_4": MemberInfo { name: "long_name_long_4", array_size: 0, type_info: SymbolType { type: "struct", dims: 0, instance_id: 0xfce }, offset: 264 }, "long_name_long_6": MemberInfo { name: "long_name_long_6", array_size: 0, type_info: SymbolType { type: "struct", dims: 0, instance_id: 0xfce }, offset: 440 }, "long_name_long_12": MemberInfo { name: "long_name_long_12", array_size: 0, type_info: SymbolType { type: "struct", dims: 0, instance_id: 0xfce }, offset: 968 }, "long_name_long_1": MemberInfo { name: "long_name_long_1", array_size: 0, type_info: SymbolType { type: "struct", dims: 0, instance_id: 0xfce }, offset: 0 }, "long_name_long_8": MemberInfo { name: "long_name_long_8", array_size: 0, type_info: SymbolType { type: "struct", dims: 0, instance_id: 0xfce }, offset: 616 }, "long_name_long_14": 
MemberInfo { name: "long_name_long_14", array_size: 0, type_info: SymbolType { type: "struct", dims: 0, instance_id: 0xfce }, offset: 1144 }, "long_name_long_15": MemberInfo { name: "long_name_long_15", array_size: 0, type_info: SymbolType { type: "struct", dims: 0, instance_id: 0xfce }, offset: 1232 }, "long_name_long_5": MemberInfo { name: "long_name_long_5", array_size: 0, type_info: SymbolType { type: "struct", dims: 0, instance_id: 0xfce }, offset: 352 }, "long_name_long_11": MemberInfo { name: "long_name_long_11", array_size: 0, type_info: SymbolType { type: "struct", dims: 0, instance_id: 0xfce }, offset: 880 }, "long_name_long_7": MemberInfo { name: "long_name_long_7", array_size: 0, type_info: SymbolType { type: "struct", dims: 0, instance_id: 0xfce }, offset: 528 }, "long_name_long_13": MemberInfo { name: "long_name_long_13", array_size: 0, type_info: SymbolType { type: "struct", dims: 0, instance_id: 0xfce }, offset: 1056 }, "long_name_long_16": MemberInfo { name: "long_name_long_16", array_size: 0, type_info: SymbolType { type: "struct", dims: 0, instance_id: 0xfce }, offset: 1320 }, "long_name_long_9": MemberInfo { name: "long_name_long_9", array_size: 0, type_info: SymbolType { type: "struct", dims: 0, instance_id: 0xfce }, offset: 704 }, "long_name_long_10": MemberInfo { name: "long_name_long_10", array_size: 0, type_info: SymbolType { type: "struct", dims: 0, instance_id: 0xfce }, offset: 792 }} }

The template structure_size indicates how large the instance of the template will be.

read UDT's members separately

let mut res:BigUdt = ...;

//member1
let tag= EPath::parse_tag("test_frag.long_name_long_1")?;
let value: TagValue<i32> = client.read_tag(tag).await?;
res.member1 = value.value;

//member2
let tag= EPath::parse_tag("test_frag.long_name_long_2")?;
let value: TagValue<i32> = client.read_tag(tag).await?;
res.member2 = value.value;

//other members...

To be more efficient, you can try multiple service packet service.

Joylei commented 2 years ago

I've got read_tag_fragmented working. I will publish a new version soon. I'm closing the issue. If you have issues or questions, please open new issues.