$SCRDR over TCP

When the SpringCore device is configured for Smart Reader mode + $SCRDR over TCP, it accepts the host as a TCP client (the device is TCP server). Once the host is connected, the device sends $SCRDR Messages and accepts READER COMMAND Messages over the TCP channel.

IMPORTANT NOTE: The SpringCore device running as a TCP Server can accept only one TCP Client at a time.

Configuration checklist

  • Define the IPv4 configuration of the device in register 0280. Leave this register empty to get the configuration from DHCP.
  • Set register 02C0 to 24 (TCP server, Smart Reader operation)
  • Set register 02A0 to 00xxxx01xx (SCRDR format over the Network link)
  • (Optionaly) define the Port for UDP and TCP servers in register 0285. Default port is 4000.

Sample host software

Use the following Python script as a reference for using the Smart Reader with configuration $SCRDR over TCP.

The script does the following:

  • Connect to the Smart Reader device specified using the --addr= parameter (provide the IP address of the device, or its hostname if it has been registered in your DNS system),
  • Wait for incoming messages and display them
  • If the --wink, --accept or --deny parameters have been set, send back the corresponding sequence command to the device.
# libraries import
from threading import Thread, Event
import logging
import socket
import getopt
import sys
import os


# helpers import
from helpers.ctrlccatcher import CtrlCCatcher


# display_help function
def display_help( script_name ):

    print( script_name )
    print( "[--addr=<addr>]                 Address of the target device" )
    print( "[--port=<port>]                 TCP port on the target device (default: 4000)" )
    print( "[--wink]                        Send wink message in reply to every incoming message" )
    print( "[--accept]                      Send accept message in reply to every incoming message" )
    print( "[--deny]                        Send deny message in reply to every incoming message" )
    sys.exit()


# main function  
def main( script_name, argv ):
    
    # default settings
    port = 4000
    addr = ""
    reply = False

    # options parsing
    try:
        opts, _ = getopt.getopt(argv,"h",[ "help", "addr=", "ip=", "port=", "nolog", "logtofile", "wink", "accept", "deny" ])
    except getopt.GetoptError as e:
        print(e)
        display_help( script_name )

    for opt, arg in opts:
        if opt in ( "-h", "--help"):
            display_help( script_name )
        elif opt == "--addr":
            addr = str(arg)
        elif opt == "--ip":
            addr = str(arg)
        elif opt == "--port":                
            try:
                port = int(arg)
            except ValueError:
                print( "Port must be an integer number!" )
                sys.exit()
        elif opt == "--wink":
            reply = b"$SCCMD;SEQ=0E"                
        elif opt == "--accept":
            reply = b"$SCCMD;SEQ=60"
        elif opt == "--deny":
            reply = b"$SCCMD;SEQ=61"

    if addr == "":
        print( "Server IP address must be specified!" )
        sys.exit()       

    # set logging options
    logging.basicConfig(level=logging.DEBUG)

    # CTRL+C catcher thread (this could be useful on some Windows platforms)
    ctrlccatch = CtrlCCatcher()
    ctrlccatch.start()

    # Create a TCP/IP socket
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)    
    sock.setblocking(0)
    sock.settimeout(0.5)

    # TCP mode, try to connect to our SCRDR server
    logging.info( f"connecting to {addr} port {port}" )
    try:
        # try to connect to this server
        sock.connect( ( addr, port ) )
        logging.info( f"connected, use Ctrl+C to exit" )
        # look for CTRL+C
        while ctrlccatch.wait():
            try:
                # wait for new data
                data, address = sock.recvfrom(512)
                if data:
                    data = data.decode( "ascii" )
                    logging.info( data )
                    if reply:
                        logging.info( "Sending reply: " + str(reply) )
                        sock.send( reply )                    
            except socket.timeout:
                pass
    
    except socket.timeout:
        logging.info( "Can't connect to this server..." )

    # stop all process and exit
    logging.info( "Cleaning..." )
    ctrlccatch.terminate()
    ctrlccatch.join()
    logging.info( "Done." )


# entry point
if __name__ == "__main__":
    # add "this script" folder to the library search path
    # could be useful on Windows platform
    sys.path.append( os.path.dirname( os.path.realpath( __file__ ) ) )
  
    # start our application
    main( os.path.basename( __file__ ), sys.argv[1:] )
    
# EOF