Class LgxProbe

  • All Implemented Interfaces:
    CipReplyConsumer

    public class LgxProbe
    extends java.lang.Object
    implements CipReplyConsumer
    Implementation of Rockwell's Data Access manual's tag discovery process. With helpers to construct the various requests and to process responses. The entire probe process is kicked off by supplying a UCMM message processor instance and a route path. A CompletableFuture delivers the results.

    The manual describing the tag discovery process, data type decoding, and the tag read/write services is publicly available:

    Note that Micro8xx controllers implement the global tag enumeration part of this procedure, without any support for the GetAttributeList service or templates. GetAttributeSingle is supported, but only for Class Attributes of Symbol Class 0x6b. That means dimensions for controller tags must be obtained during the GetInstanceAttributeList sequence.

    While not declared, Micro8xx controllers permit tag accesses to items that aren't enumerated by this procedure, using normal encodings of ANSI symbols and member segments in the application path. Only leaf nodes of structures and arrays are accessible.

    The manual describing Micro8xx support (appendix D in particular) is also publicly available:

    Progress Listeners may be attached before probe start and will be called as each complete query is received (except the last). The progress object points to the results obtained to that point.

    The procedure may be tweaked to exclude system tags/types and/or exclude program tags. The tag enumeration pass can also be tweaked to obtain tag attributes 3, 5, 7, 10, and 11. These options are set in the constructor.

    After probe completion, this object may be used to construct tag read and write requests and decode their responses.

    • Field Detail

      • sLogger

        public static final org.slf4j.Logger sLogger
      • tags

        protected java.util.Map<java.lang.Integer,​java.util.Map<java.lang.Integer,​LgxProbeReport.LgxProbedTag>> tags
        Contains all tags and tag-like objects returned in a GIAL response from the target's Symbol Class. The outer map is the instance of the program object within the Symbol Class, or zero for global tags.
      • programs

        protected java.util.Map<java.lang.Integer,​LgxProbeReport.LgxProbedProgram> programs
        Contains all tag-like objects returned in a GIAL response from the target's Symbol class that refer to Programs. Programs must be probed with an addition GIAL sequence to identify Program-local tags.
      • incompleteTags

        protected java.util.Map<java.lang.Integer,​java.util.Set<LgxProbeReport.LgxProbedTag>> incompleteTags
        While probing, contains those tags that reported any array dimensions that have not yet been retrieved.
      • programGALs

        protected java.util.LinkedList<GetAttrListReq> programGALs
        While probing controller tags, construct GALs to obtain the max instance number of any programs encountered, so all program tag scans can show progress.
      • incompletePrograms

        protected java.util.Set<LgxProbeReport.LgxProbedProgram> incompletePrograms
        While probing, contains those programs that have not been scanned for program-local tags.
      • neededTypes

        protected java.util.Set<java.lang.Integer> neededTypes
        While probing, holds structure IDs that are used by any tag or other template member but are not yet probed.
      • incompleteTypes

        protected java.util.Set<LgxProbeReport.LgxProbedType> incompleteTypes
        While probing, hold types that have had their basic attributes retrieved, but do not yet have a recursively complete member list.
      • types

        protected java.util.Map<java.lang.Integer,​LgxProbeReport.LgxProbedType> types
        Contains all structured types that have at least their basic attributes.
      • strictTags

        public final boolean strictTags
        Scan settings.
      • scanPrograms

        public final boolean scanPrograms
      • verbose

        public final boolean verbose
      • attrsGIAL

        protected final int[] attrsGIAL
      • idxA35

        protected final int idxA35
      • idxA7

        protected final int idxA7
      • idxA8

        protected final int idxA8
      • idxA9

        protected final int idxA9
      • idxA1011

        protected final int idxA1011
      • route

        protected transient CipPath route
      • capacity

        protected transient int capacity
      • tplReadClip

        protected transient int tplReadClip
      • future

        protected transient java.util.concurrent.CompletableFuture<LgxProbeReport> future
      • sender

        protected transient java.lang.Thread sender
      • requestQueue

        protected transient java.util.concurrent.LinkedBlockingDeque<CipRequest> requestQueue
      • log

        protected transient java.io.StringWriter log
      • changeManagement

        protected transient int[] changeManagement
      • doSymbolGAL0

        protected transient boolean doSymbolGAL0
      • checkMicro8xx

        protected transient boolean checkMicro8xx
      • lastInstance

        protected transient int lastInstance
      • maxInstance

        protected transient int maxInstance
      • receivedCount

        protected transient int receivedCount
      • abort

        protected transient volatile boolean abort
      • abortEqual

        protected transient volatile boolean abortEqual
      • skipChgManagement

        protected transient LgxProbeReport skipChgManagement
      • Micro8xxMaxInst

        public static CipPath Micro8xxMaxInst
      • Micro8xxChgMgmt

        public static CipPath Micro8xxChgMgmt
    • Constructor Detail

      • LgxProbe

        public LgxProbe()
        Common options for common modern Logix processors.
      • LgxProbe

        public LgxProbe​(boolean verbose)
        Get everything possible, optionally verbose.
        Parameters:
        verbose -
      • LgxProbe

        public LgxProbe​(boolean strictTags,
                        boolean scanPrograms,
                        boolean allTypes,
                        boolean verbose,
                        boolean getA35,
                        boolean getA7,
                        boolean deferA8,
                        boolean getA9,
                        boolean getA1011)
        An instance of this class manages the series of requests need to obtain tag names and datatype details from a Logix processor, using the procedure documented in the public Data Access Manual:

        Probing doesn't start until the .start() method is called, supplying a UCMM and a route path. Callers should attach a listener, if desired, before calling .start(). If any listener is attached, the log will be delivered piecemeal with the interim reports.

        Parameters:
        strictTags - When scanning, strictly discard tags as directed in the Data Access Manual. When false, all non-tag elements other than Programs will be included in the reported lists of tags.
        scanPrograms - When scanning controller tags, capture the entries for Programs, and then scan them for tags, too.
        allTypes - Instead of scanning only template types used by tags, probe all 4095 instance numbers.
        verbose - Log all requests sent and replies received.
        getA35 - Include address attributes 3 and 5 in the tag enumeration.
        getA7 - Include element size attribute 7 in the tag enumeration.
        deferA8 - Omit array dimensions from tag enumeration. Tags with dimensions will be probed with GAL seperately. Not supported by Micro8xx.
        getA9 - Include CIP Safety boolean attribute 9 in the tag enumeration.
        getA1011 - Include attributes 10 and 11 in the tag enumeration to determine if the tag is readonly.
    • Method Detail

      • setSkipChgMgmt

        public void setSkipChgMgmt​(LgxProbeReport priorReport)
        The probe sequence can be terminated early when the request for the change management information yields the same value(s) as recorded in the report supplied here. If there's a match, the report given here is delivered to the CompletableFuture instead of a new report.

        ControlLogix and CompactLogix use an array of five values. Micro8xx uses a single value.

        Parameters:
        priorReport - Complete previous report to compare against.
      • addLog

        protected void addLog​(java.lang.String s)
      • logException

        protected void logException​(java.lang.Throwable t)
      • conditionalLogException

        protected boolean conditionalLogException​(CipReply reply)
      • resetLog

        protected java.lang.String resetLog()
      • start

        public java.util.concurrent.CompletableFuture<LgxProbeReport> start​(CipMsgProcessor mp,
                                                                            CipPath route)
        Actual message traffic begins when an UnConnected Message Manager port is supplied, along with a route path to the target processor (through the port). Execution proceeds asynchronously via a dedicated thread.

        Progress reports are delivered to listeners as responses are received, except when assembling fragments of a data type template definition.

        Parameters:
        mp - This message processor instance must be a UnConnected Message Manager. Typically, it will be an instance of TcpConx, though it could also be an implementation of AbstractPort.
        route - The route may be null or empty if connecting to a target processor's built-in ethernet port.
        Returns:
        The completable future that will receive the final LgxProbeReport. Use of the .whenComplete() method to attach a handler is recommended.
      • makeGIAL

        protected CipRequest makeGIAL​(java.lang.String program,
                                      int instance)
      • makeTemplateRead

        protected CipRequest makeTemplateRead​(CipPath target,
                                              int offset,
                                              int targetLen)
      • determineNext

        protected CipRequest determineNext()
      • _accept

        protected void _accept​(CipReply reply)
      • handleGIAL

        protected CipRequest handleGIAL​(CipReply reply,
                                        CipRequest req)
        Get Instance Attribute List Service is only used to read tag names/symbol type codes from the Symbol Class (0x6b). Per the Logix Data Access manual. It can have large responses, so is never placed in a multiple-service request. It can report error code 6 along with a payload when more records are available after the last instance in the payload.

        When processing program tags, any error other than code 6 will remove the program from the set of incomplete programs.

        This routine is only called from the outermost .accept() method.

        Parameters:
        reply - The complete reply object, typically with payload.
        req - The original request object. Used to distinguish between queries against the list of controller tags versus against a particular program's tags.
        Returns:
        A continuation request if this reply was code 6. Null if the list is complete.
      • handleTemplateRead

        protected CipRequest handleTemplateRead​(CipReply reply,
                                                CipRequest req)
        Template Read Service is only used to read data type details (name, members) from the Template Class (0x6c). Per the Logix Data Access manual. It can have large responses, so is never placed in a multiple-service request. It can report error code 6 along with a payload when more bytes are available beyond the end of the payload.

        Any error other than code 6 will remove the data type from the set of incomplete types.

        This routine is only called from the outermost .accept() method.

        Parameters:
        reply - The complete reply object, typically with payload.
        req - The original request object. Used to recover the byte offset into definition and the definition length requested. The latter may be less than the ideal in some cases (reduced for certain errors).
        Returns:
        A continuation request if this reply was code 6. Null if the data type is complete.
      • handleGAL

        protected CipRequest handleGAL​(CipReply reply,
                                       CipRequest req)
        The Get Attribute List service is used to obtain array dimensions of tags and to obtain critical attributes of data types. All of its uses have known reply sizes, so can be combined efficiently into multiple service requests.

        The scan algorithm can yield a solo GAL to send directly to the UCMM, so this routine may be called by the primary .accept() method or by the CipReplyConsumer dedicated to requests embedded in a multiple service request.

        Parameters:
        reply -
        req -