@@ -7,37 +7,47 @@ use tokio::net::TcpStream;
77
88use super :: { Connectable , ConnectionManagement , EthernetIpClient } ;
99
10+ /// Shared helper for connect() and reconnect().
11+ async fn open_session ( ip : & str ) -> io:: Result < ( TcpStream , u32 ) > {
12+ let mut stream = TcpStream :: connect ( format ! ( "{ip}:44818" ) ) . await ?;
13+
14+ // Build RegisterSession packet
15+ let mut reg = EncapsulationHeader :: new ( COMMAND_REGISTER_SESSION , 4 , 0 )
16+ . to_bytes ( )
17+ . to_vec ( ) ;
18+ reg. extend_from_slice ( & 1u16 . to_le_bytes ( ) ) ;
19+ reg. extend_from_slice ( & 0u16 . to_le_bytes ( ) ) ;
20+
21+ stream. write_all ( & reg) . await ?;
22+
23+ // Read 24‑byte header
24+ let mut h_buf = [ 0u8 ; 24 ] ;
25+ stream. read_exact ( & mut h_buf) . await ?;
26+ let hdr = EncapsulationHeader :: from_bytes ( & h_buf)
27+ . ok_or ( io:: Error :: other ( "Handshake failed: invalid header" ) ) ?;
28+
29+ if hdr. status != 0 {
30+ return Err ( io:: Error :: other ( format ! (
31+ "RegisterSession failed with status 0x{:04X}" ,
32+ hdr. status
33+ ) ) ) ;
34+ }
35+
36+ // Read protocol version + options
37+ let mut s_buf = [ 0u8 ; 4 ] ;
38+ stream. read_exact ( & mut s_buf) . await ?;
39+
40+ Ok ( ( stream, hdr. session ) )
41+ }
42+
1043#[ async_trait:: async_trait]
1144impl Connectable for EthernetIpClient {
1245 async fn connect ( ip : & str ) -> io:: Result < Self > {
13- let mut stream = TcpStream :: connect ( format ! ( "{ip}:44818" ) ) . await ?;
14-
15- let mut reg = EncapsulationHeader :: new ( COMMAND_REGISTER_SESSION , 4 , 0 )
16- . to_bytes ( )
17- . to_vec ( ) ;
18- reg. extend_from_slice ( & 1u16 . to_le_bytes ( ) ) ;
19- reg. extend_from_slice ( & 0u16 . to_le_bytes ( ) ) ;
20-
21- stream. write_all ( & reg) . await ?;
22-
23- let mut h_buf = [ 0u8 ; 24 ] ;
24- stream. read_exact ( & mut h_buf) . await ?;
25- let hdr = EncapsulationHeader :: from_bytes ( & h_buf)
26- . ok_or ( io:: Error :: other ( "Handshake failed: invalid header" ) ) ?;
27-
28- if hdr. status != 0 {
29- return Err ( io:: Error :: other ( format ! (
30- "RegisterSession failed with status 0x{:04X}" ,
31- hdr. status
32- ) ) ) ;
33- }
34-
35- let mut s_buf = [ 0u8 ; 4 ] ;
36- stream. read_exact ( & mut s_buf) . await ?;
46+ let ( stream, session) = open_session ( ip) . await ?;
3747
3848 Ok ( Self {
3949 stream,
40- session : hdr . session ,
50+ session,
4151 slot : None ,
4252 connection_id : None ,
4353 sequence : 1 ,
@@ -82,33 +92,9 @@ impl ConnectionManagement for EthernetIpClient {
8292
8393impl EthernetIpClient {
8494 pub ( crate ) async fn reconnect ( & mut self ) -> io:: Result < ( ) > {
85- let mut stream = TcpStream :: connect ( format ! ( "{}:44818" , self . ip) ) . await ?;
86-
87- let mut reg = EncapsulationHeader :: new ( COMMAND_REGISTER_SESSION , 4 , 0 )
88- . to_bytes ( )
89- . to_vec ( ) ;
90- reg. extend_from_slice ( & 1u16 . to_le_bytes ( ) ) ;
91- reg. extend_from_slice ( & 0u16 . to_le_bytes ( ) ) ;
92-
93- stream. write_all ( & reg) . await ?;
94-
95- let mut h_buf = [ 0u8 ; 24 ] ;
96- stream. read_exact ( & mut h_buf) . await ?;
97- let hdr = EncapsulationHeader :: from_bytes ( & h_buf)
98- . ok_or ( io:: Error :: other ( "Handshake failed: invalid header" ) ) ?;
99-
100- if hdr. status != 0 {
101- return Err ( io:: Error :: other ( format ! (
102- "RegisterSession failed with status 0x{:04X}" ,
103- hdr. status
104- ) ) ) ;
105- }
106-
107- let mut s_buf = [ 0u8 ; 4 ] ;
108- stream. read_exact ( & mut s_buf) . await ?;
109-
95+ let ( stream, session) = open_session ( & self . ip ) . await ?;
11096 self . stream = stream;
111- self . session = hdr . session ;
97+ self . session = session;
11298 Ok ( ( ) )
11399 }
114100}
0 commit comments