def logix_remote( count, svraddr, kwargs ): try: time.sleep(.25) # Wait for server to be established # Confirm that a known Register encodes as expected data = cpppo.dotdict() data.enip = {} data.enip.options = 0 data.enip.session_handle = 0 data.enip.status = 0 data.enip.sender_context = {} data.enip.sender_context.input = bytearray( [0x00] * 8 ) data.enip.CIP = {} data.enip.CIP.register = {} data.enip.CIP.register.options = 0 data.enip.CIP.register.protocol_version = 1 data.enip.input = bytearray( enip.CIP.produce( data.enip )) data.input = bytearray( enip.enip_encode( data.enip )) log.normal( "Register Request: %r" % data ) assert bytes( data.input ) == rss_004_request # Try to Register a real session, followed by commands timeout = 5 begun = cpppo.timer() cli = client.client( host=svraddr[0], port=svraddr[1] ) assert cli.writable( timeout=timeout ) elapsed = cpppo.timer() - begun log.normal( "Client Connected in %7.3f/%7.3fs" % ( elapsed, timeout )) begun = cpppo.timer() with cli: cli.register( timeout=timeout ) data,elapsed = client.await_response( cli, timeout=timeout ) log.normal( "Client Register Rcvd %7.3f/%7.3fs: %r", elapsed, timeout, data ) assert data is not None and 'enip.CIP.register' in data, "Failed to receive Register response" assert data.enip.status == 0, "Register response indicates failure: %s" % data.enip.status # Establish the EtherNet/IP "session handle" used by all further requests cli.session = data.enip.session_handle start = cpppo.timer() with cli: for _ in range( count ): begun = cpppo.timer() cli.read( path=[{'symbolic': 'SCADA'}, {'element': 12}], elements=201, offset=2, timeout=timeout ) data,elapsed = client.await_response( cli, timeout=timeout ) log.normal( "Client ReadFrg. Rcvd %7.3f/%7.3fs: %r", elapsed, timeout, data ) duration = cpppo.timer() - start log.warning( "Client ReadFrg. Average %7.3f TPS (%7.3fs ea)." % ( count / duration, duration / count )) log.normal( "Signal shutdown w/ server.control in object %s", id( kwargs['server']['control'] )) finally: kwargs['server']['control'].done= True # Signal the server to terminate
def test_list_interfaces_udp(self): with client.connector(host=self.enip_server_udp.addr, port=self.enip_server_udp.port, timeout=4.0, udp=True, broadcast=True) as conn: conn.list_interfaces() # TODO: udp does not cleanly shutdown. We get OSError. while True: response, ela = client.await_response(conn, timeout=4.0) if response: self.assertDictEqual( {'count': 0}, response['enip']['CIP']['list_interfaces']['CPF']) else: break
def test_list_interfaces_tcp(self): with client.connector(host=self.enip_server_tcp.addr, port=self.enip_server_tcp.port, timeout=4.0, udp=False, broadcast=False) as conn: conn.list_interfaces() conn.shutdown() while True: response, ela = client.await_response(conn, timeout=4.0) if response: self.assertDictEqual( {'count': 0}, response['enip']['CIP']['list_interfaces']['CPF']) else: break
def test_list_identity_udp(self): with client.connector(host=self.enip_server_udp.addr, port=self.enip_server_udp.port, timeout=4.0, udp=True, broadcast=True) as connection: connection.list_identity() # TODO: udp does not cleanly shutdown. We get OSError. while True: response, ela = client.await_response(connection, timeout=4.0) if response: expected = self.enip_server_tcp.config.product_name self.assertEqual( expected, response['enip']['CIP']['list_identity'] ['CPF']['item'][0]['identity_object']['product_name']) else: break
def test_list_services_tcp(self): # test tcp with client.connector(host=self.enip_server_tcp.addr, port=self.enip_server_tcp.port, timeout=4.0, udp=False, broadcast=False) as connection: connection.list_services() connection.shutdown() while True: response, ela = client.await_response(connection, timeout=4.0) if response: self.assertEqual( "Communications", response['enip']['CIP']['list_services']['CPF']['item'] [0]['communications_service']['service_name']) else: break
def test_list_identity_tcp(self): # test tcp with client.connector(host=self.enip_server_tcp.addr, port=self.enip_server_tcp.port, timeout=4.0, udp=False, broadcast=False) as connection: connection.list_identity() connection.shutdown() while True: response, ela = client.await_response(connection, timeout=4.0) if response: expected = self.enip_server_tcp.config.product_name self.assertEqual( expected, response['enip']['CIP']['list_identity'] ['CPF']['item'][0]['identity_object']['product_name']) else: break
def test_list_services_udp(self): # test udp with client.connector(host=self.enip_server_udp.addr, port=self.enip_server_udp.port, timeout=4.0, udp=True, broadcast=True) as connection: connection.list_services() # TODO: udp does not cleanly shutdown. We get OSError. while True: response, ela = client.await_response(connection, timeout=4.0) if response: self.assertEqual( "Communications", response['enip']['CIP']['list_services']['CPF']['item'] [0]['communications_service']['service_name']) else: break
def list_identity(address=('255.255.255.255', enip.address[1]), broadcast=True, timeout=1.0, udp=True): """Yields a sequence of 0 or more List Identity responses from the target IP or Broadcast (address,port) address. Defaults to UDP/IP. """ with client.client(host=address[0], port=address[1], broadcast=broadcast, udp=udp) as conn: begin = cpppo.timer() conn.list_identity(timeout=timeout) while True: used = cpppo.timer() - begin response, elapsed = client.await_response(conn, timeout=max( 0, timeout - used)) if not response: break # No response (None) w'in timeout or EOF ({}) yield response
# path = [ # # {'symbolic': 'A63FGRDT'}, # {'class':1}, {'instance':1},# {'attribute':7}, # ] ) else: route_path, send_path = None, None # Routed (eg. C*Logix) #route_path, send_path = defaults.route_path_default, defaults.send_path_default connection = client.connector( host = hostname, timeout = timeout, sender_context = sender_context, ) with connection as conn: data = True while True: # Perform some I/O on the Connected channel begun = cpppo.timer() operations = client.parse_operations( params, route_path=route_path, send_path=send_path ) failed,txs = conn.process( operations=operations, depth=depth, multiple=multiple, fragment=fragment, printing=printing, timeout=timeout ) elapsed = cpppo.timer() - begun # Now, wait for spontaneous data data,elapsed = client.await_response( conn, timeout=1 ) if data: log.normal( "Received: {data!r}".format( data=data ))
def await_cpf_response(connection, command): response, _ = client.await_response(connection, timeout=4.0) return response["enip"]["CIP"][command]["CPF"]
def await_cpf_response(connection, command): response, _ = client.await_response(connection, timeout=4.0) return response['enip']['CIP'][command]['CPF']
addr = args.address.split(':') assert 1 <= len( addr ) <= 2, "Invalid --address [<interface>]:[<port>}: %s" % args.address addr = ( str( addr[0] ) if addr[0] else enip.address[0], int( addr[1] ) if len( addr ) > 1 and addr[1] else enip.address[1] ) timeout = float( args.timeout ) failures = 0 try: with client.connector( host=addr[0], port=addr[1], timeout=timeout, udp=args.udp, broadcast=args.broadcast, source_address=args.source_address ) as connection: connection.list_services() if args.list_identity: connection.list_identity() if args.list_interfaces: connection.list_interfaces() connection.shutdown() # starts a client-initiated clean shutdown for TCP/IP while True: response,ela = client.await_response( connection, timeout=timeout ) if response: print( enip.enip_format( response )) else: break # No response (None) w'in timeout or EOF ({}) except Exception as exc: failures = 1 logging.warning( "Failed to receive List Services reply: %s\n%s", exc, traceback.format_exc() ) sys.exit( 1 if failures else 0 )
"""python -m cpppo.server.enip.list_identity_simple <hostname> Returns any List Identity responses from the given hostname or IP address (default: 255.255.255.255), received before timeout (default: 1.0 second) expires. """ from __future__ import absolute_import, print_function, division try: from future_builtins import zip, map # Use Python 3 "lazy" zip, map except ImportError: pass import sys from cpppo.server import enip from cpppo.server.enip import client timeout = 1.0 host = sys.argv[1] if sys.argv[1:] else '255.255.255.255' with client.client( host=host, udp=True, broadcast=True ) as conn: conn.list_identity( timeout=timeout ) while True: response,elapsed= client.await_response( conn, timeout=timeout ) if response: print( enip.enip_format( response )) else: break # No response (None) w'in timeout or EOF ({})